diff --git a/HISTORY b/HISTORY
index 610db740..d1ff6034 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,4 +1,8 @@
-2023-02-23 6.2.1
+2023-03-20 6.4.0
+ - Resource Action: New actions to add / remove mixins (#209)
+ - AEMaaCS doesn't start AECU Migration, due to wrong check in AecuCloudStartupService (#210)
+
+2023-02-23 6.3.0
- Upgrade of Orbinson Groovy Console to version 19.0.3 (#205, #208)
- New filter method: filterByNodeRootPaths() (#204)
- AecuService: added new execute(String path, String data) method which accepts a JSON data string to be used within scipts (#204)
diff --git a/Readme.md b/Readme.md
index cc59ea7f..00d8072f 100644
--- a/Readme.md
+++ b/Readme.md
@@ -512,6 +512,21 @@ aecu.contentUpgradeBuilder()
.run()
```
+#### Update Mixins
+
+* doAddMixin(String mixinName): adds a mixin to a node if the mixin is valid
+* doRemoveMixin(String mixinName): removes a mixin from a node if the mixin is present
+
+```java
+aecu.contentUpgradeBuilder()
+ .forChildResourcesOf("/content/we-retail/ca/en")
+ .filterByNodeName("jcr:content")
+ .doAddMixin("mix:versionable")
+ .doAddMixin("mix:mymixin")
+ .doRemoveMixin("mix:lockable")
+ .run()
+```
+
#### Copy and Move Properties
This will copy or move a property to a subnode. You can also change the property name.
diff --git a/api/pom.xml b/api/pom.xml
index 52902982..f26cfd34 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -4,7 +4,7 @@
de.valtech.aecu
aecu
- 6.3.0
+ 6.4.0
aecu.api
diff --git a/api/src/main/java/de/valtech/aecu/api/groovy/console/bindings/ContentUpgrade.java b/api/src/main/java/de/valtech/aecu/api/groovy/console/bindings/ContentUpgrade.java
index 83773db6..0c9f65f3 100644
--- a/api/src/main/java/de/valtech/aecu/api/groovy/console/bindings/ContentUpgrade.java
+++ b/api/src/main/java/de/valtech/aecu/api/groovy/console/bindings/ContentUpgrade.java
@@ -704,6 +704,23 @@ public interface ContentUpgrade {
*/
ContentUpgrade doCheckPageRendering(String textPresent, String textNotPresent);
+
+ /**
+ * Adds a mixin
+ *
+ * @param mixinName valid mixin name
+ * @return upgrade object
+ */
+ ContentUpgrade doAddMixin(String mixinName);
+
+ /**
+ * Removes a mixin
+ *
+ * @param mixinName valid mixin name present on the node
+ * @return upgrade object
+ */
+ ContentUpgrade doRemoveMixin(String mixinName);
+
/**
* Print path
*
diff --git a/api/src/main/java/de/valtech/aecu/api/groovy/console/bindings/package-info.java b/api/src/main/java/de/valtech/aecu/api/groovy/console/bindings/package-info.java
index 09601dda..283837de 100644
--- a/api/src/main/java/de/valtech/aecu/api/groovy/console/bindings/package-info.java
+++ b/api/src/main/java/de/valtech/aecu/api/groovy/console/bindings/package-info.java
@@ -22,7 +22,7 @@
*
* @author Roxana Muresan
*/
-@Version("4.9.0")
+@Version("4.10.0")
package de.valtech.aecu.api.groovy.console.bindings;
import org.osgi.annotation.versioning.Version;
diff --git a/cloud.startup.hook/pom.xml b/cloud.startup.hook/pom.xml
index f7c8531b..5bae48bb 100644
--- a/cloud.startup.hook/pom.xml
+++ b/cloud.startup.hook/pom.xml
@@ -4,7 +4,7 @@
de.valtech.aecu
aecu
- 6.3.0
+ 6.4.0
aecu.cloud.startup.hook
diff --git a/cloud.startup.hook/src/main/java/de/valtech/aecu/startuphook/AecuCloudStartupService.java b/cloud.startup.hook/src/main/java/de/valtech/aecu/startuphook/AecuCloudStartupService.java
index 6884261b..a8a3e5c4 100644
--- a/cloud.startup.hook/src/main/java/de/valtech/aecu/startuphook/AecuCloudStartupService.java
+++ b/cloud.startup.hook/src/main/java/de/valtech/aecu/startuphook/AecuCloudStartupService.java
@@ -18,16 +18,19 @@
*/
package de.valtech.aecu.startuphook;
+import de.valtech.aecu.api.service.AecuException;
+import de.valtech.aecu.api.service.AecuService;
+import de.valtech.aecu.api.service.HistoryEntry;
+import de.valtech.aecu.api.service.HistoryEntry.STATE;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;
-
import javax.jcr.Session;
-
import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.ResourceResolver;
import org.osgi.framework.Bundle;
-import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.BundleContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
@@ -38,19 +41,13 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import be.orbinson.aem.groovy.console.api.BindingExtensionProvider;
-
-import de.valtech.aecu.api.service.AecuException;
-import de.valtech.aecu.api.service.AecuService;
-import de.valtech.aecu.api.service.HistoryEntry;
-import de.valtech.aecu.api.service.HistoryEntry.STATE;
-
/**
* Service that executes the AECU migration if the node store type is composite (AEM Cloud).
*/
@Component(service = AecuCloudStartupService.class, immediate = true, name = "AECU cloud startup hook")
public class AecuCloudStartupService {
+ private static final String GROOVY_CONSOLE_BUNDLE_SYMBOLIC_NAME = "aem-groovy-console-bundle";
private static final String STAR_IMPORT_EXTENSION_PROVIDER = "StarImportExtensionProvider";
private static final String BINDING_EXTENSION_PROVIDER = "BindingExtensionProvider";
private static final String DEFAULT_EXTENSION_SERVICE =
@@ -70,8 +67,11 @@ public class AecuCloudStartupService {
@Reference
private ServiceComponentRuntime serviceComponentRuntime;
+ private BundleContext bundleContext;
+
@Activate
- public void activate() {
+ public void activate(final BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
Runnable runnable = this::checkAndRunMigration;
Thread thread = new Thread(runnable);
thread.start();
@@ -101,7 +101,7 @@ protected void checkAndRunMigration() {
/**
* Checks if an AECU migration is already in progress. If AECU history tells migration is in
* progress then wait max. for MIGRATION_TIMEOUT.
- *
+ *
* @return migration in progress
*/
protected boolean isMigrationInProgress() {
@@ -121,7 +121,7 @@ protected boolean isMigrationInProgress() {
/**
* Waits till Groovy Console took up our services.
- *
+ *
* @return services are ok
* @throws InterruptedException sleep failed
*/
@@ -140,7 +140,12 @@ protected boolean waitForServices() throws InterruptedException {
* Checks if our services are already injected.
*/
private boolean servicesAreOk() {
- Bundle bundle = FrameworkUtil.getBundle(BindingExtensionProvider.class);
+ Bundle bundle = Arrays.stream(bundleContext.getBundles())
+ .filter(b -> GROOVY_CONSOLE_BUNDLE_SYMBOLIC_NAME.equals(b.getSymbolicName()))
+ .findFirst().orElse(null);
+ if (bundle == null) {
+ return false;
+ }
ComponentDescriptionDTO componentDescription =
serviceComponentRuntime.getComponentDescriptionDTO(bundle, DEFAULT_EXTENSION_SERVICE);
if ((componentDescription == null) || !serviceComponentRuntime.isComponentEnabled(componentDescription)) {
@@ -176,7 +181,7 @@ void startAecuMigration() {
/**
* Returns the resource resolver to be used
- *
+ *
* @return the resource resolver
*/
private ResourceResolver getResourceResolver() {
diff --git a/complete-cloud/pom.xml b/complete-cloud/pom.xml
index 061b6224..1eebbdcb 100644
--- a/complete-cloud/pom.xml
+++ b/complete-cloud/pom.xml
@@ -5,7 +5,7 @@
de.valtech.aecu
aecu
- 6.3.0
+ 6.4.0
aecu.complete.cloud
diff --git a/complete/pom.xml b/complete/pom.xml
index 3f38cb5a..2c41250c 100644
--- a/complete/pom.xml
+++ b/complete/pom.xml
@@ -5,7 +5,7 @@
de.valtech.aecu
aecu
- 6.3.0
+ 6.4.0
aecu.complete
diff --git a/core/pom.xml b/core/pom.xml
index 93186c75..0af477a3 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -4,7 +4,7 @@
de.valtech.aecu
aecu
- 6.3.0
+ 6.4.0
aecu.core
diff --git a/core/src/main/java/de/valtech/aecu/core/groovy/console/bindings/actions/resource/AddMixin.java b/core/src/main/java/de/valtech/aecu/core/groovy/console/bindings/actions/resource/AddMixin.java
new file mode 100644
index 00000000..3668d316
--- /dev/null
+++ b/core/src/main/java/de/valtech/aecu/core/groovy/console/bindings/actions/resource/AddMixin.java
@@ -0,0 +1,49 @@
+package de.valtech.aecu.core.groovy.console.bindings.actions.resource;
+
+import de.valtech.aecu.core.groovy.console.bindings.actions.Action;
+import de.valtech.aecu.core.groovy.console.bindings.actions.util.MixinUtil;
+import javax.annotation.Nonnull;
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.sling.api.resource.PersistenceException;
+import org.apache.sling.api.resource.Resource;
+
+/**
+ * Adds a mixin to a resource/node if the mixin exists.
+ *
+ * @author Bart Thierens
+ * @author Eric Manzi
+ */
+public class AddMixin implements Action {
+
+ private final String mixinName;
+
+ public AddMixin(String mixinName) {
+ this.mixinName = mixinName;
+ }
+
+ @Override
+ public String doAction(@Nonnull Resource resource) throws PersistenceException {
+ if (StringUtils.isBlank(mixinName)) {
+ return "WARNING: mixin name is empty";
+ }
+
+ Node node = resource.adaptTo(Node.class);
+ if (node == null) {
+ return "WARNING: could not get node for " + resource.getPath();
+ }
+
+ try {
+ MixinUtil.ensureMixin(node, mixinName);
+ return String.format("Adding mixin %s to %s", mixinName, resource.getPath());
+ } catch (NoSuchNodeTypeException nsnte) {
+ return "WARNING: non-existing mixin: " + mixinName;
+ }
+ catch (RepositoryException re) {
+ throw new PersistenceException("Problem when adding mixin to node", re);
+ }
+ }
+
+}
diff --git a/core/src/main/java/de/valtech/aecu/core/groovy/console/bindings/actions/resource/RemoveMixin.java b/core/src/main/java/de/valtech/aecu/core/groovy/console/bindings/actions/resource/RemoveMixin.java
new file mode 100644
index 00000000..bed1d967
--- /dev/null
+++ b/core/src/main/java/de/valtech/aecu/core/groovy/console/bindings/actions/resource/RemoveMixin.java
@@ -0,0 +1,50 @@
+package de.valtech.aecu.core.groovy.console.bindings.actions.resource;
+
+import de.valtech.aecu.core.groovy.console.bindings.actions.Action;
+import de.valtech.aecu.core.groovy.console.bindings.actions.util.MixinUtil;
+import javax.annotation.Nonnull;
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.sling.api.resource.PersistenceException;
+import org.apache.sling.api.resource.Resource;
+
+/**
+ * Removes a mixin from a resource/node if the mixin is present.
+ *
+ * @author Bart Thierens
+ * @author Eric Manzi
+ */
+public class RemoveMixin implements Action {
+
+ private final String mixinName;
+
+ public RemoveMixin(String mixinName) {
+ this.mixinName = mixinName;
+ }
+
+ @Override
+ public String doAction(@Nonnull Resource resource) throws PersistenceException {
+ if (StringUtils.isBlank(mixinName)) {
+ return "WARNING: mixin name is empty";
+ }
+ Node node = resource.adaptTo(Node.class);
+ if (node == null) {
+ return "WARNING: could not get node for " + resource.getPath();
+ }
+
+ try {
+ if (MixinUtil.hasMixin(node, mixinName)) {
+ node.removeMixin(mixinName);
+ return String.format("Removing mixin %s from %s", mixinName, resource.getPath());
+ }
+ return String.format("No mixin %s present on %s", mixinName, resource.getPath());
+ } catch (NoSuchNodeTypeException nsnte) {
+ return "WARNING: non-existing mixin: " + mixinName;
+ } catch (RepositoryException re) {
+ throw new PersistenceException("Problem when removing mixin from node", re);
+ }
+ }
+
+}
diff --git a/core/src/main/java/de/valtech/aecu/core/groovy/console/bindings/actions/util/MixinUtil.java b/core/src/main/java/de/valtech/aecu/core/groovy/console/bindings/actions/util/MixinUtil.java
new file mode 100644
index 00000000..0bba329e
--- /dev/null
+++ b/core/src/main/java/de/valtech/aecu/core/groovy/console/bindings/actions/util/MixinUtil.java
@@ -0,0 +1,43 @@
+package de.valtech.aecu.core.groovy.console.bindings.actions.util;
+
+import java.util.Arrays;
+import javax.annotation.Nonnull;
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+/**
+ * Utility class for mixin related actions
+ *
+ * @author Bart Thierens
+ */
+public class MixinUtil {
+
+ private MixinUtil() {
+ throw new UnsupportedOperationException("Cannot instantiate MixinUtil");
+ }
+
+ /**
+ * Checks if a mixin is present on a node
+ * @param node the non-null node to check
+ * @param mixin the non-null mixin to check (can be a non-existing mixin type)
+ * @return true if the mixin is present on the node, otherwise false
+ * @throws RepositoryException if an exception occurs while performing repository operations
+ */
+ public static boolean hasMixin(@Nonnull Node node, @Nonnull String mixin) throws RepositoryException {
+ return Arrays.stream(node.getMixinNodeTypes())
+ .anyMatch(nodeType -> nodeType.isNodeType(mixin));
+ }
+
+ /**
+ * Ensures a mixin is set on a node if it wasn't already
+ * @param node the non-null node to add the mixin to
+ * @param mixin the non-null mixin to add
+ * @throws RepositoryException if an exception occurs while performing repository operations
+ */
+ public static void ensureMixin(@Nonnull Node node, @Nonnull String mixin) throws RepositoryException {
+ if (!hasMixin(node, mixin) && node.canAddMixin(mixin)) {
+ node.addMixin(mixin);
+ }
+ }
+
+}
diff --git a/core/src/main/java/de/valtech/aecu/core/groovy/console/bindings/impl/ContentUpgradeImpl.java b/core/src/main/java/de/valtech/aecu/core/groovy/console/bindings/impl/ContentUpgradeImpl.java
index da876311..4eb477db 100644
--- a/core/src/main/java/de/valtech/aecu/core/groovy/console/bindings/impl/ContentUpgradeImpl.java
+++ b/core/src/main/java/de/valtech/aecu/core/groovy/console/bindings/impl/ContentUpgradeImpl.java
@@ -74,6 +74,7 @@
import de.valtech.aecu.core.groovy.console.bindings.actions.properties.MovePropertyToRelativePath;
import de.valtech.aecu.core.groovy.console.bindings.actions.properties.RenameProperty;
import de.valtech.aecu.core.groovy.console.bindings.actions.properties.SetProperty;
+import de.valtech.aecu.core.groovy.console.bindings.actions.resource.AddMixin;
import de.valtech.aecu.core.groovy.console.bindings.actions.resource.ChangePrimaryType;
import de.valtech.aecu.core.groovy.console.bindings.actions.resource.CopyResourceToRelativePath;
import de.valtech.aecu.core.groovy.console.bindings.actions.resource.CreateResource;
@@ -81,6 +82,7 @@
import de.valtech.aecu.core.groovy.console.bindings.actions.resource.DeleteResource;
import de.valtech.aecu.core.groovy.console.bindings.actions.resource.MoveResourceToPathRegex;
import de.valtech.aecu.core.groovy.console.bindings.actions.resource.MoveResourceToRelativePath;
+import de.valtech.aecu.core.groovy.console.bindings.actions.resource.RemoveMixin;
import de.valtech.aecu.core.groovy.console.bindings.actions.resource.RenameResource;
import de.valtech.aecu.core.groovy.console.bindings.actions.resource.ReorderNode;
import de.valtech.aecu.core.groovy.console.bindings.actions.resource.ReplaceResourcePropertyValues;
@@ -642,6 +644,18 @@ public ContentUpgrade doCheckPageRendering(String textPresent, String textNotPre
return this;
}
+ @Override
+ public ContentUpgrade doAddMixin(String mixinName) {
+ actions.add(new AddMixin(mixinName));
+ return this;
+ }
+
+ @Override
+ public ContentUpgrade doRemoveMixin(String mixinName) {
+ actions.add(new RemoveMixin(mixinName));
+ return this;
+ }
+
@Override
public ContentUpgrade printPath() {
LOG.debug("printPath");
diff --git a/core/src/test/java/de/valtech/aecu/core/groovy/console/bindings/actions/resource/AddMixinTest.java b/core/src/test/java/de/valtech/aecu/core/groovy/console/bindings/actions/resource/AddMixinTest.java
new file mode 100644
index 00000000..0d8b0644
--- /dev/null
+++ b/core/src/test/java/de/valtech/aecu/core/groovy/console/bindings/actions/resource/AddMixinTest.java
@@ -0,0 +1,83 @@
+package de.valtech.aecu.core.groovy.console.bindings.actions.resource;
+
+import javax.jcr.Node;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
+import javax.jcr.nodetype.NodeType;
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.sling.api.resource.Resource;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+/**
+ * Tests AddMixin
+ *
+ * @author Bart Thierens
+ */
+@ExtendWith(MockitoExtension.class)
+class AddMixinTest {
+
+ @Mock
+ private Resource resource;
+
+ @Mock
+ private Node node;
+
+ @Mock
+ private NodeType versionableNodeType;
+
+ @Test
+ void testDoAddMixin() throws Exception {
+ when(resource.adaptTo(Node.class)).thenReturn(node);
+ when(node.getMixinNodeTypes()).thenReturn(new NodeType[0]);
+ doNothing().when(node).addMixin(JcrConstants.MIX_VERSIONABLE);
+ when(node.canAddMixin(JcrConstants.MIX_VERSIONABLE)).thenReturn(true);
+
+ AddMixin action = new AddMixin(JcrConstants.MIX_VERSIONABLE);
+ action.doAction(resource);
+ verify(node, times(1)).canAddMixin(JcrConstants.MIX_VERSIONABLE);
+ verify(node, times(1)).addMixin(JcrConstants.MIX_VERSIONABLE);
+ }
+
+ @Test
+ void testDoAddEmptyMixin() throws Exception {
+ AddMixin action = new AddMixin(null);
+ assertEquals("WARNING: mixin name is empty", action.doAction(resource));
+ verify(node, times(0)).canAddMixin(JcrConstants.MIX_VERSIONABLE);
+ verify(node, times(0)).addMixin(JcrConstants.MIX_VERSIONABLE);
+ }
+
+ @Test
+ void testAddPresentMixin() throws Exception {
+ when(versionableNodeType.isNodeType(JcrConstants.MIX_VERSIONABLE)).thenReturn(true);
+ when(resource.adaptTo(Node.class)).thenReturn(node);
+ when(node.getMixinNodeTypes()).thenReturn(new NodeType[]{versionableNodeType});
+
+ AddMixin action = new AddMixin(JcrConstants.MIX_VERSIONABLE);
+ action.doAction(resource);
+ verify(node, times(0)).canAddMixin(JcrConstants.MIX_VERSIONABLE);
+ verify(node, times(0)).addMixin(JcrConstants.MIX_VERSIONABLE);
+ }
+
+ @Test
+ void testAddNonExistingMixin() throws Exception {
+ when(resource.adaptTo(Node.class)).thenReturn(node);
+ when(node.getMixinNodeTypes()).thenReturn(new NodeType[0]);
+ when(node.canAddMixin(anyString())).thenReturn(true);
+ doThrow(NoSuchNodeTypeException.class).when(node).addMixin(anyString());
+
+ String nonExistingMixin = "mix:max";
+ AddMixin action = new AddMixin(nonExistingMixin);
+ assertEquals("WARNING: non-existing mixin: " + nonExistingMixin, action.doAction(resource));
+ }
+
+}
\ No newline at end of file
diff --git a/core/src/test/java/de/valtech/aecu/core/groovy/console/bindings/actions/resource/RemoveMixinTest.java b/core/src/test/java/de/valtech/aecu/core/groovy/console/bindings/actions/resource/RemoveMixinTest.java
new file mode 100644
index 00000000..e7e9750d
--- /dev/null
+++ b/core/src/test/java/de/valtech/aecu/core/groovy/console/bindings/actions/resource/RemoveMixinTest.java
@@ -0,0 +1,65 @@
+package de.valtech.aecu.core.groovy.console.bindings.actions.resource;
+
+import javax.jcr.Node;
+import javax.jcr.nodetype.NodeType;
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.sling.api.resource.Resource;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+/**
+ * Tests RemoveMixin
+ *
+ * @author Bart Thierens
+ */
+@ExtendWith(MockitoExtension.class)
+class RemoveMixinTest {
+
+ @Mock
+ private Resource resource;
+
+ @Mock
+ private Node node;
+
+ @Mock
+ private NodeType versionableNodeType;
+
+ @Test
+ void testDoRemoveMixin() throws Exception {
+ when(resource.adaptTo(Node.class)).thenReturn(node);
+ when(versionableNodeType.isNodeType(JcrConstants.MIX_VERSIONABLE)).thenReturn(true);
+ when(node.getMixinNodeTypes()).thenReturn(new NodeType[]{versionableNodeType});
+ doNothing().when(node).removeMixin(JcrConstants.MIX_VERSIONABLE);
+
+ RemoveMixin action = new RemoveMixin(JcrConstants.MIX_VERSIONABLE);
+ action.doAction(resource);
+ verify(node, times(1)).removeMixin(JcrConstants.MIX_VERSIONABLE);
+ }
+
+ @Test
+ void testDoRemoveEmptyMixin() throws Exception {
+ RemoveMixin action = new RemoveMixin(null);
+ assertEquals("WARNING: mixin name is empty", action.doAction(resource));
+ verify(node, times(0)).removeMixin(JcrConstants.MIX_VERSIONABLE);
+ }
+
+ @Test
+ void testRemoveNotPresentMixin() throws Exception {
+ when(resource.adaptTo(Node.class)).thenReturn(node);
+ when(resource.getPath()).thenReturn("/content/some/path");
+ when(node.getMixinNodeTypes()).thenReturn(new NodeType[0]);
+
+ RemoveMixin action = new RemoveMixin(JcrConstants.MIX_VERSIONABLE);
+ assertEquals(String.format("No mixin %s present on %s", JcrConstants.MIX_VERSIONABLE, resource.getPath()), action.doAction(resource));
+ verify(node, times(0)).removeMixin(JcrConstants.MIX_VERSIONABLE);
+ }
+
+}
\ No newline at end of file
diff --git a/examples-cloud/pom.xml b/examples-cloud/pom.xml
index 9cf97bba..7faa0b6d 100644
--- a/examples-cloud/pom.xml
+++ b/examples-cloud/pom.xml
@@ -5,7 +5,7 @@
de.valtech.aecu
aecu
- 6.3.0
+ 6.4.0
aecu.examples-cloud
diff --git a/examples/pom.xml b/examples/pom.xml
index 7dad660c..a9c318af 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -5,7 +5,7 @@
de.valtech.aecu
aecu
- 6.3.0
+ 6.4.0
aecu.examples
diff --git a/oak.index/pom.xml b/oak.index/pom.xml
index 2cb0b7df..f98504f8 100644
--- a/oak.index/pom.xml
+++ b/oak.index/pom.xml
@@ -5,7 +5,7 @@
de.valtech.aecu
aecu
- 6.3.0
+ 6.4.0
aecu.oak.index
diff --git a/pom.xml b/pom.xml
index 1125fa20..125d5562 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
de.valtech.aecu
aecu
pom
- 6.3.0
+ 6.4.0
AECU
AEM Easy Content Upgrade
https://github.com/valtech/aem-easy-content-upgrade
@@ -390,7 +390,7 @@
org.owasp
dependency-check-maven
- 7.4.4
+ 8.1.2
0
true
diff --git a/sonar-project.properties b/sonar-project.properties
index 4b8dc60b..356dd758 100644
--- a/sonar-project.properties
+++ b/sonar-project.properties
@@ -2,7 +2,7 @@
sonar.projectKey=aecu
# this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1.
sonar.projectName=AEM Easy Content Upgrade
-sonar.projectVersion=6.3.0-SNAPSHOT
+sonar.projectVersion=6.4.0-SNAPSHOT
# Encoding of the source code. Default is default system encoding
sonar.sourceEncoding=UTF-8
diff --git a/ui.apps.structure/pom.xml b/ui.apps.structure/pom.xml
index c1ed1745..509f160f 100644
--- a/ui.apps.structure/pom.xml
+++ b/ui.apps.structure/pom.xml
@@ -5,7 +5,7 @@
de.valtech.aecu
aecu
- 6.3.0
+ 6.4.0
aecu.ui.apps.structure
diff --git a/ui.apps/pom.xml b/ui.apps/pom.xml
index feb62881..48db504e 100644
--- a/ui.apps/pom.xml
+++ b/ui.apps/pom.xml
@@ -5,7 +5,7 @@
de.valtech.aecu
aecu
- 6.3.0
+ 6.4.0
aecu.ui.apps
diff --git a/ui.content/pom.xml b/ui.content/pom.xml
index a85a8e7d..8381a340 100644
--- a/ui.content/pom.xml
+++ b/ui.content/pom.xml
@@ -5,7 +5,7 @@
de.valtech.aecu
aecu
- 6.3.0
+ 6.4.0
aecu.ui.content