Sunday, September 11, 2011

ATG Made Easy - part 1

Here is a quick introduction to ATG now Oracle Commerce.

1) Nucleus:
Is a java bean that has a property file contain the default values for

certain attributes , you can inject also other nucleus/components using the property file.
It contain 2 important attributes:
-$Class=/osa/ora/ClassName which represent the class of this nucleus.
-$scope=GLOBAL (default), SESSION or REQUEST ..
The power of the nucleus is that you can configure it with different behavior according to:
-Environment
-Included Layers
Change the behavior is either by implementing different property values or by even change the nucleus class.
Configuration are placed in config path configured by ATG-Configh-Path in manifest.mf file (in meta-inf folder)
This is called: configuration layering
-Another advantage is you can change the nucleus values from dyna-admin (ATG-Admin interface) at the run time.

You can use the dyna-admin to identify all the layers of such component , using the definitionfiles or view service configurations of the nucleus where you can find the overriding files in any layer, this would be useful in troubleshooting when you change the property/xml files and it is not reflected in your application (last one will be the last overriding one).

You can still resolve global components from the code by using:
(cast to component) Nucleus.getSystemNucleus().resolveName("/osa/ora/.... component full name");
And if you want to resolve it from the request you can use:
ServletUtil.getCurrentRequest().resolveName("/osa/ora/.... component full name");

* Logging:
Defined in GLOBAL.properties in ATG/config path..
You can override the values in your module/nucleus/path according to the layering ...
Some components define debugLevel from 1-15 where 1=minimal , 15=maximum.

2) Droplet:ATG Servlet Bean:
View component called from DSP (Dynamo Server Pages) ...
<@taglib uri="/dspTaglib" prefix="dsp"%>
then you can use them using :
<dsp:page> ......page logic using dsp tags ...

The droplet is needed to encapsulate view logic that is repeated into single location of processing.
Droplet extends DynamoServlet class.

The dsp:droplet tag lets you invoke a servlet bean from a JSP page. It encapsulates programming logic in a server-side JavaBean and makes that logic accessible to the JSP page that calls it. Tag output is held by its parameters, which can be referenced by nested tags.

The following example show how we can use this tag:
<dsp:droplet name="/atg/dynamo/droplet/ForEach">
<dsp:param name="array" bean="/samples/Student_01.subjects"/>
<dsp:oparam name="outputStart">
<p>The student is registered for these courses:</p>
</dsp:oparam>
<ul>
<dsp:oparam name="output">
<li><dsp:valueof param="element"></dsp:valueof></li>
</dsp:oparam>
<dsp:oparam name="outputEnd">
</ul>
</dsp:oparm>
</dsp:droplet>

We have 3 types of parameters here:
1) Input : The previous example supplies the input parameter array to identify the type of data to process
2) Output : In the previous example, element is an output parameter that contains the value of the current array element.
3) Open : 3 types: marked by dsp:oparam tags, and specify code to execute at different stages of servlet processing :
-outputStart : executed just before loop processing begins
-output : executed during each loop processing
-outputEnd : executed just after the processing completed.

We can use also EL to access the output properties: example :

<dsp:droplet name="/atg/dynamo/droplet/ForEach" var="fe">
....
....
<dsp:oparam name="output">
<li><c:out value="${fe.element}"/></li>
</dsp:oparam>
....
....
</dsp:droplet>

ATG Servlet Beans and Servlets
Your Servlet must be a subclass of DynamoServlet. Its service method took DynamoHttpServletRequest and DynamoHttpServletResponse objects as parameters.

These interfaces are subclasses of standard servlet interfaces. DynamoHttpServletRequest extends HttpServletRequest and adds several functions that are used to access ATG servlet bean functionality.
The DynamoHttpServletResponse extends HttpServletResponse and also adds a couple of useful functions.
The DynamoServlet class implements the javax.servlet.Servlet interface. It passes requests to the service method by passing a DynamoHttpServletRequest and DynamoHttpServletResponse as parameters.
The DynamoServlet class extends atg.nucleus.GenericService, which allows an ATG servlet bean to act as a Nucleus component. This means that the ATG servlet bean has access to logging interfaces, can be viewed in the Component Browser, and has all the other advantages of a Nucleus service.
A servlet invoked with the DSP tag library tag need not be a subclass of DynamoServlet; it only needs to implement the javax.servlet.Servlet interface.
Any servlets that you write for other application servers can be used inserted in JSPs with DSP tag library tags. However, those servlets lack access to all other facilities available to Nucleus components. If you write ATG servlet beans from scratch, the DynamoServlet class provides an easier starting point.

