Skip to content

Commit

Permalink
Merge branch 'release/5.2.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
gruberrolandvaltech committed Mar 28, 2022
2 parents d37bb2a + 5d3d061 commit 6a96c16
Show file tree
Hide file tree
Showing 39 changed files with 718 additions and 71 deletions.
7 changes: 7 additions & 0 deletions HISTORY
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
2022-03-28 5.2.0
- Added forResourcesByPropertyQuery() to binding
- added subNodepath parameter to doSetProperty()/doDeleteProperty()/doRenameProperty() (142)
- Rerun failed scripts in install hook and JMX (169)
- Possibility to run a prechecks script before the real script (79)
- Fixed primary type of navigation entries (168)

2021-08-27 5.1.0
- Added doReorderNode() to binding

Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ See COPYRIGHT for complete list of licenses.

MIT License

Copyright (c) 2018 - 2019 Valtech GmbH
Copyright (c) 2018 - 2022 Valtech GmbH

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
16 changes: 15 additions & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,12 @@ run mode combinations can be separated with ";" (e.g. "folder.author.test;author
was already executed before.
* Fallback selector: if a script name ends with ".fallback.groovy" then it will be executed only if
the corresponding script failed with an exception. E.g. if there is "script.groovy" and "script.fallback.groovy" then the fallback script only gets executed if "script.groovy" fails.
* Prechecks selector: if a script name ends with ".prechecks.groovy" then it will be executed before
the corresponding script. If it fails with an exception then the corresponding script will be skipped. E.g. if there is "script.groovy" and "script.prechecks.groovy" then the "script.groovy" only gets executed if "script.prechecks.groovy" runs without exception.
* Reserved file names
* fallback.groovy: optional directory level fallback script. This will be executed if a script fails and no script specific fallback script is provided.

* prechecks.groovy: optional directory level prechecks script. This will be executed before a script runs and no script specific prechecks script is provided.

<a name="execution"></a>

# Execution of Migration Scripts
Expand Down Expand Up @@ -279,6 +282,8 @@ In the collect phase you define which nodes should be checked for a migration.
* forDescendantResourcesOf(String path): use the whole subtree under this path excluding the parent root node
* forResourcesInSubtree(String path): use the whole subtree under this path including the parent root node
* forResourcesBySql2Query(String query): executes the query and applies actions on found resources
* forResourcesByPropertyQuery(String path, Map<String, String> conditionProperties): search in given path for the given list of property values (node type nt:base)
* forResourcesByPropertyQuery(String path, Map<String, String> conditionProperties, String nodeType): search in given path for the given list of property values using a specific node type (e.g. "nt:base")

You can call these methods multiple times and combine them. They will be merged together.

Expand All @@ -291,6 +296,8 @@ aecu.contentUpgradeBuilder()
.forDescendantResourcesOf("/content/we-retail/us/en/experience")
.forResourcesInSubtree("/content/we-retail/us/en/experience")
.forResourcesBySql2Query("SELECT * FROM [cq:Page] AS s WHERE ISDESCENDANTNODE(s,'/content/we-retail/us/en/experience')")
.forResourcesByPropertyQuery("/content/we-retail/us", Collections.singletonMap("sling:resourceType", "weretail/components/content/heroimage"))
.forResourcesByPropertyQuery("/content/we-retail/us", Collections.singletonMap("sling:resourceType", "%/heroimage"), "nt:base")
.doSetProperty("name", "value")
.run()
```
Expand Down Expand Up @@ -421,16 +428,23 @@ aecu.contentUpgradeBuilder()
#### Update Single-value Properties

* doSetProperty(String name, Object value): sets the given property to the value. Any existing value is overwritten.
* doSetProperty(String name, Object value, String pathToSubnode): sets the given property in the subnode to the value. If subnode does not exist it will be created as nt:unstructured (incl. missing intermediate nodes). Any existing value is overwritten.
* doSetProperty(String name, Object value, String pathToSubnode, String primaryType): sets the given property in the subnode to the value. If subnode does not exist it will be created as given in primaryType (incl. missing intermediate nodes). Any existing value is overwritten.
* doDeleteProperty(String name): removes the property with the given name if existing.
* doDeleteProperty(String name, String pathToSubnode): removes the property on subnode pathToSubnode with the given name if existing.
* doRenameProperty(String oldName, String newName): renames the given property if existing. If the new property name already exists it will be overwritten.
* doRenameProperty(String oldName, String newName, String pathToSubnode): renames the given property on subnode pathToSubnode if existing. If the new property name already exists it will be overwritten.

```java
aecu.contentUpgradeBuilder()
.forChildResourcesOf("/content/we-retail/ca/en")
.filterByNodeName("jcr:content")
.doSetProperty("name", "value")
.doSetProperty("name", "value", "root/breadCrumb")
.doDeleteProperty("nameToDelete")
.doDeleteProperty("nameToDelete", "root/breadCrumb")
.doRenameProperty("oldName", "newName")
.doRenameProperty("oldName", "newName", "root/breadCrumb")
.run()
```

Expand Down
2 changes: 1 addition & 1 deletion api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>de.valtech.aecu</groupId>
<artifactId>aecu</artifactId>
<version>5.1.0</version>
<version>5.2.0</version>
</parent>

<artifactId>aecu.api</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2018 - 2021 Valtech GmbH
* Copyright 2018 - 2022 Valtech GmbH
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction,
Expand Down Expand Up @@ -76,6 +76,28 @@ public interface ContentUpgrade {
*/
ContentUpgrade forResourcesBySql2Query(String query);

/**
* Loops over resources found by the SQL2 query generated by the path and properties and the
* default node type "nt:base".
*
* @param path search path
* @param conditionProperties properties to generate AND conditions (values containing % will be
* matched using LIKE)
* @return upgrade object
*/
ContentUpgrade forResourcesByPropertyQuery(String path, Map<String, String> conditionProperties);

/**
* Loops over resources found by the SQL2 query generated by the nodeType, path and properties.
*
* @param path search path
* @param conditionProperties properties to generate AND conditions (values containing % will be
* matched using LIKE)
* @param nodeType node type (e.g. "nt:base")
* @return upgrade object
*/
ContentUpgrade forResourcesByPropertyQuery(String path, Map<String, String> conditionProperties, String nodeType);

/**
* Filters by existence of a single property.
*
Expand Down Expand Up @@ -186,6 +208,27 @@ public interface ContentUpgrade {
**/
ContentUpgrade doSetProperty(String name, Object value);

/**
* Sets a property value on a subnode.
*
* @param name property name
* @param value property value
* @param pathToSubnode path to subnode where property will be set
* @return upgrade object
**/
ContentUpgrade doSetProperty(String name, Object value, String pathToSubnode);

/**
* Sets a property value on a subnode.
*
* @param name property name
* @param value property value
* @param pathToSubnode path to subnode where property will be set
* @param primaryType primary type if subnode or intermediate nodes need to be created
* @return upgrade object
**/
ContentUpgrade doSetProperty(String name, Object value, String pathToSubnode, String primaryType);

/**
* Joins a property value into a single value. Uses "," to join multiple values. Deletes
* properties with empty array values.
Expand Down Expand Up @@ -222,6 +265,15 @@ public interface ContentUpgrade {
*/
ContentUpgrade doDeleteProperty(String name);

/**
* Deletes a property if existing.
*
* @param name property name
* @param pathToSubnode path to subnode where property will be set
* @return upgrade object
*/
ContentUpgrade doDeleteProperty(String name, String pathToSubnode);

/**
* Renames a property if existing.
*
Expand All @@ -231,6 +283,16 @@ public interface ContentUpgrade {
*/
ContentUpgrade doRenameProperty(String oldName, String newName);

/**
* Renames a property if existing.
*
* @param oldName old property name
* @param newName new property name
* @param pathToSubnode path to subnode where property will be set
* @return upgrade object
*/
ContentUpgrade doRenameProperty(String oldName, String newName, String pathToSubnode);

/**
* Copies a property to a relative path.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,12 @@ public ANDFilter(@Nonnull List<FilterBy> filters) {

@Override
public boolean filter(@Nonnull Resource resource, StringBuilder output) {
boolean foundFalse = filters.parallelStream().filter(f -> f.filter(resource, output) == false).findAny().isPresent();
return !foundFalse;

for (FilterBy filter : filters) {
if (!filter.filter(resource, output)) {
return false;
}
}
return true;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,11 @@ public ORFilter(List<FilterBy> filters) {

@Override
public boolean filter(@Nonnull Resource resource, StringBuilder output) {
boolean foundTrue = filters.parallelStream().filter(f -> f.filter(resource, output)).findAny().isPresent();
return foundTrue;
for (FilterBy filter : filters) {
if (filter.filter(resource, output)) {
return true;
}
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
*
* @author Roxana Muresan
*/
@Version("4.6.0")
@Version("4.7.0")
package de.valtech.aecu.api.groovy.console.bindings;

import org.osgi.annotation.versioning.Version;
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/*
* Copyright 2021 Valtech GmbH
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package de.valtech.aecu.core.groovy.console.bindings.filters;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.sling.api.resource.Resource;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import de.valtech.aecu.api.groovy.console.bindings.filters.ANDFilter;
import de.valtech.aecu.api.groovy.console.bindings.filters.FilterBy;

/**
* Tests ANDFilter
*
* @author Roland Gruber
*/
@RunWith(MockitoJUnitRunner.class)
public class ANDFilterTest {

@Mock
private FilterBy matches1;

@Mock
private FilterBy matches2;

@Mock
private FilterBy notMatches1;

@Mock
private FilterBy notMatches2;

@Mock
private Resource resource;

private StringBuilder stringBuilder;

@Before
public void setup() {
stringBuilder = new StringBuilder();
when(matches1.filter(resource, stringBuilder)).thenReturn(true);
when(matches2.filter(resource, stringBuilder)).thenReturn(true);
when(notMatches1.filter(resource, stringBuilder)).thenReturn(false);
when(notMatches2.filter(resource, stringBuilder)).thenReturn(false);
}

@Test
public void filter_match1() {
List<FilterBy> filters = new ArrayList<>(Arrays.asList(matches1));

ANDFilter filter = new ANDFilter(filters);

assertTrue(filter.filter(resource, stringBuilder));
}

@Test
public void filter_match2() {
List<FilterBy> filters = new ArrayList<>(Arrays.asList(matches1, matches2));

ANDFilter filter = new ANDFilter(filters);

assertTrue(filter.filter(resource, stringBuilder));
}

@Test
public void filter_no_match1() {
List<FilterBy> filters = new ArrayList<>(Arrays.asList(notMatches1));

ANDFilter filter = new ANDFilter(filters);

assertFalse(filter.filter(resource, stringBuilder));
}

@Test
public void filter_no_match2() {
List<FilterBy> filters = new ArrayList<>(Arrays.asList(notMatches2, notMatches1));

ANDFilter filter = new ANDFilter(filters);

assertFalse(filter.filter(resource, stringBuilder));
}

@Test
public void filter_mixed1() {
List<FilterBy> filters = new ArrayList<>(Arrays.asList(matches1, notMatches2, notMatches1));

ANDFilter filter = new ANDFilter(filters);

assertFalse(filter.filter(resource, stringBuilder));
}

@Test
public void filter_mixed2() {
List<FilterBy> filters = new ArrayList<>(Arrays.asList(notMatches1, notMatches2, matches1));

ANDFilter filter = new ANDFilter(filters);

assertFalse(filter.filter(resource, stringBuilder));
}

}
Loading

0 comments on commit 6a96c16

Please sign in to comment.