ART#203 How to add a new property to out of the box item-descriptor (non-versioned repository) ?

Now you must be wondering, what is this "Non-versioned repository"?. Let get to that first.

Versioned Repository:-
A versioned repository stores versions of assets. For example, someone changes a product's name, the previous version and the new version (with new name); both will be stored (but of course, the new one will be live on the site)
Versioned repositories are created mostly for data which can be modified by the business user. (For example, product name, product description, category name, store timings etc.)
The data in these repositories are generally modified by business user, using BCC.
We will not be covering more details on this one in this section. We will go into details for these repositories when we cover "BCC".

Non-Versioned Repository:-
A non-versioned repository does not store versions of assets. These repositories generally cannot be modified by business users (except some rare cases using CSC). The data in these repositories is generally modified by ATG system. For example, an order in OrderRepository will be modified by ATG system internally, and not by business users.
Many non-versioned repositories include, ProfileAdapterRepository (for profiles and related data), Order Repository (order details and data), InventoryRepository (inventory of product/sku etc).

Now, let us move on to extending an out of the box repository. Let us take up "ProfileAdapterRepository". 
For extending any out of the box repository, you will always have:-
1. Out of the box tables
2. The repository component (i.e OOTB configuration file)
3. Repository definition file (i.e. OOTB xml file for repository definition)
4. OOTB class to support the component (GSARepository or any custom class that extends it) - Mostly, customization for this class is not required.

What do you aim to do?
Figure out what you want to do with this repository. Basically, you can:-

1. Add a property (any type) to an OOTB item-descriptor. 
2. Add an entirely new item-descriptor.
3. Remove a property from OOTB item-descriptor.
4. Entirely remove OOTB item-descriptor. (this scenario is rare, but sometimes required, when you want a custom item-descriptor to be present in one ATG module but not other).

Add a property to OOTB item-descriptor.
This seems pretty easy, just follow the below steps and you'll be good to go.

1. Find the item-descriptor you want to extend.
Find out which item-descriptor you want to add a property to.
Let us say, we want to add a new property "myProperty" of type String in "user" item-descriptor".

2. Find out where to keep your custom (new) repository XML file.

i) Search & open the repository you want to extend in dyn/admin (in our case ProfileAdapterRepository)

ii) Next, click on "Examine Repository Definition" (see below screenshot).

iii) Scroll down a bit and see

    a. CONFIGPATH Filename : /atg/userprofiling/userProfile.xml
    b. Source Files: A list of layered XML files (from top to bottom)
See below screenshot for details.

iv) Now, you have to layer the userProfile.xml in your custom ATG module at the same location in config path as OOTB xml (i.e. at <CONFIG_PATH>/atg/userprofiling/userProfile.xml).
Layering can be done according to the needs as defined in previous article ART#202 : How to layer XML files in ATG.
This way, your newly layered XML file will start appearing in "Source Files" list mentioned in Step(iii)-b as last item. (We will see what to write in the XML soon)

TIP: You can try keeping your new XML file at <ATG_HOME>/localconfig/<your_full_path_to_XML>, instead of keeping it in ATG module's config path while testing, so that you don't have to rebuild the application again and again in case of errors caused by incorrect XML. You can simply change the XML in localconfig folder and restart the server.
[Example path: <ATG_HOME>/localconfig/atg/userprofiling/userProfile.xml ]
Once your XML file is free of errors, you can move it into your ATG module's config path and remove it from localconfig folder.

3. Creating/Modifying tables for the repository.

i) Now that we know "where" to keep our repository XMLs, we need to write something in it to make it work. Before we jump onto that, we have to make sure that the property which we are introducing (myProperty) in "user" item-descriptor, must be present as a column in some table.

ii) Now, our task is to find that table. Go back to step (2)-(ii) and click on "Examine Repository Definition". Scroll down and locate the item-descriptor "user". (Press Ctrl+F on your browser type and search for: name="user") Search for this until you find an <item-descriptor> tag with the attribute name="user".
Inside this item-descriptor tag, there should be a <table> tag with attribute type=primary. It would look something like:-