3) ATG Repositories:
-Profile, Content, Commerce repositories is example for these repositories.
*Repository Item : (atg.repository.RepositoryItem) : must have id +/- any other properties.
Some droplets use these repositories:
-RQQueryForEach & RQQueryRange
-ItemLookupDroplet & RepositoryLookup..

-How to define repository XML:
<gsa-template>
<item-descriptor name="...." ....>
..... description here.....
</item-descriptor>
</gsa-template>

-Elements attributes could be :
1) Transient: not persisted in DB.
2) Persisted: stored in DB , you need to provide the DB table/column.
the table relation type could be "primary" , "auxiliary" or "multi".
3) Derived: Calculated with each request, you need to provide derivation

class that extends DerivationMethodImpl class.

Properties could be:
-Simple : string, integer..
-Enumerated: option value=x code=x where the code is what stored in DB.
-Items: refer to other items.

Also it could be:
-Single Values
-Multi-values: Array, Set and Map of other objects.

**Inheritance:
It is supported in XML...
Base ---> item-descriptor ....sub-type=class
Child --> item-descriptor ....super-type=class

- You can also use layering to override , replace , remove elements according to your needs...
just specify the xml-combine attribute with either:
-"remove", "append" or "replace".

Some repositories already defined and you can extend the repository/modify by having a layer (or layers) that define that repository definition file as:
userprofile.xml (for User Repository)
customCatalog.xml (for Commerce catalog repository)
priceLists.xml (for commerce price lists)

NB: You can cascade in relations by cascade="delete"
NB: You can group some properties for better performance: property=first group=full_name and property=last group=full_name
NB: You can use id generator to generate Ids for repository by :
<item-descriptor name=xxx id-space-name="unique name for id generation"
This is either auto-generated or explicitly configured in /atg/dynamo/sevices/idspaces.xml

**Object Types:
1) Repository: used to get repositoryItem (with its id) and to obtain repositoryView
--> Methods : getItem() and getView()
2) RepositoryItem : represents the individual item of the repository.
--> Methods: getRepositoryValue()
3) RepositoryView : to execute queries to return array of repositoryItem.
--> Methods: executeQuery()
4) MutableRepository : methods to insert/update/detlete repostiryItems
--> Methods : addItem(), createItem(), updateItem(), removeItem() and getItemForUpdate()
5) MutableRepositiryItem : used to change/set values of repositoryItem.
-->setPropertyValue()

Example: To Update
MutableRepositoryItem mutableItem=mutableRepository.getItemForUpdate(id,"Article");
mutableItem.setProperty(...., ...);
mutableRepository.update(mutableItem);

Example: To create
MutableRepositoryItem mutableItem=mutableRepository.createItem("Article");
mutableItem.setProperty(...., ...);
mutableRepository.addItem(mutableItem);

**Using RQL queries: either as statement (String) or named query (in repository XML)
RepositoryView myView=repos.getView("Article");
Object rqlParams=new Object[];
rqlParams[0]= "Osama";
RqlStatement statement=RqlStatement.parseRqlStatement("name = ?0");
RepositoryItem[] artcileList=statement.executeQuery(myView, reqlParams);
..... loop over the results......

In XML:
<item-descriptor name="Article">
....
<named-query>
<rql-query>
<query-name>MyQuery</query-name>
<rql> name = ?0 </rql>
</named-query>
....
</item-descriptor name="Article">

And in the code:
NamedQueryView view=(NamedQueryView) myView;
Query namedQuery=view.getNamedQuery("MyQuery");
....
ParameterSupportView pView=(ParameterSupportView)myView;
RepositoryItem[] artcileList=pView.executeQuery(namedQuery, rqlParams);
....

**Caching:
In repositories definition files, you can configure the cache mode and cache size and other cache related properties , you can check the cache statistics by accessing the dyna-admin page of these components..
The important thing you need to be aware of is the locking cache module where you have 1 lock server in the cluster and other servers have client lock managers to manage the requests to this server.. a configurable timeout for obtaining such locks, you shouldn't use this lock mode unless you need this as in OrderRepository for example.
• /atg/dynamo/service/ServerLockManager
• /atg/dynamo/service/ClientLockManager

Example of how you can obtain a lock over an order:
TransactionDemarcation td = new TransactionDemarcation();
try {
td.begin(getTransactionManager(), td.REQUIRED);
getClientLockManager().acquireWriteLock(pOrderId);
LockReleaser lr = new LockReleaser(getClientLockManager(),
getTransactionManager().getTransaction());
lr.addWriteLock(pOrderId);
<insert your code here>
} catch (Exception de) {
.....
return false;
} finally {
try {
td.end();
}
catch(TransactionDemarcationException tde) {
...
}
}


Reference: ATG Platform documentation set : Version 9.1 - 7/31/09

1 comment: