/** A simple audit entry Currently we ignore filtering here. */
  public void audit(String source, String description, NodeRef key, Object... args) {
    final AuditState auditInfo = new AuditState(auditConfiguration);
    AuditMode auditMode = AuditMode.UNSET;
    try {
      auditMode = onApplicationAudit(auditMode, auditInfo, source, description, key, args);
      if ((auditMode == AuditMode.ALL) || (auditMode == AuditMode.SUCCESS)) {
        RetryingTransactionCallback<Object> cb =
            new RetryingTransactionCallback<Object>() {
              public Object execute() throws Throwable {
                auditDAO.audit(auditInfo);
                return null;
              }
            };
        transactionService.getRetryingTransactionHelper().doInTransaction(cb, false, false);
      }
    } catch (Throwable t) {
      auditMode = onError(auditMode, auditInfo, t, source, description, key, args);
      if ((auditMode == AuditMode.ALL) || (auditMode == AuditMode.FAIL)) {
        try {
          RetryingTransactionCallback<Object> cb =
              new RetryingTransactionCallback<Object>() {
                public Object execute() throws Throwable {
                  auditDAO.audit(auditInfo);
                  return null;
                }
              };

          transactionService.getRetryingTransactionHelper().doInTransaction(cb, false, true);
        } catch (Throwable tt) {
          throw new AuditException("Failed to audit exception", new Object[] {tt}, t);
        }
      }
      throw new AuditException("Application audit failed", t);
    }
  }
  /** Initialise - after bootstrap of schema and tenant admin service */
  public void init() {
    PropertyCheck.mandatory(this, "dictionaryDAO", dictionaryDAO);
    PropertyCheck.mandatory(this, "contentService", contentService);
    PropertyCheck.mandatory(this, "nodeService", nodeService);
    PropertyCheck.mandatory(this, "tenantAdminService", tenantAdminService);
    PropertyCheck.mandatory(this, "namespaceService", namespaceService);
    PropertyCheck.mandatory(this, "messageService", messageService);
    PropertyCheck.mandatory(this, "transactionService", transactionService);
    PropertyCheck.mandatory(this, "policyComponent", policyComponent);

    if (onLoadDynamicModelDelegate == null) {
      onLoadDynamicModelDelegate =
          policyComponent.registerClassPolicy(DynamicModelPolicies.OnLoadDynamicModel.class);
    }

    transactionService
        .getRetryingTransactionHelper()
        .doInTransaction(
            new RetryingTransactionCallback<Object>() {
              public Object execute() throws Exception {
                onDictionaryInit();
                initMessages();

                return (Object) null;
              }
            },
            transactionService.isReadOnly(),
            false);
  }
  public void testLoggingAutoActivate() throws Throwable {
    assertFalse(
        "Auto-logging of misuse of the wrapper should be off",
        BorrowedConnectionProxy.isCallStackTraced());

    UserTransaction txn = transactionService.getUserTransaction();
    Connection connection;
    try {
      txn.begin();
      // Dig the proxy out of ... somewhere
      ConnectionHolder conHolder =
          (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
      connection = conHolder.getConnection();
      txn.commit();
    } catch (Throwable e) {
      try {
        txn.rollback();
      } catch (Throwable ee) {
      }
      throw e;
    }
    // Now mess with the connection, which is protected by the Hibernate wrapper
    try {
      connection.commit();
      fail("Use case should have generated a HibernateException");
    } catch (HibernateException e) {
      // Expected
    }
    assertTrue(
        "Auto-logging of misuse of the wrapper should now be on",
        BorrowedConnectionProxy.isCallStackTraced());

    // Now start a new transaction and we should see logging
    txn = transactionService.getUserTransaction();
    try {
      txn.begin();
      // Dig the proxy out of ... somewhere
      ConnectionHolder conHolder =
          (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
      connection = conHolder.getConnection();
      txn.commit();
    } catch (Throwable e) {
      try {
        txn.rollback();
      } catch (Throwable ee) {
      }
      throw e;
    }
    // Now mess with the connection, which is protected by the Hibernate wrapper
    try {
      connection.commit();
      fail("Use case should have generated a HibernateException");
    } catch (HibernateException e) {
      // Expected
    }
    // Check for error logs
  }
  /**
   * @param storeValue
   * @param rootPath
   * @param context
   * @param nodeService
   * @param searchService
   * @param namespaceService
   * @param tenantService
   * @param m_transactionService
   */
  private void initializeRootNode(
      String storeValue,
      String rootPath,
      WebApplicationContext context,
      NodeService nodeService,
      SearchService searchService,
      NamespaceService namespaceService,
      TenantService tenantService,
      TransactionService m_transactionService) {

    // Use the system user as the authenticated context for the filesystem initialization

    AuthenticationContext authComponent =
        (AuthenticationContext) context.getBean("authenticationContext");
    authComponent.setSystemUserAsCurrentUser();

    // Wrap the initialization in a transaction

    UserTransaction tx = m_transactionService.getUserTransaction(true);

    try {
      // Start the transaction

      if (tx != null) tx.begin();

      StoreRef storeRef = new StoreRef(storeValue);

      if (nodeService.exists(storeRef) == false) {
        throw new RuntimeException("No store for path: " + storeRef);
      }

      NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);

      List<NodeRef> nodeRefs =
          searchService.selectNodes(storeRootNodeRef, rootPath, null, namespaceService, false);

      if (nodeRefs.size() > 1) {
        throw new RuntimeException(
            "Multiple possible children for : \n"
                + "   path: "
                + rootPath
                + "\n"
                + "   results: "
                + nodeRefs);
      } else if (nodeRefs.size() == 0) {
        throw new RuntimeException("Node is not found for : \n" + "   root path: " + rootPath);
      }

      defaultRootNode = nodeRefs.get(0);

      // Commit the transaction
      if (tx != null) tx.commit();
    } catch (Exception ex) {
      logger.error(ex);
    } finally {
      // Clear the current system user

      authComponent.clearCurrentSecurityContext();
    }
  }
  /**
   * Internal audit of a method invocation
   *
   * @param mi - the method to audit
   * @return - the return object from the audited method
   * @throws Throwable - any Throwable that can be thrown by th audtied method.
   */
  public Object auditImpl(MethodInvocation mi, boolean execute) throws Throwable {
    final AuditState auditInfo = new AuditState(auditConfiguration);
    // RecordOptions recordOptions = auditModel.getAuditRecordOptions(mi);
    AuditMode auditMode = AuditMode.UNSET;
    try {
      Object o = null;
      auditMode = beforeInvocation(auditMode, auditInfo, mi);
      if (execute) {
        o = mi.proceed();
        auditMode = postInvocation(auditMode, auditInfo, mi, o);
      }
      if ((auditMode == AuditMode.ALL) || (auditMode == AuditMode.SUCCESS)) {
        RetryingTransactionCallback<Object> cb =
            new RetryingTransactionCallback<Object>() {
              public Object execute() throws Throwable {
                auditDAO.audit(auditInfo);
                return null;
              }
            };
        boolean requiresNew =
            (AlfrescoTransactionSupport.getTransactionReadState() != TxnReadState.TXN_READ_WRITE);
        transactionService.getRetryingTransactionHelper().doInTransaction(cb, false, requiresNew);
      }
      return o;
    } catch (Throwable t) {
      auditMode = onError(auditMode, auditInfo, mi, t);
      if ((auditMode == AuditMode.ALL) || (auditMode == AuditMode.FAIL)) {
        try {
          RetryingTransactionCallback<Object> cb =
              new RetryingTransactionCallback<Object>() {
                public Object execute() throws Throwable {
                  auditDAO.audit(auditInfo);
                  return null;
                }
              };

          transactionService.getRetryingTransactionHelper().doInTransaction(cb, false, true);
        } catch (Throwable tt) {
          throw new AuditException("Failed to audit exception", new Object[] {tt}, t);
        }
      }
      throw t;
    }
  }
  @Override
  protected void onBootstrap(ApplicationEvent event) {
    // Do nothing if the repo is read-only
    if (transactionService.isReadOnly()) {
      return;
    }

    if (fLockingService instanceof AVMLockingServiceImpl) {
      ((AVMLockingServiceImpl) fLockingService).init();
    }
  }
 public void testSimpleCommit() throws Throwable {
   UserTransaction txn = transactionService.getUserTransaction();
   try {
     txn.begin();
     txn.commit();
   } catch (Throwable e) {
     try {
       txn.rollback();
     } catch (Throwable ee) {
     }
     throw e;
   }
 }
  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()));
  }
 /** Initialise the dictionary, ensuring that a transaction is available */
 @Override
 public void onDictionaryInit() {
   if (onLoadDynamicModelDelegate == null) {
     onLoadDynamicModelDelegate =
         policyComponent.registerClassPolicy(DynamicModelPolicies.OnLoadDynamicModel.class);
   }
   RetryingTransactionCallback<Void> initCallback =
       new RetryingTransactionCallback<Void>() {
         @Override
         public Void execute() throws Throwable {
           onDictionaryInitInTxn();
           return null;
         }
       };
   transactionService.getRetryingTransactionHelper().doInTransaction(initCallback, true, false);
 }
  private void assertDocumentVersionAndName(final String versionLabel, final String name) {
    transactionService
        .getRetryingTransactionHelper()
        .doInTransaction(
            new RetryingTransactionCallback<Void>() {
              @Override
              public Void execute() throws Throwable {
                Map<QName, Serializable> properties =
                    getAndAssertProperties(document, versionLabel);
                assertEquals(name, properties.get(ContentModel.PROP_NAME));

                return null;
              }
            },
            true);
  }
  /**
   * {@inheritDoc}
   *
   * @since 3.2
   */
  public Map<String, Serializable> recordAuditValues(
      String rootPath, Map<String, Serializable> values) {
    ParameterCheck.mandatory("rootPath", rootPath);
    AuditApplication.checkPathFormat(rootPath);

    if (values == null || values.isEmpty() || !isSourcePathMapped(rootPath)) {
      return Collections.emptyMap();
    }

    // Build the key paths using the session root path
    Map<String, Serializable> pathedValues = new HashMap<String, Serializable>(values.size() * 2);
    for (Map.Entry<String, Serializable> entry : values.entrySet()) {
      String pathElement = entry.getKey();
      String path = AuditApplication.buildPath(rootPath, pathElement);
      pathedValues.put(path, entry.getValue());
    }

    // Translate the values map
    PathMapper pathMapper = auditModelRegistry.getAuditPathMapper();
    final Map<String, Serializable> mappedValues = pathMapper.convertMap(pathedValues);
    if (mappedValues.isEmpty()) {
      return mappedValues;
    }

    // We have something to record.  Start a transaction, if necessary
    TxnReadState txnState = AlfrescoTransactionSupport.getTransactionReadState();
    switch (txnState) {
      case TXN_NONE:
      case TXN_READ_ONLY:
        // New transaction
        RetryingTransactionCallback<Map<String, Serializable>> callback =
            new RetryingTransactionCallback<Map<String, Serializable>>() {
              public Map<String, Serializable> execute() throws Throwable {
                return recordAuditValuesImpl(mappedValues);
              }
            };
        return transactionService
            .getRetryingTransactionHelper()
            .doInTransaction(callback, false, true);
      case TXN_READ_WRITE:
        return recordAuditValuesImpl(mappedValues);
      default:
        throw new IllegalStateException("Unknown txn state: " + txnState);
    }
  }
  @Override
  protected void tearDown() throws Exception {
    globalProperties.setProperty(AUTO_VERSION_PROPS_KEY, "false");
    transactionService
        .getRetryingTransactionHelper()
        .doInTransaction(
            new RetryingTransactionCallback<Void>() {
              @Override
              public Void execute() throws Throwable {
                if (null != parentFolder) {
                  nodeService.deleteNode(parentFolder);
                }

                authenticationService.clearCurrentSecurityContext();

                return null;
              }
            });
  }