Every item-descriptor must have a "primary" table, which is defined by the attribute "type" in <table> item-descriptor. OOTB item-descriptors would always have a primary table. Notice the name of the table (which is OOTB) "dps_user" defined by the "name" attribute of the <table> tag. 
Also, just beside the table name, we have the attribute "id-column-name" which defines which column of this table stores the unique "id" of the repository-item. This is generally the primary key of the table too.

iii) Now that we have found our table, we have to take a decision.
  • Either alter this (OOTB) table and add our new column to it - (A strict NO-NO. We never touch OOTB tables.)
  • OR Create a new table which extends the original table and add our custom properties (This seems to be a nice solution)
iv) We never-ever change out of the box tables (its not that it does not work, it surely will, but we dont do it and keep the integrity of ATG).
So, we create a new table and name it as CUSTOM_USER (and we call it an auxiliary table), which should have the following:-
  • A column which stores the repository id of this item-descriptor - we name it as USER_ID. This is basically the primary key of our new (auxiliary) table and is the foreign key for dps_user. This means that the value of column "id" of dps_user is same as "user_id" in custom_user. This is to ensure that our new table is linked to previous table.
  • A column which stores our new property. We will name this column MY_PROPERTY. This will be our new property in user item-descriptor (of type String).
See below diagram for details.

Also, your SQL to create table should look like:-

v) Since most of your non-versioned repository tables exist in CORE schema, your SQL should run in CORE schema (as profile tables exist in core schema).

4. What to write in your new repository XML?
Now that, we have created our tables and we know where to keep our XML files, we can move on to writing stuff in XML files.

i) Create your XML file userProfile.xml and place it in your config-path as described in STEP#2.

ii) Your new xml file should always start with the tag <gsa-template xml-combine="[your combination mode]"> and end with </gsa-template>.
In our case, since we need to add a property, we will use the mode, xml-combine="append". Since the default mode is append, we can also chose to skip this attribute. For more details on xml-combine modes, you can refer to our previous article, 
ART#202 : How to layer XML files in ATG.

iii) Below diagram defines how the mapping for repository is done.

In above XML, we have defined how the item-descriptor maps two tables into a single item.
Now, we have successfully added a new property into user item-descriptor.

NOTE: If you do not wish to use the same config path or XML file name for definition, you can create your layered XML using rules mentioned in the ART#202 : How to layer XML files in ATG, and name it as per your wish (e.g. myUserProfile.xml), and place it at some other location in the config path (e.g. <CONFIG_PATH>/atg/userprofiling/custom/myUserProfile.xml). Next you can override the ProfileAdapterRepository component's configuration file, and set the property "definitionFiles" to point to your XML file with your custom name.
Your overridden configuration file might look like:-
Although this process would work absolutely fine, you should avoid using this process in case of extending repositories, and stick with the process mentioned in Step#4.

Now that we have covered the topic on how to add a new property to OOTB item-descriptor, let us discuss some more details on extending OOTB repositories. Let us go on and create an entirely new item-descriptor for out of the box repository.




  1. I've successfully added the xml file using above tutorial using jboss server.
    now i removed my custom module from eclipse and made a new module with the same name using weblogic and with the same xml, every time i tried starting the server it gives me error on the same line i added previous xml i get follwing errors
    Error parsing file "/atg/userprofiling/userProfile.xml" at line 8, col 78. Message=Attribute "column_name" must be declared for element type "property".
    **** Error Sat Jun 10 14:59:38 PKT 2017 1497088778731 /atg/userprofiling/ProfileAdapterRepository Error parsing template: atg.repository.RepositoryException: File "/atg/userprofiling/userProfile.xml" has parsing errors. atg.repository.RepositoryException: File "/atg/userprofiling/userProfile.xml" has parsing errors.

    1. Since you are trying to create a persistent property, you should have column_name attribute for tag, which contains the mapping of this property to the database column you wish to link to.



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