public void testImmediateRemoval() throws Exception {
    eagerCleaner.setEagerOrphanCleanup(false);

    final StoreRef storeRef = nodeService.createStore("test", getName() + "-" + GUID.generate());
    RetryingTransactionCallback<ContentData> testCallback =
        new RetryingTransactionCallback<ContentData>() {
          public ContentData execute() throws Throwable {
            // Create some content
            NodeRef rootNodeRef = nodeService.getRootNode(storeRef);
            Map<QName, Serializable> properties = new HashMap<QName, Serializable>(13);
            properties.put(ContentModel.PROP_NAME, (Serializable) "test.txt");
            NodeRef contentNodeRef =
                nodeService
                    .createNode(
                        rootNodeRef,
                        ContentModel.ASSOC_CHILDREN,
                        ContentModel.ASSOC_CHILDREN,
                        ContentModel.TYPE_CONTENT,
                        properties)
                    .getChildRef();
            ContentWriter writer =
                contentService.getWriter(contentNodeRef, ContentModel.PROP_CONTENT, true);
            writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
            writer.putContent("INITIAL CONTENT");
            ContentData contentData = writer.getContentData();

            // Delete the first node
            nodeService.deleteNode(contentNodeRef);

            // Done
            return contentData;
          }
        };
    ContentData contentData =
        transactionService.getRetryingTransactionHelper().doInTransaction(testCallback);
    // Make sure that the content URL still exists
    ContentReader reader = contentService.getRawReader(contentData.getContentUrl());
    assertNotNull(reader);
    assertTrue("Content should not have been eagerly deleted.", reader.exists());

    // fire the cleaner
    cleaner.setProtectDays(0);
    cleaner.execute();

    reader = contentService.getRawReader(contentData.getContentUrl());
    // the content should have disappeared as it is not in the database
    assertFalse("Unprotected content was not deleted", reader.exists());
    assertTrue("Content listener was not called", deletedUrls.contains(reader.getContentUrl()));
  }
  public void testProtectedRemoval() throws Exception {
    cleaner.setProtectDays(1);
    // add some content to the store
    ContentWriter writer = store.getWriter(ContentStore.NEW_CONTENT_CONTEXT);
    writer.putContent("ABC");
    String contentUrl = writer.getContentUrl();

    // fire the cleaner
    cleaner.execute();

    // the content should have disappeared as it is not in the database
    assertTrue("Protected content was deleted", store.exists(contentUrl));
    assertFalse(
        "Content listener was called with deletion of protected URL",
        deletedUrls.contains(contentUrl));
  }
  private void clean() {
    ContentStoreCleanerListener listener =
        new ContentStoreCleanerListener() {
          private int count = 0;

          public void beforeDelete(ContentStore store, String contentUrl)
              throws ContentIOException {
            count++;
            if (count % 1000 == 0) {
              System.out.println(String.format("   Total deleted: %6d", count));
            }
          }
        };
    // We use the default cleaners, but fix them up a bit
    EagerContentStoreCleaner eagerCleaner =
        (EagerContentStoreCleaner) ctx.getBean("eagerContentStoreCleaner");
    eagerCleaner.setListeners(Collections.singletonList(listener));
    eagerCleaner.setStores(Collections.singletonList(contentStore));
    cleaner = (ContentStoreCleaner) ctx.getBean("contentStoreCleaner");
    cleaner.setProtectDays(0);

    // The cleaner has its own txns
    cleaner.execute();
  }