ART#216 - How to add functionality to transient properties in ATG?

Back



Next Chapter!




In the previous topic we discussed a scenario, where we store the user's registration date in the profile, and show the number of days (months and years) user has been registered since. For this we created a transient property called registeredSince of the type string.

Our transient property has been created, and we know what logic to apply. Let us understand how we can link this "logic" to our very own transient property.
If you are rusty on transient properties, or do not know what they are, you can visit the topic HERE.

STEP#1: Create a custom property descriptor

The technical term might tick you off, but its way easier than it sounds. We have to write our logic for converting the registrationDate into registeredSince string.
Create a brand new class (e.g. com.test.rest.RegisteredSincePropertyDescriptor) which extends out of the box class GSAPropertyDescriptor. This class has a method which we need (which we can obviously override).
public Object getPropertyValue(RepositoryItemImpl pItem, Object pValue)
This method is called when you fetch a property. Therefore, if you want to do some actions while fetching a property, you can override this method and write your custom code. In our case, we would have to override this method, and write the logic for converting the registrationDate into registeredSince, and return the value. The argument pItem (highlighted) holds the reference of current item of which this property belongs (in our case user). The psuedo-code for this would look something like:-
public Object getPropertyValue(RepositoryItemImpl pItem, Object pValue) {
//get registration date from user
 Date date = pItem.getPropertyValue(pItem, "registrationDate");
//code to convert above date to days, months, years
 String registeredSince = logic(date);
//return the string
 return registeredSince;
}
Now, we have written our logic in our right place. 
Next question arises - How does our transient property know, it has to use the class we created above?

STEP#2: Link Property Descriptor to transient property

This can be done using very simple syntax. You just need to know two things:-
1. The name of your transient property (and its repository XML)
2. Fully qualified class name of your custom property descriptor (created in STEP#1)

Now, since we are modifying user item-descriptor of ProfileAdapterRepository, we will go into userProfile.xml, where our transient property is displayed. In the previous artcile, our transient property XML looks something like:-
<item-descriptor name="user" .. some other stuff.. >
  <property name="registeredSince" data-type="string" />
  <table name="TABLE_NAME" type="primary or auxiliary or whatever">
      <property name="registrationDate" column-name="SOME_COLUMN" />
   </table>
</item-descriptor>

Now, the highlighted property, has to be linked to our custom class (a subclass of GSAPropertyDescriptor), in order to execute the logic we have written, whenever a property is fetched. For this, we use the property-type attribute in our XML, and refer it to our custom class.
Your XML would look something like:-
<item-descriptor name="user" .. some other stuff.. >
  <property name="registeredSince" data-type="string" property-type="com.test.rest.RegisteredSincePropertyDescriptor" />
  <table name="TABLE_NAME" type="primary or auxiliary or whatever">
      <property name="registrationDate" column-name="SOME_COLUMN" />
   </table>

</item-descriptor>

Now, your custom class has been linked to your transient property. Therefore, whenever a property is fetched, getPropertyValue() method of the custom class is called, which calculates the days/months/years from the registration date and returns the string. 

Extra Notes

1. Non transient properties: We did some customization based on transient properties, but we are not limited to transient properties. We can do the same using normal (non-transient) properties too. The getPropertyValue() method can be overridden, to fetch the original value from the repository (by calling super class getPropertyValue()), and then this property can be modified to display to the user.

2. setPropertyValue() method: GSAPropertyDescriptor has another method:
public void setPropertyValue(RepositoryItemImpl pItem, Object pValue)

This method is called when a property is SET. In other words, you can use this method for a normal, non-transient properties too. For example, in some countries people enter phone numbers using hifins (-) e.g. 1-800-1234-1234, but you need to store the number without hifins. In this case, you can override the setPropertyValue method, modify the property value and call the super.setPropertyValue, while passing the new value (without hifins). Calling the super.setPropertyValue would induce the OOTB behaviour of saving the item to a repository.

3. Using component instead of a class: There might be scenarios, wherein, you would want a component to do the same functionality instead of a plain java class. In that case, use the property-accessor attribute instead of the property-type attribute and refer to the component. E.g.
property-accessor="/com/test/rest/RegisteredSincePropertyDescriptorComponent"

Back



Next Chapter!

2 comments:

  1. hi monis, is transient properties will be lost after ending user session. As much I think of repository item is global scope not session scope. If explicitly I am converting it into session scope using sessionproperty descriptor that too is not good idea as it is depricated. I have a lot of confusion. could please suggest how to make it session scope.I cant use session to hold the property.

    ReplyDelete
    Replies
    1. Transient property value will be calculated every time this property is fetched. There is no scope associated with it. If you want to hold this in session, you can do
      request.getSession().setAttribute("your-attribute-name", your-transient-property-value)
      If you do not have the request object in your java class, you can do:
      ServletUtil.getCurrentRequest().getSession().setAttribute("your-attribute-name", your-transient-property-value)

      Delete

Subscribe

Get All The Latest Updates Delivered Straight Into Your Inbox For Free!

Flickr