1158 lines
43 KiB
Java
1158 lines
43 KiB
Java
package org.gcube.data.access.storagehub.services;
|
|
|
|
import java.net.MalformedURLException;
|
|
import java.net.URL;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Collections;
|
|
import java.util.LinkedList;
|
|
import java.util.List;
|
|
|
|
import javax.jcr.ItemNotFoundException;
|
|
import javax.jcr.Node;
|
|
import javax.jcr.NodeIterator;
|
|
import javax.jcr.RepositoryException;
|
|
import javax.jcr.Session;
|
|
import javax.jcr.lock.LockException;
|
|
import javax.jcr.version.Version;
|
|
|
|
import org.gcube.common.authorization.control.annotations.AuthorizationControl;
|
|
import org.gcube.common.gxrest.response.outbound.GXOutboundErrorResponse;
|
|
import org.gcube.common.storagehub.model.Excludes;
|
|
import org.gcube.common.storagehub.model.NodeConstants;
|
|
import org.gcube.common.storagehub.model.exceptions.BackendGenericError;
|
|
import org.gcube.common.storagehub.model.exceptions.IdNotFoundException;
|
|
import org.gcube.common.storagehub.model.exceptions.InvalidCallParameters;
|
|
import org.gcube.common.storagehub.model.exceptions.InvalidItemException;
|
|
import org.gcube.common.storagehub.model.exceptions.ItemLockedException;
|
|
import org.gcube.common.storagehub.model.exceptions.StorageHubException;
|
|
import org.gcube.common.storagehub.model.items.AbstractFileItem;
|
|
import org.gcube.common.storagehub.model.items.FolderItem;
|
|
import org.gcube.common.storagehub.model.items.Item;
|
|
import org.gcube.common.storagehub.model.items.SharedFolder;
|
|
import org.gcube.common.storagehub.model.items.VreFolder;
|
|
import org.gcube.common.storagehub.model.items.nodes.Content;
|
|
import org.gcube.common.storagehub.model.service.ItemList;
|
|
import org.gcube.common.storagehub.model.service.ItemWrapper;
|
|
import org.gcube.common.storagehub.model.service.VersionList;
|
|
import org.gcube.common.storagehub.model.storages.MetaInfo;
|
|
import org.gcube.common.storagehub.model.types.ItemAction;
|
|
import org.gcube.common.storagehub.model.types.NodeProperty;
|
|
import org.gcube.data.access.storagehub.AuthorizationChecker;
|
|
import org.gcube.data.access.storagehub.Constants;
|
|
import org.gcube.data.access.storagehub.PathUtil;
|
|
import org.gcube.data.access.storagehub.Range;
|
|
import org.gcube.data.access.storagehub.StorageHubApplicationManager;
|
|
import org.gcube.data.access.storagehub.Utils;
|
|
import org.gcube.data.access.storagehub.accounting.AccountingHandler;
|
|
import org.gcube.data.access.storagehub.handlers.ClassHandler;
|
|
import org.gcube.data.access.storagehub.handlers.DownloadHandler;
|
|
import org.gcube.data.access.storagehub.handlers.PublicLinkHandler;
|
|
import org.gcube.data.access.storagehub.handlers.TrashHandler;
|
|
import org.gcube.data.access.storagehub.handlers.VersionHandler;
|
|
import org.gcube.data.access.storagehub.handlers.items.Item2NodeConverter;
|
|
import org.gcube.data.access.storagehub.handlers.items.Node2ItemConverter;
|
|
import org.gcube.data.access.storagehub.handlers.plugins.StorageOperationMediator;
|
|
import org.gcube.data.access.storagehub.repository.StoragehubRepository;
|
|
import org.gcube.data.access.storagehub.types.PublicLink;
|
|
import org.gcube.smartgears.annotations.ManagedBy;
|
|
import org.gcube.smartgears.utils.InnerMethodName;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
|
|
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
|
|
|
|
import jakarta.enterprise.context.RequestScoped;
|
|
import jakarta.inject.Inject;
|
|
import jakarta.servlet.ServletContext;
|
|
import jakarta.ws.rs.Consumes;
|
|
import jakarta.ws.rs.DELETE;
|
|
import jakarta.ws.rs.FormParam;
|
|
import jakarta.ws.rs.GET;
|
|
import jakarta.ws.rs.PUT;
|
|
import jakarta.ws.rs.Path;
|
|
import jakarta.ws.rs.PathParam;
|
|
import jakarta.ws.rs.Produces;
|
|
import jakarta.ws.rs.QueryParam;
|
|
import jakarta.ws.rs.core.Context;
|
|
import jakarta.ws.rs.core.MediaType;
|
|
import jakarta.ws.rs.core.Response;
|
|
import jakarta.ws.rs.core.Response.Status;
|
|
|
|
|
|
@Path("items")
|
|
@ManagedBy(StorageHubApplicationManager.class)
|
|
@RequestHeaders({
|
|
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
|
|
})
|
|
public class ItemsManager extends Impersonable{
|
|
|
|
private static final Logger log = LoggerFactory.getLogger(ItemsManager.class);
|
|
|
|
private final StoragehubRepository repository = StoragehubRepository.repository;
|
|
|
|
@Inject
|
|
AccountingHandler accountingHandler;
|
|
|
|
@RequestScoped
|
|
@PathParam("id")
|
|
String id;
|
|
|
|
@Context
|
|
ServletContext context;
|
|
|
|
@Inject
|
|
AuthorizationChecker authChecker;
|
|
|
|
@Inject
|
|
VersionHandler versionHandler;
|
|
|
|
@Inject
|
|
DownloadHandler downloadHandler;
|
|
|
|
@Inject
|
|
TrashHandler trashHandler;
|
|
|
|
@Inject PathUtil pathUtil;
|
|
|
|
@Inject Node2ItemConverter node2Item;
|
|
@Inject Item2NodeConverter item2Node;
|
|
|
|
|
|
|
|
@Inject
|
|
StorageOperationMediator opMediator;
|
|
|
|
|
|
@Inject
|
|
PublicLinkHandler publicLinkHandler;
|
|
|
|
|
|
@GET
|
|
@Path("{id}")
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
public ItemWrapper<Item> getById(@QueryParam("exclude") List<String> excludes){
|
|
InnerMethodName.set("getById");
|
|
Session ses = null;
|
|
Item toReturn = null;
|
|
try{
|
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
|
Node node = ses.getNodeByIdentifier(id);
|
|
authChecker.checkReadAuthorizationControl(ses, currentUser, id);
|
|
toReturn = node2Item.getItem(node, excludes);
|
|
}catch (ItemNotFoundException e) {
|
|
log.error("id {} not found",id,e);
|
|
GXOutboundErrorResponse.throwException(new IdNotFoundException(id, e), Status.NOT_FOUND);
|
|
}catch(RepositoryException re){
|
|
log.error("jcr error getting item", re);
|
|
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error getting item", re));
|
|
}catch(StorageHubException she ){
|
|
log.error(she.getErrorMessage(), she);
|
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
|
}finally{
|
|
if (ses!=null)
|
|
ses.logout();
|
|
}
|
|
|
|
return new ItemWrapper<Item>(toReturn);
|
|
}
|
|
|
|
@GET
|
|
@Path("{id}/path")
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
public ItemWrapper<Item> getByRelativePath(@QueryParam("path") String path, @QueryParam("exclude") List<String> excludes){
|
|
InnerMethodName.set("getByPath");
|
|
Session ses = null;
|
|
Item toReturn = null;
|
|
try{
|
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
|
authChecker.checkReadAuthorizationControl(ses, currentUser, id);
|
|
|
|
String relativePath = path.startsWith("/")? path.substring(1) : path;
|
|
if (path.endsWith("/"))
|
|
relativePath.substring(0,relativePath.lastIndexOf("/"));
|
|
|
|
if (relativePath.isEmpty()) throw new InvalidCallParameters("empty path");
|
|
|
|
Item item =null;
|
|
String nextId = id;
|
|
String[] paths = relativePath.split("/");
|
|
for (String actualPath: paths) {
|
|
item = getChildrenMatchingName(ses, nextId, actualPath, Excludes.ALL);
|
|
if (item ==null) throw new InvalidCallParameters("relative path "+actualPath+" not found under item with id "+nextId);
|
|
authChecker.checkReadAuthorizationControl(ses, currentUser, item.getId());
|
|
nextId = item.getId();
|
|
}
|
|
|
|
if (excludes.containsAll(Excludes.ALL))
|
|
return new ItemWrapper<Item>(item);
|
|
else
|
|
return new ItemWrapper<Item>(node2Item.getItem(ses.getNodeByIdentifier(item.getId()), excludes));
|
|
}catch(RepositoryException re){
|
|
log.error("jcr error getting item by path", re);
|
|
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error getting item by path", re));
|
|
}catch(StorageHubException she ){
|
|
log.error(she.getErrorMessage(), she);
|
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
|
}finally{
|
|
if (ses!=null)
|
|
ses.logout();
|
|
}
|
|
|
|
return new ItemWrapper<Item>(toReturn);
|
|
}
|
|
|
|
private Item getChildrenMatchingName(Session ses, String id, String name, List<String> excludes) throws ItemNotFoundException , RepositoryException, StorageHubException {
|
|
|
|
NodeIterator it = ses.getNodeByIdentifier(id).getNodes();
|
|
while (it.hasNext()) {
|
|
Node child= it.nextNode();
|
|
String nodeName = child.getName();
|
|
if (!child.hasProperty(NodeProperty.TITLE.toString())) continue;
|
|
String title = child.getProperty(NodeProperty.TITLE.toString()).getString();
|
|
|
|
if (nodeName.equals(name) || title.equals(name)){
|
|
return node2Item.getItem(child, excludes);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Deprecated
|
|
@GET
|
|
@Path("{id}/items/{name}")
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
public ItemList findChildrenByNamePatternInPath(@QueryParam("exclude") List<String> excludes, @PathParam("name") String name){
|
|
InnerMethodName.set("findChildrenByNamePattern");
|
|
return _findChildrenByNamePattern(excludes, name);
|
|
}
|
|
|
|
@GET
|
|
@Path("{id}/items")
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
public ItemList findChildrenByNamePattern(@QueryParam("exclude") List<String> excludes, @QueryParam("name") String name){
|
|
InnerMethodName.set("findChildrenByNamePattern");
|
|
return _findChildrenByNamePattern(excludes, name);
|
|
}
|
|
|
|
public ItemList _findChildrenByNamePattern(List<String> excludes, String name){
|
|
Session ses = null;
|
|
List<Item> toReturn = new ArrayList<>();
|
|
try{
|
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
|
authChecker.checkReadAuthorizationControl(ses, currentUser, id);
|
|
|
|
//NOT using the internal pattern matching of jcr because of title for shared folder
|
|
NodeIterator it = ses.getNodeByIdentifier(id).getNodes();
|
|
while (it.hasNext()) {
|
|
Node child= it.nextNode();
|
|
String nodeName = child.getName();
|
|
if (!child.hasProperty(NodeProperty.TITLE.toString())) continue;
|
|
String title = child.getProperty(NodeProperty.TITLE.toString()).getString();
|
|
|
|
String cleanedName = name;
|
|
if (name.startsWith("*")) cleanedName = name.substring(1);
|
|
if (name.endsWith("*")) cleanedName = name.substring(0, name.length()-1);
|
|
|
|
if ((name.startsWith("*") && (nodeName.endsWith(cleanedName) || title.endsWith(cleanedName))) || (name.endsWith("*") && (nodeName.startsWith(cleanedName) || title.startsWith(cleanedName)))
|
|
|| (nodeName.equals(cleanedName) || title.equals(cleanedName)))
|
|
toReturn.add(node2Item.getItem(child, excludes));
|
|
}
|
|
}catch (ItemNotFoundException e) {
|
|
log.error("id {} not found",id,e);
|
|
GXOutboundErrorResponse.throwException(new IdNotFoundException(id, e), Status.NOT_FOUND);
|
|
}catch(RepositoryException re){
|
|
log.error("jcr error searching item", re);
|
|
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error searching item", re));
|
|
}catch(StorageHubException she ){
|
|
log.error(she.getErrorMessage(), she);
|
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
|
}finally{
|
|
if (ses!=null)
|
|
ses.logout();
|
|
}
|
|
|
|
return new ItemList(toReturn);
|
|
|
|
}
|
|
|
|
@GET
|
|
@Path("{id}/children/count")
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
public Long countById(@QueryParam("showHidden") Boolean showHidden, @QueryParam("exclude") List<String> excludes, @QueryParam("onlyType") String nodeType){
|
|
InnerMethodName.set("countById");
|
|
Session ses = null;
|
|
Long toReturn = null;
|
|
|
|
try{
|
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
|
authChecker.checkReadAuthorizationControl(ses, currentUser, id);
|
|
toReturn = Utils.getItemCount(ses.getNodeByIdentifier(id), showHidden==null?false:showHidden, nodeType!=null ? ClassHandler.instance().get(nodeType) : null);
|
|
}catch (ItemNotFoundException e) {
|
|
log.error("id {} not found",id,e);
|
|
GXOutboundErrorResponse.throwException(new IdNotFoundException(id, e), Status.NOT_FOUND);
|
|
}catch(RuntimeException | RepositoryException re){
|
|
log.error("jcr error counting item", re);
|
|
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
|
|
}catch(StorageHubException she ){
|
|
log.error(she.getErrorMessage(), she);
|
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
|
}finally{
|
|
if (ses!=null)
|
|
ses.logout();
|
|
}
|
|
return toReturn ;
|
|
}
|
|
|
|
@GET
|
|
@Path("{id}/children")
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
public ItemList listById(@QueryParam("showHidden") Boolean showHidden, @QueryParam("exclude") List<String> excludes, @QueryParam("onlyType") String nodeType){
|
|
InnerMethodName.set("listById");
|
|
Session ses = null;
|
|
List<? extends Item> toReturn = null;
|
|
try{
|
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
|
authChecker.checkReadAuthorizationControl(ses, currentUser, id);
|
|
toReturn = Utils.getItemList(ses.getNodeByIdentifier(id), excludes, null, showHidden==null?false:showHidden, nodeType!=null ? ClassHandler.instance().get(nodeType) : null);
|
|
}catch (ItemNotFoundException e) {
|
|
log.error("id {} not found",id,e);
|
|
GXOutboundErrorResponse.throwException(new IdNotFoundException(id, e), Status.NOT_FOUND);
|
|
}catch(RepositoryException re){
|
|
log.error("jcr error getting children", re);
|
|
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
|
|
}catch(StorageHubException she ){
|
|
log.error(she.getErrorMessage(), she);
|
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
|
}finally{
|
|
if (ses!=null)
|
|
ses.logout();
|
|
}
|
|
|
|
return new ItemList(toReturn);
|
|
}
|
|
|
|
@GET
|
|
@Path("{id}/search")
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
public ItemList searchItems(@QueryParam("showHidden") Boolean showHidden, @QueryParam("excludeTrashed") Boolean excludeTrashed, @QueryParam("exclude") List<String> excludes, @QueryParam("onlyType") String nodeType,@QueryParam("name") String name ){
|
|
InnerMethodName.set("search");
|
|
Session ses = null;
|
|
List<? extends Item> toReturn = null;
|
|
try{
|
|
log.debug("search for node {}",name);
|
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
|
authChecker.checkReadAuthorizationControl(ses, currentUser, id);
|
|
toReturn = Utils.searchByNameOnFolder(ses, currentUser, authChecker, ses.getNodeByIdentifier(id), excludes, null, showHidden==null?false:showHidden,excludeTrashed==true?false:excludeTrashed , nodeType!=null ? ClassHandler.instance().get(nodeType) : null, name);
|
|
log.debug("search retrieved {} elements",toReturn.size());
|
|
}catch (ItemNotFoundException e) {
|
|
log.error("id {} not found",id,e);
|
|
GXOutboundErrorResponse.throwException(new IdNotFoundException(id, e), Status.NOT_FOUND);
|
|
}catch(RepositoryException re){
|
|
log.error("jcr error getting children", re);
|
|
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
|
|
}catch(StorageHubException she ){
|
|
log.error(she.getErrorMessage(), she);
|
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
|
}finally{
|
|
if (ses!=null)
|
|
ses.logout();
|
|
}
|
|
|
|
return new ItemList(toReturn);
|
|
}
|
|
|
|
@GET
|
|
@Path("{id}/children/paged")
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
public ItemList listByIdPaged(@QueryParam("showHidden") Boolean showHidden, @QueryParam("start") Integer start, @QueryParam("limit") Integer limit, @QueryParam("exclude") List<String> excludes, @QueryParam("onlyType") String nodeType){
|
|
InnerMethodName.set("listByIdPaged");
|
|
Session ses = null;
|
|
List<? extends Item> toReturn = null;
|
|
try{
|
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
|
authChecker.checkReadAuthorizationControl(ses, currentUser, id);
|
|
toReturn = Utils.getItemList(ses.getNodeByIdentifier(id), excludes, new Range(start, limit),showHidden==null?false:showHidden, nodeType!=null ? ClassHandler.instance().get(nodeType) : null);
|
|
}catch (ItemNotFoundException e) {
|
|
log.error("id {} not found",id,e);
|
|
GXOutboundErrorResponse.throwException(new IdNotFoundException(id, e), Status.NOT_FOUND);
|
|
}catch(RepositoryException re){
|
|
log.error("jcr error getting paged children", re);
|
|
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
|
|
}catch(StorageHubException she ){
|
|
log.error(she.getErrorMessage(), she);
|
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
|
}finally{
|
|
if (ses!=null)
|
|
ses.logout();
|
|
}
|
|
|
|
return new ItemList(toReturn);
|
|
}
|
|
|
|
@GET
|
|
@Path("publiclink/{id}")
|
|
@AuthorizationControl(allowedUsers={"URIResolver"})
|
|
public Response resolvePublicLink() {
|
|
InnerMethodName.set("resolvePubliclink");
|
|
|
|
log.warn("arrived id is {}",id);
|
|
Session ses = null;
|
|
try{
|
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
|
PublicLink publicLink = publicLinkHandler.resolveEnchriptedId(id);
|
|
switch (publicLink.getType()) {
|
|
case VOLATILE:
|
|
return downloadHandler.downloadFileFromStorageBackend(publicLink.getId(), publicLink.getStorageName());
|
|
case VERSIONED:
|
|
Item versionedItem = node2Item.getItem(publicLink.getId(), ses, Excludes.GET_ONLY_CONTENT);
|
|
return downloadHandler.downloadVersionedItem(ses, currentUser, (AbstractFileItem) versionedItem, publicLink.getVersion(), true);
|
|
default:
|
|
Item currentItem = node2Item.getItem(publicLink.getId(), ses, Excludes.GET_ONLY_CONTENT);
|
|
return downloadHandler.downloadFileItem(ses,(AbstractFileItem) currentItem, currentUser, true);
|
|
}
|
|
|
|
}catch(RepositoryException re ){
|
|
log.error("jcr error getting public link", re);
|
|
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
|
|
}catch(StorageHubException she ){
|
|
log.error(she.getErrorMessage(), she);
|
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
|
}finally{
|
|
if (ses!=null)
|
|
ses.logout();
|
|
}
|
|
return Response.serverError().build();
|
|
}
|
|
|
|
@GET
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
@Path("{id}/publiclink")
|
|
public URL getPublicLink(@QueryParam("version") String version) {
|
|
InnerMethodName.set("getPubliclink");
|
|
Session ses = null;
|
|
URL toReturn = null;
|
|
try{
|
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
|
authChecker.checkReadAuthorizationControl(ses, currentUser, id);
|
|
|
|
Node selectedNode = ses.getNodeByIdentifier(id);
|
|
|
|
Item item = node2Item.getItem(selectedNode, Arrays.asList(NodeConstants.ACCOUNTING_NAME, NodeConstants.METADATA_NAME));
|
|
|
|
if (!(item instanceof AbstractFileItem)) throw new InvalidCallParameters("the choosen item is not a File");
|
|
|
|
if (version!=null) {
|
|
boolean versionFound = false;
|
|
VersionList versions = getVersions();
|
|
for (org.gcube.common.storagehub.model.service.Version v: versions.getItemlist() )
|
|
if (v.getName().equals(version)) {
|
|
versionFound = true;
|
|
break;
|
|
}
|
|
if (!versionFound) throw new InvalidCallParameters("the selected file has no version "+version);
|
|
}
|
|
|
|
/* NOT SETTING THE PUBLIC ATTRIBUTE FOR SOME STRANGE REASON
|
|
ses.getWorkspace().getLockManager().lock(selectedNode.getPath(), false, true, 0,login);
|
|
try {
|
|
selectedNode.setProperty(NodeProperty.IS_PUBLIC.toString(), true);
|
|
ses.save();
|
|
}finally {
|
|
ses.getWorkspace().getLockManager().unlock(selectedNode.getPath());
|
|
}*/
|
|
|
|
|
|
String url = version!=null ? publicLinkHandler.getForVersionedItem(id, version, context):
|
|
publicLinkHandler.getForItem(id, context);
|
|
|
|
|
|
toReturn = new URL(url);
|
|
|
|
}catch(RepositoryException | MalformedURLException re ){
|
|
log.error("jcr error getting public link", re);
|
|
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
|
|
}catch(StorageHubException she ){
|
|
log.error(she.getErrorMessage(), she);
|
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
|
}finally{
|
|
if (ses!=null)
|
|
ses.logout();
|
|
}
|
|
|
|
return toReturn;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@PUT
|
|
@Path("{id}/publish")
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
public String makeFolderPublic(@FormParam("publish") boolean publish){
|
|
InnerMethodName.set("makeFolderPublic("+publish+")");
|
|
Session ses = null;
|
|
Item folder= null;
|
|
try{
|
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
|
authChecker.checkWriteAuthorizationControl(ses, currentUser, id, false);
|
|
Node currentNode =ses.getNodeByIdentifier(id);
|
|
log.trace("current node is {}",currentNode.getPath());
|
|
|
|
folder = node2Item.getItem(currentNode, Excludes.ALL);
|
|
|
|
if (!(folder instanceof FolderItem))
|
|
throw new InvalidCallParameters("item is not a folder");
|
|
|
|
currentNode.setProperty(NodeProperty.IS_PUBLIC.toString(), publish);
|
|
|
|
ses.save();
|
|
|
|
}catch(RepositoryException re ){
|
|
log.error("jcr error publishing folder", re);
|
|
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
|
|
}catch(StorageHubException she ){
|
|
log.error(she.getErrorMessage(), she);
|
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
|
}finally{
|
|
if (ses!=null)
|
|
ses.logout();
|
|
}
|
|
return id;
|
|
}
|
|
|
|
|
|
@GET
|
|
@Path("{id}/rootSharedFolder")
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
public ItemWrapper<Item> getRootSharedFolder(@QueryParam("exclude") List<String> excludes){
|
|
InnerMethodName.set("getRootSharedFolder");
|
|
Session ses = null;
|
|
Item sharedParent= null;
|
|
try{
|
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
|
authChecker.checkReadAuthorizationControl(ses, currentUser, id);
|
|
Node currentNode =ses.getNodeByIdentifier(id);
|
|
log.trace("current node is {}",currentNode.getPath());
|
|
|
|
Node sharedParentNode = getSharedParentNode(currentNode);
|
|
|
|
if (sharedParentNode==null)
|
|
throw new InvalidCallParameters("item is not shared");
|
|
|
|
sharedParent = node2Item.getItem(sharedParentNode, excludes);
|
|
|
|
}catch(RepositoryException re ){
|
|
log.error("jcr error getting rootSharedFolder", re);
|
|
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
|
|
}catch(StorageHubException she ){
|
|
log.error(she.getErrorMessage(), she);
|
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
|
}finally{
|
|
if (ses!=null)
|
|
ses.logout();
|
|
}
|
|
return new ItemWrapper<Item>(sharedParent);
|
|
}
|
|
|
|
private Node getSharedParentNode(Node node) throws RepositoryException, BackendGenericError{
|
|
Item currentItem = node2Item.getItem(node, Excludes.ALL);
|
|
if (!currentItem.isShared())
|
|
return null;
|
|
Node currentNode = node;
|
|
while (!node2Item.checkNodeType(currentNode, SharedFolder.class))
|
|
currentNode = currentNode.getParent();
|
|
return currentNode;
|
|
}
|
|
|
|
@GET
|
|
@Path("{id}/versions")
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
public VersionList getVersions(){
|
|
InnerMethodName.set("getVersions");
|
|
Session ses = null;
|
|
List<org.gcube.common.storagehub.model.service.Version> versions = new ArrayList<>();
|
|
try{
|
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
|
authChecker.checkReadAuthorizationControl(ses, currentUser, id);
|
|
|
|
Node node = ses.getNodeByIdentifier(id);
|
|
|
|
Item currentItem = node2Item.getItem(node, Excludes.GET_ONLY_CONTENT);
|
|
if (!(currentItem instanceof AbstractFileItem))
|
|
throw new InvalidItemException("this item is not versioned");
|
|
|
|
List<Version> jcrVersions = versionHandler.getContentVersionHistory(node);
|
|
|
|
for (Version version: jcrVersions) {
|
|
boolean currentVersion = ((AbstractFileItem)currentItem).getContent().getStorageId().equals(version.getFrozenNode().getProperty(NodeProperty.STORAGE_ID.toString()).getString());
|
|
|
|
versions.add(new org.gcube.common.storagehub.model.service.Version(version.getIdentifier(), version.getName(), version.getCreated(), currentVersion));
|
|
}
|
|
}catch(RepositoryException re ){
|
|
log.error("jcr error retrieving versions", re);
|
|
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
|
|
}catch(StorageHubException she ){
|
|
log.error(she.getErrorMessage(), she);
|
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
|
}finally{
|
|
if (ses!=null)
|
|
ses.logout();
|
|
}
|
|
return new VersionList(versions);
|
|
}
|
|
|
|
@GET
|
|
@Path("{id}/versions/{version}/download")
|
|
public Response downloadVersion(@PathParam("version") String versionName){
|
|
InnerMethodName.set("downloadSpecificVersion");
|
|
Session ses = null;
|
|
try{
|
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
|
authChecker.checkReadAuthorizationControl(ses, currentUser, id);
|
|
Node node = ses.getNodeByIdentifier(id);
|
|
Item currentItem = node2Item.getItem(node, Excludes.ALL);
|
|
if (!(currentItem instanceof AbstractFileItem))
|
|
throw new InvalidItemException("this item is not a file");
|
|
|
|
return downloadHandler.downloadVersionedItem(ses, currentUser, (AbstractFileItem) currentItem, versionName, true);
|
|
|
|
}catch(RepositoryException re ){
|
|
log.error("jcr error downloading version", re);
|
|
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
|
|
}catch(StorageHubException she ){
|
|
log.error(she.getErrorMessage(), she);
|
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
|
}finally{
|
|
if (ses!=null)
|
|
ses.logout();
|
|
}
|
|
return Response.serverError().build();
|
|
}
|
|
|
|
@DELETE
|
|
@Path("{id}/versions/{version}")
|
|
public void deleteVersion(@PathParam("version") String versionName){
|
|
InnerMethodName.set("deleteVersion");
|
|
Session ses = null;
|
|
try{
|
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
|
authChecker.checkWriteAuthorizationControl(ses, currentUser, id, false);
|
|
Node node = ses.getNodeByIdentifier(id);
|
|
Item currentItem = node2Item.getItem(node, Excludes.GET_ONLY_CONTENT);
|
|
if (!(currentItem instanceof AbstractFileItem))
|
|
throw new InvalidItemException("this item is not a file");
|
|
|
|
List<Version> versions = versionHandler.getContentVersionHistory(node);
|
|
|
|
boolean found = false;
|
|
|
|
for(Version version : versions)
|
|
if (version.getName().equals(versionName)) {
|
|
boolean currentVersion = ((AbstractFileItem)currentItem).getContent().getStorageId().equals(version.getFrozenNode().getProperty(NodeProperty.STORAGE_ID.toString()).getString());
|
|
if (currentVersion)
|
|
throw new InvalidCallParameters("current version cannot be removed");
|
|
versionHandler.removeContentVersion(node, versionName);
|
|
accountingHandler.createVersionDeleted(currentItem.getTitle(), versionName, ses, node, currentUser, false);
|
|
ses.save();
|
|
found = true;
|
|
break;
|
|
}
|
|
|
|
if (!found) throw new InvalidItemException("the version "+versionName+" is not valid or is current version for item "+currentItem.getTitle());
|
|
}catch(RepositoryException re ){
|
|
log.error("jcr error removing version", re);
|
|
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
|
|
}catch(StorageHubException she ){
|
|
log.error(she.getErrorMessage(), she);
|
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
|
}finally{
|
|
if (ses!=null)
|
|
ses.logout();
|
|
}
|
|
}
|
|
|
|
|
|
@GET
|
|
@Path("{id}/anchestors")
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
public ItemList getAnchestors(@QueryParam("exclude") List<String> excludes){
|
|
InnerMethodName.set("getAnchestors");
|
|
org.gcube.common.storagehub.model.Path absolutePath = pathUtil.getWorkspacePath(currentUser);
|
|
Session ses = null;
|
|
List<Item> toReturn = new LinkedList<>();
|
|
try{
|
|
|
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
|
authChecker.checkReadAuthorizationControl(ses, currentUser, id);
|
|
Node currentNode = ses.getNodeByIdentifier(id);
|
|
Item currentItem = node2Item.getItem(currentNode, excludes);
|
|
log.trace("current node is {}",currentNode.getPath());
|
|
while (!(currentNode.getPath().matches("/Home/[^/]{1,}/Workspace"))) {
|
|
if (currentItem instanceof SharedFolder){
|
|
NodeIterator sharedSetIterator = currentNode.getSharedSet();
|
|
boolean found = false;
|
|
while (sharedSetIterator.hasNext()) {
|
|
Node sharedNode = sharedSetIterator.nextNode();
|
|
if (sharedNode.getPath().startsWith(absolutePath.toPath())) {
|
|
currentNode = sharedNode.getParent();
|
|
found=true;
|
|
break;
|
|
}
|
|
}
|
|
if (!found) break;
|
|
currentItem = node2Item.getItem(currentNode, excludes);
|
|
}else {
|
|
currentNode = currentNode.getParent();
|
|
currentItem = node2Item.getItem(currentNode, excludes);
|
|
}
|
|
|
|
log.trace("current node is {}",currentNode.getPath());
|
|
toReturn.add(currentItem);
|
|
}
|
|
|
|
}catch(RepositoryException re ){
|
|
log.error("jcr error getting anchestors", re);
|
|
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
|
|
}catch(StorageHubException she ){
|
|
log.error(she.getErrorMessage(), she);
|
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
|
}finally{
|
|
if (ses!=null)
|
|
ses.logout();
|
|
}
|
|
|
|
log.trace("item list to return is empty ? {}",toReturn.isEmpty());
|
|
|
|
return new ItemList(toReturn);
|
|
}
|
|
|
|
|
|
|
|
|
|
@GET
|
|
@Path("{id}/download")
|
|
public Response download(@QueryParam("exclude") List<String> excludes){
|
|
InnerMethodName.set("downloadById");
|
|
Session ses = null;
|
|
try{
|
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
|
final Node node = ses.getNodeByIdentifier(id);
|
|
authChecker.checkReadAuthorizationControl(ses, currentUser, id);
|
|
final Item item = node2Item.getItem(node, null);
|
|
if (item instanceof AbstractFileItem){
|
|
return downloadHandler.downloadFileItem(ses, (AbstractFileItem) item, currentUser, true);
|
|
} else if (item instanceof FolderItem){
|
|
return downloadHandler.downloadFolderItem(ses, currentUser, (FolderItem)item, true);
|
|
} else throw new InvalidItemException("item type not supported for download: "+item.getClass());
|
|
|
|
}catch(RepositoryException re ){
|
|
log.error("jcr error download", re);
|
|
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
|
|
}catch(StorageHubException she ){
|
|
log.error(she.getErrorMessage(), she);
|
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
|
} finally{
|
|
if (ses!=null) ses.logout();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
|
|
@PUT
|
|
@Path("{id}/move")
|
|
public String move(@FormParam("destinationId") String destinationId){
|
|
InnerMethodName.set("move");
|
|
|
|
Session ses = null;
|
|
try{
|
|
|
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
|
|
|
authChecker.checkMoveOpsForProtectedFolders(ses, id);
|
|
authChecker.checkWriteAuthorizationControl(ses, currentUser, destinationId, true);
|
|
authChecker.checkWriteAuthorizationControl(ses, currentUser, id, false);
|
|
|
|
final Node nodeToMove = ses.getNodeByIdentifier(id);
|
|
final Node destination = ses.getNodeByIdentifier(destinationId);
|
|
Node originalParent = nodeToMove.getParent();
|
|
|
|
Item destinationItem = node2Item.getItem(destination,null);
|
|
final Item item = node2Item.getItem(nodeToMove, null);
|
|
|
|
if (item instanceof SharedFolder)
|
|
throw new InvalidItemException("shared folder cannot be moved");
|
|
|
|
if (item instanceof FolderItem && Utils.hasSharedChildren(nodeToMove))
|
|
throw new InvalidItemException("folder item with shared children cannot be moved");
|
|
|
|
if (Constants.FOLDERS_TO_EXLUDE.contains(item.getTitle()) || Constants.FOLDERS_TO_EXLUDE.contains(destinationItem.getTitle()))
|
|
throw new InvalidItemException("protected folder cannot be moved");
|
|
|
|
if (!(destinationItem instanceof FolderItem))
|
|
throw new InvalidItemException("destination item is not a folder");
|
|
|
|
boolean movingSharedItemOutside = item.isShared() && (!destinationItem.isShared() || !getSharedParentNode(nodeToMove).getIdentifier().equals(getSharedParentNode(destination).getIdentifier()));
|
|
|
|
try {
|
|
ses.getWorkspace().getLockManager().lock(destination.getPath(), false, true, 0,currentUser);
|
|
ses.getWorkspace().getLockManager().lock(nodeToMove.getPath(), true, true, 0,currentUser);
|
|
}catch (LockException e) {
|
|
throw new ItemLockedException(e);
|
|
}
|
|
try {
|
|
String uniqueName =(Utils.checkExistanceAndGetUniqueName(ses, destination, nodeToMove.getName()));
|
|
String newPath = String.format("%s/%s",destination.getPath(), uniqueName);
|
|
|
|
ses.move(nodeToMove.getPath(), newPath);
|
|
Utils.setPropertyOnChangeNode(ses.getNode(newPath), currentUser, ItemAction.MOVED);
|
|
|
|
String mimeTypeForAccounting = (item instanceof AbstractFileItem)? ((AbstractFileItem) item).getContent().getMimeType(): null;
|
|
|
|
if (movingSharedItemOutside)
|
|
item2Node.updateOwnerOnSubTree(nodeToMove, currentUser);
|
|
|
|
//add onMove (if it changes the remotePath) and in case of different backend
|
|
|
|
accountingHandler.createFolderAddObj(uniqueName, item.getClass().getSimpleName(), mimeTypeForAccounting, ses, currentUser, destination, false);
|
|
accountingHandler.createFolderRemoveObj(item.getTitle(), item.getClass().getSimpleName(), mimeTypeForAccounting, ses, currentUser, originalParent, false);
|
|
|
|
ses.save();
|
|
}finally {
|
|
ses.getWorkspace().getLockManager().unlock(nodeToMove.getPath());
|
|
ses.getWorkspace().getLockManager().unlock(destination.getPath());
|
|
}
|
|
|
|
}catch(RepositoryException re ){
|
|
log.error("jcr error moving item", re);
|
|
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
|
|
}catch(StorageHubException she ){
|
|
log.error(she.getErrorMessage(), she);
|
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
|
} finally{
|
|
if (ses!=null) {
|
|
ses.logout();
|
|
}
|
|
}
|
|
return id;
|
|
}
|
|
|
|
@PUT
|
|
@Path("{id}/copy")
|
|
public String copy(@FormParam("destinationId") String destinationId, @FormParam("fileName") String newFileName){
|
|
InnerMethodName.set("copy");
|
|
//TODO: check if identifier is The Workspace root, or the trash folder or the VREFolder root or if the item is thrashed
|
|
Session ses = null;
|
|
String newFileIdentifier = null;
|
|
try{
|
|
|
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
|
|
|
authChecker.checkWriteAuthorizationControl(ses, currentUser, destinationId, true);
|
|
authChecker.checkReadAuthorizationControl(ses, currentUser, id);
|
|
|
|
final Node nodeToCopy = ses.getNodeByIdentifier(id);
|
|
final Node destination = ses.getNodeByIdentifier(destinationId);
|
|
FolderItem destinationItem = (FolderItem)node2Item.getItem(destination,null);
|
|
|
|
final Item item = node2Item.getItem(nodeToCopy, Arrays.asList(NodeConstants.ACCOUNTING_NAME, NodeConstants.METADATA_NAME));
|
|
|
|
if (item instanceof FolderItem)
|
|
throw new InvalidItemException("folder cannot be copied");
|
|
|
|
try {
|
|
ses.getWorkspace().getLockManager().lock(destination.getPath(), false, true, 0,currentUser);
|
|
ses.getWorkspace().getLockManager().lock(nodeToCopy.getPath(), true, true, 0,currentUser);
|
|
}catch (LockException e) {
|
|
throw new ItemLockedException(e);
|
|
}
|
|
|
|
try {
|
|
String uniqueName = Utils.checkExistanceAndGetUniqueName(ses, destination, newFileName);
|
|
String newPath= String.format("%s/%s", destination.getPath(), uniqueName);
|
|
ses.getWorkspace().copy(nodeToCopy.getPath(), newPath);
|
|
Node newNode = ses.getNode(newPath);
|
|
newFileIdentifier = newNode.getIdentifier();
|
|
|
|
Content contentToCopy = ((AbstractFileItem) item).getContent();
|
|
|
|
MetaInfo contentInfo = opMediator.copy(contentToCopy, destinationItem.getBackend(), destination.getPath(), uniqueName, currentUser);
|
|
|
|
Utils.setContentFromMetaInfo((AbstractFileItem) item, contentInfo);
|
|
item2Node.replaceContent(newNode, (AbstractFileItem) item, ItemAction.CLONED);
|
|
|
|
Utils.setPropertyOnChangeNode(newNode, currentUser, ItemAction.CLONED);
|
|
newNode.setProperty(NodeProperty.PORTAL_LOGIN.toString(), currentUser);
|
|
newNode.setProperty(NodeProperty.IS_PUBLIC.toString(), false);
|
|
newNode.setProperty(NodeProperty.TITLE.toString(), uniqueName);
|
|
|
|
String mimeTypeForAccounting = (item instanceof AbstractFileItem)? ((AbstractFileItem) item).getContent().getMimeType(): null;
|
|
accountingHandler.createFolderAddObj(uniqueName, item.getClass().getSimpleName(), mimeTypeForAccounting, ses, currentUser, destination, false);
|
|
|
|
|
|
ses.save();
|
|
|
|
}finally {
|
|
ses.getWorkspace().getLockManager().unlock(nodeToCopy.getPath());
|
|
ses.getWorkspace().getLockManager().unlock(destination.getPath());
|
|
}
|
|
|
|
}catch(RepositoryException re ){
|
|
log.error("jcr error moving item", re);
|
|
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
|
|
}catch(StorageHubException she ){
|
|
log.error(she.getErrorMessage(), she);
|
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
|
}finally{
|
|
if (ses!=null) {
|
|
ses.logout();
|
|
}
|
|
}
|
|
return newFileIdentifier;
|
|
}
|
|
|
|
@PUT
|
|
@Path("{id}/rename")
|
|
public Response rename(@FormParam("newName") String newName){
|
|
InnerMethodName.set("rename");
|
|
Session ses = null;
|
|
|
|
try{
|
|
|
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
|
|
|
authChecker.checkMoveOpsForProtectedFolders(ses, id);
|
|
authChecker.checkWriteAuthorizationControl(ses, currentUser, id, false);
|
|
|
|
final Node nodeToMove = ses.getNodeByIdentifier(id);
|
|
|
|
final Item item = node2Item.getItem(nodeToMove, null);
|
|
|
|
if (item instanceof SharedFolder)
|
|
if (getSharedParentNode(nodeToMove).getIdentifier() == item.getId())
|
|
throw new InvalidItemException("root shared folder name cannot be modfied");
|
|
|
|
String uniqueName = Utils.checkExistanceAndGetUniqueName(ses, nodeToMove.getParent(), newName);
|
|
|
|
try {
|
|
ses.getWorkspace().getLockManager().lock(nodeToMove.getPath(), true, true, 0,currentUser);
|
|
ses.getWorkspace().getLockManager().lock(nodeToMove.getParent().getPath(), false, true, 0,currentUser);
|
|
}catch (LockException e) {
|
|
throw new ItemLockedException(e);
|
|
}
|
|
try {
|
|
String newPath = String.format("%s/%s", nodeToMove.getParent().getPath(), uniqueName);
|
|
nodeToMove.setProperty(NodeProperty.TITLE.toString(), uniqueName);
|
|
Utils.setPropertyOnChangeNode(nodeToMove, currentUser, ItemAction.RENAMED);
|
|
ses.move(nodeToMove.getPath(), newPath);
|
|
accountingHandler.createRename(item.getTitle(), uniqueName, ses.getNode(newPath), currentUser, ses, false);
|
|
ses.save();
|
|
}finally {
|
|
ses.getWorkspace().getLockManager().unlock(nodeToMove.getPath());
|
|
ses.getWorkspace().getLockManager().unlock(nodeToMove.getParent().getPath());
|
|
}
|
|
|
|
}catch(RepositoryException re ){
|
|
log.error("jcr error moving item", re);
|
|
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
|
|
}catch(StorageHubException she ){
|
|
log.error(she.getErrorMessage(), she);
|
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
|
}finally{
|
|
if (ses!=null) {
|
|
ses.logout();
|
|
}
|
|
|
|
}
|
|
return Response.ok(id).build();
|
|
}
|
|
|
|
//TODO: transform this and setMetadata in a generic method for all properties
|
|
@PUT
|
|
@Consumes(MediaType.APPLICATION_JSON)
|
|
@Path("/{id}/hidden")
|
|
public Response setItemAsHidden(Boolean hidden){
|
|
InnerMethodName.set("setHidden");
|
|
|
|
Session ses = null;
|
|
|
|
try{
|
|
|
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
|
|
|
authChecker.checkWriteAuthorizationControl(ses, currentUser, id, false);
|
|
|
|
final Node nodeToUpdate = ses.getNodeByIdentifier(id);
|
|
|
|
try {
|
|
ses.getWorkspace().getLockManager().lock(nodeToUpdate.getPath(), false, true, 0,currentUser);
|
|
}catch (LockException e) {
|
|
throw new ItemLockedException(e);
|
|
}
|
|
try {
|
|
item2Node.updateHidden(nodeToUpdate, hidden, currentUser);
|
|
ses.save();
|
|
}finally {
|
|
ses.getWorkspace().getLockManager().unlock(nodeToUpdate.getPath());
|
|
}
|
|
//TODO: UPDATE accounting
|
|
|
|
}catch(RepositoryException re ){
|
|
log.error("jcr error moving item", re);
|
|
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
|
|
}catch(StorageHubException she ){
|
|
log.error(she.getErrorMessage(), she);
|
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
|
}finally{
|
|
if (ses!=null) {
|
|
ses.logout();
|
|
}
|
|
|
|
}
|
|
return Response.ok(id).build();
|
|
}
|
|
|
|
//TODO: transform this and setMetadata in a generic method for all properties
|
|
@PUT
|
|
@Consumes(MediaType.APPLICATION_JSON)
|
|
@Path("/{id}/description")
|
|
public Response setDescription(String description){
|
|
InnerMethodName.set("setDescription");
|
|
|
|
Session ses = null;
|
|
|
|
try{
|
|
|
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
|
|
|
authChecker.checkWriteAuthorizationControl(ses, currentUser, id, false);
|
|
|
|
final Node nodeToUpdate = ses.getNodeByIdentifier(id);
|
|
|
|
try {
|
|
ses.getWorkspace().getLockManager().lock(nodeToUpdate.getPath(), false, true, 0,currentUser);
|
|
}catch (LockException e) {
|
|
throw new ItemLockedException(e);
|
|
}
|
|
try {
|
|
item2Node.updateDescription(nodeToUpdate, description, currentUser);
|
|
ses.save();
|
|
}finally {
|
|
ses.getWorkspace().getLockManager().unlock(nodeToUpdate.getPath());
|
|
}
|
|
//TODO: UPDATE accounting
|
|
|
|
}catch(RepositoryException re ){
|
|
log.error("jcr error moving item", re);
|
|
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
|
|
}catch(StorageHubException she ){
|
|
log.error(she.getErrorMessage(), she);
|
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
|
}finally{
|
|
if (ses!=null) {
|
|
ses.logout();
|
|
}
|
|
|
|
}
|
|
return Response.ok(id).build();
|
|
}
|
|
|
|
@PUT
|
|
@Consumes(MediaType.APPLICATION_JSON)
|
|
@Path("/{id}/metadata")
|
|
public Response setMetadata(org.gcube.common.storagehub.model.Metadata metadata){
|
|
InnerMethodName.set("updateMetadata");
|
|
|
|
Session ses = null;
|
|
|
|
try{
|
|
|
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
|
|
|
authChecker.checkWriteAuthorizationControl(ses, currentUser, id, false);
|
|
|
|
final Node nodeToUpdate = ses.getNodeByIdentifier(id);
|
|
|
|
try {
|
|
ses.getWorkspace().getLockManager().lock(nodeToUpdate.getPath(), false, true, 0,currentUser);
|
|
}catch (LockException e) {
|
|
throw new ItemLockedException(e);
|
|
}
|
|
try {
|
|
item2Node.updateMetadataNode(nodeToUpdate, metadata.getMap(), currentUser);
|
|
ses.save();
|
|
}finally {
|
|
ses.getWorkspace().getLockManager().unlock(nodeToUpdate.getPath());
|
|
}
|
|
//TODO: UPDATE accounting
|
|
|
|
}catch(RepositoryException re ){
|
|
log.error("jcr error moving item", re);
|
|
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
|
|
}catch(StorageHubException she ){
|
|
log.error(she.getErrorMessage(), she);
|
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
|
}finally{
|
|
if (ses!=null) {
|
|
ses.logout();
|
|
}
|
|
|
|
}
|
|
return Response.ok(id).build();
|
|
}
|
|
|
|
|
|
|
|
@DELETE
|
|
@Path("{id}")
|
|
public Response deleteItem(@QueryParam("force") boolean force){
|
|
InnerMethodName.set("deleteItem("+force+")");
|
|
|
|
Session ses = null;
|
|
try{
|
|
|
|
log.info("removing node with id {}", id);
|
|
|
|
//TODO check if it is possible to change all the ACL on a workspace
|
|
ses = repository.getRepository().login(Constants.JCR_CREDENTIALS);
|
|
|
|
authChecker.checkWriteAuthorizationControl(ses, currentUser, id, false);
|
|
authChecker.checkMoveOpsForProtectedFolders(ses, id);
|
|
|
|
final Node nodeToDelete = ses.getNodeByIdentifier(id);
|
|
Item itemToDelete = node2Item.getItem(nodeToDelete, Excludes.GET_ONLY_CONTENT);
|
|
|
|
if (itemToDelete instanceof SharedFolder || itemToDelete instanceof VreFolder || (itemToDelete instanceof FolderItem && Utils.hasSharedChildren(nodeToDelete)))
|
|
throw new InvalidItemException("SharedFolder, VreFolder or folders with shared children cannot be deleted");
|
|
|
|
if (itemToDelete.isExternalManaged() && !force)
|
|
throw new InvalidItemException("External managed Items cannot be moved to Trash");
|
|
|
|
log.debug("item is trashed? {}", itemToDelete.isTrashed());
|
|
|
|
if (!itemToDelete.isTrashed() && !force) {
|
|
trashHandler.moveToTrash(ses, nodeToDelete, itemToDelete, currentUser);
|
|
}else
|
|
trashHandler.removeNodes(ses, Collections.singletonList(itemToDelete));
|
|
|
|
}catch (LockException e) {
|
|
|
|
}catch(RepositoryException re ){
|
|
log.error("jcr error moving item", re);
|
|
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
|
|
}catch(StorageHubException she ){
|
|
log.error(she.getErrorMessage(), she);
|
|
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
|
|
}finally{
|
|
if (ses!=null) {
|
|
ses.logout();
|
|
}
|
|
}
|
|
return Response.ok().build();
|
|
}
|
|
|
|
|
|
} |