Search in sources :

Example 6 with SynchronizationRoots

use of org.nuxeo.drive.service.SynchronizationRoots in project nuxeo-drive-server by nuxeo.

the class DefaultTopLevelFolderItem method getChildren.

/*--------------------- FolderItem -----------------*/
@Override
public List<FileSystemItem> getChildren() {
    List<FileSystemItem> children = new ArrayList<FileSystemItem>();
    Map<String, SynchronizationRoots> syncRootsByRepo = Framework.getService(NuxeoDriveManager.class).getSynchronizationRoots(principal);
    for (String repositoryName : syncRootsByRepo.keySet()) {
        try (CloseableCoreSession session = CoreInstance.openCoreSession(repositoryName, principal)) {
            Set<IdRef> syncRootRefs = syncRootsByRepo.get(repositoryName).getRefs();
            Iterator<IdRef> syncRootRefsIt = syncRootRefs.iterator();
            while (syncRootRefsIt.hasNext()) {
                IdRef idRef = syncRootRefsIt.next();
                // See https://jira.nuxeo.com/browse/NXP-11146
                if (!session.hasPermission(idRef, SecurityConstants.READ)) {
                    if (log.isDebugEnabled()) {
                        log.debug(String.format("User %s has no READ access on synchronization root %s, not including it in children.", session.getPrincipal().getName(), idRef));
                    }
                    continue;
                }
                DocumentModel doc = session.getDocument(idRef);
                // NXP-19442: Avoid useless and costly call to DocumentModel#getLockInfo
                FileSystemItem child = getFileSystemItemAdapterService().getFileSystemItem(doc, this, false, false, false);
                if (child == null) {
                    if (log.isDebugEnabled()) {
                        log.debug(String.format("Synchronization root %s cannot be adapted as a FileSystemItem, not including it in children.", idRef));
                    }
                    continue;
                }
                if (log.isDebugEnabled()) {
                    log.debug(String.format("Including synchronization root %s in children.", idRef));
                }
                children.add(child);
            }
        }
    }
    Collections.sort(children);
    return children;
}
Also used : FileSystemItem(org.nuxeo.drive.adapter.FileSystemItem) ArrayList(java.util.ArrayList) CloseableCoreSession(org.nuxeo.ecm.core.api.CloseableCoreSession) SynchronizationRoots(org.nuxeo.drive.service.SynchronizationRoots) IdRef(org.nuxeo.ecm.core.api.IdRef) NuxeoDriveManager(org.nuxeo.drive.service.NuxeoDriveManager) DocumentModel(org.nuxeo.ecm.core.api.DocumentModel)

Example 7 with SynchronizationRoots

use of org.nuxeo.drive.service.SynchronizationRoots in project nuxeo-drive-server by nuxeo.

the class NuxeoDriveManagerImpl method getChangeSummary.

