Display Files from a Server Path in Pega Using an Activity and Java Step

 In some enterprise applications, you may need to display the list of files and folders available in a server directory directly inside a Pega application. This can be useful for:

  • Monitoring batch file drops
  • Viewing integration files
  • Validating document uploads
  • Supporting admin utilities
  • Troubleshooting file-processing jobs

This article explains how to create a Pega Activity that reads files from a server directory using Java and stores the results into a Page List for UI display or further processing.

Use Case

The requirement is simple:

Read all files and folders from a server directory and display:

  • File name
  • Folder name
  • File size
  • File creation date/time

The solution uses:

  • A Pega Activity
  • Java Step
  • Code-Pega-List
  • pxResults
  • Java File APIs

To display the files in the server path Create Activity and add these steps
Java used for this activity
try { 
  ClipboardPage PLPage = tools.createPage("Code-Pega-List" , "");
  ClipboardPage ResultPage = tools.createPage("Data-", "");
   oLog.infoForced("[FilesInDirectory] try block started "); 

		java.io.File fileContents[] = new java.io.File(Directory).listFiles();
		if (fileContents != null) {
			for (int i = 0; i < fileContents.length; i++) {
				   if(fileContents[i].isDirectory())
        {
            ResultPage.putString ("pyLabel", "[FilesInDirectory] Folder: "+fileContents[i]);
tools.findPage("PLPage").getProperty("pxResults").add(ResultPage);

          oLog.infoForced("[FilesInDirectory] Folder: "+fileContents[i]); 
        }
				 else
         {
           //long fileSize = fileContents[i].length();
           ResultPage.putString ("pyLabel", "[FilesInDirectory] File: "+fileContents[i]);
           ResultPage.putString ("pyNote", "[FilesInDirectory] size(bytes): "+fileContents[i].length());
           
           
           // Getting the file creation datetime
 java.nio.file.Path filePath = fileContents[i].toPath();
 java.nio.file.attribute.BasicFileAttributes attrs = java.nio.file.Files.readAttributes(filePath, java.nio.file.attribute.BasicFileAttributes.class);
      java.nio.file.attribute.FileTime creationTime = attrs.creationTime();
             
         // Adding the creation time to the ResultPage
        ResultPage.putString("TempSelectedEffectiveDate", "[FilesInDirectory] Creation Time: " + creationTime.toString());
           
           

        tools.findPage("PLPage").getProperty("pxResults").add(ResultPage);
           oLog.infoForced("[FilesInDirectory] File: "+fileContents[i]);
         }
				}
			}   
  oLog.infoForced("[FilesInDirectory] try block Ended "); 

			
} catch (Exception ex) { 
	oLog.error("[FilesInDirectory] catch block expected", ex);
}

Download files From the Server Path in Pega

In many Pega applications, there are scenarios where files are generated dynamically and stored temporarily on the server. Users may then need to download these files directly from the application UI. One practical approach is to create a custom Activity that reads the file from the server path and streams it to the browser for download.


This blog explains how to implement file download functionality in Pega using Java steps inside an Activity.

Use Case

Suppose your application:

  • Generates PDF reports
  • Creates Excel exports
  • Produces temporary documents on the server
  • Stores files in a shared directory

You can allow users to download these files directly using a Pega Activity.


Solution Overview

The implementation works as follows:

  1. Pass the server file path as a parameter
  2. Read the file from the server
  3. Convert the file into a byte array
  4. Use tools.sendFile() to stream the file to the browser
  5. Optionally delete the file after download

Add a Java Step

Add a Java step inside the Activity and use the following code

Java used for this activity

