예제 #1
0
  @Test
  public void testCheckInCheckOut() throws Exception {
    DocumentModel doc = new DocumentModelImpl("/", "file#789", "File");
    assertTrue(doc.isCheckedOut());
    doc = session.createDocument(doc);
    assertTrue(session.isCheckedOut(doc.getRef()));
    assertTrue(doc.isCheckedOut());
    session.save();
    assertTrue(session.isCheckedOut(doc.getRef()));
    assertTrue(doc.isCheckedOut());

    DocumentRef verRef = session.checkIn(doc.getRef(), null, null);
    DocumentModel ver = session.getDocument(verRef);
    assertTrue(ver.isVersion());
    doc.refresh();
    assertFalse(session.isCheckedOut(doc.getRef()));
    assertFalse(doc.isCheckedOut());

    session.checkOut(doc.getRef());
    assertTrue(session.isCheckedOut(doc.getRef()));

    // using DocumentModel API
    DocumentRef verRef2 = doc.checkIn(null, null);
    DocumentModel ver2 = session.getDocument(verRef2);
    assertTrue(ver2.isVersion());
    assertFalse(doc.isCheckedOut());
    doc.checkOut();
    assertTrue(doc.isCheckedOut());
  }
예제 #2
0
  @Test
  public void testAllowVersionWrite() {
    DocumentModel doc = session.createDocumentModel("/", "doc", "File");
    doc.setPropertyValue("icon", "icon1");
    doc = session.createDocument(doc);
    DocumentRef verRef = session.checkIn(doc.getRef(), null, null);

    // regular version cannot be written
    DocumentModel ver = session.getDocument(verRef);
    ver.setPropertyValue("icon", "icon2");
    try {
      session.saveDocument(ver);
      fail("Should not allow version write");
    } catch (PropertyException e) {
      assertTrue(e.getMessage(), e.getMessage().contains("Cannot set property on a version"));
    }

    // with proper option, it's allowed
    ver.setPropertyValue("icon", "icon3");
    ver.putContextData(CoreSession.ALLOW_VERSION_WRITE, Boolean.TRUE);
    session.saveDocument(ver);
    // refetch to check
    ver = session.getDocument(verRef);
    assertEquals("icon3", ver.getPropertyValue("icon"));
  }
예제 #3
0
  @Test
  public void testSaveRestoredVersionWithVersionAutoIncrement() {
    // check-in version 1.0, 2.0 and restore version 1.0
    DocumentModel doc = new DocumentModelImpl("/", "myfile", "File");
    doc = session.createDocument(doc);
    doc = session.saveDocument(doc);
    DocumentRef co = doc.getRef();
    DocumentRef ci1 = session.checkIn(co, VersioningOption.MAJOR, "first check-in");
    session.checkOut(co);
    maybeSleepToNextSecond();
    DocumentRef ci2 = session.checkIn(co, VersioningOption.MAJOR, "second check-in");
    waitForFulltextIndexing();
    maybeSleepToNextSecond();
    session.restoreToVersion(co, ci1);

    // save document with auto-increment should produce version 3.0
    doc = session.getDocument(co);
    assertEquals(doc.getVersionLabel(), "1.0");
    doc.getContextData()
        .putScopedValue(
            ScopeType.DEFAULT, VersioningService.VERSIONING_OPTION, VersioningOption.MAJOR);
    // mark as dirty - must change the value
    doc.setPropertyValue("dc:title", doc.getPropertyValue("dc:title") + " dirty");
    doc = session.saveDocument(doc);
    assertEquals(doc.getVersionLabel(), "3.0");
  }
예제 #4
0
  @Override
  public void initTree(
      String sid,
      CoreSession coreSession,
      Map<String, String> parameters,
      PublishedDocumentFactory factory,
      String configName,
      String title) {
    super.initTree(sid, coreSession, parameters, factory, configName, title);

    DocumentRef ref = new PathRef(rootPath);
    boolean exists = coreSession.exists(ref);
    if (!exists) {
      log.debug(
          "Root section "
              + rootPath
              + " doesn't exist. Check "
              + "publicationTreeConfig with name "
              + configName);
    }
    if (exists && coreSession.hasPermission(ref, SecurityConstants.READ)) {
      treeRoot = coreSession.getDocument(new PathRef(rootPath));
      rootNode = new CoreFolderPublicationNode(treeRoot, getConfigName(), sid, factory);
    } else {
      rootNode =
          new VirtualCoreFolderPublicationNode(
              coreSession.getSessionId(), rootPath, getConfigName(), sid, factory);
      sessionId = coreSession.getSessionId();
    }
  }
  @Override
  public String endTask(
      CoreSession coreSession,
      NuxeoPrincipal principal,
      Task task,
      String comment,
      String eventName,
      boolean isValidated)
      throws ClientException {

    // put user comment on the task
    if (!StringUtils.isEmpty(comment)) {
      task.addComment(principal.getName(), comment);
    }

    // end the task, adding boolean marker that task was validated or
    // rejected
    task.setVariable(TaskService.VariableName.validated.name(), String.valueOf(isValidated));
    task.end(coreSession);
    coreSession.saveDocument(task.getDocument());
    // notify
    Map<String, Serializable> eventProperties = new HashMap<String, Serializable>();
    ArrayList<String> notificationRecipients = new ArrayList<String>();
    notificationRecipients.add(task.getInitiator());
    notificationRecipients.addAll(task.getActors());
    eventProperties.put(NotificationConstants.RECIPIENTS_KEY, notificationRecipients);
    // try to resolve document when notifying
    DocumentModel document = null;
    String docId = task.getVariable(TaskService.VariableName.documentId.name());
    String docRepo = task.getVariable(TaskService.VariableName.documentRepositoryName.name());
    if (coreSession.getRepositoryName().equals(docRepo)) {
      try {
        document = coreSession.getDocument(new IdRef(docId));
      } catch (Exception e) {
        log.error(
            String.format(
                "Could not fetch document with id '%s:%s' for notification", docRepo, docId),
            e);
      }
    } else {
      log.error(
          String.format(
              "Could not resolve document for notification: "
                  + "document is on repository '%s' and given session is on "
                  + "repository '%s'",
              docRepo, coreSession.getRepositoryName()));
    }

    TaskEventNotificationHelper.notifyEvent(
        coreSession, document, principal, task, eventName, eventProperties, comment, null);

    String seamEventName =
        isValidated
            ? TaskEventNames.WORKFLOW_TASK_COMPLETED
            : TaskEventNames.WORKFLOW_TASK_REJECTED;
    return seamEventName;
  }
 protected DocumentRoute instantiateAndRun(
     CoreSession session, List<String> docIds, Map<String, Serializable> map) {
   DocumentRoutingService routing = Framework.getLocalService(DocumentRoutingService.class);
   DocumentRoute route = validate(routeDoc, session);
   // create instance and start
   String id =
       Framework.getLocalService(DocumentRoutingService.class)
           .createNewInstance(route.getDocument().getName(), docIds, map, session, true);
   return session.getDocument(new IdRef(id)).getAdapter(DocumentRoute.class);
 }
예제 #7
0
  @Test
  public void testCreateSingleTaskAndRunOperationChain() throws Exception {
    OperationContext ctx = new OperationContext(coreSession);
    ctx.setInput(document);

    List<Task> tasks = taskService.getTaskInstances(document, (NuxeoPrincipal) null, coreSession);
    assertNotNull(tasks);
    assertEquals(0, tasks.size());

    automationService.run(ctx, "createSingleTaskAndRunOperationChain");

    tasks = taskService.getTaskInstances(document, (NuxeoPrincipal) null, coreSession);
    assertEquals(1, tasks.size());

    Task task = tasks.get(0);

    // accept task
    taskService.acceptTask(
        coreSession, (NuxeoPrincipal) coreSession.getPrincipal(), task, "ok i'm in");
    coreSession.save();
    // test task again
    tasks = taskService.getTaskInstances(document, (NuxeoPrincipal) null, coreSession);
    // ended tasks are filtered
    assertEquals(0, tasks.size());

    // check document metadata, refetching doc from core
    document = coreSession.getDocument(document.getRef());
    assertEquals("This document has been accepted", document.getPropertyValue("dc:description"));

    // run another time, and this time reject
    automationService.run(ctx, "createSingleTaskAndRunOperationChain");
    tasks = taskService.getTaskInstances(document, (NuxeoPrincipal) null, coreSession);
    assertEquals(1, tasks.size());
    taskService.rejectTask(
        coreSession,
        (NuxeoPrincipal) coreSession.getPrincipal(),
        tasks.get(0),
        "i don't agree with what you're saying");
    document = coreSession.getDocument(document.getRef());
    assertEquals(
        "This document has been rejected !!!", document.getPropertyValue("dc:description"));
  }
  @Override
  public String getPathById(String uuid, CoreSession session) throws ClientException {
    DocumentModel model = session.getDocument(new IdRef(uuid));
    if (model == null) {
      return null;
    }

    String path = model.getPathAsString();
    Backend backend = getBackend(session);
    return backend.getVirtualPath(path);
  }