protected FileSystemChangeSummary getChangeSummary(Principal principal, Map<String, Set<IdRef>> lastActiveRootRefs, Map<String, SynchronizationRoots> roots, Map<String, Set<String>> collectionSyncRootMemberIds, long lowerBound, boolean integerBounds) {
    List<FileSystemItemChange> allChanges = new ArrayList<FileSystemItemChange>();
    // Compute the list of all repositories to consider for the aggregate summary
    Set<String> allRepositories = new TreeSet<String>();
    allRepositories.addAll(roots.keySet());
    allRepositories.addAll(lastActiveRootRefs.keySet());
    allRepositories.addAll(collectionSyncRootMemberIds.keySet());
    long syncDate;
    long upperBound;
    if (integerBounds) {
        upperBound = changeFinder.getUpperBound(allRepositories);
        // Truncate sync date to 0 milliseconds
        syncDate = System.currentTimeMillis();
        syncDate = syncDate - (syncDate % 1000);
    } else {
        upperBound = changeFinder.getCurrentDate();
        syncDate = upperBound;
    }
    Boolean hasTooManyChanges = Boolean.FALSE;
    int limit = Integer.parseInt(Framework.getProperty(DOCUMENT_CHANGE_LIMIT_PROPERTY, "1000"));
    if (!allRepositories.isEmpty() && lowerBound >= 0 && upperBound > lowerBound) {
        for (String repositoryName : allRepositories) {
            try (CloseableCoreSession session = CoreInstance.openCoreSession(repositoryName, principal)) {
                // Get document changes
                Set<IdRef> lastRefs = lastActiveRootRefs.get(repositoryName);
                if (lastRefs == null) {
                    lastRefs = Collections.emptySet();
                }
                SynchronizationRoots activeRoots = roots.get(repositoryName);
                if (activeRoots == null) {
                    activeRoots = SynchronizationRoots.getEmptyRoots(repositoryName);
                }
                Set<String> repoCollectionSyncRootMemberIds = collectionSyncRootMemberIds.get(repositoryName);
                if (repoCollectionSyncRootMemberIds == null) {
                    repoCollectionSyncRootMemberIds = Collections.emptySet();
                }
                if (log.isDebugEnabled()) {
                    log.debug(String.format("Start: getting FileSystemItem changes for repository %s / user %s between %s and %s with activeRoots = %s", repositoryName, principal.getName(), lowerBound, upperBound, activeRoots.getPaths()));
                }
                List<FileSystemItemChange> changes;
                if (integerBounds) {
                    changes = changeFinder.getFileSystemChangesIntegerBounds(session, lastRefs, activeRoots, repoCollectionSyncRootMemberIds, lowerBound, upperBound, limit);
                } else {
                    changes = changeFinder.getFileSystemChanges(session, lastRefs, activeRoots, lowerBound, upperBound, limit);
                }
                allChanges.addAll(changes);
            } catch (TooManyChangesException e) {
                hasTooManyChanges = Boolean.TRUE;
                allChanges.clear();
                break;
            }
        }
    }
    // Send back to the client the list of currently active roots to be able
    // to efficiently detect root unregistration events for the next
    // incremental change summary
    Map<String, Set<IdRef>> activeRootRefs = new HashMap<String, Set<IdRef>>();
    for (Map.Entry<String, SynchronizationRoots> rootsEntry : roots.entrySet()) {
        activeRootRefs.put(rootsEntry.getKey(), rootsEntry.getValue().getRefs());
    }
    FileSystemChangeSummary summary = new FileSystemChangeSummaryImpl(allChanges, activeRootRefs, syncDate, upperBound, hasTooManyChanges);
    if (log.isDebugEnabled()) {
        log.debug(String.format("End: getting %d FileSystemItem changes for user %s between %s and %s with activeRoots = %s -> %s", allChanges.size(), principal.getName(), lowerBound, upperBound, roots, summary));
    }
    return summary;
}
Also used : Set(java.util.Set) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) HashMap(java.util.HashMap) FileSystemChangeSummary(org.nuxeo.drive.service.FileSystemChangeSummary) ArrayList(java.util.ArrayList) CloseableCoreSession(org.nuxeo.ecm.core.api.CloseableCoreSession) SynchronizationRoots(org.nuxeo.drive.service.SynchronizationRoots) IdRef(org.nuxeo.ecm.core.api.IdRef) TreeSet(java.util.TreeSet) FileSystemItemChange(org.nuxeo.drive.service.FileSystemItemChange) TooManyChangesException(org.nuxeo.drive.service.TooManyChangesException) Map(java.util.Map) HashMap(java.util.HashMap)

Example 8 with SynchronizationRoots

use of org.nuxeo.drive.service.SynchronizationRoots in project nuxeo-drive-server by nuxeo.

the class NuxeoDriveManagerImpl method isSynchronizationRoot.

@Override
public boolean isSynchronizationRoot(Principal principal, DocumentModel doc) {
    String repoName = doc.getRepositoryName();
    SynchronizationRoots syncRoots = getSynchronizationRoots(principal).get(repoName);
    return syncRoots.getRefs().contains(doc.getRef());
}
Also used : SynchronizationRoots(org.nuxeo.drive.service.SynchronizationRoots)

Example 9 with SynchronizationRoots

use of org.nuxeo.drive.service.SynchronizationRoots in project nuxeo-drive-server by nuxeo.

the class NuxeoDriveManagerImpl method registerSynchronizationRoot.

