Saturday, February 17, 2018

Extend ATG Commerce Pipeline processor

Pipeline Manager : system executes a series of processor

Pipeline Processor : component executes piece of functionality and return status code

Pipeline Processor Chain : processor are linked by processor chain

Status Code : Status code decides which processor to execute next

<Pipeline Manager >
      <Pipeline Chain>
   
             </pipeline link>
 
       </Pipeline Chain>

</Pipeline Manager >

Example : A example is taken when a order quantity reaches maximum value, user not allowed to continue with order.

Source of Action :  Step 1 : First User account saves if successful calls ""


XML Change : 
<pipelinemanager>

    <pipelinechain name="updateOrder" transaction="TX_REQUIRED" headlink="setInputParameters" xml-combine="replace">


 <pipelinelink transaction="TX_MANDATORY" name="updateUserAccount">
            <processor jndi="/att/ecom/checkout/commerce/order/processor/updateUserAccount"/>
            <transition returnvalue="1" link="processOrderQuantity"/>
        </pipelinelink>


<pipelinelink transaction="TX_MANDATORY" name="processOrderQuantity">
     <processor jndi="/atg/commerce/order/processor/ProcessOrderQuantity"/>
     <transition returnvalue="1" link="sendEmilConfirmation"/>
</pipelinelink>


 <pipelinelink transaction="TX_MANDATORY" name="sendEmilConfirmation">
     <processor jndi="/att/ecom/shopcore/commerce/order/processor/sendEmilConfirmation"/>
     <transition returnvalue="1" link="notifyOrdergateway"/>
   </pipelinelink>

<pipelinemanager>

</pipelinechain>


Processor Java File:

public class ProcessOrderQuantity implements PipelineProcessor {

/**
* Pipeline success code.
*/
private final int SUCCESS = 1;


public int runProcess(Object pParam, PipelineResult pResult) throws Exception {
final HashMap map = (HashMap) pParam;

                    if (map != null) {
final OnlineOrder order = (OnlineOrder) map.get(PipelineConstants.ORDER);
String commitmentTermId = null;
            if (order != null) {

                       }
}

return SUCCESS;
}


public int[] getRetCodes() {
int[] ret = { SUCCESS };
return ret;
}


}


Processor Properties File

$class=com.att.ecom.shop.processor.ProcessOrderQuantity 
$scope=global




Wednesday, January 8, 2014

ATG FormHandler - Create a New FormHandler

Form Handler Introduction :

Form handlers are specialized Nucleus components that can be embedded in our JSPs to do form validation and based on the results do certain actions like inserting into database, forwarding the user to some other JSP page etc. Form Handlers is based on  “Service to Workers” (push based) approach of MVC2 design pattern.





Step 1 : Create a Form Handler java class for example "LoginFormHandler"

LoginFormHandler.java


Step 2 : Create a properties file for LoginFormHandler class


Step 3 : Access in Login JSP

Enable java Debugger in Eclipse


ATG Droplet - Creating a New Droplet

Droplet Introduction : 

Dynamo Servlet Beans are specialized Nucleus components that can be embedded in our JSPs to display dynamic content.  Droplets are based on MVC2 Dispatcher View (pull based) design pattern.

Writing New Droplet :

CustomDroplet.java

Step 1 :  Create a Java file for example "CustomDroplet" extending DynamoServlet  and override Service method to contruct the logic.

public class CustomDroplet extends DynamoServlet {

public void service(DynamoHttpServletRequest dynamoHttpServletRequest,
            DynamoHttpServletResponse dynamoHttpServletResponse)
            throws ServletException, IOException {


dynamoHttpServletRequest.setParameter("CustomValue", "i am a new user");

dynamoHttpServletRequest.serviceLocalParameter("output",
                dynamoHttpServletRequest, dynamoHttpServletResponse);


}

Here serviceLocalParameter can also be replaceable with serviceParameter. serviceLocalParameter method makes the output parameter available only to that droplet i .e (DynamoServlet  block(as show below) in jsp  and outside the droplet block, the parameter wont be available) and where as serviceParameter makes the output accessible outside the droplet also.

Step 2 : Create a properties file for example "CustomDroplet" with scope as global.

CustomDroplet.properties

$class=com.view.CustomDroplet

Step 3: Access the Droplet in JSP.