예제 #9
0
  @Test
  public void addRemoveToFavoritesTest() {
    DocumentModel testWorkspace =
        session.createDocumentModel("/default-domain/workspaces", "testWorkspace", "Workspace");
    testWorkspace = session.createDocument(testWorkspace);
    DocumentModel testFile =
        session.createDocumentModel(testWorkspace.getPathAsString(), TEST_FILE_NAME, "File");
    testFile = session.createDocument(testFile);

    favoritesManager.addToFavorites(testFile, session);

    testFile = session.getDocument(testFile.getRef());

    assertTrue(favoritesManager.isFavorite(testFile, session));

    favoritesManager.removeFromFavorites(testFile, session);

    testFile = session.getDocument(testFile.getRef());

    assertFalse(favoritesManager.isFavorite(testFile, session));
  }
예제 #10
0
 @Test
 public void testAllowVersionWriteACL() {
   DocumentModel doc = session.createDocumentModel("/", "doc", "File");
   doc = session.createDocument(doc);
   DocumentRef verRef = session.checkIn(doc.getRef(), null, null);
   DocumentModel ver = session.getDocument(verRef);
   ACL acl = new ACLImpl("acl1", false);
   ACE ace = new ACE("princ1", "perm1", true);
   acl.add(ace);
   ACP acp = new ACPImpl();
   acp.addACL(acl);
   // check that ACP can be set
   ver.setACP(acp, true);
 }
예제 #11
0
  @Before
  public void initRepo() throws Exception {
    document = coreSession.createDocumentModel("/", "task-root", "TaskRoot");
    document.setPropertyValue("dc:title", "Task");
    document = coreSession.createDocument(document);

    document = coreSession.createDocumentModel("/", "src", "Folder");
    document.setPropertyValue("dc:title", "Source");
    document = coreSession.createDocument(document);

    coreSession.save();
    document = coreSession.getDocument(document.getRef());

    Framework.getService(EventService.class).waitForAsyncCompletion();
  }
예제 #12
0
  protected List<String> computeAllowedTypes(DocumentModel currentDoc) {
    List<String> types = new ArrayList<String>();

    DocumentModel parent = documentManager.getRootDocument();

    DocumentRef parentRef = currentDoc.getParentRef();
    if (parentRef != null && documentManager.hasPermission(parentRef, SecurityConstants.READ)) {
      parent = documentManager.getDocument(parentRef);
    }

    for (Type type : typeManager.findAllAllowedSubTypesFrom(currentDoc.getType(), parent)) {
      types.add(type.getId());
    }

    return types;
  }
예제 #13
0
  // security on versions, see TestLocalAPIWithCustomVersioning
  @Test
  public void testVersionSecurity() throws Exception {
    DocumentModel folder = new DocumentModelImpl("/", "folder", "Folder");
    folder = session.createDocument(folder);
    ACP acp = new ACPImpl();
    ACE ace = new ACE("princ1", "perm1", true);
    ACL acl = new ACLImpl("acl1", false);
    acl.add(ace);
    acp.addACL(acl);
    session.setACP(folder.getRef(), acp, true);
    DocumentModel file = new DocumentModelImpl("/folder", "file", "File");
    file = session.createDocument(file);
    // set security
    acp = new ACPImpl();
    ace = new ACE("princ2", "perm2", true);
    acl = new ACLImpl("acl2", false);
    acl.add(ace);
    acp.addACL(acl);
    session.setACP(file.getRef(), acp, true);
    session.save();

    DocumentModel proxy = session.publishDocument(file, folder);
    DocumentModel version = session.getLastDocumentVersion(file.getRef());
    session.save();

    // check security on version
    acp = session.getACP(version.getRef());
    ACL[] acls = acp.getACLs();
    assertEquals(2, acls.length);
    acl = acls[0];
    assertEquals(1, acl.size());
    assertEquals("princ2", acl.get(0).getUsername());
    acl = acls[1];
    assertEquals(1 + 3, acl.size()); // 1 + 3 root defaults
    assertEquals("princ1", acl.get(0).getUsername());

    // remove live document (there's a proxy so the version stays)
    session.removeDocument(file.getRef());
    session.save();
    // recheck security on version (works because we're administrator)
    acp = session.getACP(version.getRef());
    assertNull(acp);
    // check proxy still accessible (in another session)
    try (CoreSession session2 = openSessionAs(SecurityConstants.ADMINISTRATOR)) {
      session2.getDocument(proxy.getRef());
    }
  }
예제 #14
0
  public DocumentModel getDocumentFor(String mainTabId, DocumentModel defaultDocument) {
    DocumentModel doc = documentsByMainTabs.get(mainTabId);
    if (doc == null
        || !documentManager.exists(doc.getRef())
        || !documentManager.hasPermission(doc.getRef(), SecurityConstants.READ)) {
      documentsByMainTabs.put(mainTabId, defaultDocument);
      doc = null;
    }

    if (doc != null && !documentManager.exists(new PathRef(doc.getPathAsString()))) {
      // path has changed, refresh the document to have a correct URL
      doc = documentManager.getDocument(doc.getRef());
      documentsByMainTabs.put(mainTabId, doc);
    }

    return doc != null ? doc : defaultDocument;
  }
예제 #15
0
  @Test
  public void testRestoreToVersion() throws Exception {
    String name2 = "file#456";
    DocumentModel doc = new DocumentModelImpl("/", name2, "File");
    doc = session.createDocument(doc);
    DocumentRef docRef = doc.getRef();

    session.save();
    DocumentRef v1Ref = session.checkIn(docRef, null, null);
    assertFalse(session.isCheckedOut(docRef));
    session.checkOut(docRef);
    assertTrue(session.isCheckedOut(docRef));

    doc.setProperty("file", "filename", "second name");
    doc.setProperty("dc", "title", "f1");
    doc.setProperty("dc", "description", "desc 1");
    session.saveDocument(doc);
    session.save();

    maybeSleepToNextSecond();
    DocumentRef v2Ref = session.checkIn(docRef, null, null);
    session.checkOut(docRef);

    DocumentModel newDoc = session.getDocument(docRef);
    assertNotNull(newDoc);
    assertNotNull(newDoc.getRef());
    assertEquals("second name", newDoc.getProperty("file", "filename"));

    waitForFulltextIndexing();
    maybeSleepToNextSecond();
    DocumentModel restoredDoc = session.restoreToVersion(docRef, v1Ref);

    assertNotNull(restoredDoc);
    assertNotNull(restoredDoc.getRef());
    assertNull(restoredDoc.getProperty("file", "filename"));

    waitForFulltextIndexing();
    maybeSleepToNextSecond();
    restoredDoc = session.restoreToVersion(docRef, v2Ref);

    assertNotNull(restoredDoc);
    assertNotNull(restoredDoc.getRef());
    String pr = (String) restoredDoc.getProperty("file", "filename");
    assertEquals("second name", pr);
  }
 protected DocumentRoute instantiateAndRun(CoreSession session, Map<String, Serializable> map) {
   DocumentRoutingService routing = Framework.getLocalService(DocumentRoutingService.class);
   // route model
   DocumentRoute route = routeDoc.getAdapter(DocumentRoute.class);
   // draft -> validated
   if (!route.isValidated()) {
     route = routing.validateRouteModel(route, session);
   }
   session.save();
   // create instance and start
   String id =
       routing.createNewInstance(
           route.getDocument().getName(),
           Collections.singletonList(doc.getId()),
           map,
           session,
           true);
   return session.getDocument(new IdRef(id)).getAdapter(DocumentRoute.class);
 }
 /** Looks if an existing Document has the same value for a given property. */
 public static DocumentModel getExistingDocByPropertyName(
     CoreSession documentManager, String path, String value, String propertyName)
     throws ClientException {
   DocumentModel existing = null;
   String parentId = documentManager.getDocument(new PathRef(path)).getId();
   String query =
       "SELECT * FROM Document WHERE ecm:parentId = '"
           + parentId
           + "' AND "
           + propertyName
           + " = '"
           + value.replace("'", "\\\'")
           + "' AND ecm:currentLifeCycleState != '"
           + LifeCycleConstants.DELETED_STATE
           + "'";
   DocumentModelList docs = documentManager.query(query, 1);
   if (docs.size() > 0) {
     existing = docs.get(0);
   }
   return existing;
 }
 public synchronized void run() {
   TransactionHelper.startTransaction(transactionTimeout);
   synchronized (this) {
     if (isRunning) {
       throw new IllegalStateException("Task already running");
     }
     isRunning = true;
     // versions have no path, target document can be null
     if (rootSource == null) {
       isRunning = false;
       throw new IllegalArgumentException("source node must be specified");
     }
   }
   try {
     session = CoreInstance.openCoreSessionSystem(repositoryName);
     log.info("Starting new import task");
     if (rootDoc != null) {
       // reopen the root to be sure the session is valid
       rootDoc = session.getDocument(rootDoc.getRef());
     }
     recursiveCreateDocumentFromNode(rootDoc, rootSource);
     session.save();
     GenericMultiThreadedImporter.addCreatedDoc(taskId, uploadedFiles);
     TransactionHelper.commitOrRollbackTransaction();
   } catch (Exception e) { // deals with interrupt below
     log.error("Error during import", e);
     ExceptionUtils.checkInterrupt(e);
     notifyImportError();
   } finally {
     log.info("End of task");
     if (session != null) {
       session.close();
       session = null;
     }
     synchronized (this) {
       isRunning = false;
     }
   }
 }