@Override
public void registerSynchronizationRoot(Principal principal, final DocumentModel newRootContainer, CoreSession session) {
    final String userName = principal.getName();
    if (log.isDebugEnabled()) {
        log.debug(String.format("Registering synchronization root %s for %s", newRootContainer, userName));
    }
    // If new root is child of a sync root, ignore registration, except for
    // the 'Locally Edited' collection: it is under the personal workspace
    // and we want to allow both the personal workspace and the 'Locally
    // Edited' collection to be registered as sync roots
    Map<String, SynchronizationRoots> syncRoots = getSynchronizationRoots(principal);
    SynchronizationRoots synchronizationRoots = syncRoots.get(session.getRepositoryName());
    if (!NuxeoDriveManager.LOCALLY_EDITED_COLLECTION_NAME.equals(newRootContainer.getName())) {
        for (String syncRootPath : synchronizationRoots.getPaths()) {
            String syncRootPrefixedPath = syncRootPath + "/";
            if (newRootContainer.getPathAsString().startsWith(syncRootPrefixedPath)) {
                // the only exception is when the right inheritance is
                // blocked
                // in the hierarchy
                boolean rightInheritanceBlockedInTheHierarchy = false;
                // should get only parents up to the sync root
                Path parentPath = newRootContainer.getPath().removeLastSegments(1);
                while (!"/".equals(parentPath.toString())) {
                    String parentPathAsString = parentPath.toString() + "/";
                    if (!parentPathAsString.startsWith(syncRootPrefixedPath)) {
                        break;
                    }
                    PathRef parentRef = new PathRef(parentPathAsString);
                    if (!session.hasPermission(principal, parentRef, SecurityConstants.READ)) {
                        rightInheritanceBlockedInTheHierarchy = true;
                        break;
                    }
                    parentPath = parentPath.removeLastSegments(1);
                }
                if (!rightInheritanceBlockedInTheHierarchy) {
                    return;
                }
            }
        }
    }
    checkCanUpdateSynchronizationRoot(newRootContainer, session);
    // Unregister any sub-folder of the new root, except for the 'Locally
    // Edited' collection
    String newRootPrefixedPath = newRootContainer.getPathAsString() + "/";
    for (String existingRootPath : synchronizationRoots.getPaths()) {
        if (!existingRootPath.endsWith(NuxeoDriveManager.LOCALLY_EDITED_COLLECTION_NAME)) {
            if (existingRootPath.startsWith(newRootPrefixedPath)) {
                // Unregister the nested root sub-folder first
                PathRef ref = new PathRef(existingRootPath);
                if (session.exists(ref)) {
                    DocumentModel subFolder = session.getDocument(ref);
                    unregisterSynchronizationRoot(principal, subFolder, session);
                }
            }
        }
    }
    UnrestrictedSessionRunner runner = new UnrestrictedSessionRunner(session) {

        @Override
        public void run() {
            if (!newRootContainer.hasFacet(NUXEO_DRIVE_FACET)) {
                newRootContainer.addFacet(NUXEO_DRIVE_FACET);
            }
            fireEvent(newRootContainer, session, NuxeoDriveEvents.ABOUT_TO_REGISTER_ROOT, userName);
            @SuppressWarnings("unchecked") List<Map<String, Object>> subscriptions = (List<Map<String, Object>>) newRootContainer.getPropertyValue(DRIVE_SUBSCRIPTIONS_PROPERTY);
            boolean updated = false;
            for (Map<String, Object> subscription : subscriptions) {
                if (userName.equals(subscription.get("username"))) {
                    subscription.put("enabled", Boolean.TRUE);
                    subscription.put("lastChangeDate", Calendar.getInstance(UTC));
                    updated = true;
                    break;
                }
            }
            if (!updated) {
                Map<String, Object> subscription = new HashMap<String, Object>();
                subscription.put("username", userName);
                subscription.put("enabled", Boolean.TRUE);
                subscription.put("lastChangeDate", Calendar.getInstance(UTC));
                subscriptions.add(subscription);
            }
            newRootContainer.setPropertyValue(DRIVE_SUBSCRIPTIONS_PROPERTY, (Serializable) subscriptions);
            newRootContainer.putContextData(NXAuditEventsService.DISABLE_AUDIT_LOGGER, true);
            newRootContainer.putContextData(NotificationConstants.DISABLE_NOTIFICATION_SERVICE, true);
            newRootContainer.putContextData(CoreSession.SOURCE, "drive");
            DocumentModel savedNewRootContainer = session.saveDocument(newRootContainer);
            newRootContainer.putContextData(NXAuditEventsService.DISABLE_AUDIT_LOGGER, false);
            newRootContainer.putContextData(NotificationConstants.DISABLE_NOTIFICATION_SERVICE, false);
            fireEvent(savedNewRootContainer, session, NuxeoDriveEvents.ROOT_REGISTERED, userName);
            session.save();
        }
    };
    runner.runUnrestricted();
    invalidateSynchronizationRootsCache(userName);
    invalidateCollectionSyncRootMemberCache(userName);
}
Also used : Path(org.nuxeo.common.utils.Path) PathRef(org.nuxeo.ecm.core.api.PathRef) HashMap(java.util.HashMap) SynchronizationRoots(org.nuxeo.drive.service.SynchronizationRoots) DocumentModel(org.nuxeo.ecm.core.api.DocumentModel) UnrestrictedSessionRunner(org.nuxeo.ecm.core.api.UnrestrictedSessionRunner) List(java.util.List) ArrayList(java.util.ArrayList) Map(java.util.Map) HashMap(java.util.HashMap)