 CustomeDropletPage.jsp

<dsp:page>
<dsp:importbean bean="/com/view/CustomDroplet"/>

<dsp:droplet name="CustomDroplet">
    <dsp:oparam name="output">
        New Value: <b><dsp:valueof param="CustomValue">CustomValueis Null</dsp:valueof></b> <br/>
    </dsp:oparam>
</dsp:droplet>

</dsp:page>




Monday, July 22, 2013

How to customize tag Converter in ATG

Tag Converters


Oracle ATG Web Commerce provides tag converter classes that let you explicitly control how form data is converted on input and displayed on output, and when exceptions are thrown. Certain DSP tags such as dsp:inputand dsp:valueofcan specify these tag converters; details about syntax and usage is provided in the ATG Page Developer's Guide.

Tag Converter can mask the input data and also change the format of the data displayed.


Tag Converter can be applied to following DSP tags.

dsp:a
dsp:input
dsp:param
dsp:postfield
dsp:select
dsp:setvalue
dsp:textarea
dsp:valueof


 Out of Box, ATG Provides following tag converter 


The following table lists the standard ATG tag converters:


Converter
Inputdatatype
Outputdatatype
Function
creditCard
numeric string
integer, float, etc.
Determines how a credit card number is displayed.
currency
currencyConversion
euro

numeric string
string
Displays currency in a format appropriate for the locale
date
String
Date
Parses strings into Dates; displays Dates in a variety of formats.
map
Map
Map
Ensures that key-value pairs are parsed correctly for the specified map property.
nullable
any
any
If field is left empty, corresponding property is set to null
number
numeric string
integer, float, etc.
Displays numeric data-types in a variety of formats
required
any
any
Throws a form exception if the user specifies a null or empty value
valueishtml
string
string
Displays a string as formatted HTML text rather than escaped text.


Create Our Own Custom Tag Converter


Now will go through, how to customize our own tag converter.

Here i have taken a example to , "mask all the input data leaving the number of character specified by user not to mask"

for example:  My input is "ASDG123$%%%3456", and output will be "XXXXXXXXXXX3456"




Step 1: Create a Component "MaskStringConverter"


1) Place MaskStringConverter.properties to config folder

MaskStringConverter.properties

  $class=com.att.ecom.checkout.view.MaskStringConverter
  $scope=global
  loggingDebug=true


2)  Create a java class MaskStringConverter extends GenericService implements TagConverter

placed the complete code for understanding MaskStringConverter.java

Step 2:  Register new TagConverter "MaskStringConverter" with the TagConverterManager (atg.droplet.TagConverterManager) by calling TagConverterManager.registerTagConverter()

Please check below code, where marked in Yellow 


MaskStringConverter.java 

// Constant Variable mentioning number of character not to be masked
static final String NUMBERSUNMASKED = "numcharsunmasked";

// Register the tag converter with the manager
    public void doStartService() {
        TagConverterManager.registerTagConverter(this);
        if (isLoggingInfo()) {
            logInfo("Registered '" + getName() + "' tag converter");
        }
    }


// Array of input attributes , can have as many as input attributes. here we have only one //attribute numcharsunmasked mentioned in jsp
    private static final TagAttributeDescriptor[] S_TAG_ATTRIBUTE_DESCRIPTORS = { new TagAttributeDescriptor(
            NUMBERSUNMASKED, "If this attribute is present, The number of digits mentioned will not be masked", false,
            false) };