예제 #19
0
  @Test
  public void testGetDocumentWithVersion() throws Exception {
    String name2 = "file#248";
    DocumentModel childFile = new DocumentModelImpl("/", name2, "File");
    childFile = session.createDocument(childFile);
    session.save();
    DocumentRef v1Ref = session.checkIn(childFile.getRef(), null, null);
    session.checkOut(childFile.getRef());

    childFile.setProperty("file", "filename", "second name");
    childFile.setProperty("dc", "title", "f1");
    childFile.setProperty("dc", "description", "desc 1");
    session.saveDocument(childFile);
    session.save();
    maybeSleepToNextSecond();
    DocumentRef v2Ref = session.checkIn(childFile.getRef(), null, null);

    DocumentModel newDoc = session.getDocument(childFile.getRef());
    assertNotNull(newDoc);
    assertNotNull(newDoc.getRef());
    assertEquals("second name", newDoc.getProperty("file", "filename"));

    // restore, no snapshot as already pristine
    waitForFulltextIndexing();
    maybeSleepToNextSecond();
    DocumentModel restoredDoc = session.restoreToVersion(childFile.getRef(), v1Ref);

    assertNotNull(restoredDoc);
    assertNotNull(restoredDoc.getRef());
    assertNull(restoredDoc.getProperty("file", "filename"));

    DocumentModel last = session.getLastDocumentVersion(childFile.getRef());
    assertNotNull(last);
    assertNotNull(last.getRef());
    assertEquals(v2Ref.reference(), last.getId());
    assertEquals("second name", last.getProperty("file", "filename"));
  }
예제 #20
0
  @Test
  public void testVersionLifecycle() throws Exception {
    DocumentModel root = session.getRootDocument();
    DocumentModel doc = new DocumentModelImpl("/", "doc", "File");

    doc = session.createDocument(doc);
    doc.setProperty("dublincore", "title", "t1");
    doc = session.saveDocument(doc);

    session.publishDocument(doc, root);
    session.save();

    // get version
    DocumentModel ver = session.getLastDocumentVersion(doc.getRef());
    assertTrue(ver.isVersion());

    assertEquals("project", ver.getCurrentLifeCycleState());
    ver.followTransition("approve");
    session.save();

    doc = session.getDocument(new PathRef("/doc"));
    ver = session.getLastDocumentVersion(doc.getRef());
    assertEquals("approved", ver.getCurrentLifeCycleState());
  }