Beispiel #13
0
  /** Monkeys with the created date on a wiki page */
  private void pushPageCreatedDateBack(String name, int daysAgo) throws Exception {
    NodeRef container = siteService.getContainer(SITE_SHORT_NAME_WIKI, "wiki");
    NodeRef node = nodeService.getChildByName(container, ContentModel.ASSOC_CONTAINS, name);

    Date created = (Date) nodeService.getProperty(node, ContentModel.PROP_CREATED);
    Date newCreated = new Date(created.getTime() - daysAgo * 24 * 60 * 60 * 1000);

    UserTransaction txn = transactionService.getUserTransaction();
    txn.begin();

    this.policyBehaviourFilter.disableBehaviour(ContentModel.ASPECT_AUDITABLE);
    internalNodeService.setProperty(node, ContentModel.PROP_CREATED, newCreated);
    this.policyBehaviourFilter.enableBehaviour(ContentModel.ASPECT_AUDITABLE);

    txn.commit();

    // Now chance something else on the node to have it re-indexed
    nodeService.setProperty(node, ContentModel.PROP_CREATED, newCreated);
    nodeService.setProperty(node, ContentModel.PROP_DESCRIPTION, "Forced change");
  }
  public void testAutoVersionIncrementOnPropertiesUpdateByLockOwnerAlf14584() throws Exception {
    final String name = generateDocumentName(DOCUMENT_NAME, "0.2");

    transactionService
        .getRetryingTransactionHelper()
        .doInTransaction(
            new RetryingTransactionCallback<Void>() {
              @Override
              public Void execute() throws Throwable {
                Map<QName, Serializable> properties = getAndAssertProperties(document, "0.1");

                Serializable autoVersionProps =
                    properties.get(ContentModel.PROP_AUTO_VERSION_PROPS);
                assertNotNull(
                    ("Autoversion property is NULL! NodeRef = '" + document.toString() + "'"),
                    autoVersionProps);
                assertTrue(
                    ("Autoversion must be TRUE! NodeRef = '" + document.toString() + "'"),
                    (Boolean) autoVersionProps);

                lockService.lock(document, LockType.WRITE_LOCK);

                LockStatus lockStatus = lockService.getLockStatus(document);
                assertFalse(
                    ("Node with NodeRef = '"
                        + document.toString()
                        + "' must not be locked for "
                        + AuthenticationUtil.getFullyAuthenticatedUser()
                        + " user! The user is lock owner"),
                    isLocked(document));
                assertEquals(LockStatus.LOCK_OWNER, lockService.getLockStatus(document));

                nodeService.setProperty(document, ContentModel.PROP_NAME, name);

                return null;
              }
            });

    assertDocumentVersionAndName("0.2", name);
  }
  private void loadData(final int maxCount) {
    final MutableInt doneCount = new MutableInt(0);
    // Batches of 1000 objects
    RetryingTransactionCallback<Integer> makeNodesCallback =
        new RetryingTransactionCallback<Integer>() {
          public Integer execute() throws Throwable {
            for (int i = 0; i < 1000; i++) {
              // We don't need to write anything
              String contentUrl = FileContentStore.createNewFileStoreUrl();
              ContentData contentData =
                  new ContentData(contentUrl, MimetypeMap.MIMETYPE_TEXT_PLAIN, 10, "UTF-8");
              nodeHelper.makeNode(contentData);

              int count = doneCount.intValue();
              count++;
              doneCount.setValue(count);

              // Do some reporting
              if (count % 1000 == 0) {
                System.out.println(
                    String.format("   " + (new Date()) + "Total created: %6d", count));
              }

              // Double check for shutdown
              if (vmShutdownListener.isVmShuttingDown()) {
                break;
              }
            }
            return maxCount;
          }
        };
    int repetitions = (int) Math.floor((double) maxCount / 1000.0);
    for (int i = 0; i < repetitions; i++) {
      transactionService.getRetryingTransactionHelper().doInTransaction(makeNodesCallback);
    }
  }
  @Override
  protected void setUp() throws Exception {
    globalProperties.setProperty(AUTO_VERSION_PROPS_KEY, "true");
    transactionService
        .getRetryingTransactionHelper()
        .doInTransaction(
            new RetryingTransactionCallback<Void>() {
              @Override
              public Void execute() throws Throwable {
                authenticationService.authenticate(
                    ADMIN_CREDENTIAL, ADMIN_CREDENTIAL.toCharArray());

                ResultSet query = null;
                NodeRef rootNode = null;
                try {
                  query =
                      searchService.query(
                          StoreRef.STORE_REF_WORKSPACE_SPACESSTORE,
                          SearchService.LANGUAGE_LUCENE,
                          ROOT_NODE_TERM);
                  rootNode = query.getNodeRef(0);
                } finally {
                  if (null != query) {
                    query.close();
                  }
                }

                Map<QName, Serializable> properties = new HashMap<QName, Serializable>();
                properties.put(ContentModel.PROP_NAME, PARENT_FOLDER_NAME);
                parentFolder =
                    nodeService
                        .createNode(
                            rootNode,
                            ContentModel.ASSOC_CONTAINS,
                            QName.createQName(ContentModel.USER_MODEL_URI, PARENT_FOLDER_NAME),
                            ContentModel.TYPE_FOLDER,
                            properties)
                        .getChildRef();

                properties.clear();
                properties.put(ContentModel.PROP_NAME, DOCUMENT_NAME);

                document =
                    nodeService
                        .createNode(
                            parentFolder,
                            ContentModel.ASSOC_CONTAINS,
                            QName.createQName(ContentModel.USER_MODEL_URI, DOCUMENT_NAME),
                            ContentModel.TYPE_CONTENT,
                            properties)
                        .getChildRef();
                contentService
                    .getWriter(document, ContentModel.PROP_CONTENT, true)
                    .putContent(TEST_CONTENT_01);

                if (!nodeService.hasAspect(document, ContentModel.ASPECT_VERSIONABLE)) {
                  Map<QName, Serializable> versionProperties = new HashMap<QName, Serializable>();
                  versionProperties.put(ContentModel.PROP_VERSION_LABEL, "0.1");
                  versionProperties.put(ContentModel.PROP_INITIAL_VERSION, true);
                  versionProperties.put(ContentModel.PROP_VERSION_TYPE, VersionType.MINOR);
                  nodeService.addAspect(
                      document, ContentModel.ASPECT_VERSIONABLE, versionProperties);
                }

                return null;
              }
            });
  }
  public void testEagerCleanupOnCommit() throws Exception {
    eagerCleaner.setEagerOrphanCleanup(true);
    // Create a new file
    RetryingTransactionCallback<NodeRef> makeContentCallback =
        new RetryingTransactionCallback<NodeRef>() {
          public NodeRef execute() throws Throwable {
            // Create some content
            StoreRef storeRef =
                nodeService.createStore("test", "testEagerCleanupOnCommit-" + GUID.generate());
            NodeRef rootNodeRef = nodeService.getRootNode(storeRef);
            Map<QName, Serializable> properties =
                Collections.singletonMap(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");
            // Done
            return contentNodeRef;
          }
        };
    final NodeRef contentNodeRef =
        transactionService.getRetryingTransactionHelper().doInTransaction(makeContentCallback);
    ContentReader contentReader =
        contentService.getReader(contentNodeRef, ContentModel.PROP_CONTENT);
    assertTrue("Expect content to exist", contentReader.exists());

    // Now update the node, but force a failure i.e. txn rollback
    final List<String> newContentUrls = new ArrayList<String>();
    RetryingTransactionCallback<String> failUpdateCallback =
        new RetryingTransactionCallback<String>() {
          public String execute() throws Throwable {
            ContentWriter writer =
                contentService.getWriter(contentNodeRef, ContentModel.PROP_CONTENT, true);
            writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
            writer.putContent("CONTENT FOR FAIL");
            // This will have updated the metadata, so we can fail now
            newContentUrls.add(writer.getContentUrl());
            // Done
            throw new RuntimeException("FAIL");
          }
        };
    try {
      transactionService.getRetryingTransactionHelper().doInTransaction(failUpdateCallback);
      fail("Transaction was meant to fail");
    } catch (RuntimeException e) {
      if (e.getMessage().equals("FAIL")) {
        // Expected
      } else {
        // Ooops
        throw e;
      }
    }
    // Make sure that the new content is not there
    // The original content must still be there
    assertEquals("Expected one content URL to play with", 1, newContentUrls.size());
    ContentReader readerMissing = contentService.getRawReader(newContentUrls.get(0));
    assertFalse("Newly created content should have been removed.", readerMissing.exists());
    assertTrue("Original content should still be there.", contentReader.exists());

    // Now update the node successfully
    RetryingTransactionCallback<String> successUpdateCallback =
        new RetryingTransactionCallback<String>() {
          public String execute() throws Throwable {
            ContentWriter writer =
                contentService.getWriter(contentNodeRef, ContentModel.PROP_CONTENT, true);
            writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
            writer.putContent("CONTENT FOR SUCCESS");
            // Done
            return writer.getContentUrl();
          }
        };
    String newContentUrl =
        transactionService.getRetryingTransactionHelper().doInTransaction(successUpdateCallback);
    // Make sure that the new content is there
    // The original content was disposed of
    ContentReader contentReaderNew = contentService.getRawReader(newContentUrl);
    assertTrue("Newly created content should be present.", contentReaderNew.exists());
    assertFalse("Original content should have been removed.", contentReader.exists());

    // Now delete the node
    RetryingTransactionCallback<Object> deleteNodeCallback =
        new RetryingTransactionCallback<Object>() {
          public Object execute() throws Throwable {
            nodeService.deleteNode(contentNodeRef);
            // Done
            return null;
          }
        };
    transactionService.getRetryingTransactionHelper().doInTransaction(deleteNodeCallback);
    // The new content must have disappeared
    assertFalse("Newly created content should be removed.", contentReaderNew.exists());
  }
  /**
   * Create ContentData set it on a Node, delete the Node, then set the ContentData on a new node
   * and check that the content is preserved during eager cleanup.
   */
  public void testEagerCleanupDereferencing() throws Exception {
    eagerCleaner.setEagerOrphanCleanup(true);

    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);

            ContentReader reader = contentService.getRawReader(contentData.getContentUrl());
            assertNotNull(reader);
            assertTrue("Content was cleaned before end of transaction", reader.exists());

            // Make a new copy using the same ContentData
            properties.put(ContentModel.PROP_NAME, (Serializable) "test2.txt");
            properties.put(ContentModel.PROP_CONTENT, contentData);
            contentNodeRef =
                nodeService
                    .createNode(
                        rootNodeRef,
                        ContentModel.ASSOC_CHILDREN,
                        ContentModel.ASSOC_CHILDREN,
                        ContentModel.TYPE_CONTENT,
                        properties)
                    .getChildRef();

            reader = contentService.getRawReader(contentData.getContentUrl());
            assertNotNull(reader);
            assertTrue("Content was cleaned before end of transaction", reader.exists());

            // 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 was cleaned despite being re-referenced in the transaction", reader.exists());
  }
  public void testMultipleCheckoutsCheckInsWithPropChange() {
    // Note: this test assumes cm:autoVersionProps=true by default (refer to cm:versionableAspect in
    // contentModel.xml)

    // Create a new node
    ChildAssociationRef childAssocRef =
        nodeService.createNode(
            rootNodeRef,
            ContentModel.ASSOC_CHILDREN,
            QName.createQName("test"),
            ContentModel.TYPE_CONTENT,
            null);
    final NodeRef testNodeRef = childAssocRef.getChildRef();

    // Add the version aspect to the created node
    nodeService.addAspect(testNodeRef, ContentModel.ASPECT_VERSIONABLE, null);

    setComplete();
    endTransaction();

    // Checkout
    final NodeRef workingCopy1 =
        transactionService
            .getRetryingTransactionHelper()
            .doInTransaction(
                new RetryingTransactionCallback<NodeRef>() {
                  public NodeRef execute() throws Exception {
                    return cociService.checkout(testNodeRef);
                  }
                });

    // Change property and checkin
    transactionService
        .getRetryingTransactionHelper()
        .doInTransaction(
            new RetryingTransactionCallback<Object>() {
              public Object execute() throws Exception {
                nodeService.setProperty(workingCopy1, ContentModel.PROP_AUTHOR, "author1");

                Map<String, Serializable> versionProperties = new HashMap<String, Serializable>();
                versionProperties.put(Version.PROP_DESCRIPTION, "This is a test version 1");
                cociService.checkin(workingCopy1, versionProperties);

                return null;
              }
            });

    // Checkout
    final NodeRef workingCopy2 =
        transactionService
            .getRetryingTransactionHelper()
            .doInTransaction(
                new RetryingTransactionCallback<NodeRef>() {
                  public NodeRef execute() throws Exception {
                    return cociService.checkout(testNodeRef);
                  }
                });

    // Change property and checkin
    transactionService
        .getRetryingTransactionHelper()
        .doInTransaction(
            new RetryingTransactionCallback<Object>() {
              public Object execute() throws Exception {
                nodeService.setProperty(workingCopy2, ContentModel.PROP_AUTHOR, "author2");

                Map<String, Serializable> versionProperties = new HashMap<String, Serializable>();
                versionProperties.put(Version.PROP_DESCRIPTION, "This is a test version 2");
                cociService.checkin(workingCopy2, versionProperties);

                return null;
              }
            });

    // Checkout
    final NodeRef workingCopy3 =
        transactionService
            .getRetryingTransactionHelper()
            .doInTransaction(
                new RetryingTransactionCallback<NodeRef>() {
                  public NodeRef execute() throws Exception {
                    return cociService.checkout(testNodeRef);
                  }
                });

    // Change property and checkin
    transactionService
        .getRetryingTransactionHelper()
        .doInTransaction(
            new RetryingTransactionCallback<Object>() {
              public Object execute() throws Exception {
                nodeService.setProperty(workingCopy3, ContentModel.PROP_AUTHOR, "author3");

                Map<String, Serializable> versionProperties = new HashMap<String, Serializable>();
                versionProperties.put(Version.PROP_DESCRIPTION, "This is a test version 3");
                cociService.checkin(workingCopy3, versionProperties);

                return null;
              }
            });
  }
  @Override
  public void setUp() throws Exception {
    ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean("ServiceRegistry");
    authenticationService = serviceRegistry.getAuthenticationService();
    imapService = serviceRegistry.getImapService();
    importerService = serviceRegistry.getImporterService();
    NodeService nodeService = serviceRegistry.getNodeService();
    SearchService searchService = serviceRegistry.getSearchService();
    NamespaceService namespaceService = serviceRegistry.getNamespaceService();
    PersonService personService = serviceRegistry.getPersonService();
    FileFolderService fileFolderService = serviceRegistry.getFileFolderService();
    TransactionService transactionService = serviceRegistry.getTransactionService();
    PermissionService permissionService = serviceRegistry.getPermissionService();

    // start the transaction
    UserTransaction txn = transactionService.getUserTransaction();
    txn.begin();

    authenticationService.authenticate(USER_NAME, USER_PASSWORD.toCharArray());

    anotherUserName = "******";

    NodeRef person = personService.getPerson(anotherUserName);

    if (person != null) {
      personService.deletePerson(anotherUserName);
      PropertyMap testUser = new PropertyMap();
      testUser.put(ContentModel.PROP_USERNAME, anotherUserName);
      testUser.put(ContentModel.PROP_FIRSTNAME, anotherUserName);
      testUser.put(ContentModel.PROP_LASTNAME, anotherUserName);
      testUser.put(ContentModel.PROP_EMAIL, anotherUserName + "@alfresco.com");
      testUser.put(ContentModel.PROP_JOBTITLE, "jobTitle");
      personService.createPerson(testUser);
    }
    if (authenticationService.authenticationExists(anotherUserName)) {
      authenticationService.deleteAuthentication(anotherUserName);
    }
    authenticationService.createAuthentication(anotherUserName, anotherUserName.toCharArray());

    user =
        new AlfrescoImapUser(anotherUserName + "@alfresco.com", anotherUserName, anotherUserName);

    String storePath = "workspace://SpacesStore";
    String companyHomePathInStore = "/app:company_home";

    StoreRef storeRef = new StoreRef(storePath);
    NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);

    List<NodeRef> nodeRefs =
        searchService.selectNodes(
            storeRootNodeRef, companyHomePathInStore, null, namespaceService, false);
    NodeRef companyHomeNodeRef = nodeRefs.get(0);

    ChildApplicationContextFactory imap = (ChildApplicationContextFactory) ctx.getBean("imap");
    ApplicationContext imapCtx = imap.getApplicationContext();
    ImapServiceImpl imapServiceImpl = (ImapServiceImpl) imapCtx.getBean("imapService");

    // Delete test folder
    nodeRefs =
        searchService.selectNodes(
            storeRootNodeRef,
            companyHomePathInStore
                + "/"
                + NamespaceService.CONTENT_MODEL_PREFIX
                + ":"
                + TEST_IMAP_ROOT_FOLDER_NAME,
            null,
            namespaceService,
            false);
    if (nodeRefs.size() == 1) {
      NodeRef ch = nodeRefs.get(0);
      nodeService.deleteNode(ch);
    }

    // Creating IMAP test folder for IMAP root
    LinkedList<String> folders = new LinkedList<String>();
    folders.add(TEST_IMAP_ROOT_FOLDER_NAME);
    FileFolderServiceImpl.makeFolders(
        fileFolderService, companyHomeNodeRef, folders, ContentModel.TYPE_FOLDER);

    // Setting IMAP root
    RepositoryFolderConfigBean imapHome = new RepositoryFolderConfigBean();
    imapHome.setStore(storePath);
    imapHome.setRootPath(companyHomePathInStore);
    imapHome.setFolderPath(TEST_IMAP_ROOT_FOLDER_NAME);
    imapServiceImpl.setImapHome(imapHome);

    // Starting IMAP
    imapServiceImpl.startupInTxn(true);

    nodeRefs =
        searchService.selectNodes(
            storeRootNodeRef,
            companyHomePathInStore
                + "/"
                + NamespaceService.CONTENT_MODEL_PREFIX
                + ":"
                + TEST_IMAP_ROOT_FOLDER_NAME,
            null,
            namespaceService,
            false);

    // Used to create User's folder
    NodeRef userFolderRef = imapService.getUserImapHomeRef(anotherUserName);
    permissionService.setPermission(
        userFolderRef, anotherUserName, PermissionService.ALL_PERMISSIONS, true);

    importTestData("imap/load_test_data.acp", userFolderRef);

    reauthenticate(anotherUserName, anotherUserName);

    AlfrescoImapFolder testDataFolder =
        imapService.getOrCreateMailbox(user, TEST_DATA_FOLDER_NAME, true, false);

    SimpleStoredMessage m = testDataFolder.getMessages().get(0);
    m = testDataFolder.getMessage(m.getUid());

    AlfrescoImapFolder folder = imapService.getOrCreateMailbox(user, TEST_FOLDER_NAME, false, true);

    logger.info("Creating folders...");
    long t = System.currentTimeMillis();

    try {
      for (int i = 0; i < MESSAGE_QUANTITY; i++) {
        System.out.println("i = " + i);
        folder.appendMessage(m.getMimeMessage(), new Flags(), new Date());
      }
    } catch (Exception e) {
      logger.error(e, e);
    }

    t = System.currentTimeMillis() - t;
    logger.info("Create time: " + t + " ms (" + t / 1000 + " s (" + t / 60000 + " min))");

    txn.commit();
  }
  public void setUp() throws Exception {
    if (AlfrescoTransactionSupport.getTransactionReadState() != TxnReadState.TXN_NONE) {
      throw new AlfrescoRuntimeException(
          "A previous tests did not clean up transaction: "
              + AlfrescoTransactionSupport.getTransactionId());
    }

    nodeService = (NodeService) applicationContext.getBean("nodeService");
    dictionaryService =
        (DictionaryService)
            applicationContext.getBean(ServiceRegistry.DICTIONARY_SERVICE.getLocalName());
    permissionService = (PermissionServiceSPI) applicationContext.getBean("permissionService");
    permissionServiceImpl =
        (PermissionServiceImpl) applicationContext.getBean("permissionServiceImpl");
    namespacePrefixResolver =
        (NamespacePrefixResolver)
            applicationContext.getBean(ServiceRegistry.NAMESPACE_SERVICE.getLocalName());
    authenticationService =
        (MutableAuthenticationService) applicationContext.getBean("authenticationService");
    authenticationComponent =
        (AuthenticationComponent) applicationContext.getBean("authenticationComponent");
    serviceRegistry =
        (ServiceRegistry) applicationContext.getBean(ServiceRegistry.SERVICE_REGISTRY);
    permissionModelDAO = (ModelDAO) applicationContext.getBean("permissionsModelDAO");
    personService = (PersonService) applicationContext.getBean("personService");
    authorityService = (AuthorityService) applicationContext.getBean("authorityService");
    authorityDAO = (AuthorityDAO) applicationContext.getBean("authorityDAO");

    authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName());
    authenticationDAO = (MutableAuthenticationDao) applicationContext.getBean("authenticationDao");
    nodeDAO = (NodeDAO) applicationContext.getBean("nodeDAO");
    aclDaoComponent = (AclDAO) applicationContext.getBean("aclDAO");

    publicServiceAccessService =
        (PublicServiceAccessService) applicationContext.getBean("publicServiceAccessService");

    retryingTransactionHelper =
        (RetryingTransactionHelper) applicationContext.getBean("retryingTransactionHelper");

    transactionService = (TransactionService) applicationContext.getBean("transactionComponent");

    testTX = transactionService.getUserTransaction();
    testTX.begin();

    testStoreRef =
        nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.nanoTime());
    rootNodeRef = nodeService.getRootNode(testStoreRef);

    QName children = ContentModel.ASSOC_CHILDREN;
    QName system = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "system");
    QName container = ContentModel.TYPE_CONTAINER;
    QName types = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "people");

    systemNodeRef = nodeService.createNode(rootNodeRef, children, system, container).getChildRef();
    NodeRef typesNodeRef =
        nodeService.createNode(systemNodeRef, children, types, container).getChildRef();
    Map<QName, Serializable> props = createPersonProperties("andy");
    nodeService
        .createNode(typesNodeRef, children, ContentModel.TYPE_PERSON, container, props)
        .getChildRef();
    props = createPersonProperties("lemur");
    nodeService
        .createNode(typesNodeRef, children, ContentModel.TYPE_PERSON, container, props)
        .getChildRef();

    // create an authentication object e.g. the user
    if (authenticationDAO.userExists("andy")) {
      authenticationService.deleteAuthentication("andy");
    }
    authenticationService.createAuthentication("andy", "andy".toCharArray());

    if (authenticationDAO.userExists("lemur")) {
      authenticationService.deleteAuthentication("lemur");
    }
    authenticationService.createAuthentication("lemur", "lemur".toCharArray());

    if (authenticationDAO.userExists(AuthenticationUtil.getAdminUserName())) {
      authenticationService.deleteAuthentication(AuthenticationUtil.getAdminUserName());
    }
    authenticationService.createAuthentication(
        AuthenticationUtil.getAdminUserName(), "admin".toCharArray());

    authenticationComponent.clearCurrentSecurityContext();

    assertTrue(permissionServiceImpl.getAnyDenyDenies());
  }
  public void testAutoVersionIncrementOnPropertiesUpdateAfterCheckInAlf14584() throws Exception {
    final String name02 = generateDocumentName(DOCUMENT_NAME, "0.2");
    final String name11 = generateDocumentName(DOCUMENT_NAME, "1.1");

    transactionService
        .getRetryingTransactionHelper()
        .doInTransaction(
            new RetryingTransactionCallback<Void>() {
              @Override
              public Void execute() throws Throwable {
                Map<QName, Serializable> properties = getAndAssertProperties(document, "0.1");

                Serializable autoVersionProps =
                    properties.get(ContentModel.PROP_AUTO_VERSION_PROPS);
                assertNotNull(
                    ("Autoversion property is NULL! NodeRef = '" + document.toString() + "'"),
                    autoVersionProps);
                assertTrue(
                    ("Autoversion must be TRUE! NodeRef = '" + document.toString() + "'"),
                    (Boolean) autoVersionProps);

                nodeService.setProperty(document, ContentModel.PROP_NAME, name02);

                return null;
              }
            });

    transactionService
        .getRetryingTransactionHelper()
        .doInTransaction(
            new RetryingTransactionCallback<Void>() {
              @Override
              public Void execute() throws Throwable {
                Map<QName, Serializable> properties = getAndAssertProperties(document, "0.2");
                assertEquals(name02, properties.get(ContentModel.PROP_NAME));

                NodeRef workingCopy = checkOutCheckInService.checkout(document);
                contentService
                    .getWriter(workingCopy, ContentModel.PROP_CONTENT, true)
                    .putContent(TEST_CONTENT_10);

                Map<String, Serializable> versionProperties = new HashMap<String, Serializable>();
                versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MAJOR);
                document = checkOutCheckInService.checkin(workingCopy, versionProperties);

                return null;
              }
            });

    assertDocumentVersionAndName("1.0", name02);

    transactionService
        .getRetryingTransactionHelper()
        .doInTransaction(
            new RetryingTransactionCallback<Void>() {
              @Override
              public Void execute() throws Throwable {
                nodeService.setProperty(document, ContentModel.PROP_NAME, name11);

                return null;
              }
            });

    assertDocumentVersionAndName("1.1", name11);
  }
  @Override
  public void setUp() throws Exception {
    ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean("ServiceRegistry");
    transactionService = serviceRegistry.getTransactionService();
    nodeService = serviceRegistry.getNodeService();
    importerService = serviceRegistry.getImporterService();
    personService = serviceRegistry.getPersonService();
    authenticationService = serviceRegistry.getAuthenticationService();
    permissionService = serviceRegistry.getPermissionService();
    imapService = serviceRegistry.getImapService();
    searchService = serviceRegistry.getSearchService();
    namespaceService = serviceRegistry.getNamespaceService();
    fileFolderService = serviceRegistry.getFileFolderService();

    flags = new Flags();
    flags.add(Flags.Flag.SEEN);
    flags.add(Flags.Flag.FLAGGED);
    flags.add(Flags.Flag.ANSWERED);
    flags.add(Flags.Flag.DELETED);

    // start the transaction
    txn = transactionService.getUserTransaction();
    txn.begin();
    authenticationService.authenticate(USER_NAME, USER_PASSWORD.toCharArray());

    // downgrade integrity
    IntegrityChecker.setWarnInTransaction();

    anotherUserName = "******" + System.currentTimeMillis();

    PropertyMap testUser = new PropertyMap();
    testUser.put(ContentModel.PROP_USERNAME, anotherUserName);
    testUser.put(ContentModel.PROP_FIRSTNAME, anotherUserName);
    testUser.put(ContentModel.PROP_LASTNAME, anotherUserName);
    testUser.put(ContentModel.PROP_EMAIL, anotherUserName + "@alfresco.com");
    testUser.put(ContentModel.PROP_JOBTITLE, "jobTitle");

    personService.createPerson(testUser);

    // create the ACEGI Authentication instance for the new user
    authenticationService.createAuthentication(anotherUserName, anotherUserName.toCharArray());

    user =
        new AlfrescoImapUser(anotherUserName + "@alfresco.com", anotherUserName, anotherUserName);

    String storePath = "workspace://SpacesStore";
    String companyHomePathInStore = "/app:company_home";

    StoreRef storeRef = new StoreRef(storePath);

    NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);

    List<NodeRef> nodeRefs =
        searchService.selectNodes(
            storeRootNodeRef, companyHomePathInStore, null, namespaceService, false);
    NodeRef companyHomeNodeRef = nodeRefs.get(0);

    ChildApplicationContextFactory imap = (ChildApplicationContextFactory) ctx.getBean("imap");
    ApplicationContext imapCtx = imap.getApplicationContext();
    ImapServiceImpl imapServiceImpl = (ImapServiceImpl) imapCtx.getBean("imapService");

    // Creating IMAP test folder for IMAP root
    LinkedList<String> folders = new LinkedList<String>();
    folders.add(TEST_IMAP_FOLDER_NAME);
    FileFolderServiceImpl.makeFolders(
        fileFolderService, companyHomeNodeRef, folders, ContentModel.TYPE_FOLDER);

    // Setting IMAP root
    RepositoryFolderConfigBean imapHome = new RepositoryFolderConfigBean();
    imapHome.setStore(storePath);
    imapHome.setRootPath(companyHomePathInStore);
    imapHome.setFolderPath(TEST_IMAP_FOLDER_NAME);
    imapServiceImpl.setImapHome(imapHome);

    // Starting IMAP
    imapServiceImpl.startup();

    nodeRefs =
        searchService.selectNodes(
            storeRootNodeRef,
            companyHomePathInStore
                + "/"
                + NamespaceService.CONTENT_MODEL_PREFIX
                + ":"
                + TEST_IMAP_FOLDER_NAME,
            null,
            namespaceService,
            false);
    testImapFolderNodeRef = nodeRefs.get(0);

    /*
     * Importing test folders:
     *
     * Test folder contains: "___-___folder_a"
     *
     * "___-___folder_a" contains: "___-___folder_a_a",
     *                             "___-___file_a",
     *                             "Message_485.eml" (this is IMAP Message)
     *
     * "___-___folder_a_a" contains: "____-____file_a_a"
     *
     */
    importInternal("imap/imapservice_test_folder_a.acp", testImapFolderNodeRef);

    reauthenticate(anotherUserName, anotherUserName);
  }