// Masking Logic
    public Object convertStringToObject(DynamoHttpServletRequest request, String string, Properties properties)
            throws TagConversionException {
        Integer numberNotMasked = 0;
        if (StringUtils.isEmpty(string)) {
            return null;
        }
        if (!StringUtils.isEmpty(properties.getProperty(NUMBERSUNMASKED))
                && StringUtils.isNumeric(properties.getProperty(NUMBERSUNMASKED))) {
            logInfo("get the number of character not to be masked");
            numberNotMasked = new Integer(properties.getProperty(NUMBERSUNMASKED).toString());
            return buildOutput(string, numberNotMasked);
        }
        return null;
    }

    public String convertObjectToString(DynamoHttpServletRequest request, Object pValue, Properties properties)
            throws TagConversionException {
        int numberNotMasked = 0;
        if (pValue == null) {
            return null;
        }
        if (!StringUtils.isEmpty(properties.getProperty(NUMBERSUNMASKED))
                && StringUtils.isNumeric(properties.getProperty(NUMBERSUNMASKED))) {
            logInfo("get the number of character not to be masked");
            numberNotMasked = new Integer(properties.getProperty(NUMBERSUNMASKED).toString());
            return buildOutput(pValue.toString(), numberNotMasked);
        }
        return null;
    }

    private String buildOutput(String driversLicense, int numberNotMasked) {

        String convertedString = "";

        int maskedLength = driversLicense.length() - numberNotMasked;
        convertedString = org.apache.commons.lang.StringUtils.repeat("X", maskedLength)
                + driversLicense.subSequence(maskedLength, driversLicense.length());

        return convertedString;
    }

   

 //getting the converter name which has to be mentioned in jsp.
  @Override
    public String getName() {
        return "inputStringMasking";
    }



//Returns an array of TagAttributeDescriptors (atg.droplet.TagAttributeDescriptor).
    @Override
    public TagAttributeDescriptor[] getTagAttributeDescriptors() {
        return S_TAG_ATTRIBUTE_DESCRIPTORS;
    }



Step 3 : Initial and Start Tag Converter on ATG Start up  by putting entry in InitialService.properties file in config folder 

InitialService.properties 

$class=atg.nucleus.InitialService

initialServices+=\
    /att/ecom/checkout/view/MaskStringConverter



Step 4 :  Call from jsp, the attributes for custom component should be

<dsp:input id="maskingInputId" converter="inputStringMasking" converterattributes="numcharsunmasked=4" bean="MyInputStringBean" maxlength="25" value="${maskingInput}">   



For more details on Tag Converters and Customization, Follow ATGPlatformProgGuide.

Monday, July 15, 2013

Mockito

Mockito is a unit test frame work helps in creating mocks and spies in simple way.

For more details on Mocks and Spies, Please refer below introduction

Introduction To Unit Testing
  • Dummy - an empty object passed in an invocation (usually only to satisfy a compiler when a method ar- gument is required)
  • Fake - an object having a functional implementation, but usually in a simplified form, just to satisfy the test (e.g., an in-memory database)
  • Stub - an object with hardcoded behavior suitable for a given test (or a group of tests)
  • Mock - an object with the ability to
             a) have a programmed expected behavior, and

 b) verify the interactions occurring in its lifetime (this object is usually created with the help  of mocking framework)
  • Spy - a mock created as a proxy to an existing real object; some methods can be stubbed, while the un- stubbed ones are forwarded to the covered object
 
 

Tuesday, July 9, 2013

Display Selected Values for drop down in ATG

Select Values can be displayed using JSTL or DSP tags. Will see one by one

Using JSTL:

<dsp:select id="state" name="state" bean="PersonaFormHandler.PersonalInfoInputBean.driversLicenseBean.State">

<option value="FL"<c:if test="${State == 'FL'}">selected="selected"</c:if>>Florida</option>
<option value="GA"<c:if test="${State == 'GA'}">selected="selected"</c:if>>Georgia</option>
<option value="HI"<c:if test="${State == 'HI'}">selected="selected"</c:if>>Hawaii</option>

</dsp:select>

Here, C:if checks the dynamic variable State agaist static value 'FL' and if so, selected is applied

Using ATG DSP:

<dsp:select id="state" name="state" bean="PersonaFormHandler.PersonalInfoInputBean.driversLicenseBean.State">

<dsp:option value="FL" selected="${State == 'FL'}">Florida</dsp:option>
<dsp:option value="GA" selected="${State == 'GA'}">Georgia</dsp:option>
<dsp:option value="HI" selected="${State == 'HI'}">Hawaii</dsp:option>
<dsp:option value="ID" selected="${State == 'ID'}">Idaho</dsp:option>

</dsp:select>

DSP accepts selected="true" or selected="false"   
and the equality check is handled by ${State == 'FL'}. If dynamic variable State value is equal to 'FL' then true is returned and that particular drop down is selected