예제 #21
0
  @SuppressWarnings({"unchecked", "boxing"})
  public static AdditionalDocumentAuditParams getAuditParamsForUUID(
      String uuid, CoreSession session) {

    AdditionalDocumentAuditParams result = null;
    IdRef ref = new IdRef(uuid);
    if (session.exists(ref)) {
      DocumentModel doc = session.getDocument(ref);

      String targetUUID = null;

      if (doc.isProxy() || doc.isVersion()) {
        SourceDocumentResolver resolver = new SourceDocumentResolver(session, doc);
        resolver.runUnrestricted();
        if (resolver.sourceDocument != null) {
          targetUUID = resolver.sourceDocument.getId();

          // now get from Audit Logs the creation date of
          // the version / proxy
          AuditReader reader = Framework.getLocalService(AuditReader.class);
          FilterMapEntry filter = new FilterMapEntry();
          filter.setColumnName("eventId");
          filter.setOperator("=");
          filter.setQueryParameterName("eventId");
          filter.setObject(DocumentEventTypes.DOCUMENT_CREATED);
          Map<String, FilterMapEntry> filters = new HashMap<String, FilterMapEntry>();
          filters.put("eventId", filter);
          List<LogEntry> entries = reader.getLogEntriesFor(uuid, filters, false);

          if (entries != null && entries.size() > 0) {
            result = new AdditionalDocumentAuditParams();
            result.maxDate = entries.get(0).getEventDate();
            result.targetUUID = targetUUID;
            result.eventId = entries.get(0).getId();
          } else {
            // we have no entry in audit log to get the maxDate
            // fallback to repository timestamp
            // this code is here only for compatibility
            // so that it works before version events were added to
            // the audit log
            if (doc.getPropertyValue("dc:modified") != null) {
              result = new AdditionalDocumentAuditParams();
              Calendar estimatedDate = ((Calendar) doc.getPropertyValue("dc:modified"));

              // We can not directly use the repo timestamp
              // because Audit and VCS can be in separated DB
              // => try to find the matching TS in Audit
              StringBuilder queryString = new StringBuilder();
              queryString.append("from LogEntry log where log.docUUID in (");
              queryString.append("'" + targetUUID + "'");
              if (doc.isVersion()) {
                DocumentModelList proxies = session.getProxies(doc.getRef(), null);
                for (DocumentModel proxy : proxies) {
                  queryString.append(",'" + proxy.getId() + "'");
                }
              }
              queryString.append(",'" + doc.getId() + "'");
              queryString.append(") AND log.eventId IN (");
              queryString.append("'" + DocumentEventTypes.DOCUMENT_CREATED + "'");
              queryString.append(",'" + DocumentEventTypes.DOCUMENT_CHECKEDIN + "'");
              queryString.append(") AND log.eventDate >= :minDate ");
              queryString.append(" order by log.eventId asc");

              estimatedDate.add(Calendar.MILLISECOND, -500);
              Map<String, Object> params = new HashMap<String, Object>();
              params.put("minDate", estimatedDate.getTime());

              List<LogEntry> dateEntries =
                  (List<LogEntry>) reader.nativeQuery(queryString.toString(), params, 0, 20);
              if (dateEntries.size() > 0) {
                result.targetUUID = targetUUID;
                Calendar maxDate = new GregorianCalendar();
                maxDate.setTime(dateEntries.get(0).getEventDate());
                maxDate.add(Calendar.MILLISECOND, -500);
                result.maxDate = maxDate.getTime();
              } else {
                // no other choice : use the VCS TS
                // results may be truncated in some DB config
                result.targetUUID = targetUUID;
                result.maxDate = ((Calendar) doc.getPropertyValue("dc:modified")).getTime();
              }
            }
          }
        }
      }
    }
    return result;
  }
  @Test
  public void testClientSideUser1() throws Exception {

    // ---------------------------------------------
    // Check active factories
    // ---------------------------------------------
    TopLevelFolderItemFactory topLevelFolderItemFactory =
        fileSystemItemAdapterService.getTopLevelFolderItemFactory();
    assertEquals(
        "org.nuxeo.drive.hierarchy.permission.factory.PermissionTopLevelFactory",
        topLevelFolderItemFactory.getName());

    Set<String> activeFactories = fileSystemItemAdapterService.getActiveFileSystemItemFactories();
    assertEquals(5, activeFactories.size());
    assertTrue(activeFactories.contains("collectionSyncRootFolderItemFactory"));
    assertTrue(activeFactories.contains("defaultFileSystemItemFactory"));
    assertTrue(activeFactories.contains("userSyncRootParentFactory"));
    assertTrue(activeFactories.contains("permissionSyncRootFactory"));
    assertTrue(activeFactories.contains("sharedSyncRootParentFactory"));

    // ---------------------------------------------
    // Check top level folder: "Nuxeo Drive"
    // ---------------------------------------------
    Blob topLevelFolderJSON =
        (Blob) clientSession1.newRequest(NuxeoDriveGetTopLevelFolder.ID).execute();
    assertNotNull(topLevelFolderJSON);

    PermissionTopLevelFolderItem topLevelFolder =
        mapper.readValue(topLevelFolderJSON.getStream(), PermissionTopLevelFolderItem.class);

    assertNotNull(topLevelFolder);
    assertEquals(TOP_LEVEL_ID, topLevelFolder.getId());
    assertNull(topLevelFolder.getParentId());
    assertEquals("/" + TOP_LEVEL_ID, topLevelFolder.getPath());
    assertEquals("Nuxeo Drive", topLevelFolder.getName());
    assertTrue(topLevelFolder.isFolder());
    assertEquals("system", topLevelFolder.getCreator());
    assertEquals("system", topLevelFolder.getLastContributor());
    assertFalse(topLevelFolder.getCanRename());
    assertFalse(topLevelFolder.getCanDelete());
    assertFalse(topLevelFolder.getCanCreateChild());

    /**
     *
     *
     * <pre>
     * ===================================================
     * User workspace registered as a synchronization root
     * ===================================================
     * => Expected client side for user1:
     *
     * Nuxeo Drive
     *   |-- My Docs
     *   |     |-- user1File2
     *   |     |-- user1Folder1
     *   |     |     |-- user1File1
     *   |     |     |-- user1Folder2
     *   |     |-- user1Folder3
     *   |     |      |-- user1File3
     *   |     |-- user1Folder4
     *   |
     *   |-- Other Docs
     *   |     |-- user2Folder1
     *   |     |     |-- user2File1
     *   |     |     |-- user2Folder2
     *   |     |-- user2Folder3
     *   |     |     |-- user2File3
     *
     * </pre>
     */
    TransactionHelper.commitOrRollbackTransaction();
    TransactionHelper.startTransaction();
    nuxeoDriveManager.registerSynchronizationRoot(
        session1.getPrincipal(), userWorkspace1, session1);

    TransactionHelper.commitOrRollbackTransaction();
    TransactionHelper.startTransaction();

    // ---------------------------------------------
    // Check top level folder children
    // ---------------------------------------------
    Blob topLevelChildrenJSON =
        (Blob)
            clientSession1
                .newRequest(NuxeoDriveGetChildren.ID)
                .set("id", topLevelFolder.getId())
                .execute();

    ArrayNode topLevelChildren =
        mapper.readValue(topLevelChildrenJSON.getStream(), ArrayNode.class);
    assertNotNull(topLevelChildren);
    assertEquals(2, topLevelChildren.size());

    // Check "My Docs"
    UserSyncRootParentFolderItem userSyncRootParent =
        mapper.readValue(topLevelChildren.get(0), UserSyncRootParentFolderItem.class);
    assertEquals(userWorkspace1ItemId, userSyncRootParent.getId());
    assertEquals(TOP_LEVEL_ID, userSyncRootParent.getParentId());
    assertEquals(userWorkspace1ItemPath, userSyncRootParent.getPath());
    assertEquals("My Docs", userSyncRootParent.getName());
    assertTrue(userSyncRootParent.isFolder());
    assertEquals("user1", userSyncRootParent.getCreator());
    assertEquals("user1", userSyncRootParent.getLastContributor());
    assertFalse(userSyncRootParent.getCanRename());
    assertFalse(userSyncRootParent.getCanDelete());
    // Can create a child since "My Docs" is the user workspace
    assertTrue(userSyncRootParent.getCanCreateChild());

    // Check "Other Docs"
    SharedSyncRootParentFolderItem sharedSyncRootParent =
        mapper.readValue(topLevelChildren.get(1), SharedSyncRootParentFolderItem.class);
    assertEquals(SHARED_SYNC_ROOT_PARENT_ID, sharedSyncRootParent.getId());
    assertEquals(TOP_LEVEL_ID, sharedSyncRootParent.getParentId());
    assertEquals(
        "/" + TOP_LEVEL_ID + "/" + SHARED_SYNC_ROOT_PARENT_ID, sharedSyncRootParent.getPath());
    assertEquals("Other Docs", sharedSyncRootParent.getName());
    assertTrue(sharedSyncRootParent.isFolder());
    assertEquals("system", sharedSyncRootParent.getCreator());
    assertEquals("system", sharedSyncRootParent.getLastContributor());
    assertFalse(sharedSyncRootParent.getCanRename());
    assertFalse(sharedSyncRootParent.getCanDelete());
    assertFalse(sharedSyncRootParent.getCanCreateChild());

    // --------------------------------------------
    // Check user synchronization roots
    // --------------------------------------------
    Blob userSyncRootsJSON =
        (Blob)
            clientSession1
                .newRequest(NuxeoDriveGetChildren.ID)
                .set("id", userSyncRootParent.getId())
                .execute();

    ArrayNode userSyncRoots = mapper.readValue(userSyncRootsJSON.getStream(), ArrayNode.class);
    assertNotNull(userSyncRoots);
    assertEquals(4, userSyncRoots.size());

    DocumentBackedFolderItem folderItem;
    DocumentBackedFileItem childFileItem;
    DocumentBackedFileItem fileItem;
    DocumentBackedFolderItem childFolderItem;

    JsonNode[] rootNodes = sortNodeByName(userSyncRoots);

    // user1File2
    fileItem = mapper.readValue(rootNodes[0], DocumentBackedFileItem.class);
    checkFileItem(
        fileItem,
        DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX,
        user1File2,
        userWorkspace1ItemId,
        userWorkspace1ItemPath,
        "user1File2.txt",
        "user1",
        "user1");

    // user1Folder1
    folderItem = mapper.readValue(rootNodes[1], DocumentBackedFolderItem.class);
    checkFolderItem(
        folderItem,
        DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX,
        user1Folder1,
        userWorkspace1ItemId,
        userWorkspace1ItemPath,
        "user1Folder1",
        "user1",
        "user1");
    Blob folderItemChildrenJSON =
        (Blob)
            clientSession1
                .newRequest(NuxeoDriveGetChildren.ID)
                .set("id", folderItem.getId())
                .execute();
    ArrayNode folderItemChildren =
        mapper.readValue(folderItemChildrenJSON.getStream(), ArrayNode.class);
    assertNotNull(folderItemChildren);
    assertEquals(2, folderItemChildren.size());
    {
      JsonNode[] nodes = sortNodeByName(folderItemChildren);

      // user1File1
      childFileItem = mapper.readValue(nodes[0], DocumentBackedFileItem.class);
      checkFileItem(
          childFileItem,
          DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX,
          user1File1,
          folderItem.getId(),
          folderItem.getPath(),
          "user1File1.txt",
          "user1",
          "user1");

      // user1Folder2
      childFolderItem = mapper.readValue(nodes[1], DocumentBackedFolderItem.class);
      checkFolderItem(
          childFolderItem,
          DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX,
          user1Folder2,
          folderItem.getId(),
          folderItem.getPath(),
          "user1Folder2",
          "user1",
          "user1");
    }

    // user1Folder3
    folderItem = mapper.readValue(rootNodes[2], DocumentBackedFolderItem.class);
    checkFolderItem(
        folderItem,
        DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX,
        user1Folder3,
        userWorkspace1ItemId,
        userWorkspace1ItemPath,
        "user1Folder3",
        "user1",
        "user1");
    {
      folderItemChildrenJSON =
          (Blob)
              clientSession1
                  .newRequest(NuxeoDriveGetChildren.ID)
                  .set("id", folderItem.getId())
                  .execute();
      folderItemChildren = mapper.readValue(folderItemChildrenJSON.getStream(), ArrayNode.class);
      assertNotNull(folderItemChildren);
      assertEquals(1, folderItemChildren.size());
      // user1File3
      childFileItem = mapper.readValue(folderItemChildren.get(0), DocumentBackedFileItem.class);
      checkFileItem(
          childFileItem,
          DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX,
          user1File3,
          folderItem.getId(),
          folderItem.getPath(),
          "user1File3.txt",
          "user1",
          "user1");
    }

    // user1Folder4
    folderItem = mapper.readValue(rootNodes[3], DocumentBackedFolderItem.class);
    checkFolderItem(
        folderItem,
        DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX,
        user1Folder4,
        userWorkspace1ItemId,
        userWorkspace1ItemPath,
        "user1Folder4",
        "user1",
        "user1");

    // ---------------------------------------------
    // Check shared synchronization roots
    // ---------------------------------------------
    Blob sharedSyncRootsJSON =
        (Blob)
            clientSession1
                .newRequest(NuxeoDriveGetChildren.ID)
                .set("id", sharedSyncRootParent.getId())
                .execute();

    List<DefaultSyncRootFolderItem> sharedSyncRoots =
        mapper.readValue(
            sharedSyncRootsJSON.getStream(),
            new TypeReference<List<DefaultSyncRootFolderItem>>() {});
    Collections.sort(sharedSyncRoots);

    assertNotNull(sharedSyncRoots);
    assertEquals(2, sharedSyncRoots.size());

    // user2Folder1
    DefaultSyncRootFolderItem sharedSyncRoot = sharedSyncRoots.get(0);
    checkFolderItem(
        sharedSyncRoot,
        SYNC_ROOT_ID_PREFIX,
        session1.getDocument(user2Folder1.getRef()),
        sharedSyncRootParent.getId(),
        sharedSyncRootParent.getPath(),
        "user2Folder1",
        "user2",
        "user1");
    Blob sharedSyncRootChildrenJSON =
        (Blob)
            clientSession1
                .newRequest(NuxeoDriveGetChildren.ID)
                .set("id", sharedSyncRoot.getId())
                .execute();
    ArrayNode sharedSyncRootChildren =
        mapper.readValue(sharedSyncRootChildrenJSON.getStream(), ArrayNode.class);
    assertNotNull(sharedSyncRootChildren);
    assertEquals(2, sharedSyncRootChildren.size());
    DocumentBackedFolderItem sharedSyncRootChildFolderItem;
    DocumentBackedFileItem sharedSyncRootChildFileItem;
    {
      JsonNode[] nodes = sortNodeByName(sharedSyncRootChildren);
      // user2File1
      sharedSyncRootChildFileItem = mapper.readValue(nodes[0], DocumentBackedFileItem.class);
      checkFileItem(
          sharedSyncRootChildFileItem,
          DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX,
          session1.getDocument(user2File1.getRef()),
          sharedSyncRoot.getId(),
          sharedSyncRoot.getPath(),
          "user2File1.txt",
          "user2",
          "user2");
      // user2Folder2
      sharedSyncRootChildFolderItem = mapper.readValue(nodes[1], DocumentBackedFolderItem.class);
      checkFolderItem(
          sharedSyncRootChildFolderItem,
          DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX,
          session1.getDocument(user2Folder2.getRef()),
          sharedSyncRoot.getId(),
          sharedSyncRoot.getPath(),
          "user2Folder2",
          "user2",
          "user2");
    }
    // user2Folder3
    sharedSyncRoot = sharedSyncRoots.get(1);
    checkFolderItem(
        sharedSyncRoot,
        SYNC_ROOT_ID_PREFIX,
        session1.getDocument(user2Folder3.getRef()),
        sharedSyncRootParent.getId(),
        sharedSyncRootParent.getPath(),
        "user2Folder3",
        "user2",
        "user1");
    sharedSyncRootChildrenJSON =
        (Blob)
            clientSession1
                .newRequest(NuxeoDriveGetChildren.ID)
                .set("id", sharedSyncRoot.getId())
                .execute();
    sharedSyncRootChildren =
        mapper.readValue(sharedSyncRootChildrenJSON.getStream(), ArrayNode.class);
    assertNotNull(sharedSyncRootChildren);
    assertEquals(1, sharedSyncRootChildren.size());
    // user2File3
    sharedSyncRootChildFileItem =
        mapper.readValue(sharedSyncRootChildren.get(0), DocumentBackedFileItem.class);
    checkFileItem(
        sharedSyncRootChildFileItem,
        DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX,
        session1.getDocument(user2File3.getRef()),
        sharedSyncRoot.getId(),
        sharedSyncRoot.getPath(),
        "user2File3.txt",
        "user2",
        "user2");

    /**
     *
     *
     * <pre>
     * =======================================================
     * User workspace NOT registered as a synchronization root
     * =======================================================
     * => Expected client side for user1:
     *
     * Nuxeo Drive
     *   |-- My Docs
     *   |
     *   |-- Other Docs (unchanged)
     *   |     |-- user2Folder1
     *   |     |     |-- user2File1
     *   |     |     |-- user2Folder2
     *   |     |-- user2Folder3
     *   |     |     |-- user2File3
     *
     * </pre>
     */
    TransactionHelper.commitOrRollbackTransaction();
    TransactionHelper.startTransaction();
    nuxeoDriveManager.unregisterSynchronizationRoot(
        session1.getPrincipal(), userWorkspace1, session1);

    TransactionHelper.commitOrRollbackTransaction();
    TransactionHelper.startTransaction();
    // ---------------------------------------------
    // Check "My Docs"
    // ---------------------------------------------
    Blob userSyncRootParentJSON =
        (Blob)
            clientSession1
                .newRequest(NuxeoDriveGetFileSystemItem.ID)
                .set("id", userWorkspace1ItemId)
                .execute();
    assertNotNull(userSyncRootParentJSON);

    userSyncRootParent =
        mapper.readValue(userSyncRootParentJSON.getStream(), UserSyncRootParentFolderItem.class);
    assertEquals(userWorkspace1ItemId, userSyncRootParent.getId());
    assertEquals(TOP_LEVEL_ID, userSyncRootParent.getParentId());
    assertEquals(userWorkspace1ItemPath, userSyncRootParent.getPath());
    assertEquals("My Docs", userSyncRootParent.getName());
    assertTrue(userSyncRootParent.isFolder());
    assertEquals("user1", userSyncRootParent.getCreator());
    assertEquals("user1", userSyncRootParent.getLastContributor());
    assertFalse(userSyncRootParent.getCanRename());
    assertFalse(userSyncRootParent.getCanDelete());
    // Cannot create a child since "My Docs" is only the parent of the
    // synchronization roots, not the user workspace
    assertFalse(userSyncRootParent.getCanCreateChild());

    // --------------------------------------------
    // Check user synchronization roots
    // --------------------------------------------
    userSyncRootsJSON =
        (Blob)
            clientSession1
                .newRequest(NuxeoDriveGetChildren.ID)
                .set("id", userSyncRootParent.getId())
                .execute();

    userSyncRoots = mapper.readValue(userSyncRootsJSON.getStream(), ArrayNode.class);
    assertNotNull(userSyncRoots);
    assertEquals(0, userSyncRoots.size());

    /**
     *
     *
     * <pre>
     * =======================================================
     * User workspace NOT registered as a synchronization root
     * but specific folders yes: user1Folder3, user1Folder4
     * =======================================================
     * => Expected client side for user1:
     *
     * Nuxeo Drive
     *   |-- My Docs
     *   |     |-- user1Folder3
     *   |     |      |-- user1File3
     *   |     |-- user1Folder4
     *   |
     *   |-- Other Docs (unchanged)
     *   |     |-- user2Folder1
     *   |     |     |-- user2File1
     *   |     |     |-- user2Folder2
     *   |     |-- user2Folder3
     *   |     |     |-- user2File3
     *
     * </pre>
     */
    TransactionHelper.commitOrRollbackTransaction();
    TransactionHelper.startTransaction();
    nuxeoDriveManager.registerSynchronizationRoot(session1.getPrincipal(), user1Folder3, session1);
    nuxeoDriveManager.registerSynchronizationRoot(session1.getPrincipal(), user1Folder4, session1);
    TransactionHelper.commitOrRollbackTransaction();
    TransactionHelper.startTransaction();

    // --------------------------------------------
    // Check user synchronization roots
    // --------------------------------------------
    userSyncRootsJSON =
        (Blob)
            clientSession1
                .newRequest(NuxeoDriveGetChildren.ID)
                .set("id", userSyncRootParent.getId())
                .execute();

    userSyncRoots = mapper.readValue(userSyncRootsJSON.getStream(), ArrayNode.class);
    assertNotNull(userSyncRoots);
    assertEquals(2, userSyncRoots.size());

    // user1Folder3
    folderItem = mapper.readValue(userSyncRoots.get(0), DocumentBackedFolderItem.class);
    checkFolderItem(
        folderItem,
        SYNC_ROOT_ID_PREFIX,
        user1Folder3,
        userWorkspace1ItemId,
        userWorkspace1ItemPath,
        "user1Folder3",
        "user1",
        "user1");
    folderItemChildrenJSON =
        (Blob)
            clientSession1
                .newRequest(NuxeoDriveGetChildren.ID)
                .set("id", folderItem.getId())
                .execute();
    folderItemChildren = mapper.readValue(folderItemChildrenJSON.getStream(), ArrayNode.class);
    assertNotNull(folderItemChildren);
    assertEquals(1, folderItemChildren.size());
    // user1File3
    childFileItem = mapper.readValue(folderItemChildren.get(0), DocumentBackedFileItem.class);
    checkFileItem(
        childFileItem,
        DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX,
        user1File3,
        folderItem.getId(),
        folderItem.getPath(),
        "user1File3.txt",
        "user1",
        "user1");
    // user1Folder4
    folderItem = mapper.readValue(userSyncRoots.get(1), DocumentBackedFolderItem.class);
    checkFolderItem(
        folderItem,
        SYNC_ROOT_ID_PREFIX,
        user1Folder4,
        userWorkspace1ItemId,
        userWorkspace1ItemPath,
        "user1Folder4",
        "user1",
        "user1");

    /**
     *
     *
     * <pre>
     * =======================================================
     * Unregister a shared folder: user2Folder1
     * =======================================================
     * => Expected client side for user1:
     *
     * Nuxeo Drive
     *   |-- My Docs (unchanged)
     *   |     |-- user1Folder3
     *   |     |      |-- user1File3
     *   |     |-- user1Folder4
     *   |
     *   |-- Other Docs
     *   |     |-- user2Folder3
     *   |     |     |-- user2File3
     *
     * </pre>
     */
    TransactionHelper.commitOrRollbackTransaction();
    TransactionHelper.startTransaction();
    nuxeoDriveManager.unregisterSynchronizationRoot(
        session1.getPrincipal(), session1.getDocument(user2Folder1.getRef()), session1);
    TransactionHelper.commitOrRollbackTransaction();
    TransactionHelper.startTransaction();

    // ---------------------------------------------
    // Check shared synchronization roots
    // ---------------------------------------------
    sharedSyncRootsJSON =
        (Blob)
            clientSession1
                .newRequest(NuxeoDriveGetChildren.ID)
                .set("id", sharedSyncRootParent.getId())
                .execute();

    sharedSyncRoots =
        mapper.readValue(
            sharedSyncRootsJSON.getStream(),
            new TypeReference<List<DefaultSyncRootFolderItem>>() {});
    assertNotNull(sharedSyncRoots);
    assertEquals(1, sharedSyncRoots.size());

    // user2Folder3
    sharedSyncRoot = sharedSyncRoots.get(0);
    checkFolderItem(
        sharedSyncRoot,
        SYNC_ROOT_ID_PREFIX,
        session1.getDocument(user2Folder3.getRef()),
        sharedSyncRootParent.getId(),
        sharedSyncRootParent.getPath(),
        "user2Folder3",
        "user2",
        "user1");
    sharedSyncRootChildrenJSON =
        (Blob)
            clientSession1
                .newRequest(NuxeoDriveGetChildren.ID)
                .set("id", sharedSyncRoot.getId())
                .execute();
    sharedSyncRootChildren =
        mapper.readValue(sharedSyncRootChildrenJSON.getStream(), ArrayNode.class);
    assertNotNull(sharedSyncRootChildren);
    assertEquals(1, sharedSyncRootChildren.size());
    // user2File3
    sharedSyncRootChildFileItem =
        mapper.readValue(sharedSyncRootChildren.get(0), DocumentBackedFileItem.class);
    checkFileItem(
        sharedSyncRootChildFileItem,
        DEFAULT_FILE_SYSTEM_ITEM_ID_PREFIX,
        session1.getDocument(user2File3.getRef()),
        sharedSyncRoot.getId(),
        sharedSyncRoot.getPath(),
        "user2File3.txt",
        "user2",
        "user2");

    /**
     *
     *
     * <pre>
     * =======================================================
     * Remove permission on a shared folder: user2Folder3
     * =======================================================
     * => Expected client side for user1:
     *
     * Nuxeo Drive
     *   |-- My Docs (unchanged)
     *   |     |-- user1Folder3
     *   |     |      |-- user1File3
     *   |     |-- user1Folder4
     *   |
     *   |-- Other Docs
     *
     * </pre>
     */
    resetPermissions(user2Folder3.getRef(), "user1");

    TransactionHelper.commitOrRollbackTransaction();
    TransactionHelper.startTransaction();
    // ---------------------------------------------
    // Check shared synchronization roots
    // ---------------------------------------------
    sharedSyncRootsJSON =
        (Blob)
            clientSession1
                .newRequest(NuxeoDriveGetChildren.ID)
                .set("id", sharedSyncRootParent.getId())
                .execute();

    sharedSyncRoots =
        mapper.readValue(
            sharedSyncRootsJSON.getStream(),
            new TypeReference<List<DefaultSyncRootFolderItem>>() {});
    assertNotNull(sharedSyncRoots);
    assertEquals(0, sharedSyncRoots.size());
  }
  /**
   * Initializes the test hierarchy.
   *
   * <pre>
   * Server side for user1
   * ==============================
   *
   * /user1 (user workspace)
   *   |-- user1Folder1
   *   |     |-- user1File1
   *   |     |-- user1Folder2
   *   |-- user1File2
   *   |-- user1Folder3
   *   |     |-- user1File3
   *   |-- user1Folder4
   *
   * Server side for user2
   * ==============================
   *
   * /user2 (user workspace)
   *   |-- user2Folder1       (registered as a synchronization root with ReadWrite permission for user1)
   *   |     |-- user2File1
   *   |     |-- user2Folder2
   *   |-- user2File2
   *   |-- user2Folder3       (registered as a synchronization root with ReadWrite permission for user1)
   *   |     |-- user2File3
   *
   * </pre>
   */
  @Before
  public void init() throws Exception {

    // Create test users
    createUser("user1", "user1");
    createUser("user2", "user2");

    // Open a core session for each user
    session1 = coreFeature.openCoreSession("user1");
    session2 = coreFeature.openCoreSession("user2");

    // Create user workspace for each user
    userWorkspace1 = userWorkspaceService.getCurrentUserPersonalWorkspace(session1, null);
    userWorkspace2 = userWorkspaceService.getCurrentUserPersonalWorkspace(session2, null);

    userWorkspace1ItemId = USER_SYNC_ROOT_PARENT_ID_PREFIX + userWorkspace1.getId();
    userWorkspace1ItemPath = "/" + TOP_LEVEL_ID + "/" + userWorkspace1ItemId;

    // Populate user workspaces
    // user1
    user1Folder1 =
        createFolder(session1, userWorkspace1.getPathAsString(), "user1Folder1", "Folder");
    user1File1 =
        createFile(
            session1,
            user1Folder1.getPathAsString(),
            "user1File1",
            "File",
            "user1File1.txt",
            CONTENT_PREFIX + "user1File1");
    user1Folder2 = createFolder(session1, user1Folder1.getPathAsString(), "user1Folder2", "Folder");
    user1File2 =
        createFile(
            session1,
            userWorkspace1.getPathAsString(),
            "user1File2",
            "File",
            "user1File2.txt",
            CONTENT_PREFIX + "user1File2");
    user1Folder3 =
        createFolder(session1, userWorkspace1.getPathAsString(), "user1Folder3", "Folder");
    user1File3 =
        createFile(
            session1,
            user1Folder3.getPathAsString(),
            "user1File3",
            "File",
            "user1File3.txt",
            CONTENT_PREFIX + "user1File3");
    user1Folder4 =
        createFolder(session1, userWorkspace1.getPathAsString(), "user1Folder4", "Folder");
    TransactionHelper.commitOrRollbackTransaction();
    TransactionHelper.startTransaction();
    // user2
    user2Folder1 =
        createFolder(session2, userWorkspace2.getPathAsString(), "user2Folder1", "Folder");
    user2File1 =
        createFile(
            session2,
            user2Folder1.getPathAsString(),
            "user2File1",
            "File",
            "user2File1.txt",
            CONTENT_PREFIX + "user2File1");
    user2Folder2 = createFolder(session2, user2Folder1.getPathAsString(), "user2Folder2", "Folder");
    user2File2 =
        createFile(
            session2,
            userWorkspace2.getPathAsString(),
            "user2File2",
            "File",
            "user2File2.txt",
            CONTENT_PREFIX + "user2File2");
    user2Folder3 =
        createFolder(session2, userWorkspace2.getPathAsString(), "user2Folder3", "Folder");
    user2File3 =
        createFile(
            session2,
            user2Folder3.getPathAsString(),
            "user2File3",
            "File",
            "user2File3.txt",
            CONTENT_PREFIX + "user2File3");
    TransactionHelper.commitOrRollbackTransaction();
    TransactionHelper.startTransaction();
    setPermission(user2Folder1, "user1", SecurityConstants.READ_WRITE, true);
    setPermission(user2Folder3, "user1", SecurityConstants.READ_WRITE, true);

    // Register shared folders as synchronization roots for user1
    nuxeoDriveManager.registerSynchronizationRoot(
        session1.getPrincipal(), session1.getDocument(user2Folder1.getRef()), session1);
    nuxeoDriveManager.registerSynchronizationRoot(
        session1.getPrincipal(), session1.getDocument(user2Folder3.getRef()), session1);

    // Get an Automation client session for user1
    clientSession1 = automationClient.getSession("user1", "user1");

    mapper = new ObjectMapper();
  }
  @Test
  public void testIntegrationTestsSetupAndTearDown() throws Exception {

    // ---------------------------------------------------------
    // Setup the integration tests environment as Administrator
    // ---------------------------------------------------------
    Blob testUserCredentialsBlob =
        (Blob)
            clientSession
                .newRequest(NuxeoDriveSetupIntegrationTests.ID)
                .set("userNames", "joe,jack")
                .execute();
    assertNotNull(testUserCredentialsBlob);

    // Check test users
    String testUserCredentials = IOUtils.toString(testUserCredentialsBlob.getStream(), "UTF-8");
    assertNotNull(testUserCredentials);
    String[] testUserCrendentialsArray = StringUtils.split(testUserCredentials, ",");
    assertEquals(2, testUserCrendentialsArray.length);
    assertTrue(testUserCrendentialsArray[0].startsWith("nuxeoDriveTestUser_joe:"));
    assertTrue(testUserCrendentialsArray[1].startsWith("nuxeoDriveTestUser_jack:"));

    // useMembersGroup is false by default
    NuxeoPrincipal joePrincipal = userManager.getPrincipal("nuxeoDriveTestUser_joe");
    assertNotNull(joePrincipal);
    assertFalse(joePrincipal.getGroups().contains("members"));
    NuxeoPrincipal jackPrincipal = userManager.getPrincipal("nuxeoDriveTestUser_jack");
    assertNotNull(jackPrincipal);
    assertFalse(jackPrincipal.getGroups().contains("members"));

    // Check test workspace
    DocumentRef testWorkspaceRef = new PathRef(TEST_WORKSPACE_PATH);
    DocumentModel testWorkspace = session.getDocument(testWorkspaceRef);
    assertEquals("Workspace", testWorkspace.getType());
    assertEquals("Nuxeo Drive Test Workspace", testWorkspace.getTitle());
    assertTrue(session.hasPermission(joePrincipal, testWorkspaceRef, SecurityConstants.WRITE));
    assertTrue(session.hasPermission(jackPrincipal, testWorkspaceRef, SecurityConstants.WRITE));

    // Create test users' personal workspaces for cleanup check
    userWorkspaceService.getUserPersonalWorkspace(
        "nuxeoDriveTestUser_joe", session.getRootDocument());
    userWorkspaceService.getUserPersonalWorkspace(
        "nuxeoDriveTestUser_jack", session.getRootDocument());
    assertNotNull(
        session.getDocument(new PathRef(USER_WORKSPACE_PARENT_PATH + "/nuxeoDriveTestUser-joe")));
    assertNotNull(
        session.getDocument(new PathRef(USER_WORKSPACE_PARENT_PATH + "/nuxeoDriveTestUser-jack")));

    // ----------------------------------------------------------------------
    // Setup the integration tests environment with other user names without
    // having teared it down previously => should start by cleaning it up
    // ----------------------------------------------------------------------
    testUserCredentialsBlob =
        (Blob)
            clientSession
                .newRequest(NuxeoDriveSetupIntegrationTests.ID)
                .set("userNames", "sarah")
                .set("useMembersGroup", true)
                .execute();
    assertNotNull(testUserCredentialsBlob);

    // Check cleanup
    assertNull(userManager.getPrincipal("nuxeoDriveTestUser_joe"));
    assertNull(userManager.getPrincipal("nuxeoDriveTestUser_jack"));
    // Invalid VCS cache
    session.save();
    try {
      session.getDocument(new PathRef(USER_WORKSPACE_PARENT_PATH + "/nuxeoDriveTestUser-joe"));
      fail("User workspace should not exist.");
    } catch (ClientException e) {
      assertEquals(
          "Failed to get document " + USER_WORKSPACE_PARENT_PATH + "/nuxeoDriveTestUser-joe",
          e.getMessage());
    }
    try {
      session.getDocument(new PathRef(USER_WORKSPACE_PARENT_PATH + "/nuxeoDriveTestUser-jack"));
      fail("User workspace should not exist.");
    } catch (ClientException e) {
      assertEquals(
          "Failed to get document " + USER_WORKSPACE_PARENT_PATH + "/nuxeoDriveTestUser-jack",
          e.getMessage());
    }

    // Check test users
    testUserCredentials = IOUtils.toString(testUserCredentialsBlob.getStream(), "UTF-8");
    assertNotNull(testUserCredentials);
    testUserCrendentialsArray = StringUtils.split(testUserCredentials, ",");
    assertEquals(1, testUserCrendentialsArray.length);
    assertTrue(testUserCrendentialsArray[0].startsWith("nuxeoDriveTestUser_sarah:"));

    NuxeoPrincipal sarahPrincipal = userManager.getPrincipal("nuxeoDriveTestUser_sarah");
    assertNotNull(sarahPrincipal);
    assertTrue(sarahPrincipal.getGroups().contains("members"));

    // Check test workspace
    testWorkspace = session.getDocument(testWorkspaceRef);
    assertEquals("Nuxeo Drive Test Workspace", testWorkspace.getTitle());
    assertTrue(session.hasPermission(sarahPrincipal, testWorkspaceRef, SecurityConstants.WRITE));

    // Create test users' personal workspaces for cleanup check
    userWorkspaceService.getUserPersonalWorkspace(
        "nuxeoDriveTestUser_sarah", session.getRootDocument());
    assertNotNull(
        session.getDocument(new PathRef(USER_WORKSPACE_PARENT_PATH + "/nuxeoDriveTestUser-sarah")));

    // ----------------------------------------------------------------------
    // Try to setup the integration tests environment as an unauthorized
    // user => should fail
    // ----------------------------------------------------------------------
    Session unauthorizedSession =
        automationClient.getSession("nuxeoDriveTestUser_sarah", testUserCrendentialsArray[0]);
    try {
      unauthorizedSession
          .newRequest(NuxeoDriveSetupIntegrationTests.ID)
          .set("userNames", "john,bob")
          .execute();
      fail(
          "NuxeoDrive.SetupIntegrationTests operation should not be callable by a non administrator.");
    } catch (Exception e) {
      // Expected
    }

    // ----------------------------------------------------------------------
    // Try to tear down the integration tests environment as an unauthorized
    // user => should fail
    // ----------------------------------------------------------------------
    try {
      unauthorizedSession.newRequest(NuxeoDriveTearDownIntegrationTests.ID).execute();
      fail(
          "NuxeoDrive.TearDownIntegrationTests operation should not be callable by a non administrator.");
    } catch (Exception e) {
      // Expected
    }

    // ----------------------------------------------------------------------
    // Tear down the integration tests environment as Administrator
    // ----------------------------------------------------------------------
    clientSession.newRequest(NuxeoDriveTearDownIntegrationTests.ID).execute();
    assertTrue(userManager.searchUsers("nuxeoDriveTestUser_").isEmpty());
    // Invalid VCS cache
    session.save();
    try {
      session.getDocument(new PathRef(USER_WORKSPACE_PARENT_PATH + "/nuxeoDriveTestUser-sarah"));
      fail("User workspace should not exist.");
    } catch (ClientException e) {
      assertEquals(
          "Failed to get document " + USER_WORKSPACE_PARENT_PATH + "/nuxeoDriveTestUser-sarah",
          e.getMessage());
    }
    assertFalse(session.exists(testWorkspaceRef));
  }