Example 10 with SynchronizationRoots

use of org.nuxeo.drive.service.SynchronizationRoots in project nuxeo-drive-server by nuxeo.

the class NuxeoDriveManagerImpl method queryAndFetchSynchronizationRoots.

protected Map<String, SynchronizationRoots> queryAndFetchSynchronizationRoots(CoreSession session, String query) {
    Map<String, SynchronizationRoots> syncRoots = new HashMap<String, SynchronizationRoots>();
    Set<IdRef> references = new LinkedHashSet<IdRef>();
    Set<String> paths = new LinkedHashSet<String>();
    IterableQueryResult results = session.queryAndFetch(query, NXQL.NXQL);
    try {
        for (Map<String, Serializable> result : results) {
            IdRef docRef = new IdRef(result.get("ecm:uuid").toString());
            try {
                DocumentModel doc = session.getDocument(docRef);
                references.add(docRef);
                paths.add(doc.getPathAsString());
            } catch (DocumentNotFoundException e) {
                log.warn(String.format("Document %s not found, not adding it to the list of synchronization roots for user %s.", docRef, session.getPrincipal().getName()));
            } catch (DocumentSecurityException e) {
                log.warn(String.format("User %s cannot access document %s, not adding it to the list of synchronization roots.", session.getPrincipal().getName(), docRef));
            }
        }
    } finally {
        results.close();
    }
    SynchronizationRoots repoSyncRoots = new SynchronizationRoots(session.getRepositoryName(), paths, references);
    syncRoots.put(session.getRepositoryName(), repoSyncRoots);
    return syncRoots;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Serializable(java.io.Serializable) DocumentNotFoundException(org.nuxeo.ecm.core.api.DocumentNotFoundException) HashMap(java.util.HashMap) SynchronizationRoots(org.nuxeo.drive.service.SynchronizationRoots) DocumentSecurityException(org.nuxeo.ecm.core.api.DocumentSecurityException) IdRef(org.nuxeo.ecm.core.api.IdRef) DocumentModel(org.nuxeo.ecm.core.api.DocumentModel) IterableQueryResult(org.nuxeo.ecm.core.api.IterableQueryResult)

Aggregations

SynchronizationRoots (org.nuxeo.drive.service.SynchronizationRoots)11 IdRef (org.nuxeo.ecm.core.api.IdRef)8 ArrayList (java.util.ArrayList)7 NuxeoDriveManager (org.nuxeo.drive.service.NuxeoDriveManager)6 CloseableCoreSession (org.nuxeo.ecm.core.api.CloseableCoreSession)6 DocumentModel (org.nuxeo.ecm.core.api.DocumentModel)6 HashMap (java.util.HashMap)4 FileSystemItem (org.nuxeo.drive.adapter.FileSystemItem)4 Map (java.util.Map)3 LinkedHashSet (java.util.LinkedHashSet)2 FileSystemItemChange (org.nuxeo.drive.service.FileSystemItemChange)2 TooManyChangesException (org.nuxeo.drive.service.TooManyChangesException)2 Serializable (java.io.Serializable)1 HashSet (java.util.HashSet)1 List (java.util.List)1 Set (java.util.Set)1 TreeSet (java.util.TreeSet)1 HttpServletRequest (javax.servlet.http.HttpServletRequest)1 Path (org.nuxeo.common.utils.Path)1 FileSystemChangeSummary (org.nuxeo.drive.service.FileSystemChangeSummary)1