Skip to content
Open
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,8 @@ CloseableIterator<ICitation> getAllGroupItems(IUser user, String groupId, String

void deleteLocalGroupCitations(String groupId);

void deleteFile(IUser user, String zoteroGroupId, String itemId, String documentId)
throws GroupDoesNotExistException, CannotFindCitationException, ZoteroHttpStatusException,
ZoteroConnectionException, CitationIsOutdatedException, ZoteroItemCreationFailedException;

}
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
package edu.asu.diging.citesphere.core.service.giles;

import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.HttpClientErrorException;

import edu.asu.diging.citesphere.user.IUser;

public interface IGilesConnector {

<T> ResponseEntity<T> sendRequest(IUser user, String endpoint, Class<T> returnType)
<T> ResponseEntity<T> sendRequest(IUser user, String endpoint, Class<T> returnType, HttpMethod httpMethod)
throws HttpClientErrorException;

byte[] getFile(IUser user, String fileId);

}

/**
* Deletes a document for the given user.
* @param user The user performing the document deletion.
* @param documentId The ID of the document to be deleted.
* @return The HTTP status code indicating the success or failure of the delete operation.
* @throws RestClientException if there is an issue sending the delete request to the server.
*/
HttpStatus deleteDocument(IUser user, String documentId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package edu.asu.diging.citesphere.core.service.giles;

import org.springframework.social.zotero.exception.ZoteroConnectionException;

import edu.asu.diging.citesphere.core.exceptions.CitationIsOutdatedException;
import edu.asu.diging.citesphere.core.exceptions.ZoteroHttpStatusException;
import edu.asu.diging.citesphere.core.exceptions.ZoteroItemCreationFailedException;
import edu.asu.diging.citesphere.model.bib.ICitation;
import edu.asu.diging.citesphere.model.bib.IGilesUpload;
import edu.asu.diging.citesphere.user.IUser;

public interface IGilesDeletionChecker {
void addDocumentCitationMap(IGilesUpload upload, ICitation citation, String zoteroId, IUser user);

void checkDeletion() throws ZoteroConnectionException, CitationIsOutdatedException, ZoteroHttpStatusException, ZoteroItemCreationFailedException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
Expand All @@ -29,6 +30,9 @@ public class GilesConnector implements IGilesConnector {
@Value("${giles_file_endpoint}")
private String fileEndpoint;

@Value("${giles_document_endpoint}")
private String documentEndpoint;

@Autowired
private InternalTokenManager internalTokenManager;

Expand All @@ -44,25 +48,29 @@ public void init() {
* @see edu.asu.diging.citesphere.core.service.giles.impl.IGilesConnector#sendRequest(edu.asu.diging.citesphere.user.IUser, java.lang.String, java.lang.Class)
*/
@Override
public <T> ResponseEntity<T> sendRequest(IUser user, String endpoint,Class<T> returnType) throws HttpClientErrorException {
public <T> ResponseEntity<T> sendRequest(IUser user, String endpoint,Class<T> returnType, HttpMethod httpMethod) throws HttpClientErrorException {
String token = internalTokenManager.getAccessToken(user).getValue();

HttpHeaders headers = new HttpHeaders();
headers.setBearerAuth(token);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(
headers);

return restTemplate.exchange(
gilesBaseurl + endpoint,
HttpMethod.GET, requestEntity, returnType);
httpMethod, requestEntity, returnType);
}

/* (non-Javadoc)
* @see edu.asu.diging.citesphere.core.service.giles.impl.IGilesConnector#getFile(edu.asu.diging.citesphere.user.IUser, java.lang.String)
*/
@Override
public byte[] getFile(IUser user, String fileId) {
ResponseEntity<byte[]> content = sendRequest(user, fileEndpoint.replace("{0}", fileId), byte[].class);
ResponseEntity<byte[]> content = sendRequest(user, fileEndpoint.replace("{0}", fileId), byte[].class, HttpMethod.GET);
return content.getBody();
}

@Override
public HttpStatus deleteDocument(IUser user, String documentId) {
ResponseEntity<String> response = sendRequest(user, documentEndpoint.replace("{documentId}", documentId), String.class, HttpMethod.DELETE);
return response.getStatusCode();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package edu.asu.diging.citesphere.core.service.giles.impl;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.social.zotero.exception.ZoteroConnectionException;
import org.springframework.stereotype.Component;

import edu.asu.diging.citesphere.core.exceptions.CitationIsOutdatedException;
import edu.asu.diging.citesphere.core.exceptions.ZoteroHttpStatusException;
import edu.asu.diging.citesphere.core.exceptions.ZoteroItemCreationFailedException;
import edu.asu.diging.citesphere.core.service.ICitationManager;
import edu.asu.diging.citesphere.core.service.giles.IGilesConnector;
import edu.asu.diging.citesphere.core.service.giles.IGilesDeletionChecker;
import edu.asu.diging.citesphere.core.user.IUserManager;
import edu.asu.diging.citesphere.model.bib.ICitation;
import edu.asu.diging.citesphere.model.bib.IGilesUpload;
import edu.asu.diging.citesphere.user.IUser;

@Component
@PropertySource({ "classpath:config.properties",
"${appConfigFile:classpath:}/app.properties" })
public class GilesDeletionChecker implements IGilesDeletionChecker {

@Autowired
private IUserManager userManager;

@Autowired
private ICitationManager citationManager;

@Autowired
private IGilesConnector gilesConnector;

@Value("${giles_document_deletion_check_endpoint}")
private String gilesDeletionCheckEndpoint;

private Queue<Map<String, String>> deletionQueue;

@PostConstruct
public void init() {
deletionQueue = new ConcurrentLinkedQueue<Map<String, String>>();
}

@Override
public void addDocumentCitationMap(IGilesUpload upload, ICitation citation, String zoteroId, IUser user) {
HashMap<String, String> documentCitationMap = new HashMap<String, String>();
documentCitationMap.put("documentId", upload.getDocumentId());
documentCitationMap.put("citationKey", citation.getKey());
documentCitationMap.put("userName", user.getUsername());
documentCitationMap.put("zoteroId", zoteroId);
if (!deletionQueue.contains(documentCitationMap)) {
deletionQueue.add(documentCitationMap);
}
}

@Override
@Scheduled(fixedDelay = 60000)
public void checkDeletion() throws ZoteroConnectionException, CitationIsOutdatedException, ZoteroHttpStatusException, ZoteroItemCreationFailedException {
for (Map<String, String> documentCitationMap: deletionQueue) {
String documentId = documentCitationMap.get("documentId");
String citationKey = documentCitationMap.get("citationKey");
String zoteroId = documentCitationMap.get("zoteroId");
ICitation citation = citationManager.getCitation(citationKey);
IUser user = userManager.findByUsername(documentCitationMap.get("userName"));
ResponseEntity<String> response = gilesConnector.sendRequest(user, gilesDeletionCheckEndpoint.replace("{documentId}", documentId), String.class, HttpMethod.GET);
if(response.getStatusCode().equals(HttpStatus.OK)) {
for (Iterator<IGilesUpload> gileUpload = citation.getGilesUploads().iterator(); gileUpload.hasNext();) {
IGilesUpload g = gileUpload.next();
if (g.getDocumentId() != null && g.getDocumentId().equals(documentId)) {
gileUpload.remove();
}
}
citationManager.updateCitation(user, zoteroId, citation);
deletionQueue.remove(documentCitationMap);
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
Expand All @@ -18,6 +19,7 @@
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.util.CloseableIterator;
import org.springframework.http.HttpStatus;
import org.springframework.social.zotero.api.ZoteroUpdateItemsStatuses;
import org.springframework.social.zotero.exception.ZoteroConnectionException;
import org.springframework.stereotype.Service;
Expand All @@ -37,12 +39,15 @@
import edu.asu.diging.citesphere.core.service.ICitationManager;
import edu.asu.diging.citesphere.core.service.ICitationStore;
import edu.asu.diging.citesphere.core.service.IGroupManager;
import edu.asu.diging.citesphere.core.service.giles.IGilesConnector;
import edu.asu.diging.citesphere.core.service.giles.IGilesDeletionChecker;
import edu.asu.diging.citesphere.core.zotero.IZoteroManager;
import edu.asu.diging.citesphere.data.bib.CitationGroupRepository;
import edu.asu.diging.citesphere.data.bib.ICitationDao;
import edu.asu.diging.citesphere.model.bib.ICitation;
import edu.asu.diging.citesphere.model.bib.ICitationCollection;
import edu.asu.diging.citesphere.model.bib.ICitationGroup;
import edu.asu.diging.citesphere.model.bib.IGilesUpload;
import edu.asu.diging.citesphere.model.bib.ItemType;
import edu.asu.diging.citesphere.model.bib.impl.BibField;
import edu.asu.diging.citesphere.model.bib.impl.CitationGroup;
Expand Down Expand Up @@ -83,6 +88,12 @@ public class CitationManager implements ICitationManager {

@Autowired
private IAsyncCitationProcessor asyncCitationProcessor;

@Autowired
private IGilesConnector gilesConnector;

@Autowired
private IGilesDeletionChecker gilesDeletionChecker;

private Map<String, BiFunction<ICitation, ICitation, Integer>> sortFunctions;

Expand Down Expand Up @@ -494,4 +505,20 @@ public CitationPage getPrevAndNextCitation(IUser user, String groupId, String co
public void deleteLocalGroupCitations(String groupId) {
citationStore.deleteCitationByGroupId(groupId);
}

@Override
public void deleteFile(IUser user, String zoteroGroupId, String itemId, String documentId)
throws GroupDoesNotExistException, CannotFindCitationException, ZoteroHttpStatusException,
ZoteroConnectionException, CitationIsOutdatedException, ZoteroItemCreationFailedException {
ICitation citation = getCitation(user, zoteroGroupId, itemId);
for (Iterator<IGilesUpload> gileUpload = citation.getGilesUploads().iterator(); gileUpload.hasNext();) {
IGilesUpload g = gileUpload.next();
if (g.getDocumentId() != null && g.getDocumentId().equals(documentId)) {
HttpStatus deletionStatus = gilesConnector.deleteDocument(user, documentId);
if (deletionStatus.equals(HttpStatus.OK)) {
gilesDeletionChecker.addDocumentCitationMap(g, citation, zoteroGroupId, user);
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,33 @@

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.social.zotero.exception.ZoteroConnectionException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import edu.asu.diging.citesphere.core.exceptions.CannotFindCitationException;
import edu.asu.diging.citesphere.core.exceptions.CitationIsOutdatedException;
import edu.asu.diging.citesphere.core.exceptions.GroupDoesNotExistException;
import edu.asu.diging.citesphere.core.exceptions.ZoteroHttpStatusException;
import edu.asu.diging.citesphere.core.exceptions.ZoteroItemCreationFailedException;
import edu.asu.diging.citesphere.core.search.service.SearchEngine;
import edu.asu.diging.citesphere.core.service.ICitationManager;
import edu.asu.diging.citesphere.core.service.impl.CitationPage;
import edu.asu.diging.citesphere.core.service.impl.async.AsyncDeleteCitationsResponse;
import edu.asu.diging.citesphere.model.bib.ICitation;
import edu.asu.diging.citesphere.user.IUser;
import edu.asu.diging.citesphere.model.bib.IGilesUpload;

@Controller
public class ItemController {
Expand Down Expand Up @@ -54,6 +63,7 @@ public String getItem(Authentication authentication, Model model, @PathVariable(
List<ICitation> notes = citationManager.getNotes((IUser)authentication.getPrincipal(), zoteroGroupId, itemId);
model.addAttribute("notes", notes);
model.addAttribute("citation", citation);
model.addAttribute("itemId", itemId);
List<String> fields = new ArrayList<>();
citationManager.getItemTypeFields((IUser)authentication.getPrincipal(), citation.getItemType()).forEach(f -> fields.add(f.getFilename()));
model.addAttribute("fields", fields);
Expand All @@ -66,4 +76,15 @@ public String getItem(Authentication authentication, Model model, @PathVariable(
}
return "auth/group/item";
}

@RequestMapping(value = "/auth/group/{zoteroGroupId}/file/delete", method = RequestMethod.POST)
public ResponseEntity<String> deleteFile(Authentication authentication,
@PathVariable("zoteroGroupId") String zoteroGroupId,
@RequestParam(value = "documentId", required = false) String documentId,
@RequestParam(value = "itemId", required = false) String itemId)
throws GroupDoesNotExistException, CannotFindCitationException, ZoteroHttpStatusException,
ZoteroConnectionException, CitationIsOutdatedException, ZoteroItemCreationFailedException {
citationManager.deleteFile((IUser) authentication.getPrincipal(), zoteroGroupId, itemId, documentId);
return new ResponseEntity<>(HttpStatus.OK);
}
}
2 changes: 2 additions & 0 deletions citesphere/src/main/resources/config.properties
Original file line number Diff line number Diff line change
Expand Up @@ -88,5 +88,7 @@ elasticsearch.connect.timeout=${elasticsearch.connect.timeout}
giles_upload_endpoint=/api/v2/files/upload
giles_check_endpoint=/api/v2/files/upload/check/
giles_file_endpoint=/api/v2/resources/files/{0}/content
giles_document_endpoint=/api/v2/resources/documents/{documentId}
giles_document_deletion_check_endpoint=/api/v2/files/deletion/check/{documentId}

javers_default_author=${javers.default.author}
Loading