예제 #25
0
파일: Site.java 프로젝트: nuxeo/lm-labs
 public List<LabsNews> getNews(String pRef) throws ClientException {
   CoreSession session = getCoreSession();
   DocumentModel pageNews = session.getDocument(new IdRef(pRef));
   return Tools.getAdapter(PageNews.class, pageNews, session).getAllNews();
 }
예제 #26
0
  @Test
  public void testVersioningOnLiveProxy() throws Exception {
    DocumentModel folder = session.createDocumentModel("/", "folder", "Folder");
    folder = session.createDocument(folder);
    DocumentModel section = session.createDocumentModel("/", "section", "Folder");
    section = session.createDocument(section);
    DocumentModel doc = session.createDocumentModel("/", "testfile1", "File");
    doc = session.createDocument(doc);
    doc.setPropertyValue("dc:title", "A");
    doc = session.saveDocument(doc);
    DocumentRef docRef = doc.getRef();
    assertTrue(doc.isCheckedOut());
    assertVersion("0.0", doc);
    assertVersionLabel("0.0", doc);
    assertLatestVersion(null, doc);

    // create a live proxy
    DocumentModel proxy = session.createProxy(doc.getRef(), section.getRef());
    assertTrue(proxy.isCheckedOut());
    assertVersion("0.0", proxy);
    assertVersionLabel("0.0", proxy);
    assertLatestVersion(null, proxy);

    // save live proxy with no option, use default
    proxy.setPropertyValue("dc:title", "B");
    proxy = session.saveDocument(proxy);
    assertTrue(proxy.isCheckedOut());
    assertVersion("0.0", proxy);
    assertVersionLabel("0.0", proxy);
    assertLatestVersion(null, proxy);

    // change live proxy and save with minor increment
    proxy.setPropertyValue("dc:title", "C");
    proxy.putContextData(VersioningService.VERSIONING_OPTION, VersioningOption.MINOR);
    proxy = session.saveDocument(proxy);
    assertFalse(proxy.isCheckedOut());
    assertVersion("0.1", proxy);
    assertVersionLabel("0.1", proxy);
    assertLatestVersion("0.1", proxy);

    // check the source document is also changed
    doc = session.getDocument(docRef);
    assertFalse(doc.isCheckedOut());
    assertVersion("0.1", doc);
    assertVersionLabel("0.1", doc);
    assertLatestVersion("0.1", doc);
    DocumentModel v01 = session.getLastDocumentVersion(docRef);
    assertEquals(v01.getId(), session.getBaseVersion(docRef).reference());

    // change with no increment, the proxy is checked out
    proxy.setPropertyValue("dc:title", "D");
    proxy = session.saveDocument(proxy);
    assertTrue(proxy.isCheckedOut());
    assertVersion("0.1", proxy);
    assertVersionLabel("0.1+", proxy);

    // check source doc
    doc = session.getDocument(docRef);
    assertEquals("D", doc.getPropertyValue("dc:title"));
    assertTrue(doc.isCheckedOut());
    assertVersion("0.1", doc);
    assertVersionLabel("0.1+", doc);
  }
