From 0e88826cbfe055cf1ffdfa321011771031c0abf6 Mon Sep 17 00:00:00 2001 From: Lucio Lelii Date: Wed, 20 Jun 2018 14:59:41 +0000 Subject: [PATCH] git-svn-id: https://svn.d4science-ii.research-infrastructures.eu/gcube/branches/data-access/storagehub-webapp/1.0@169358 82a268e6-3cf1-43bd-a215-b396298e98cf --- pom.xml | 4 +- .../storagehub/AuthorizationChecker.java | 40 ++- .../accounting/AccountingHandler.java | 52 +-- .../storagehub/handlers/ItemHandler.java | 15 +- .../data/access/storagehub/handlers/VRE.java | 48 +++ .../storagehub/handlers/VREManager.java | 59 ++++ .../handlers/VREQueryRetriever.java | 168 ++++++++++ .../storagehub/handlers/VersionHandler.java | 1 + .../logical/ISDescendantEvaluator.java | 2 +- .../storagehub/services/ItemsCreator.java | 39 +-- .../storagehub/services/ItemsManager.java | 10 +- .../storagehub/services/WorkspaceManager.java | 314 +++++++----------- 12 files changed, 487 insertions(+), 265 deletions(-) create mode 100644 src/main/java/org/gcube/data/access/storagehub/handlers/VRE.java create mode 100644 src/main/java/org/gcube/data/access/storagehub/handlers/VREManager.java create mode 100644 src/main/java/org/gcube/data/access/storagehub/handlers/VREQueryRetriever.java diff --git a/pom.xml b/pom.xml index a71acf9..8f57988 100644 --- a/pom.xml +++ b/pom.xml @@ -11,13 +11,13 @@ 4.0.0 org.gcube.data.access storagehub - 1.0.0-SNAPSHOT + 1.0.1-SNAPSHOT storagehub war - 2.14.0 + 2.16.0 7.0.40 6.1.26 1.7 diff --git a/src/main/java/org/gcube/data/access/storagehub/AuthorizationChecker.java b/src/main/java/org/gcube/data/access/storagehub/AuthorizationChecker.java index 31867e7..1fbf168 100644 --- a/src/main/java/org/gcube/data/access/storagehub/AuthorizationChecker.java +++ b/src/main/java/org/gcube/data/access/storagehub/AuthorizationChecker.java @@ -1,5 +1,6 @@ package org.gcube.data.access.storagehub; +import static org.gcube.common.storagehub.model.NodeConstants.*; import java.util.Arrays; import javax.inject.Singleton; @@ -22,7 +23,7 @@ public class AuthorizationChecker { public void checkReadAuthorizationControl(Session session, String id) throws Exception{ Node node = session.getNodeByIdentifier(id); - Item item = ItemHandler.getItem(node, Arrays.asList("hl:accounting","jcr:content")); + Item item = ItemHandler.getItem(node, Arrays.asList(ACCOUNTING_NAME,CONTENT_NAME)); if (item.isShared()) { SharedFolder parentShared = retrieveSharedFolderParent(item, session); @@ -36,37 +37,46 @@ public class AuthorizationChecker { private SharedFolder retrieveSharedFolderParent(Item item, Session session) throws Exception{ if (item instanceof SharedFolder) return (SharedFolder)item; else - return retrieveSharedFolderParent(ItemHandler.getItem(session.getNodeByIdentifier(item.getParentId()), Arrays.asList("hl:accounting","jcr:content")), session); + return retrieveSharedFolderParent(ItemHandler.getItem(session.getNodeByIdentifier(item.getParentId()), Arrays.asList(ACCOUNTING_NAME,CONTENT_NAME)), session); } - public void checkWriteAuthorizationControl(Session session, String id) throws Exception { - + public void checkWriteAuthorizationControl(Session session, String id, boolean isNewItem) throws Exception { + //in case of newItem the id is the parent otherwise the old node to replace Node node = session.getNodeByIdentifier(id); - Item item = ItemHandler.getItem(node, Arrays.asList("hl:accounting","jcr:content")); + Item item = ItemHandler.getItem(node, Arrays.asList(ACCOUNTING_NAME,CONTENT_NAME)); if (item.isShared()) { - //put it in a different method - JackrabbitAccessControlList accessControlList = AccessControlUtils.getAccessControlList(session, node.getPath()); + SharedFolder parentShared = retrieveSharedFolderParent(item, session); + JackrabbitAccessControlList accessControlList = AccessControlUtils.getAccessControlList(session, parentShared.getPath()); AccessControlEntry[] entries = accessControlList.getAccessControlEntries(); + //put it in a different method + for (AccessControlEntry entry: entries) { - if (entry.getPrincipal().getName().equals(AuthorizationProvider.instance.get().getClient().getId())) { + if (entry.getPrincipal().getName().equals(AuthorizationProvider.instance.get().getClient().getId()) || (parentShared.isVreFolder() && entry.getPrincipal().getName().equals(parentShared.getTitle()))) { for (Privilege privilege : entry.getPrivileges()){ AccessType access = AccessType.valueOf(privilege.getName()); - if (access==AccessType.ADMINISTRATOR || access==AccessType.WRITE_ALL || (access==AccessType.WRITE_OWNER && item.getOwner().equals(AuthorizationProvider.instance.get().getClient().getId()))) + if (isNewItem && access!=AccessType.READ_ONLY) return; - else throw new IllegalAccessException("Insufficent Provileges to write node with id "+id); + else + if (!isNewItem && + (access==AccessType.ADMINISTRATOR || access==AccessType.WRITE_ALL || (access==AccessType.WRITE_OWNER && item.getOwner().equals(AuthorizationProvider.instance.get().getClient().getId())))) + return; + } + throw new IllegalAccessException("Insufficent Provileges to write node with id "+id); } } - throw new IllegalAccessException("Insufficent Provileges to write node with id "+id); + } else - if(!item.getOwner().equals(AuthorizationProvider.instance.get().getClient().getId())) - throw new IllegalAccessException("Insufficent Provileges to write node with id "+id); + if(item.getOwner().equals(AuthorizationProvider.instance.get().getClient().getId())) + return; + + throw new IllegalAccessException("Insufficent Provileges to write node with id "+id); } -/* + /* private String retrieveOwner(Node node) { Node nodeOwner; //get Owner @@ -85,5 +95,5 @@ public class AuthorizationChecker { } } -*/ + */ } diff --git a/src/main/java/org/gcube/data/access/storagehub/accounting/AccountingHandler.java b/src/main/java/org/gcube/data/access/storagehub/accounting/AccountingHandler.java index 555b96d..a5c597a 100644 --- a/src/main/java/org/gcube/data/access/storagehub/accounting/AccountingHandler.java +++ b/src/main/java/org/gcube/data/access/storagehub/accounting/AccountingHandler.java @@ -7,6 +7,11 @@ import javax.inject.Singleton; import javax.jcr.Node; import javax.jcr.RepositoryException; import javax.jcr.Session; +import javax.jcr.UnsupportedRepositoryOperationException; +import javax.jcr.version.Version; +import javax.jcr.version.VersionHistory; +import javax.jcr.version.VersionIterator; +import javax.jcr.version.VersionManager; import org.gcube.common.authorization.library.provider.AuthorizationProvider; import org.gcube.common.storagehub.model.items.nodes.accounting.AccountingEntryType; @@ -17,11 +22,12 @@ import org.slf4j.LoggerFactory; @Singleton public class AccountingHandler { - - /*@Attribute("hl:user") - @Attribute("hl:date") - @Attribute("hl:version")*/ - + private static final String USER = "hl:user"; + private static final String DATE = "hl:date"; + private static final String ITEM_NAME = "hl:itemName"; + private static final String ITEM_TYPE = "hl:itemType"; + private static final String MIME_TYPE = "hl:mimeType"; + private static final Logger logger = LoggerFactory.getLogger(AccountingHandler.class); public void createReadObj(String title, Session ses, Node node, boolean saveHistory ) { @@ -35,19 +41,23 @@ public class AccountingHandler { Node accountingNodeParent = directoryNode.getNode(NodeProperty.ACCOUNTING.toString()); Node accountingNode = accountingNodeParent.addNode(UUID.randomUUID().toString(),AccountingEntryType.READ.getNodeTypeDefinition()); - accountingNode.setProperty("hl:user", AuthorizationProvider.instance.get().getClient().getId()); - accountingNode.setProperty("hl:date", Calendar.getInstance()); - accountingNode.setProperty("hl:itemName", title); - - /*try { - //VersionManager vManager = ses.getWorkspace().getVersionManager(); - //VersionManager versionManager = session.getWorkspace().getVersionManager(); - //Version version = versionManager.checkin(node.getPath()); - //Version version = vManager.getBaseVersion(node.getNode("jcr:content").getPath()); - //accountingNode.setProperty("hl:version", version.getName()); + accountingNode.setProperty(USER, AuthorizationProvider.instance.get().getClient().getId()); + accountingNode.setProperty(DATE, Calendar.getInstance()); + accountingNode.setProperty(ITEM_NAME, title); + + try { + VersionManager vManager = ses.getWorkspace().getVersionManager(); + VersionHistory history = vManager.getVersionHistory(node.getNode("jcr:content").getPath()); + VersionIterator versions = history.getAllVersions(); + Version version= null; + while (versions.hasNext()) { + version = versions.nextVersion(); + } + if (version!=null) + accountingNode.setProperty("hl:version", version.getName()); }catch(UnsupportedRepositoryOperationException uropex) { logger.warn("version cannot be retrieved", uropex); - }*/ + } if (saveHistory) ses.save(); } catch (RepositoryException e) { logger.warn("error trying to retrieve accountign node",e); @@ -65,12 +75,12 @@ public class AccountingHandler { Node accountingNodeParent = directoryNode.getNode(NodeProperty.ACCOUNTING.toString()); Node accountingNode = accountingNodeParent.addNode(UUID.randomUUID().toString(),AccountingEntryType.ADD.getNodeTypeDefinition()); - accountingNode.setProperty("hl:user", AuthorizationProvider.instance.get().getClient().getId()); - accountingNode.setProperty("hl:date", Calendar.getInstance()); - accountingNode.setProperty("hl:itemName", title); - accountingNode.setProperty("hl:itemType", itemType); + accountingNode.setProperty(USER, AuthorizationProvider.instance.get().getClient().getId()); + accountingNode.setProperty(DATE, Calendar.getInstance()); + accountingNode.setProperty(ITEM_NAME, title); + accountingNode.setProperty(ITEM_TYPE, itemType); if (mimeType!=null) - accountingNode.setProperty("hl:mimeType", mimeType); + accountingNode.setProperty(MIME_TYPE, mimeType); if (saveHistory) ses.save(); } catch (RepositoryException e) { diff --git a/src/main/java/org/gcube/data/access/storagehub/handlers/ItemHandler.java b/src/main/java/org/gcube/data/access/storagehub/handlers/ItemHandler.java index b169793..0d62f27 100644 --- a/src/main/java/org/gcube/data/access/storagehub/handlers/ItemHandler.java +++ b/src/main/java/org/gcube/data/access/storagehub/handlers/ItemHandler.java @@ -142,14 +142,13 @@ public class ItemHandler { @SuppressWarnings("rawtypes") Class returnType = field.getType(); field.set(obj, getPropertyValue(returnType, node.getProperty(attribute.value()))); - logger.debug("found field {} of type annotated as ListNodes in class {} on node {}", field.getName(), clazz.getName(), node.getName()); }catch(PathNotFoundException e){ - logger.debug("the current node dosn't contain {} property",attribute.value()); + logger.trace("the current node dosn't contain {} property",attribute.value()); } catch (Exception e ) { logger.warn("error setting value",e); } } else if (field.isAnnotationPresent(MapAttribute.class)){ - //logger.debug("found field {} of type annotated as MapAttribute in class {}", field.getName(), clazz.getName()); + logger.trace("found field {} of type annotated as MapAttribute in class {} and node name {}", field.getName(), clazz.getName(), node.getName()); field.setAccessible(true); String exclude = field.getAnnotation(MapAttribute.class).excludeStartWith(); Map mapToset = new HashMap(); @@ -159,9 +158,11 @@ public class ItemHandler { Property prop = iterator.nextProperty(); if (!exclude.isEmpty() && prop.getName().startsWith(exclude)) continue; try{ + logger.trace("adding {} in the map",prop.getName()); + mapToset.put(prop.getName(), getPropertyValue(prop)); }catch(PathNotFoundException e){ - logger.debug("the property [] is not mapped",prop.getName()); + logger.warn("the property {} is not mapped",prop.getName(),e); } catch (Exception e ) { logger.warn("error setting value",e); } @@ -169,7 +170,7 @@ public class ItemHandler { } field.set(obj, mapToset); } else if (field.isAnnotationPresent(ListNodes.class)){ - logger.debug("found field {} of type annotated as ListNodes in class {} on node {}", field.getName(), clazz.getName(), node.getName()); + logger.trace("found field {} of type annotated as ListNodes in class {} on node {}", field.getName(), clazz.getName(), node.getName()); field.setAccessible(true); String exclude = field.getAnnotation(ListNodes.class).excludeTypeStartWith(); String include = field.getAnnotation(ListNodes.class).includeTypeStartWith(); @@ -193,7 +194,7 @@ public class ItemHandler { AttributeRootNode attributeRootNode = (AttributeRootNode)subtype.getAnnotation(AttributeRootNode.class); subTypesMap.put(attributeRootNode.value(), subtype); } - } else logger.debug("no subtypes found for {}",listType.getName()); + } else logger.trace("no subtypes found for {}",listType.getName()); typeToSubtypeMap.put(listType, subTypesMap); @@ -211,7 +212,7 @@ public class ItemHandler { String primaryType = currentNode.getPrimaryNodeType().getName(); - logger.debug("the current node {} has a list",currentNode.getName()); + logger.trace("the current node {} has a list",currentNode.getName()); if (!include.isEmpty() && !primaryType.startsWith(include)) continue; diff --git a/src/main/java/org/gcube/data/access/storagehub/handlers/VRE.java b/src/main/java/org/gcube/data/access/storagehub/handlers/VRE.java new file mode 100644 index 0000000..7cd268f --- /dev/null +++ b/src/main/java/org/gcube/data/access/storagehub/handlers/VRE.java @@ -0,0 +1,48 @@ +package org.gcube.data.access.storagehub.handlers; + +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; + +import javax.jcr.Repository; +import javax.jcr.SimpleCredentials; + +import org.gcube.common.storagehub.model.items.Item; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class VRE { + + private static final Logger logger = LoggerFactory.getLogger(VRE.class); + + private Item vreFolder; + private Future> result; + private VREQueryRetriever vreQueryRetriever; + private ExecutorService executor; + + public VRE(Item item, Repository repository, SimpleCredentials credentials, ExecutorService executor) { + super(); + this.vreFolder = item; + this.executor = executor; + vreQueryRetriever = new VREQueryRetriever(repository, credentials, vreFolder); + result = executor.submit(vreQueryRetriever); + } + + public Item getVreFolder() { + return vreFolder; + } + + public synchronized List getRecents() throws Exception{ + logger.trace("getting recents"); + if (result.isDone()) { + result = executor.submit(vreQueryRetriever); + } + return result.get(); + } + + + +} + + + diff --git a/src/main/java/org/gcube/data/access/storagehub/handlers/VREManager.java b/src/main/java/org/gcube/data/access/storagehub/handlers/VREManager.java new file mode 100644 index 0000000..f5de4da --- /dev/null +++ b/src/main/java/org/gcube/data/access/storagehub/handlers/VREManager.java @@ -0,0 +1,59 @@ +package org.gcube.data.access.storagehub.handlers; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.jcr.SimpleCredentials; +import javax.servlet.ServletContext; + +import org.gcube.common.storagehub.model.items.Item; +import org.gcube.data.access.storagehub.Constants; +import org.gcube.data.access.storagehub.services.RepositoryInitializer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Singleton +public class VREManager { + + private static final Logger logger = LoggerFactory.getLogger(VREManager.class); + + private Map vreMap = new HashMap<>(); + + @Inject + RepositoryInitializer repository; + + ExecutorService executor = Executors.newFixedThreadPool(5); + + SimpleCredentials credentials; + + @Inject + public VREManager(ServletContext context) { + credentials = new SimpleCredentials(context.getInitParameter(Constants.ADMIN_PARAM_NAME),context.getInitParameter(Constants.ADMIN_PARAM_PWD).toCharArray()); + } + + + public synchronized VRE getVRE(String completeName) { + logger.trace("requesting VRE {}",completeName); + if (vreMap.containsKey(completeName)) + return vreMap.get(completeName); + else + return null; + + } + + public synchronized VRE putVRE(Item vreFolder) { + logger.trace("inserting VRE {}",vreFolder.getTitle()); + if (vreMap.containsKey(vreFolder.getTitle())) throw new RuntimeException("something went wrong (vre already present in the map)"); + else { + VRE toReturn = new VRE(vreFolder, repository.getRepository(), credentials, executor); + vreMap.put(vreFolder.getTitle(), toReturn); + return toReturn; + } + + } + +} diff --git a/src/main/java/org/gcube/data/access/storagehub/handlers/VREQueryRetriever.java b/src/main/java/org/gcube/data/access/storagehub/handlers/VREQueryRetriever.java new file mode 100644 index 0000000..917634f --- /dev/null +++ b/src/main/java/org/gcube/data/access/storagehub/handlers/VREQueryRetriever.java @@ -0,0 +1,168 @@ +package org.gcube.data.access.storagehub.handlers; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Callable; + +import javax.jcr.Credentials; +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.Property; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.observation.Event; +import javax.jcr.observation.EventJournal; +import javax.jcr.query.Query; + +import org.gcube.common.storagehub.model.items.Item; +import org.gcube.data.access.storagehub.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class VREQueryRetriever implements Callable> { + + private static final Logger logger = LoggerFactory.getLogger(VREQueryRetriever.class); + + private static final int CACHE_DIMENSION = 50; + + private Repository repository; + private Credentials credentials; + private Item vreFolder; + List cachedList = new ArrayList<>(CACHE_DIMENSION); + long lastTimestamp =0; + + + public VREQueryRetriever(Repository repository, Credentials credentials, Item vreFolder) { + super(); + this.repository = repository; + this.credentials = credentials; + this.vreFolder = vreFolder; + } + + public List call() { + logger.trace("executing recents task"); + Session ses = null; + if (lastTimestamp==0) { + try { + long start = System.currentTimeMillis(); + ses = repository.login(credentials); + String query = String.format("SELECT * FROM [nthl:workspaceLeafItem] AS node WHERE ISDESCENDANTNODE('%s') ORDER BY node.[jcr:lastModified] DESC ",vreFolder.getPath()); + logger.trace("query for recents is {}",query); + Query jcrQuery = ses.getWorkspace().getQueryManager().createQuery(query, Constants.QUERY_LANGUAGE); + jcrQuery.setLimit(CACHE_DIMENSION); + lastTimestamp = System.currentTimeMillis(); + NodeIterator it = jcrQuery.execute().getNodes(); + logger.trace("query for recents took {}",System.currentTimeMillis()-start); + while (it.hasNext()) + cachedList.add(ItemHandler.getItem(it.nextNode(), Arrays.asList("hl:accounting"))); + logger.trace("creating objects took {}",System.currentTimeMillis()-start); + return cachedList.subList(0, 10); + } catch (Exception e) { + logger.error("error querying vre {}",vreFolder.getTitle(),e); + throw new RuntimeException(e); + }finally{ + if (ses!=null) + ses.logout(); + logger.trace("recents task finished"); + } + } else { + try { + + long timestampToUse = lastTimestamp; + lastTimestamp = System.currentTimeMillis(); + + long start = System.currentTimeMillis(); + ses = repository.login(credentials); + final String[] types = { "nthl:workspaceLeafItem", "nthl:workspaceItem"}; + + EventJournal journalChanged = ses.getWorkspace().getObservationManager().getEventJournal(Event.PROPERTY_CHANGED^Event.NODE_REMOVED^Event.NODE_MOVED, vreFolder.getPath(), true, null, types); + journalChanged.skipTo(timestampToUse); + + while (journalChanged.hasNext()) { + Event event = journalChanged.nextEvent(); + switch(event.getType()) { + + case Event.PROPERTY_CHANGED: + if (ses.propertyExists(event.getPath())) { + Property property = ses.getProperty(event.getPath()); + if (property.getName().equalsIgnoreCase("jcr:lastModified")) { + logger.trace("event property changed on {} with value {} and parent {}",property.getName(), property.getValue().getString(), property.getParent().getPath()); + String identifier = property.getParent().getIdentifier(); + cachedList.removeIf(i -> i.getId().equals(identifier)); + Item item = ItemHandler.getItem(property.getParent(), Arrays.asList("hl:accounting")); + insertItemInTheRightPlace(item); + } + } + break; + case Event.NODE_REMOVED: + logger.trace("node removed event received with type {}", event.getIdentifier()); + cachedList.removeIf(i -> { + try { + return i.getId().equals(event.getIdentifier()) && i.getLastModificationTime().getTime().getTime() i.getId().equals(identifier) && !i.getPath().startsWith(vreFolder.getPath())); + } + break; + default: + throw new Exception("error in event handling"); + } + + } + + if (cachedList.size()>CACHE_DIMENSION) + cachedList.subList(51, cachedList.size()).clear(); + logger.trace("retrieving event took {}",System.currentTimeMillis()-start); + return cachedList.subList(0, 10); + } catch (Exception e) { + logger.error("error getting events for vre {}",vreFolder.getTitle(),e); + throw new RuntimeException(e); + }finally{ + if (ses!=null) + ses.logout(); + } + } + + } + + private void insertItemInTheRightPlace(Item item) { + Iterator it = cachedList.iterator(); + int index =0; + while (it.hasNext()) { + Item inListItem = it.next(); + if (item.getLastModificationTime().getTime().getTime()>=inListItem.getLastModificationTime().getTime().getTime()) break; + index++; + } + if (index { @Override public String evaluate(ISDescendant expr, Iterable>> evaluators) { - return String.format("ISDESCENDANTNODE( node , [%s])", expr.getPath().toPath()); + return String.format("ISDESCENDANTNODE('%s')", expr.getPath().toPath()); } @Override diff --git a/src/main/java/org/gcube/data/access/storagehub/services/ItemsCreator.java b/src/main/java/org/gcube/data/access/storagehub/services/ItemsCreator.java index 3d76531..3064b0e 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/ItemsCreator.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/ItemsCreator.java @@ -25,7 +25,6 @@ import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import javax.ws.rs.core.UriInfo; import org.apache.tika.config.TikaConfig; import org.apache.tika.detect.Detector; @@ -50,7 +49,7 @@ import org.gcube.data.access.storagehub.handlers.content.ContentHandler; import org.gcube.data.access.storagehub.handlers.content.ContentHandlerFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - +import static org.gcube.common.storagehub.model.NodeConstants.*; @Path("item") public class ItemsCreator { @@ -80,7 +79,7 @@ public class ItemsCreator { @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @Produces(MediaType.APPLICATION_JSON) @Path("/{id}/create/{type:(?!FILE)[^/?$]*}") - public Response createItem(@Context UriInfo uriInfo, @PathParam("id") String id, @PathParam("type") String type,@QueryParam("name") String name, @QueryParam("description") String description){ + public Response createItem(@PathParam("id") String id, @PathParam("type") String type,@QueryParam("name") String name, @QueryParam("description") String description){ CalledMethodProvider.instance.set(String.format("createItem(%s)",type)); log.info("create generic item called"); Session ses = null; @@ -98,11 +97,11 @@ public class ItemsCreator { log.info("time to connect to repo {}",(System.currentTimeMillis()-start)); Node destination = ses.getNodeByIdentifier(id); - destinationItem = ItemHandler.getItem(destination,Arrays.asList("hl:accounting","jcr:content")); + destinationItem = ItemHandler.getItem(destination,Arrays.asList(ACCOUNTING_NAME,CONTENT_NAME)); if (!(destinationItem instanceof FolderItem)) throw new Exception("an Item must be created into a directory"); - authChecker.checkWriteAuthorizationControl(ses, destinationItem.getId()); + authChecker.checkWriteAuthorizationControl(ses, destinationItem.getId(), true); ses.getWorkspace().getLockManager().lock(destinationItem.getPath(), true, true, 0,login); @@ -119,17 +118,16 @@ public class ItemsCreator { item.setOwner(login); //to inherit hidden property - item.setHidden(destinationItem.isHidden()); + //item.setHidden(destinationItem.isHidden()); log.debug("item prepared, fulfilling content"); log.debug("content prepared"); - Node newnode = ItemHandler.createNodeFromItem(ses, destination, item); - accountingHandler.createFolderAddObj(name, type, null, ses, newnode, false); + Node newNode = ItemHandler.createNodeFromItem(ses, destination, item); + accountingHandler.createFolderAddObj(name, type, null, ses, newNode, false); ses.save(); - log.info("item correctly created"); - return Response.ok(new ItemWrapper<>(item)).build(); - + log.info("item with id {} correctly created",newNode.getIdentifier()); + return Response.ok(newNode.getIdentifier()).build(); }catch(Exception e){ log.error("error creating item", e); throw new WebApplicationException(e); @@ -137,7 +135,8 @@ public class ItemsCreator { if (ses!=null){ if (destinationItem!=null) try { - ses.getWorkspace().getLockManager().unlock(destinationItem.getPath()); + if (ses.getWorkspace().getLockManager().isLocked(destinationItem.getPath())) + ses.getWorkspace().getLockManager().unlock(destinationItem.getPath()); } catch (Throwable t){ log.warn("error unlocking {}", destinationItem.getPath(), t); } @@ -168,10 +167,10 @@ public class ItemsCreator { //TODO: validate input parameters for Item Type log.info("time to connect to repo {}",(System.currentTimeMillis()-start)); Node destination = ses.getNodeByIdentifier(id); - destinationItem = ItemHandler.getItem(destination,Arrays.asList("hl:accounting","jcr:content")); + destinationItem = ItemHandler.getItem(destination,Arrays.asList(ACCOUNTING_NAME,CONTENT_NAME)); log.debug("destination item path is {}",destinationItem.getPath()); if (!(destinationItem instanceof FolderItem)) throw new Exception("an Item must be copyed to another directory"); - authChecker.checkWriteAuthorizationControl(ses, destinationItem.getId()); + ses.getWorkspace().getLockManager().lock(destinationItem.getPath(), true, true, 0,login); ContentHandler handler = getContentHandler(stream , name, destinationItem.getPath()); @@ -179,7 +178,7 @@ public class ItemsCreator { AbstractFileItem item =handler.buildItem(name, description, login); //to inherit hidden property - item.setHidden(destinationItem.isHidden()); + //item.setHidden(destinationItem.isHidden()); log.debug("item prepared, fulfilling content"); log.debug("content prepared"); @@ -188,11 +187,13 @@ public class ItemsCreator { try { newNode = ses.getNode(org.gcube.common.storagehub.model.Paths.append(org.gcube.common.storagehub.model.Paths.getPath(destinationItem.getPath()), name).toPath()); log.info("overwriting the old node"); + authChecker.checkWriteAuthorizationControl(ses, newNode.getIdentifier(), false); versionHandler.checkoutContentNode(newNode, ses); log.trace("replacing content of class {}",item.getContent().getClass()); ItemHandler.replaceContent(ses, newNode,item); }catch(PathNotFoundException pnf) { log.info("creating new node"); + authChecker.checkWriteAuthorizationControl(ses, destinationItem.getId(), true); newNode = ItemHandler.createNodeFromItem(ses, destination, item); versionHandler.makeVersionableContent(newNode, ses); } @@ -201,9 +202,8 @@ public class ItemsCreator { ses.save(); versionHandler.checkinContentNode(newNode, ses); - versionHandler.getContentVersionHistory(newNode, ses); - log.info("item correctly created"); - return Response.ok(new ItemWrapper<>(item)).build(); + log.info("file with id {} correctly created",newNode.getIdentifier()); + return Response.ok(newNode.getIdentifier()).build(); }catch(Throwable e){ log.error("error creating item", e); return Response.serverError().build(); @@ -211,7 +211,8 @@ public class ItemsCreator { if (ses!=null){ if (destinationItem!=null) try { - ses.getWorkspace().getLockManager().unlock(destinationItem.getPath()); + if (ses.getWorkspace().getLockManager().isLocked(destinationItem.getPath())) + ses.getWorkspace().getLockManager().unlock(destinationItem.getPath()); } catch (Throwable t){ log.warn("error unlocking {}", destinationItem.getPath(), t); } diff --git a/src/main/java/org/gcube/data/access/storagehub/services/ItemsManager.java b/src/main/java/org/gcube/data/access/storagehub/services/ItemsManager.java index 49b1c1e..1d87fb9 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/ItemsManager.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/ItemsManager.java @@ -1,5 +1,6 @@ package org.gcube.data.access.storagehub.services; +import static org.gcube.common.storagehub.model.NodeConstants.*; import java.io.InputStream; import java.io.OutputStream; import java.net.URL; @@ -18,7 +19,6 @@ import javax.jcr.Node; import javax.jcr.Session; import javax.jcr.SimpleCredentials; import javax.servlet.ServletContext; -import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.PUT; import javax.ws.rs.Path; @@ -313,8 +313,8 @@ public class ItemsManager { //TODO check if it is possible to change all the ACL on a workspace ses = repository.getRepository().login(new SimpleCredentials(context.getInitParameter(Constants.ADMIN_PARAM_NAME),context.getInitParameter(Constants.ADMIN_PARAM_PWD).toCharArray())); - authChecker.checkWriteAuthorizationControl(ses, destinationId); - authChecker.checkWriteAuthorizationControl(ses, identifier); + authChecker.checkWriteAuthorizationControl(ses, destinationId, true); + authChecker.checkWriteAuthorizationControl(ses, identifier, false); final Node nodeToMove = ses.getNodeByIdentifier(identifier); final Node destination = ses.getNodeByIdentifier(destinationId); @@ -369,7 +369,7 @@ public class ItemsManager { //TODO check if it is possible to change all the ACL on a workspace ses = repository.getRepository().login(new SimpleCredentials(context.getInitParameter(Constants.ADMIN_PARAM_NAME),context.getInitParameter(Constants.ADMIN_PARAM_PWD).toCharArray())); - authChecker.checkWriteAuthorizationControl(ses, identifier); + authChecker.checkWriteAuthorizationControl(ses, identifier, false); final Node nodeToDelete = ses.getNodeByIdentifier(identifier); final Node trashFolder = ses.getNode(Paths.append(Utils.getHomePath(),Constants.TRASH_ROOT_FOLDER_NAME).toPath()); @@ -430,7 +430,7 @@ public class ItemsManager { private boolean hasSharedChildren(FolderItem item, Session session) throws Exception{ Node currentNode = session.getNodeByIdentifier(item.getId()); - for (Item children : Utils.getItemList(currentNode,Arrays.asList("hl:accounting","jcr:content"), null, false)){ + for (Item children : Utils.getItemList(currentNode,Arrays.asList(ACCOUNTING_NAME,CONTENT_NAME), null, false)){ if (children instanceof FolderItem) return (children instanceof SharedFolder) || hasSharedChildren((FolderItem)item, session); } diff --git a/src/main/java/org/gcube/data/access/storagehub/services/WorkspaceManager.java b/src/main/java/org/gcube/data/access/storagehub/services/WorkspaceManager.java index 4954ad1..2bea5f2 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/WorkspaceManager.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/WorkspaceManager.java @@ -13,6 +13,7 @@ import javax.jcr.Session; import javax.jcr.SimpleCredentials; import javax.jcr.query.Query; import javax.jcr.query.QueryResult; +import javax.servlet.ServletContext; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; @@ -33,10 +34,13 @@ import org.gcube.common.storagehub.model.expressions.logical.ISDescendant; import org.gcube.common.storagehub.model.items.Item; import org.gcube.common.storagehub.model.service.ItemList; import org.gcube.common.storagehub.model.service.ItemWrapper; +import org.gcube.data.access.storagehub.AuthorizationChecker; import org.gcube.data.access.storagehub.Constants; import org.gcube.data.access.storagehub.Range; import org.gcube.data.access.storagehub.Utils; import org.gcube.data.access.storagehub.handlers.ItemHandler; +import org.gcube.data.access.storagehub.handlers.VRE; +import org.gcube.data.access.storagehub.handlers.VREManager; import org.gcube.data.access.storagehub.query.sql2.evaluators.Evaluators; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,103 +50,148 @@ import com.fasterxml.jackson.databind.ObjectMapper; @Path("") public class WorkspaceManager { - + private static final Logger log = LoggerFactory.getLogger(WorkspaceManager.class); @Inject RepositoryInitializer repository; - + @Inject Evaluators evaluator; + + @Inject + AuthorizationChecker authChecker; + + + @Inject + ServletContext context; + + @Inject + VREManager vreManager; @RequestScoped @QueryParam("exclude") private List excludes = Collections.emptyList(); + @Path("") @GET @Produces(MediaType.APPLICATION_JSON) - public ItemWrapper getWorkspace(){ + public ItemWrapper getWorkspace(@QueryParam("relPath") String relPath){ CalledMethodProvider.instance.set("getWorkspace"); Session ses = null; - org.gcube.common.storagehub.model.Path absolutePath = Utils.getHomePath(); + org.gcube.common.storagehub.model.Path absolutePath; + if (relPath==null) + absolutePath = Utils.getHomePath(); + else absolutePath = Paths.append(Utils.getHomePath(), relPath); + Item toReturn = null; try{ String login = AuthorizationProvider.instance.get().getClient().getId(); long start = System.currentTimeMillis(); ses = repository.getRepository().login(new SimpleCredentials(login,Utils.getSecurePassword(login).toCharArray())); - log.info("time to connect to repo {}",(System.currentTimeMillis()-start)); - toReturn = ItemHandler.getItem(ses.getNode(absolutePath.toPath()), excludes); + log.trace("time to connect to repo {}",(System.currentTimeMillis()-start)); + Node node = ses.getNode(absolutePath.toPath()); + authChecker.checkReadAuthorizationControl(ses, node.getIdentifier()); + toReturn = ItemHandler.getItem(node, excludes); }catch(Throwable e){ log.error("error reading the node children of {}",absolutePath,e); + throw new WebApplicationException("error getting WS folder "+absolutePath.toPath(),e) ; }finally{ if (ses!=null) ses.logout(); } - + return new ItemWrapper(toReturn); } - - + + private synchronized VRE getVreFolderItem(Session ses) throws Exception{ + org.gcube.common.storagehub.model.Path vrePath = Paths.append(Utils.getHomePath(), Constants.VRE_FOLDER_PARENT_NAME); + ScopeBean bean = new ScopeBean(ScopeProvider.instance.get()); + if (!bean.is(Type.VRE)) throw new Exception("the current scope is not a VRE"); + String entireScopeName= bean.toString().replaceAll("^/(.*)/?$", "$1").replaceAll("/", "-"); + VRE vre = vreManager.getVRE(entireScopeName); + if (vre!=null) return vre; + else { + String query = String.format("SELECT * FROM [nthl:workspaceItem] As node WHERE node.[jcr:title] like '%s' AND ISDESCENDANTNODE('%s')",entireScopeName, vrePath.toPath()); + Query jcrQuery = ses.getWorkspace().getQueryManager().createQuery(query, Constants.QUERY_LANGUAGE); + NodeIterator it = jcrQuery.execute().getNodes(); + + if (!it.hasNext()) throw new Exception("vre folder not found for context "+entireScopeName); + + Node folder = it.nextNode(); + Item vreFolder = ItemHandler.getItem(folder, excludes); + return vreManager.putVRE(vreFolder); + } + + } + + @Path("vrefolder") @GET @Produces(MediaType.APPLICATION_JSON) public ItemWrapper getVreRootFolder(){ CalledMethodProvider.instance.set("getVreRootFolder"); Session ses = null; - - org.gcube.common.storagehub.model.Path vrePath = Paths.append(Utils.getHomePath(), Constants.VRE_FOLDER_PARENT_NAME); - - try{ + try { String login = AuthorizationProvider.instance.get().getClient().getId(); - ScopeBean bean = new ScopeBean(ScopeProvider.instance.get()); - if (!bean.is(Type.VRE)) throw new Exception("the current scope is not a VRE"); - long start = System.currentTimeMillis(); ses = repository.getRepository().login(new SimpleCredentials(login,Utils.getSecurePassword(login).toCharArray())); - log.info("time to connect to repo {}",(System.currentTimeMillis()-start)); - - String entireScopename= bean.toString().replaceAll("^/(.*)/?$", "$1").replaceAll("/", "-"); - - String query = String.format("SELECT * FROM [nthl:workspaceItem] As node WHERE node.[jcr:title] like '%s'", entireScopename); - Query jcrQuery = ses.getWorkspace().getQueryManager().createQuery(query, Constants.QUERY_LANGUAGE); - NodeIterator it = jcrQuery.execute().getNodes(); - - if (!it.hasNext()) throw new Exception("vre folder not found for context "+bean.toString()); - - Node folder = it.nextNode(); - Item item = ItemHandler.getItem(folder, excludes); - - return new ItemWrapper(item); + return new ItemWrapper(getVreFolderItem(ses).getVreFolder()); }catch(Throwable e){ - log.error("error reading node {}",vrePath,e); + log.error("error reading vreNode for context {}",ScopeProvider.instance.get(),e); throw new WebApplicationException("error retrieving vre folder",e); }finally{ if (ses!=null) ses.logout(); - } - + } } - + + @Path("vrefolder/recents") + @GET + @Produces(MediaType.APPLICATION_JSON) + public ItemList getVreFolderRecentsDocument(){ + CalledMethodProvider.instance.set("getVreFolderRecents"); + Session ses = null; + + try{ + String login = AuthorizationProvider.instance.get().getClient().getId(); + ses = repository.getRepository().login(new SimpleCredentials(login,Utils.getSecurePassword(login).toCharArray())); + + VRE vre = getVreFolderItem(ses); + log.trace("VRE retrieved {}",vre.getVreFolder().getTitle()); + List recentItems = vre.getRecents(); + log.trace("recents retrieved {}",vre.getVreFolder().getTitle()); + return new ItemList(recentItems); + }catch(Throwable e){ + log.error("error reading recents for context {}",ScopeProvider.instance.get(),e); + throw new WebApplicationException("error reading recents",e); + }finally{ + if (ses!=null) + ses.logout(); + } + } + + @Path("trash") @GET @Produces(MediaType.APPLICATION_JSON) public ItemWrapper getTrashRootFolder(){ CalledMethodProvider.instance.set("getTrashRootFolder"); Session ses = null; - + org.gcube.common.storagehub.model.Path trashPath = Paths.append(Utils.getHomePath(), Constants.TRASH_ROOT_FOLDER_NAME); - + try{ String login = AuthorizationProvider.instance.get().getClient().getId(); long start = System.currentTimeMillis(); ses = repository.getRepository().login(new SimpleCredentials(login,Utils.getSecurePassword(login).toCharArray())); log.info("time to connect to repo {}",(System.currentTimeMillis()-start)); - - - + + + Node folder = ses.getNode(trashPath.toPath()); Item item = ItemHandler.getItem(folder, excludes); - + return new ItemWrapper(item); }catch(Throwable e){ log.error("error reading the node {}",trashPath,e); @@ -151,16 +200,16 @@ public class WorkspaceManager { if (ses!=null) ses.logout(); } - + } - + @Path("vrefolders") @GET @Produces(MediaType.APPLICATION_JSON) public ItemList getVreFolders(){ CalledMethodProvider.instance.set("getVreFolders"); Session ses = null; - + org.gcube.common.storagehub.model.Path vrePath = Paths.append(Utils.getHomePath(), Constants.VRE_FOLDER_PARENT_NAME); List toReturn = null; try{ @@ -169,21 +218,22 @@ public class WorkspaceManager { toReturn = Utils.getItemList(ses.getNode(vrePath.toPath()) , excludes, null, false); }catch(Throwable e){ log.error("error reading the node children of {}",vrePath,e); + throw new WebApplicationException("error reading the node children of "+vrePath.toPath(),e); }finally{ if (ses!=null) ses.logout(); } - + return new ItemList(toReturn); } - + @Path("vrefolders/paged") @GET @Produces(MediaType.APPLICATION_JSON) public ItemList getVreFoldersPaged(@QueryParam("start") Integer start, @QueryParam("limit") Integer limit){ CalledMethodProvider.instance.set("getVreFoldersPaged"); Session ses = null; - + org.gcube.common.storagehub.model.Path vrePath = Paths.append(Utils.getHomePath(), Constants.VRE_FOLDER_PARENT_NAME); List toReturn = null; try{ @@ -191,15 +241,18 @@ public class WorkspaceManager { ses = repository.getRepository().login(new SimpleCredentials(login,Utils.getSecurePassword(login).toCharArray())); toReturn = Utils.getItemList(ses.getNode(vrePath.toPath()) , excludes, new Range(start, limit), false); }catch(Throwable e){ - log.error("error reading the node children of {}",vrePath,e); + log.error("(paged) error reading the node children of {}",vrePath,e); + throw new WebApplicationException("error reading the node children of "+vrePath.toPath(),e); }finally{ if (ses!=null) ses.logout(); } - + return new ItemList(toReturn); } - + + + @Path("query") @GET @Produces(MediaType.APPLICATION_JSON) @@ -207,41 +260,42 @@ public class WorkspaceManager { CalledMethodProvider.instance.set("searchItems"); Session ses = null; List toReturn = new ArrayList<>(); - + try{ - + ObjectMapper mapper = new ObjectMapper(); Expression expression = mapper.readValue(jsonExpr, Expression.class); String stringExpression = evaluator.evaluate(new And(new ISDescendant(Utils.getHomePath()), expression)); //ADD ALSO LIMIT AND OFFSET - + String orderBy = ""; if (orderField!=null && orderField.size()>0) - orderBy= String.format("ORDER BY %s", orderField.stream().collect(Collectors.joining(",")).toString()); - - + orderBy= String.format("ORDER BY %s", orderField.stream().collect(Collectors.joining(",")).toString()); + + String sql2Query = String.format("SELECT * FROM [%s] AS node WHERE %s %s ",node, stringExpression,orderBy); - + log.info("query sent is {}",sql2Query); - - + + String login = AuthorizationProvider.instance.get().getClient().getId(); ses = repository.getRepository().login(new SimpleCredentials(login,Utils.getSecurePassword(login).toCharArray())); Query jcrQuery = ses.getWorkspace().getQueryManager().createQuery(sql2Query, Constants.QUERY_LANGUAGE); - + if (limit!=null && limit!=-1 ) jcrQuery.setLimit(limit); - + if (offset!=null && offset!=-1 ) jcrQuery.setOffset(offset); - + QueryResult result = jcrQuery.execute(); - + NodeIterator it = result.getNodes(); - + while (it.hasNext()) - toReturn.add(ItemHandler.getItem(it.nextNode(), excludes)); + toReturn.add(ItemHandler.getItem(it.nextNode(), null)); + }catch(Throwable e){ log.error("error executing the query",e); throw new WebServiceException("error executing the query", e); @@ -249,138 +303,8 @@ public class WorkspaceManager { if (ses!=null) ses.logout(); } - + return new ItemList(toReturn); } - - -/* - @POST - @Path("create") - @Consumes({MediaType.MULTIPART_FORM_DATA}) - public Response create(@FormDataParam("item") ItemWrapper itemWrapper, @FormDataParam("file") InputStream stream , @FormDataParam("file") FormDataBodyPart fileDetail, @QueryParam("path") String path){ - Session ses = null; - log.debug("method create called"); - org.gcube.common.storagehub.model.Path absolutePath = Paths.append(Utils.getHomePath(), Paths.getPath(path)); - try{ - final String login = AuthorizationProvider.instance.get().getClient().getId(); - //long start = System.currentTimeMillis(); - ses = repository.getRepository().login(new SimpleCredentials("workspacerep.imarine","gcube2010*onan".toCharArray())); - log.debug("session retrieved"); - ItemHandler handler = new ItemHandler(); - Node parentNode = ses.getNode(absolutePath.toPath()); - Item item = itemWrapper.getItem(); - - if (item instanceof AbstractFileItem){ - if (stream==null) - throw new Exception("invalid item: file without an input stream is not accepted"); - fulfillContent((AbstractFileItem)item, stream, fileDetail, absolutePath.toPath()); - } - - - Calendar now = Calendar.getInstance(); - item.setCreationTime(now); - item.setHidden(false); - item.setLastAction(ItemAction.CREATED); - item.setLastModificationTime(now); - item.setLastModifiedBy(login); - item.setOwner(login); - - handler.createNodeFromItem(ses, parentNode, item, stream); - ses.save(); - }catch(Throwable e){ - log.error("error creating file",e); - return Response.serverError().build(); - } finally{ - if (ses!=null) ses.logout(); - } - return Response.ok().build(); - } - private void fulfillContent(AbstractFileItem item, InputStream stream , FormDataBodyPart fileDetail, String path) { - if (item instanceof GenericFileItem){ - Content content = new Content(); - String remotePath= path+"/"+fileDetail.getContentDisposition().getFileName(); - content.setData("jcr:content"); - content.setRemotePath(remotePath); - content.setSize(fileDetail.getContentDisposition().getSize()); - content.setMimeType(fileDetail.getMediaType().toString()); - String storageId = Utils.getStorageClient(AuthorizationProvider.instance.get().getClient().getId()).getClient().put(true).LFile(stream).RFile(remotePath); - content.setStorageId(storageId); - ((GenericFileItem) item).setContent(content); - } else throw new RuntimeException("type file error"); - } - - @PUT - @Path("{id}/move") - public Response move(@QueryParam("path") String path, @PathParam("id") String identifier){ - Session ses = null; - try{ - final String login = AuthorizationProvider.instance.get().getClient().getId(); - long start = System.currentTimeMillis(); - //ses = RepositoryInitializer.getRepository().login(new SimpleCredentials(login,Utils.getSecurePassword(login).toCharArray())); - //TODO check if it is possible to change all the ACL on a workspace - ses = repository.getRepository().login(new SimpleCredentials("workspacerep.imarine","gcube2010*onan".toCharArray())); - - log.info("time to connect to repo {}",(System.currentTimeMillis()-start)); - final Node nodeToMove = ses.getNodeByIdentifier(identifier); - final Node destination = ses.getNode(path); - Item destinationItem = ItemHandler.getItem(destination,null); - //TODO for now only owner of the destination folder can move file - if (!destinationItem.getOwner().equals(login)){ - /*AccessControlManager accessControlManager = ses.getAccessControlManager(); - boolean canWrite = accessControlManager.hasPrivileges(path, new Privilege[] { - accessControlManager.privilegeFromName(Privilege.JCR_ADD_CHILD_NODES)});*/ - //if (!canWrite) - /* - throw new IllegalAccessException("Insufficent Provileges to write in "+path); - } - final Item item = ItemHandler.getItem(nodeToMove, null); - if (item instanceof SharedFolder){ - throw new Exception("shared item cannot be moved"); - }else if (item instanceof FolderItem){ - if (hasSharedChildren((FolderItem) item, ses)) throw new Exception("folder item with shared children cannot be moved"); - ses.getWorkspace().move(nodeToMove.getPath(), destination.getPath()+"/"+nodeToMove.getName()); - }else { - item.setParentId(destinationItem.getId()); - ses.getWorkspace().move(nodeToMove.getPath(), destination.getPath()+"/"+nodeToMove.getName()); - } - ses.save(); - }catch(Exception e){ - log.error("error moving item with id {} in path {}",identifier, path,e); - return Response.serverError().build(); - } finally{ - if (ses!=null) ses.logout(); - } - return Response.ok().build(); - } - - private boolean hasSharedChildren(FolderItem folder, Session session) throws Exception{ - Node currentNode = session.getNodeByIdentifier(folder.getId()); - for (Item item : Utils.getItemList(currentNode,null)){ - if (item instanceof FolderItem) - return (item instanceof SharedFolder) || hasSharedChildren((FolderItem)item, session); - } - return false; - - } - - @PUT - @Path("{id}/rename") - public Response rename(@QueryParam("newname") String newName, @PathParam("id") String identifier){ - Session ses = null; - try{ - final String login = AuthorizationProvider.instance.get().getClient().getId(); - long start = System.currentTimeMillis(); - ses = repository.getRepository().login(new SimpleCredentials(login,Utils.getSecurePassword(login).toCharArray())); - log.info("time to connect to repo {}",(System.currentTimeMillis()-start)); - }catch(Exception e){ - - } - return Response.ok().build(); - } -*/ - - - }