March 22, 2020
Estimated Post Reading Time ~

Groovy Script in AEM

Whether you have the need to manipulate the AEM tree structure or the content in it at a bulk/small level or you are required to generate custom reports now and then of the AEM content then you are at the right place. Groovy can do it all with very little coding and that too, without any change in the core code of your AEM project.

Introduction:
  • Groovy is a dynamic object-oriented programming language that is based on the Java platform itself.
  • The developers of groovy designed it in such a way that learning/understanding groovy comes naturally to a java developer so the learning curve to learn groovy for a java developer is very minimal.
  • With groovy, one can manipulate content in the JCR, call OSGi services, or execute arbitrary code using the AEM, Sling, or JCR APIs
  • To use and utilize the power and ease of groovy in AEM, we need to install the Groovy Console package in AEM
Installation:
To use Groovy scripting in AEM, we just need to install a groovy console package in AEM.
1. Download the groovy console package from https://github.com/OlsonDigital/aem-groovy-console
check version compatibility for specific AEM version
2. Install the downloaded package using the crx package manager
3. To verify the installation, open http://<domain>:<port>/etc/groovyconsole.html in browser to view the groovy console
Example: http://localhost:4502/etc/groovyconsole.html

Different parts of the Groovy Console:

Figure 1: Screenshot of the Groovy Console

In the screenshot of the groovy console above few important sections are marked with numbers. We will discuss each section below
1. Themes: once you can set his preferred theme to style the groovy console and coding area in it.
2. Run Script button: this button executes the currently written code in the coding area (section 6)
3. New button: this button will clear out the coding area for you to start with a new groovy script.
Be careful to save your current script before pressing this button.
4. Open button: this will open a box showing all the available saved scripts to load in the current coding area to use. This will also show the sample scripts provided by the groovy console under the samples folder, which you may prefer to know how to perform a few basic operations in AEM using groovy.
Be careful to save your current script before pressing this button.
5. Save button: this will show a popup box to fill in a filename to save your current script with that filename. If you are editing an existing script, then it will still open this box with the existing script’s filename in it. If you wish to save it in a different file, then change the name and save or else leave the name as is and save.
6. Service or adapter name search box: this is the very helpful section where you may start typing the name of any OSGI service or adapter name to look up and this will show you that service or adapter if available. If you choose that service or adapter, then a piece of script/statement would be inserted at the end of your current script which you may cut and place anywhere else as well you get access to the instance of that service or adapter.
7. Coding Area: this section just under the Data section is the area where you will write your script.
There are few more sections in the groovy console. Some of the most important of them all are Bindings, Imports, and Methods. These sections tell you about all the implicit binding objects, imports, and methods available for you to directly use inside your groovy script.

Examples:
To help you further on how you can achieve certain basic real-life objectives in AEM using groovy we will see a few examples now
1. To find the pages under a specific path that are activated after a specific date
The objective is to print the pages with their full AEM JCR paths in the groovy console itself which are activated after a specific date and this search should be carried out for pages under a specific path only.

/* To find the pages activated after a specific date */
import java.text.SimpleDateFormat;
def df = new SimpleDateFormat("dd/MM/yyyy");
def replicator = getService("com.day.cq.replication.Replicator")


def path = "/content/we-retail"
def afterDate = df.parse("20/01/2018")
println "Pages activated after "+afterDate.toString()+":"


getPage(path).recurse { page -&gt;
def content = page.node
def replicationStatus = replicator.getReplicationStatus(session, page.path)
if(replicationStatus.isActivated()) {
if(replicationStatus.getLastPublished().getTime().compareTo(afterDate) &gt; 0) {
println page.path
}
}
}


2. To add a property to all the pages under a specific path
The objective here is to add a property with some value to all the pages which are under a specific path.

def path = "/content/we-retail/us/en/user/account/order-history";
def propName = "testPropName";
def propValue = "testPropValue";