예제 #27
0
  @SuppressWarnings("deprecation")
  @Test
  @LocalDeploy("org.nuxeo.ecm.core.test.tests:test-versioningservice-contrib.xml")
  public void testOldNuxeoVersioning() throws Exception {
    ((VersioningComponent) service).service = new CompatVersioningService();

    DocumentModel folder = session.createDocumentModel("/", "folder", "Folder");
    folder = session.createDocument(folder);
    DocumentModel doc = session.createDocumentModel("/", "testfile1", "File");
    doc = session.createDocument(doc);
    doc.setPropertyValue("dc:title", "A");
    maybeSleepToNextSecond();
    doc = session.saveDocument(doc);
    DocumentRef docRef = doc.getRef();
    assertTrue(doc.isCheckedOut());
    assertVersion("1.0", doc);
    assertLatestVersion(null, doc);

    // snapshot A=1.0 and save B
    doc.setPropertyValue("dc:title", "B");
    doc.putContextData(VersioningService.VERSIONING_OPTION, VersioningOption.MINOR);
    maybeSleepToNextSecond();
    doc = session.saveDocument(doc);
    assertTrue(doc.isCheckedOut());
    assertVersion("1.1", doc);
    assertLatestVersion("1.0", doc);

    // another snapshot for B=1.1, using major inc
    doc.putContextData(VersioningService.VERSIONING_OPTION, VersioningOption.MAJOR);
    maybeSleepToNextSecond();
    doc = session.saveDocument(doc);
    assertTrue(doc.isCheckedOut());
    assertVersion("2.0", doc);
    assertLatestVersion("1.1", doc);
    DocumentModel v11 = session.getLastDocumentVersion(docRef);
    assertVersion("1.1", v11);

    // another snapshot but no increment doesn't change anything, doc is
    // clean
    doc.putContextData(
        ScopeType.REQUEST, VersioningDocument.CREATE_SNAPSHOT_ON_SAVE_KEY, Boolean.TRUE);
    doc = session.saveDocument(doc);
    assertTrue(doc.isCheckedOut());
    assertVersion("2.0", doc);
    assertLatestVersion("1.1", doc);

    // now dirty doc and snapshot+inc
    doc.setPropertyValue("dc:title", "C");
    maybeSleepToNextSecond();
    doc = session.saveDocument(doc);
    doc.putContextData(VersioningService.VERSIONING_OPTION, VersioningOption.MINOR);
    maybeSleepToNextSecond();
    doc = session.saveDocument(doc);
    assertTrue(doc.isCheckedOut());
    assertVersion("2.1", doc);
    assertLatestVersion("2.0", doc);

    // another save+inc, no snapshot
    doc.setPropertyValue("dc:title", "D");
    doc.putContextData(VersioningService.VERSIONING_OPTION, VersioningOption.MAJOR);
    maybeSleepToNextSecond();
    doc = session.saveDocument(doc);
    assertTrue(doc.isCheckedOut());
    assertVersion("3.0", doc);
    assertLatestVersion("2.1", doc);

    // checkin/checkout (old style)
    maybeSleepToNextSecond();
    session.checkIn(docRef, null);
    session.checkOut(docRef);
    doc = session.getDocument(docRef);
    assertTrue(doc.isCheckedOut());
    assertVersion("3.1", doc);
    assertLatestVersion("3.0", doc);

    // wait before doing a restore
    session.save();
    waitForAsyncCompletion();

    // restore 1.1 -> 3.2 (snapshots 3.1)
    maybeSleepToNextSecond();
    doc = session.restoreToVersion(docRef, v11.getRef());
    assertFalse(doc.isCheckedOut());
    assertVersion("1.1", doc);
    assertVersionLabel("1.1", doc);
    assertLatestVersion("3.1", doc);

    // checkout restored version
    doc.checkOut();
    assertTrue(doc.isCheckedOut());
    assertVersion("3.2", doc);
    assertVersionLabel("3.2", doc);
    assertLatestVersion("3.1", doc);
  }
  @Test
  public void documentManagementInTestCasesExample() throws ClientException {
    SchemaManager typeService = Framework.getLocalService(SchemaManager.class);

    DocumentType[] types = typeService.getDocumentTypes();
    for (DocumentType type : types) {
      System.out.println(type.getName());
    }

    DocumentModel mydoc = session.createDocumentModel("File");
    // DocumentModel mydoc = session.createDocumentModel("/", "toto",
    // "File");

    mydoc.setPathInfo("/", "toto");
    mydoc.setPropertyValue("dc:title", "Toto");
    mydoc = session.createDocument(mydoc);
    session.save();

    DocumentModelList docs = session.query("SELECT * FROM Document WHERE dc:title = 'Toto'");
    assertEquals(1, docs.size());
    mydoc = docs.get(0);
    assertEquals("toto", mydoc.getName());
    assertEquals("project", mydoc.getCurrentLifeCycleState());

    for (String state : mydoc.getAllowedStateTransitions()) {
      System.out.println("Transition : " + state);
    }

    // session.followTransition(mydoc.getRef(), "approve");
    mydoc.followTransition("approve");

    mydoc.setPropertyValue("dc:description", "My Description");
    mydoc = session.saveDocument(mydoc);
    session.save();

    assertEquals("approved", mydoc.getCurrentLifeCycleState());
    assertEquals("0.0", mydoc.getVersionLabel());
    assertEquals(0, session.getVersions(mydoc.getRef()).size());

    session.checkIn(mydoc.getRef(), VersioningOption.MINOR, "");
    mydoc = session.getDocument(mydoc.getRef());
    assertEquals("0.1", mydoc.getVersionLabel());
    assertEquals(1, session.getVersions(mydoc.getRef()).size());

    DocumentModel folder = session.createDocumentModel("/", "folder", "Folder");
    folder.setPropertyValue("dc:title", "Folder");
    folder = session.createDocument(folder);
    session.save();

    assertEquals(0, session.getChildren(folder.getRef()).size());
    session.publishDocument(mydoc, folder);
    assertEquals(1, session.getChildren(folder.getRef()).size());

    DocumentModel folder2 = session.createDocumentModel("/", "folder2", "Folder");
    folder2.setPropertyValue("dc:title", "Folder2");
    folder2 = session.createDocument(folder2);
    session.save();

    DocumentModel proxy = session.createProxy(mydoc.getRef(), folder2.getRef());

    assertEquals("Toto", proxy.getPropertyValue("dc:title"));
    mydoc.setPropertyValue("dc:title", "Tutu");
    session.saveDocument(mydoc);
    session.save();

    proxy = session.getDocument(proxy.getRef());
    assertEquals("Tutu", proxy.getPropertyValue("dc:title"));

    proxy.setPropertyValue("dc:title", "Tata");
    session.saveDocument(proxy);
    session.save();

    mydoc = session.getDocument(mydoc.getRef());
    assertEquals("Tata", mydoc.getPropertyValue("dc:title"));
  }
  /**
   * Manejador principal del restlet.
   *
   * @param req Request
   * @param res Response
   */
  @Override
  public void handle(Request req, Response res) {
    /* Conflicto con Checkstyle. No se pueden declarar como final los m&eacute;todos de
     * beans EJB que hagan uso de dependencias inyectadas, ya que dichas
     * dependencias toman el valor null.
     * No se declara como final debido a que en ese caso
     * la inyecci&oacute;n de dependencias dejar&iacute;a de funcionar.
     */
    String repo = (String) req.getAttributes().get("repo");
    String cdcDocId = (String) req.getAttributes().get("docid");
    if (cdcDocId == null) {
      handleError(res, "you must specify a CdC source document Id.");
    } else {
      String depth = getQueryParamValue(req, "depth", "1");

      if (repo == null || repo.equals("*")) {
        handleError(res, "you must specify a repository");
      } else {

        int profundidad = Integer.parseInt(depth);
        // String cdcPath =
        // Framework.getProperty(ArchivoConstantes.PROPIEDAD_CDC_PATH);
        DOMDocumentFactory domFactory = new DOMDocumentFactory();
        DOMDocument result = (DOMDocument) domFactory.createDocument();
        try {

          navigationContext.setCurrentServerLocation(new RepositoryLocation(repo));
          documentManager = navigationContext.getOrCreateDocumentManager();
          DocumentModel cdcRoot = documentManager.getDocument(new IdRef(cdcDocId));
          if (cdcRoot != null) {
            Element current = result.createElement("document");

            current.setAttribute("title", cdcRoot.getTitle());
            current.setAttribute("type", cdcRoot.getType());
            current.setAttribute("id", cdcRoot.getId());
            current.setAttribute("path", cdcRoot.getPathAsString());

            result.setRootElement((org.dom4j.Element) current);

            addChildren(result, current, cdcRoot, profundidad);
          } else {
            Element noEncontrado = result.createElement("cdCNoRegistrado");
            noEncontrado.setAttribute("variable", ArchivoConstantes.PROPIEDAD_CDC_PATH);
            noEncontrado.setAttribute("valor", cdcDocId);
            result.setRootElement((org.dom4j.Element) noEncontrado);
            LOG.error(
                "No se ha configurado la ruta del CdC; por favor configure la ruta en la propiedad "
                    + ArchivoConstantes.PROPIEDAD_CDC_PATH);
          }

          res.setEntity(result.asXML(), MediaType.TEXT_XML);
          res.getEntity().setCharacterSet(CharacterSet.UTF_8);

        }
        /**
         * Conflicto con checkstyle. Es necesario capturar la excepci&oacute;n Exception, dado que
         * el c&oacute;digo nativo de Nuxeo lanza dicha excepci&oacute;n. En caso contrario, este
         * c&oacute;digo no compilar&iacute;a
         */
        catch (Exception e) {
          LOG.error(e);
          handleError(res, e);
        }
      }
    }
  }
