Skip to content

Commit

Permalink
Merge branch 'release/3.1.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
gruberrolandvaltech committed Feb 19, 2020
2 parents 40605ed + c1d763c commit 6f11fea
Show file tree
Hide file tree
Showing 24 changed files with 570 additions and 58 deletions.
5 changes: 5 additions & 0 deletions HISTORY
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
2020-02-19 3.1.0
- Allow node creation
- JDK 11 support
- Fixes issues when a page with version history is copied

2019-12-11 3.0.1
- Fixed installation issues on new instances

Expand Down
46 changes: 39 additions & 7 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ Table of contents

AECU requires Java 8 and AEM 6.4 or above. For AEM 6.3 please install the last 1.x version of AECU. Groovy Console can be installed manually if [bundle install](#bundleInstall) is not used.

| AEM Version | Groovy Console | AECU |
| ------------- | -------------- | ---- |
| 6.3 | 12.x | 1.x |
| 6.4 | 13.x, 14.x | 2.x |
| 6.5 | 13.x, 14.x | 2.x |
| AEM Version | Groovy Console | AECU |
| ------------- | -------------- | --------- |
| 6.3 | 12.x | 1.x |
| 6.4 | 14.x, 13.x | 3.x, 2.x |
| 6.5 | 14.x, 13.x | 3.x, 2.x |

<a name="installation"></a>

Expand Down Expand Up @@ -122,7 +122,8 @@ The content of the scripts is plain Groovy code that can be run via [Groovy Cons

There are just a few naming conventions:

* Run modes: folders can contain run modes to limit the execution to a specific target environment. E.g. some scripts are for author only or for your local dev environment.
* Run modes: folders can contain run modes to limit the execution to a specific target environment. E.g. some scripts are for author only or for your local dev environment. Multiple
run mode combinations can be separated with ";" (e.g. "folder.author.test;author.stage" will be executed on test+stage author but not on prod author).
* Always selector: if a script name ends with ".always.groovy" then it will be executed by
[install hook](#installHook) on each package installation. There will be no more check if this script
was already executed before.
Expand Down Expand Up @@ -432,11 +433,34 @@ aecu.contentUpgradeBuilder()
.doRename("newNodeName")
.doCopyResourceToRelativePath("subNode")
.doCopyResourceToRelativePath("../subNode")
.doMoveResourceToRelativePath("subNode")
.doMoveResourceToRelativePath("../subNode")
.doMoveResourceToPathRegex("/content/we-retail/(\\w+)/(\\w+)/(\\w+)", "/content/somewhere/\$1/and/\$2")
.run()
```

#### Create Nodes

Sometimes a new node needs to be created e.g. to add or configure a component.

* doCreateResource(String name, String primaryType): creates a new node using the name and primary type
* doCreateResource(String name, String primaryType, Map<String, Object> properties): creates a new node using additional properties
* doCreateResource(String name, String primaryType, String relativePath): same as above but creates the node under the relative path
* doCreateResource(String name, String primaryType, Map<String, Object> properties, String relativePath): same as above but creates the node under the relative path

```java
def map = [
"testval": "test"
]

aecu.contentUpgradeBuilder()
.forResources((String[]) ["/content/we-retail/jcr:content"])
.doCreateResource("mynode1", "nt:unstructured")
.doCreateResource("mynode2", "nt:unstructured", map)
.doCreateResource("mysubnode1", "nt:unstructured", "mynode1")
.doCreateResource("mysubnode2", "nt:unstructured", map, "mynode2")
.run()
```

#### Delete Nodes

You can delete nodes that match your collection and filter.
Expand All @@ -460,6 +484,14 @@ Please note that this is for non-page resources such as commerce products. For p
* doActivateResource(): activates the current resource
* doDeactivateResource(): deactivates the current resource

```java
aecu.contentUpgradeBuilder()
.forChildResourcesOf("/content/we-retail/ca/en")
.doDeactivateResource()
.doActivateResource()
.run()
```

#### Page Actions

AECU can run actions on the page that contains a filtered resource. This is e.g. helpful if you filter by page resource type.
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>3.0.1</version>
<version>3.1.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 - 2019 Valtech GmbH
* Copyright 2018 - 2020 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 All @@ -18,13 +18,13 @@
*/
package de.valtech.aecu.api.groovy.console.bindings;

import java.util.Map;
import de.valtech.aecu.api.groovy.console.bindings.filters.FilterBy;
import de.valtech.aecu.api.service.AecuException;

import org.apache.sling.api.resource.PersistenceException;
import org.osgi.annotation.versioning.ProviderType;

import de.valtech.aecu.api.groovy.console.bindings.filters.FilterBy;
import de.valtech.aecu.api.service.AecuException;
import java.util.Map;

/**
* This class provides the builder methods to perform a content upgrade.
Expand Down Expand Up @@ -320,6 +320,46 @@ public interface ContentUpgrade {
*/
ContentUpgrade doDeleteResource(String... children);

/**
* Creates a new resource under the current one.
*
* @param name resource name
* @param primaryType jcr:primaryType
* @return upgrade object
*/
ContentUpgrade doCreateResource(String name, String primaryType);

/**
* Creates a new resource under the current one.
*
* @param name resource name
* @param primaryType jcr:primaryType
* @param properties properties excl. jcr:primaryType
* @return upgrade object
*/
ContentUpgrade doCreateResource(String name, String primaryType, Map<String, Object> properties);

/**
* Creates a new resource under the current one.
*
* @param name resource name
* @param primaryType jcr:primaryType
* @param relativePath relative path
* @return upgrade object
*/
ContentUpgrade doCreateResource(String name, String primaryType, String relativePath);

/**
* Creates a new resource under the current one.
*
* @param name resource name
* @param primaryType jcr:primaryType
* @param properties properties excl. jcr:primaryType
* @param relativePath relative path
* @return upgrade object
*/
ContentUpgrade doCreateResource(String name, String primaryType, Map<String, Object> properties, String relativePath);

/**
* Activates the resource.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
*
* @author Roxana Muresan
*/
@Version("4.0.0")
@Version("4.1.0")
package de.valtech.aecu.api.groovy.console.bindings;

import org.osgi.annotation.versioning.Version;
2 changes: 1 addition & 1 deletion bundle/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>de.valtech.aecu</groupId>
<artifactId>aecu</artifactId>
<version>3.0.1</version>
<version>3.1.0</version>
</parent>

<artifactId>aecu.bundle</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion core/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>3.0.1</version>
<version>3.1.0</version>
</parent>

<artifactId>aecu.core</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2018 Valtech GmbH
* Copyright 2018 - 2020 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 All @@ -18,13 +18,17 @@
*/
package de.valtech.aecu.core.groovy.console.bindings.actions.resource;

import de.valtech.aecu.core.groovy.console.bindings.actions.Action;
import javax.annotation.Nonnull;

import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;

import javax.annotation.Nonnull;
import com.day.cq.wcm.api.PageManager;
import com.day.cq.wcm.api.WCMException;

import de.valtech.aecu.core.groovy.console.bindings.actions.Action;
import de.valtech.aecu.core.groovy.console.bindings.actions.util.PageUtil;

/**
* @author Roxana Muresan
Expand All @@ -34,6 +38,12 @@ public class CopyResourceToRelativePath implements Action {
private String relativePath;
private ResourceResolver resourceResolver;

/**
* Constructor
*
* @param relativePath relative path
* @param resourceResolver resource resolver
*/
public CopyResourceToRelativePath(@Nonnull String relativePath, @Nonnull ResourceResolver resourceResolver) {
this.relativePath = relativePath;
this.resourceResolver = resourceResolver;
Expand All @@ -45,10 +55,21 @@ public String doAction(@Nonnull Resource resource) throws PersistenceException {
if (destinationResource != null) {
String sourceAbsPAth = resource.getPath();
String destinationAsPath = destinationResource.getPath();
resourceResolver.copy(sourceAbsPAth, destinationAsPath);
PageUtil pageUtil = new PageUtil();
if (pageUtil.isPageResource(resource)) {
PageManager pageManager = resourceResolver.adaptTo(PageManager.class);
try {
pageManager.copy(resource, destinationAsPath + "/" + resource.getName(), null, false, false, false);
} catch (WCMException | IllegalArgumentException e) {
throw new PersistenceException("Unable to copy " + sourceAbsPAth + ": " + e.getMessage());
}
} else {
resourceResolver.copy(sourceAbsPAth, destinationAsPath);
}

return "Copied " + sourceAbsPAth + " to path " + destinationAsPath;
}
return "WARNING: could not read copy destination resource " + relativePath;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright 2020 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.actions.resource;

import de.valtech.aecu.core.groovy.console.bindings.actions.Action;

import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;

import java.util.Map;

import javax.annotation.Nonnull;

/**
* Creates a new node
*
* @author Roland Gruber
*/
public class CreateResource implements Action {

private String name;
private Map<String, Object> properties;
private String relativePath;
private ResourceResolver resourceResolver;

public CreateResource(@Nonnull String name, @Nonnull Map<String, Object> properties, String relativePath,
@Nonnull ResourceResolver resourceResolver) {
this.name = name;
this.properties = properties;
this.relativePath = relativePath;
this.resourceResolver = resourceResolver;
}

@Override
public String doAction(@Nonnull Resource resource) throws PersistenceException {
Resource destinationResource = resource;
if (StringUtils.isNotBlank(relativePath)) {
destinationResource = resourceResolver.getResource(resource, relativePath);
}
if (destinationResource != null) {
Resource newResource = resourceResolver.create(destinationResource, name, properties);
return "Created " + newResource.getPath();
}
return "WARNING: could not read destination resource at " + relativePath;
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2018 Valtech GmbH
* Copyright 2018 - 2020 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 All @@ -25,7 +25,12 @@
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;

import com.day.cq.wcm.api.PageManager;
import com.day.cq.wcm.api.WCMException;

import de.valtech.aecu.core.groovy.console.bindings.actions.Action;
import de.valtech.aecu.core.groovy.console.bindings.actions.util.PageUtil;
import de.valtech.aecu.core.groovy.console.bindings.impl.BindingContext;

/**
* Action class for moving resources via regex
Expand All @@ -34,33 +39,46 @@
*/
public class MoveResourceToPathRegex implements Action {

private ResourceResolver resourceResolver;
private BindingContext context;
private String matchPattern;
private String targetPathExpr;

/**
* Constructor
*
* @param matchPattern regex pattern
* @param targetPathExpr target regex
* @param resourceResolver resolver
* @param matchPattern regex pattern
* @param targetPathExpr target regex
* @param context binding context
*/
public MoveResourceToPathRegex(@Nonnull String matchPattern, @Nonnull String targetPathExpr,
@Nonnull ResourceResolver resourceResolver) {
this.resourceResolver = resourceResolver;
@Nonnull BindingContext context) {
this.context = context;
this.matchPattern = matchPattern;
this.targetPathExpr = targetPathExpr;
}

@Override
public String doAction(@Nonnull Resource resource) throws PersistenceException {
ResourceResolver resourceResolver = context.getResolver();
String resourcePath = resource.getPath();
if (resourcePath.matches(matchPattern)) {
String targetPath = resourcePath.replaceAll(matchPattern, targetPathExpr);
Resource destinationResource = resourceResolver.getResource(targetPath);

if (destinationResource != null) {
resourceResolver.move(resourcePath, targetPath);
PageUtil pageUtil = new PageUtil();
if (pageUtil.isPageResource(resource)) {
PageManager pageManager = resourceResolver.adaptTo(PageManager.class);
try {
if (!context.isDryRun()) {
pageManager.move(resource, targetPath + "/" + resource.getName(), null, false, false, null);
}
} catch (WCMException | IllegalArgumentException e) {
throw new PersistenceException("Unable to move " + resourcePath + ": " + e.getMessage());
}
} else {
resourceResolver.move(resourcePath, targetPath);
}

return "Moved " + resourcePath + " to path " + targetPath;
}
Expand Down
Loading

0 comments on commit 6f11fea

Please sign in to comment.