getPage(path).recurse { page \->
def jcrContentNode = page.node;
if (jcrContentNode.hasProperty(propName)) {
def oldPropValue = jcrContentNode.getProperty(propName).getString();
if(!oldPropValue.equals(propValue)) {
jcrContentNode.setProperty(propName, propValue);
}
} else {
jcrContentNode.setProperty(propName, propValue);
}
}
save();


3. To remove a property from all pages under a specific path
The objective is to remove/delete a specific property from all pages which are under a specific path
def path = "/content/we-retail/us/en/user/account/order-history";
def propName = "testPropName";

getPage(path).recurse { page ->
def jcrContentNode = page.node;
if (jcrContentNode.hasProperty(propName)) {
jcrContentNode.getProperty(propName).remove();
}
}
save();


4. To generate a report as an excel of active pages along with their properties
  • The objective is to generate a report of all the active pages which are under a specific path and this report should also include the properties and their values of those pages.
  • Here we would find all the active pages, very similar to example 1, and then we would be using HSSFWorkbook API to create a workbook/spreadsheet for those pages with their properties and values resp.
  • The created workbook is still not a real file for us to access after the script finishes. To achieve that we would create an asset of .xlsx file with that workbook data in the AEM dam.
/* To generate the report of active pages along with their properties */
import java.text.SimpleDateFormat;
import com.day.cq.dam.api.AssetManager;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;

def df = new SimpleDateFormat("dd/MM/yyyy");
def replicator = getService("com.day.cq.replication.Replicator")
assetManager = resourceResolver.adaptTo(AssetManager)

def path = "/content/we-retail"

HSSFWorkbook workbook = new HSSFWorkbook();
sheet = workbook.createSheet("Sheet 1");
HSSFCellStyle cellStyle = workbook.createCellStyle();
cellStyle.setWrapText(true);
HSSFCellStyle my_style = workbook.createCellStyle();
HSSFFont my_font = workbook.createFont();

my_font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
my_font.setColor(HSSFColor.WHITE.index);
my_style.setFont(my_font);
my_style.setFillBackgroundColor(HSSFColor.BLUE.index);
my_style.setAlignment(CellStyle.ALIGN_CENTER);
my_style.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex());
my_style.setFillPattern(CellStyle.SOLID_FOREGROUND);

HSSFRow rowhead = sheet.createRow(0);

def columnCount = 0;

Cell cell = rowhead.createCell(columnCount++);
cell.setCellValue("SL No.");
cell.setCellStyle(my_style);

cell = rowhead.createCell(columnCount++);
cell.setCellValue("Page path");
cell.setCellStyle(my_style);

cell = rowhead.createCell(columnCount++);
cell.setCellValue("Page Title");
cell.setCellStyle(my_style);

cell = rowhead.createCell(columnCount++);
cell.setCellValue("Activation Date");
cell.setCellStyle(my_style);

HSSFRow row;
rowNum = 1;

getPage(path).recurse { page ->

def replicationStatus = replicator.getReplicationStatus(session, page.path)
if(replicationStatus.isActivated()) {
row = sheet.createRow((short) (rowNum));
def colCount = 0;

row.createCell(colCount++).setCellValue(rowNum);
row.createCell(colCount++).setCellValue(page.path);
row.createCell(colCount++).setCellValue(page.title);
row.createCell(colCount++).setCellValue(replicationStatus.getLastPublished().getTime().toString());

rowNum++;
}
}

while(columnCount>0){
sheet.autoSizeColumn(columnCount--);
}

Date date = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy'T'HH-mm-ss");
def dateTimeString = dateFormat.format(date);
def filename = "Report_"+dateTimeString+".xls";

createDamFileForExcel(workbook, filename);

// method to create spreadsheet asset in dam
def createDamFileForExcel(def workbook, def filename) {
def baos = new ByteArrayOutputStream();
workbook.write(baos);
def location = "/content/dam/groovy/output/"
def bais = new ByteArrayInputStream(baos.toByteArray());
def asset = assetManager.createAsset(location + filename, bais, "application/vnd.ms-excel", true);
bais.close();
baos.close();
location + filename

}


Source: 


By aem4beginner

No comments:

Post a Comment

If you have any doubts or questions, please let us know.