예제 #30
0
  @Test
  public void shouldIndexMovedSubTree() throws Exception {
    buildAndIndexTree();
    startTransaction();
    DocumentRef ref = new PathRef("/folder0/folder1/folder2");
    Assert.assertTrue(session.exists(ref));
    DocumentModel doc = session.getDocument(ref);

    // move in the same folder : rename
    session.move(ref, doc.getParentRef(), "folderA");

    TransactionHelper.commitOrRollbackTransaction();
    waitForCompletion();
    if (syncMode) {
      // in sync we split recursive update into 2 commands:
      // 1 sync non recurse + 1 async recursive
      assertNumberOfCommandProcessed(9);
    } else {
      assertNumberOfCommandProcessed(8);
    }

    startTransaction();
    SearchResponse searchResponse =
        esa.getClient()
            .prepareSearch(IDX_NAME)
            .setTypes(TYPE_NAME)
            .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
            .setFrom(0)
            .setSize(60)
            .execute()
            .actionGet();
    Assert.assertEquals(10, searchResponse.getHits().getTotalHits());

    // check sub tree search
    searchResponse =
        esa.getClient()
            .prepareSearch(IDX_NAME)
            .setTypes(TYPE_NAME)
            .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
            .setQuery(QueryBuilders.prefixQuery("ecm:path", "/folder0/folder1/folder2"))
            .execute()
            .actionGet();
    Assert.assertEquals(0, searchResponse.getHits().getTotalHits());

    searchResponse =
        esa.getClient()
            .prepareSearch(IDX_NAME)
            .setTypes(TYPE_NAME)
            .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
            .setQuery(QueryBuilders.prefixQuery("ecm:path", "/folder0/folder1/folderA"))
            .execute()
            .actionGet();
    Assert.assertEquals(8, searchResponse.getHits().getTotalHits());

    searchResponse =
        esa.getClient()
            .prepareSearch(IDX_NAME)
            .setTypes(TYPE_NAME)
            .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
            .setQuery(QueryBuilders.prefixQuery("ecm:path", "/folder0/folder1"))
            .execute()
            .actionGet();
    Assert.assertEquals(9, searchResponse.getHits().getTotalHits());
  }