``` //Get the byte array from the parameter page
//String Stream=tools.getParamValue("FileStream");
FilePath = tools.getParamValue("FilePath");
//byte[] byteArray=Base64Util.decodeToByteArray(Stream);


java.io.File originalFile = new java.io.File(FilePath);
java.io.FileInputStream fileInputStreamReader=null;
byte[] bytes=null;
try{
if(originalFile.exists())
  {

         fileInputStreamReader = new java.io.FileInputStream(originalFile);
        bytes = new byte[(int)originalFile.length()];
   fileInputStreamReader.read(bytes);
fileInputStreamReader.close();
}
  else{
    ErrMsg="Uanble to open a file/file dooesn't exist:"+FilePath;
  }
}

catch(Exception ex){
  oLog.error("Error during opening the document in ProcessAutoCreateDocument activity:"+ex.getMessage());
  ErrMsg=ex.getMessage();
}
//Get the file name from the parameter page
pdfName=tools.getParamValue("FileName");


// download the file directly
String result=tools.sendFile( bytes,pdfName,false,null,true);
// delete file from path after download
//originalFile.delete();

Generic Decision Table For Reusable Email Configuration

Email notifications are a critical part of most enterprise applications.
Whether it’s:

  • Case creation alerts
  • Approval notifications
  • SLA escalations
  • Error communications
  • Customer acknowledgements

Applications often require multiple email configurations spread across different flows and activities.

Hardcoding email details directly inside activities or utilities makes maintenance difficult and increases duplication.

A cleaner approach is to centralize email configurations using a reusable Decision Table.

This article explains how to build a Generic Email Decision Table in Pega that can be reused across the application to dynamically configure:

  • Email recipients
  • CC recipients
  • Subject lines
  • Correspondence rules
  • Data transforms

 

Why Use a Generic Email Decision Table?

Without a centralized approach:

  • Email logic becomes duplicated
  • Changes require updates in multiple places
  • Maintenance becomes error-prone
  • Business teams cannot easily manage configurations

Using a Decision Table provides:

  • Centralized email configuration
  • Reusability across applications
  • Easier maintenance
  • Cleaner activities and flows
  • Dynamic email behavior


Solution Overview

We will create a Decision Table named:

SendEmailByPurpose

This decision table will determine which email configuration to use based on a business purpose.

This Post talks about how to create a Generic Email Decision table which can be used across appliation to configure the Email parameters like To , CC , Subject and Body.

Lets Create a Decision table , SendEmailByPurpose

Sample Decision Table Configuration

pyPurposeEvaluatepyDataTransformpyCorrForSendEmailpySubjectpyToEmailString
CASE_CREATEDtruePrepareCaseEmailCaseCreatedCorrCase Created Successfully.CustomerEmailsupport@company.com
APPROVAL_REQUIREDtruePrepareApprovalEmailApprovalCorrApproval Required.ManagerEmailescalation@company.com
PAYMENT_SUCCESStruePreparePaymentEmailPaymentCorrPayment Successful.CustomerEmailfinance@company.com

Input columns in Decision table 

  • pyPurpose → Identifier used to determine which email configuration should be triggered.
  • Evaluate → Condition column using @equals("true", current-value) to validate whether the rule row should be executed.
  • Output columns in Decision table 

    • pyDataTransform → Stores the mapping Data Transform used to prepare email data before sending.
    • pyCorrForSendEmail → Defines the Correspondence rule/template used for the email content.
    • pySubject → Stores the subject line of the email.
    • pyTo → Contains the primary recipient email address(es).
    • EmailString → Contains the CC recipient email address(es). 

      Note: The above properties are sample properties and can also be implemented using custom properties based on your application design standards and business requirements.




    Architecture Benefits

    1. Centralized Email Management -All email configurations exist in one place.


    2. Reduced Hardcoding - Activities remain generic and reusable.
    3. Easier Maintenance - Business changes only require updating decision table rows.
    4. Improved Scalability - Adding a new email type requires:New row/ No code changes
    5. Better Governance - Email configurations become easier to audit and manage.


    Conclusion

    A Generic Email Decision Table is a powerful design pattern in Pega that helps standardize and centralize email notification management across applications.

    By configuring:

    • Recipients
    • Subjects
    • Correspondence rules
    • Data transforms

    in a reusable Decision Table, you can:

    • Reduce duplication
    • Simplify maintenance
    • Improve scalability
    • Build cleaner applications

    The SendEmailByPurpose approach is especially useful in large enterprise applications where multiple email types and workflows need to be managed consistently.


    Print Pega Activity Steps in Logs

    Debugging Activities in Pega can sometimes be difficult, especially when:

    • Multiple steps are executed
    • Activities call other activities
    • Parameters change dynamically
    • Errors occur intermittently

    One of the easiest ways to trace Activity execution is by enabling the internal Activity logger.

    This approach allows you to print:

    • Activity step execution
    • Method calls
    • Step transitions
    • Runtime processing details

    directly into the Pega logs.


    Use Case

    Suppose you want to debug:

    • Why an activity is failing
    • Which step is executing
    • Whether a transition condition is working
    • How parameters are flowing

    Instead of manually adding logs in every step, you can enable the built-in Activity logger.


    Steps to Enable Activity Step Logging


    Step 1: Open the Activity- Navigate to the Activity rule you want to debug.

    Step 2: Open the Activity XML - Inside the Activity rule:- Click on Actions /Select:View XML

    Step 3: Search for "Log-Helper"

        Inside the XML, search for: Log-Helper

    Step 4: Copy the Logger Name

        Copy the complete logger entry from the XML.

    Step 5: Add Logger in Logging Level Settings

    • Open Admin Studio
    • Navigate to:
        Resources → Logging Level Settings

    Step 6: Add the Logger

    Add the copied logger name.

    Configure:

    • Logging Level = ALL
    • Duration = 2 Hours
    Step 7: Save the Logger Configuration

    Save the logger settings.

    The logger becomes active immediately.

    Step 8: Execute the Activity

    Run the activity again from:

    • Case processing
    • Activity test page
    • Flow action
    • Job scheduler
    • Queue processor
    Step 9: Check the Logs

    Open:

    • PegaRULES log

    You will now see detailed activity step execution logs.

    Example output:

    Activity MyActivity Step 1 Method Obj-Open
    Activity MyActivity Step 2 Method Property-Set
    Activity MyActivity Step 3 Transition Executed

    Benefits of This Approach

    Using the Activity logger helps:

    • Troubleshoot activity execution
    • Identify failing steps
    • Debug transition logic
    • Trace parameter values
    • Understand execution flow
    without modifying the activity itself.

    Conclusion

    Enabling internal Activity loggers is a quick and powerful way to trace Pega Activity execution without modifying existing rules.

    Page-New Method

    Page-New Method

    We all know ,this Method is often used to initialize a New Page either as Temporary Page or Embedded Page.There is much more than that in Page-New Method .

    Page-New had three parameters

    1 Data transform Only Data transforms created in the step Page context (ie class referred in Pages & Classes) can be used here.
    2 Pagelist Tricky One -You can’t refer a Page list property here; you can only refer a Value list property. It simply appends the step page name to the valuelist
    3
    New Class
    if Left blank, the Page is created with context mentioned in the Pages and Classes. if Specified Overrides the Class specified in the Page and Classes and run the DT from the specified Class.

    I have created a new Activity “TestActivity” in @baseclass and used the Page New Method.


    1) Let’s use the Data transform Parameter first and Check the tracer.


    NOTE : pydefault DT is called from Assign-Worklist class which is specified in the Pages and Classes

    2) Now lets proceed with the Next Pagelist Parameter with one of the out of the box Valuelist property ie( pyTextValue) and Check the tracer.


    3) Now the last parameter ,New Class Parameter and check the tracer



    Now we have mastered the Simplest method - Page-new method in the Activity.
    Trust me, Being 5 years experienced, only while writing this post , I learnt about the Pagelist Parameter in Page-New method . Hope you understood.
    Keep Reading!! More methods are Yet to come.