ART#108 - How to extend Out Of The Box components?



The question is simple:-
Why do we need to extend a component??
Consider a situation, when there is a OOTB component. By layering configuration files we can only change the existing property values of the component. But what if we need to add some new properties to the same component? Or there could be situation when we need to add some methods to an existing component Or override the method of existing component. These tasks cannot be done alone by configuration files, addition of new properties/methods requires class-level modifications. To accomplish this we extend the component.

The answer is even simpler..


Before we extend any OOTB component, we must know the nucleus path of the component.
For example, if we need to extend OOTB ProfileFormHandler component, we should know that its nucleus path is : /atg/userprofiling/ProfileFormHandler.

Now, let us assume, that our component "Person" existing at location "/atg/commerce/Person" and is out of the box. So, our assumed "Person" component is same as we discussed in ART#104 - ATG Components. Now our assumed out-of-the-box "Person" component's properties file looks like (this can be seen in dyn/admin):-
$class=com.mypackage.Person
name=Stephen
age=20
Now that we know where our component exists, and what are its properties, we need to follow the below steps:-

  1. Extend the class: Since addition of properties/methods has to be done at class level, we need to extend the class this component is referring to. Next, we have to extend it and add our custom code. Our OOTB component "Person" refers to com.mypackage.Person class. Therefore, we will now extend Person class and add our custom code. In the below example, we are adding an additional property "gender" to our extended class.

  2. Now that we have extended the person class, we need to do two things:-
    1. Layer our configuration file at the same location as OOTB component. i.e. /atg/commerce/Person (in our module's config-path).
    2. Override the $class nucleus property to use our custom (extended) class, to tell the component to use extended class instead of the original class; so that the new property "gender" is accommodated. (New methods can also be written in this class OR existing methods of "Person" class can be overridden if needed)
    3. Next, we provide the value to our very own newborn variable "gender".
Please see the below screenshot:-




Now, our OOTB atg component uses our custom class, with newly set-properties. Similarly, other components can be easily extended.

Let us move on.. and understand a new topic of ATG, known as droplets or dynamo servlet beans...


Back



Next








19 comments:

  1. I am able to View the components created in eclipse ATG browser,But I am not able to view the ATG module i have created in Dynamo admin.Could you please help me out

    ReplyDelete
    Replies
    1. 1. Firstly, dyn/admin would not show any components which are not initialized.
      2. You can initialize a component in two ways:-
      a. Mentioning the component in initialServices [Click HERE]
      b. Hitting the component directly in dyn/admin instead of searching.
      For example, you created a component /com/myfolder/MyComponent.properties, you can hit the URL:-
      http://[hostname]:[port]/dyn/admin/nucleus/com/myfolder/MyComponent
      3. If you can see your component, then you're good. If not, then you have not assembled your application correctly.
      Please let me know if it solves the problem.

      Delete
  2. Hi Monis,
    I have a question. If we have 2 components lets say ExtendedPerson1 and ExtendedPerson2. Both are extending Person component. I have "gender" propery in ExtendedPerson1 and "region" property in ExtendedPerson2. I want both properties added to the OOTB (Person) component. Then how can i declare the class property of Person component?I mean how can we add both components (EP1 and EP2 ) to Person component through class variable?

    ReplyDelete
    Replies
    1. Hi,

      You cannot do that. There is no way to add to classes to a component.
      For a component to set a property, you need to have a property at class level.

      In your example, you have a class "Person", two subclasses viz.:
      1. ExtendedPerson1 : Having "gender" property
      2. ExtendedPerson2 : Having "region" property

      Now, you are creating a component named "MyPersonComponent".
      For this component, you would have to specify a class.
      If you choose ExtendedPerson1, you'll be able to set "gender" property and NOT "region" property.
      If you choose ExtendedPerson2, you'll be able to set "region" property and NOT "gender" property.

      To have access to both the properties, you'll have to create both "gender" and "region" properties into a single subclass e.g.
      ExtendedPerson -> which has both properties.
      Now, when you create a component, you can set the class as "ExtendedPerson" and have both properties.

      I am not sure why you'd want a single component to use multiple classes. If you could tell me your functional requirement, i'll be able to help you better with the design pattern.

      Delete
  3. ofcourse i can use both variables (gender and region)in same class (ExtendedPerson1). Can i do it with 2 components?Just like extending a class by two different classes..

    ReplyDelete
    Replies
    1. Yes, you can use the same class for different components.
      But, these will be exact copies of each other. Therefore, this does not seem a good design pattern.

      Let me know your functional requirement, so i'll be able to help you better.

      Delete
  4. I am not clear about your comments "Layer our configuration file at the same location as OOTB component. i.e. /atg/commerce/Person (in our module's config-path).". There is one OOB property file Person.properties at location : /atg/commerce/Person. Our customized property is to be copied at /atg/commerce/Person location then it will not override the file present OOB.

    ReplyDelete
    Replies
    1. Hi,

      Me statement means that the component path should be same as the out of the box path, but it should be present in your config path.
      Once you have a file there, you can easily override properties.

      Delete
    2. Hello Monis
      I bumoed into this article while looking for a solution where i have overriden a OOTB component but its properties are not loaded in 1 env , however with same config it is loaded in another env Can you please have a look
      https://community.oracle.com/thread/3886793

      Thanks
      PC

      Delete
    3. Hi,

      Can you open this component in dyn/admin, click on "View Service Configuration" and send me the full screenshot.
      Do this for both the environments and send across the screens.

      Delete
  5. Hi Monis,
    Could you please tell the steps that i need to follow to customize the OOTB CRS module. I installed CRS. But i am not able to customize it by creating my own module. Could you please help in creating my own module using CRS.

    Thanks,
    Yousuf.

    ReplyDelete
    Replies
    1. For that, you'll have to create a new ATG module on top of existing CRS installation.
      I will hash out the details in upcoming articles.

      Delete
  6. Thanks Monis for the details. Could you please list out the steps so that i can start with my custom module.

    ReplyDelete
    Replies
    1. You can refer the details here: http://learnoracleatg.blogspot.in/p/setup.html

      Delete
  7. This comment has been removed by a blog administrator.

    ReplyDelete
  8. Why is the config file named "Person.properties" instead of "ExtendedPerson.properties"? Where are the Person properties' values defined if the config file is completely overridden?

    ReplyDelete
    Replies
    1. This is because we are layering the existing component (Person.properties).
      We have assumed that Person.properties exists out of the box. We are just overriding its class and properties.

      Delete
  9. SEVERE: javax.servlet.ServletException: Error encountered while initializing Nucleus servlet: R
    javax.servlet.ServletException: Error encountered while initializing Nucleus servlet: Required
    at atg.nucleus.servlet.NucleusServlet.initializeAppLauncher(NucleusServlet.java:2201)
    at atg.nucleus.servlet.NucleusServlet.initBigEarNucleus(NucleusServlet.java:938)
    at atg.nucleus.servlet.NucleusServlet.init(NucleusServlet.java:465)
    at weblogic.servlet.internal.StubSecurityHelper$ServletInitAction.run(StubSecurityHelpe
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:3
    at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
    at weblogic.servlet.internal.StubSecurityHelper.createServlet(StubSecurityHelper.java:6
    at weblogic.servlet.internal.StubLifecycleHelper.createOneInstance(StubLifecycleHelper.
    at weblogic.servlet.internal.StubLifecycleHelper.(StubLifecycleHelper.java:48)
    at weblogic.servlet.internal.ServletStubImpl.prepareServlet(ServletStubImpl.java:539)
    at weblogic.servlet.internal.WebAppServletContext.preloadServlet(WebAppServletContext.j
    at weblogic.servlet.internal.WebAppServletContext.loadServletsOnStartup(WebAppServletCo
    at weblogic.servlet.internal.WebAppServletContext.preloadResources(WebAppServletContext
    at weblogic.servlet.internal.WebAppServletContext.start(WebAppServletContext.java:3153)



    Can someone Please help me rsolving the above error please. :(

    ReplyDelete
    Replies
    1. This is not the complete error. I assume you have modified Intial.properties file and added a new component, which is not being initialized. Send across the copy of your Initial.properties, you might not have written the component path correctly.

      Delete

Subscribe

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

Flickr