Sie sind auf Seite 1von 140

ATG Relationship Management Platform

03/01/2011

Citrisys Solutions, Chennai

Overview of E-Commerce
E-Commerce, which stands for electronic commerce (also called electronic marketing) is a way of buying and selling goods using electronic systems such as the internet or other computer networks. Main types of E-Commerce *B2C Most large retail stores have an online website for purchasing goods. This type of e-commerce is called business to consumer(B2C). *B2B B2B is selling goods between companies. It is like manufacturer supplying goods to the retailer or wholesaler. Leading E-commerce Software's * ATG * IBM Websphere e-commerce * MarketLive

03/01/2011

Citrisys Solutions, Chennai

Introduction to ATG Platform


ATG is an ecommerce software for building powerful ecommerce applications. It is purely a java based software. ATG comes with a collection of products such as Dynamo Application Server (DAS), Dynamo Commerce Server (DCS), Content Administration, ACC etc.. ATG Framework includes the following core modules. * DAF (Dynamo Application Framework) * DPS (Dynamo Personalization Server) * DSS (Dynamo Scenario Server)

03/01/2011

Citrisys Solutions, Chennai

Introduction to ATG Platform

ATG Portal

ATG ATG Commerce Publishing

ATG Personalization + ATG Scenarios Dynamo Application Framework Application Server

03/01/2011

Citrisys Solutions, Chennai

Dynamo Application Framework (DAF)


The Dynamo Application server sits on the top of our application server and supplies essential features to our application. It includes: Nucleus Repositories Tag Libraries Droplets and Form Handlers This framework is designed to run on industrys leading J2ee application server including ATGs own Dynamo Application server (DAS), Jboss, IBM Websphere, BEA Weblogic.

03/01/2011

Citrisys Solutions, Chennai

Dynamo Personalization Server (DPS)


The DPS module provides tools for setting up profile repositories, creating targeting rules and services. ATG applications use profile repositories to manage user profiles. A standard profile repository is a SQL repository component of class atg.adapter.gsa.GSARepository. A user profile is a set of attributes that represent the data you want to store for a site user, for example login name, password, e-mail address, registration date, and so on. Another feature by ATG, is to match content to individuals based on their needs and preferences. The ATG Dynamo e-Business Platform provides a rich set of features that allow companies to create rules for targeting content to particular users. These rules can be created using a graphical user interface or directly through code.

03/01/2011

Citrisys Solutions, Chennai

Dynamo Scenario Server (DSS)


Scenarios are a customer-centric method for modeling a users experience on a website. Scenarios cut development and maintenance time, allowing more features to be built in less time. The following figure shows a scenario which sends the user a friendly reminder email if the user doesnt log in again within 3 weeks.

03/01/2011

Citrisys Solutions, Chennai

DAF- 1.Nucleus
The DAF implements a component development model based on JavaBeans and JSPs. Developers assemble applications out of component beans (based on standard ATG classes or custom Java classes) by linking them together through configuration files in Nucleus, ATGs open object framework. Nucleus lets you assemble applications through simple configuration files that specify what components are used by the application, what parameters are used to initialize those components, and how those components hook up to each other. Any Java object with an empty constructor can act as a component in Nucleus Nucleus also takes on the task of creating and initializing components. Nucleus is the mechanism that gives those components a place to live, and a way for those components to find each other. Nucleus by itself provides no application-specific functions
Citrisys Solutions, Chennai 8

03/01/2011

DAF- 1.Nucleus Creating a Nucleus Component


Define the class with two properties: name (a String) and age (an integer): public class Person { String name; int age; public Person () {} public String getName () { return name; } public void setName (String name) { this.name = name; } public int getAge () { return age; } public void setAge (int age) { this.age = age; } } Put this class definition in your classes directory with the name Person.java. Next Step is to create a Nucleus component. For that create a file called Person.properties with the following contents: $class=Person (path of the java class) name=Stephen age=20 You can now view the Person component in the Components window.

03/01/2011

Citrisys Solutions, Chennai

DAF- 1.Nucleus Starting a Nucleus Component


You can start your Nucleus component by registering it with the Initial.properties file. Copy the Initial.properties file to your module and add your component to the Initial.properties file like the below: $class=atg.nucleus.InitialService initialServices=\ /atg/Initial,\ VMSystem,\ /atg/dynamo/StartServers

03/01/2011

Citrisys Solutions, Chennai

10

Nucleus- Full component names


Full component names are unique, containing folder names followed by the simple component name, separated by forward slashes

/atg/dynamo/service/SMTPEmail

03/01/2011

Citrisys Solutions, Chennai

11

GLOBAL. properties
GLOBAL.properties is a special properties file, not associated with any specific component that is often used to set logging levels for sets of components ATG7.x/DAS/config/GLOBAL.properties loggingError=true loggingWarning=true loggingInfo=true loggingDebug=false

Logging properties

Places logging messages into log # Uncomment the ScreenLog while in production mode files logListeners=\ atg/dynamo/service/logging/LogQueue,\ atg/dynamo/service/logging/ScreenLog Outputs logging messages to screen
03/01/2011 Citrisys Solutions, Chennai 12

DAF- 1.Nucleus Component Scopes


An application component can be set to one of the following scopes: Global: Component is shared among all users. Session: Separate instances of the component are provided to each user. Request: Separate instances of the component are provided to each active request. Window: Separate instances of the component are provided to each browser window.

03/01/2011

Citrisys Solutions, Chennai

13

DAF- 1.Nucleus Configuration Layering


We can start with an example: Lets say : /artists/d/DaveMathews/DaveMathews.properties file contains: $class= atg.music.Artist $scope=global name=Dave Mathews genre=folk/pop website= email= Here, we have defined a single global nucleus component of class atg.music.Artist which can be referenced by the name /artists/d/DaveMathews from within the Dynamo. Then the name property of the instance will be set to Dave Mathews and the genre property will be set to folk/pop. In this case even though our Artist bean has website and email properties we have not set these properties so they remain uninitialized.
03/01/2011 Citrisys Solutions, Chennai 14

DAF- 1.Nucleus Configuration Layering


Nucleus name Scope Java Instance (bean) atg.music.Artist name genre website email Dave Mathews folk/pop

/artists/d/DaveMathews global

03/01/2011

Citrisys Solutions, Chennai

15

DAF- 1.Nucleus Configuration Layering


In the previous example, there is only one component which is refers to the class Artist. But in reality, two or more properties files can specify the same component. For example:
A c:\music\artists\d\DaveMathews.properties file containing $class= atg.music.Artist $scope=global name=Dave Mathews genre=folk/pop A second c:\moreinfo\artists\d\DaveMathews.properties file containing website=http://www.dmb.com email=dave@dmb.com genre=rock 03/01/2011 Citrisys Solutions, Chennai 16

DAF- 1.Nucleus Configuration Layering


Nucleus name Scope Java Instance (bean) atg.music.Artist name genre website email Dave Mathews rock http://www.dmb.com dave@dmb.com

/artists/d/DaveMathews global

Here, genre properties has been replaced with a new value rock and the other two properties ( website and email ) has been initialized with
http://www.dmb.com and dave@dmb.com resp.

03/01/2011

Citrisys Solutions, Chennai

17

DAF- 1.Nucleus Configuration Layering


How does this happen? The config path is read from left to right. Properties set in later entries in the CONFIGPATH override earlier entries. In our case the genre property is specified in both properties files. The property is set to rock because that is the last value specified, (as we go from left to right through the CONFIGPATH). This process is know as configuration layering.

03/01/2011

Citrisys Solutions, Chennai

18

DAF- 2.Nucleus Tag Libraries


The ATG platform supports JSPs as its primary authoring format. The ATG platform ships with two tag libraries, located at <ATG9dir>/DAS/taglib: JSTL DSP The JavaServer Pages Standard Tag Library (JSTL) from Sun Microsystems handles generic Web application tasks that are supported by all application servers. JSTL is comprised of four tag libraries: core: evaluate and display data xml: manage XML code fmt: handle internationalization sql: interact with SQL data sources

03/01/2011

Citrisys Solutions, Chennai

19

DAF- 2.Nucleus Tag Libraries


The DSP tag library lets you access all data types in ATGs Nucleus framework. Other functions provided by these tags manage transactions and determine how to render data in a JSP. You should use tags from the DSP tag library only for tasks that involve Dynamo Application Framework (DAF) resources. For generic Web application tasks, use JSTL tags.

The DSP tag library supports both scripting and the JSP Expression Language. For example, the following two tags are equivalent: <dsp:valueof param="<%= currentCourse %>"/> <dsp:valueof param="${currentCourse}"/>

03/01/2011

Citrisys Solutions, Chennai

20

DAF- 2.Nucleus Tag Converters


To enable more control over data conversions, the ATG platform provides tag converter classes. Tag converters let you specify how data in forms is interpreted and displayed, and to control when exceptions are thrown.

Some of the OOTB Tag Converters


Credit card converters Currency converters Number converters

03/01/2011

Citrisys Solutions, Chennai

21

DAF- 2.Nucleus Tag Converters


<dsp:valueof bean="CreditCard.num" converter="creditCard" numcharsunmasked="4"/> XXXXXXXXXXXX3456

<dsp:valueof bean="CreditCard.num" converter="creditCard" maskcharacter="*" numcharsunmasked="12"/>

****567890123456

03/01/2011

Citrisys Solutions, Chennai

22

DAF- 2.Nucleus Custom Tag Converter


Create a class that implements the atg.droplet.TagConverter interface. This class must implement the four methods described below : getName Returns the name of your converter. This is the name that is used as an argument to the converter attribute in a tag. For example, Dynamo has a converter whose getName method returns currency, so you can include a tag like this in your JavaServer Pages: <dsp:valueof param="myPrice" converter="currency"/> getTagAttributeDescriptors Returns the list of attribute arguments that this converter takes. These attributes are listed along with the converter attribute in your valueof, input, or param tag.

03/01/2011

Citrisys Solutions, Chennai

23

DAF- 2.Nucleus Custom Tag Converter


convertStringToObject If you are using an input tag, when that form value is submitted, this method is called before the setX method of the component is called. Your convertStringToObject method must generate the Object value for use in the setX method. It can throw a TagConversionException if an error occurs during the conversion process. This method is also called if you use this converter with a param tag when the value of the parameter is defined. convertObjectToString This method is called in two situations: When you use a converter in a valueof tag, this method is used to convert the Object value into a String value before displaying it. When you use this tag in an input tag with a bean attribute and no existing value attribute, this method is called to fill in the value attribute with the current value of the bean property.
03/01/2011 Citrisys Solutions, Chennai 24

DAF- 2.Nucleus Custom Tag Converter Example


This example creates and configures a custom tag converter for US format Zip Codes: 91322-1232 01231-0132 83243 The tag converter class converts in the following ways: from String to a 'ZipCode' formatted String from ZipCode object to a 'ZipCode' formatted String It is used in JHTML like this:
<VALUEOF PARAM="zip" converter="ZipCode">default</VALUEOF>

Where zip may be either a string or a ZipCode object.

03/01/2011

Citrisys Solutions, Chennai

25

DAF- 2.Nucleus Custom Tag Converter Example


ZipCodeTagConverter.java public class ZipCodeTagConverter extends atg.nucleus.GenericService implements atg.droplet.TagConverter { ZipCode.java This additional class is provided to show how to convert from objects other than strings. ZipCode.properties This is the configuration file for the tag converter component. I made it a component so it could be included in an Initial.properties file to cause the self registration. $class=ZipCodeTagConverter $description=ZipCodeTagConverter $scope=global loggingDebug=true

For source code please see the attachment. For More information please refer atg documentation Progamming Guide Creating CustomTag Converters.
Adobe Acrobat Document

03/01/2011

Citrisys Solutions, Chennai

26

ATG Repository API


A repository is a data access layer that defines a generic representation of a data store. Application developers use this generic representation to access data by using only interfaces such as Repository and RepositoryItem. Developers use repositories to create, query, modify, and remove repository items. A repository item is like a JavaBean, but its properties are determined dynamically at runtime. Before knowing repository more, we need to learn about Data anywhere architecture.

03/01/2011

Citrisys Solutions, Chennai

27

Data Anywhere Architecture


ATG Data Anywhere Architecture provides a unified view of content and data across a business for organizations and their customers. The core of the ATG Data Anywhere Architecture is the Repository API. Through the Repository API, you can employ a single approach to accessing disparate data types, including SQL databases, LDAP directories, content management systems, and file systems. One of the most powerful aspects of this architecture is that the source of the data is hidden behind the ATG Repository abstraction. It is easy to change from a relational data source to an LDAP directory as none of the application logic needs to change. After data is retrieved from a data source, it is transformed into an object-oriented representation. Manipulation of the data can be done using simple getPropertyValue and setPropertyValue methods.
Citrisys Solutions, Chennai 28

03/01/2011

Data Anywhere Architecture


A high-level overview of the ATG Data Anywhere Architecture.

03/01/2011

Citrisys Solutions, Chennai

29

Data Anywhere Architecture


A simple view of Data- Anywhere Architecture

03/01/2011

Citrisys Solutions, Chennai

30

Data Anywhere Architecture


The main advantage is that data can even move from a relational database to an LDAP directory without requiring recoding. This is possible through xml mapping which acts as an interface for the ATG application and the database. This xml file is known as Repository Definition File (RDF).

03/01/2011

Citrisys Solutions, Chennai

31

A Sample Repository Definition File


<item-descriptor name="user"> <table name="ctdc_user" type="auxiliary" id-column-name="user_id"> <property name="maxNoOfLoginAttempt" data-type="int" category="Login Attempts" column-name="max_no_of_login_attempts" display-name="Number of Login Attempts"/> </table> <table name="ctdc_user_interests" type="multi" id-column-name="user_id" multi-columnname="sequence_num"> <property name="interests" data-type="list" category="User Interests" component-itemtype="ctdcInterest" column-name="user_interest" display-name="interests" /> </table> </item-descriptor> <item-descriptor name="ctdcInterest" display-name="CTDC User Interest"> <table name="ctdc_interest" type="primary" id-column-name="id"> <property name="id" display-name="id"/> <property name="name" data-type="string" column-name="name" display-name="Name"/> </table> </item-descriptor>

03/01/2011

Citrisys Solutions, Chennai

32

Repository API
Explanation of the Previous RDF <item-descriptor name="user"> In the SQL repository, for example, an item descriptor might correspond to a Single database table, or encompass multiple tables. In short, the itemdescriptor maps with the sql tables. <table name="ctdc_user" type="auxiliary" id-column-name="user_id"> Here the type defines whether its one-one or one-many relationships. ATG supports auxiliary one-to-one relationship. multi one-to-many relationship. In our case, its auxiliary. So its a one-to-one relationship.

03/01/2011

Citrisys Solutions, Chennai

33

Repository API
Explanation of the Previous RDF
<property name="maxNoOfLoginAttempt" data-type="int" category="Login Attempts" column-name="max_no_of_login_attempts" display-name="Number of Login Attempts"/> Here, each property maps to a column of a table. Each property is a RepositoryItem name -> property name. data-type -> represents data-type specifically to this property. If you want to define a property that refers to another item, use the item-type attribute to refer to that item (oneone relationship) category-> this will group the properties. ( you can see through the ACC). column-name-> represents the sql column-names. display-name-> represents the name to be displayed( you can see through the ACC) Please see the attachment to see the list of data-types ATG supports.
03/01/2011 Citrisys Solutions, Chennai
Adobe Acrobat Document

34

Repository API
<table name="ctdc_user_interests" type="multi" id-columnname="user_id" multi-column-name="sequence_num"> type=multi -> represents one-to-many relationships. multi-column-name=sequence_num -> ensures that the ordering of the multi-values are maintained. The column specified by the multi-columnname attribute is used for multi-valued properties of data type array, map, and list and is not used for sets (which are unordered). For map type properties, the values in the column specified by the multi-column-name attribute must be a string. For list or array type properties, these values should be an integer or numeric type, and must be sequential.
<property name="interests" data-type="list" category="User Interests" component-item-type="ctdcInterest" column-name="user_interest" displayname="interests" />

component-item-type -> is the name of the item descriptor that defines the item type of the members of the collection of repository items.

03/01/2011

Citrisys Solutions, Chennai

35

Repository API
If the property is a collection of primitive data types such as string, int, and double, specify the data type of the members of the collection by with the component-data-type attribute in the <property> tag for the multi item property: <property name="interests" column-name="interest" data-type="array component-data-type="string"/> When you are operating on the returned value from a List, Set, or Map property, the code should be like List l = (List) item.getPropertyValue(" interests "); ArrayList al = new ArrayList(); al.addAll(l);

03/01/2011

Citrisys Solutions, Chennai

36

Repository API Overview


Interface Repository RepositoryItem RepositoryView MutableRepository Key Methods getItem(), getView() getPropertyValue() executeQuery() addItem() getItemForUpdate() updateItem() removeItem() MutableRepositoryItem setPropertyValue()
The atg.repository.Repository interface is the base definition of any repository implementation. This interface provides methods to access RepositoryItems, RepositoryViews and ItemDescriptors, corresponding to the three main elements of the repository.

03/01/2011

Citrisys Solutions, Chennai

37

Retrieving a Repository Item by ID


public void addArtistToSong(String pSongid, String pArtistid) throws RepositoryException {
Repository repository = getRepository(); // getRepository()represents the repository name. defines in the properties file. try {
RepositoryItem artistItem =
repository.getItem(pArtistid,"artist"); // artist is the item-descriptors name.

if (ifLoggingDebug())
logDebug("adding artist: " + artistItem.getPropertyValue("name"));

} catch (RepositoryException e) {
if (isLoggingError()) {

logError("Unable to add artist to song", e); } throw e; }


}

03/01/2011

Citrisys Solutions, Chennai

38

Mutable Repositories
Repository and RepositoryItem provide a read-only view of repository elements MutableRepository is an extension that allows repository elements to be: Created Updated Deleted Manipulating a MutableRepositoryItem (a local copy of the data) only changes the repository when an explicit call to updateItem()or addItem()is made. Allow an item to be checked out of the repository, modified, and then resubmitted (so that the change will be reflected in the underlying data store) Provide a locking mechanism which prohibits any access of the data store while it is being modified

03/01/2011

Citrisys Solutions, Chennai

39

Mutable Repositories- Creating a new Item


Please see the code snippet below: public String createArtistFromUser(String pUserid) throws RepositoryException { MutableRepository mutRepos = (MutableRepository) getRepository(); RepositoryItem user = getUserRepository().getItem(pUserid, "user"); String username = (String)user.getPropertyValue("firstName") + " " + user.getPropertyValue("lastName"); MutableRepositoryItem mutArtistItem = mutRepos.createItem("artist"); mutArtistItem.setPropertyValue("name", username); copy all relevant properties mutRepos.addItem(mutArtistItem); return mutArtistItem.getRepositoryId();

03/01/2011

Citrisys Solutions, Chennai

40

Mutable Repositories- Creating a new Item


MutableRepository mutRepos = (MutableRepository) getRepository(); For creating a new item, MutableRepository is used. The method getRepository() will get the repository and we are casting it to a MutableRepository. RepositoryItem user = getUserRepository().getItem(pUserid, "user"); This code will fetch the particular user details by passing the userId. It will be a RepositoryItem because we are just retrieving the data. String username = (String)user.getPropertyValue("firstName") + " " + user.getPropertyValue("lastName"); This code will fetch the particular users firstname and LastName, then concatenated to a string. MutableRepositoryItem mutArtistItem = mutRepos.createItem("artist"); This code will create a MutableRepositoryItem for the itemDescriptor artist. mutArtistItem.setPropertyValue("name", username); This code will set the value to the property username of the itemdescriptor artist. This will only change the local copy of the data. We need to call explicitly addItem() To make changes to the repository. mutRepos.adItem(mutArtistItem); This will make the changes to the repository thus creating a new item.
03/01/2011 Citrisys Solutions, Chennai 41

Mutable Repository updating an item


Please see the code snippet.

public void addArtistToSong(String pSongid, String pArtistid) throws RepositoryException {


MutableRepository mutRepos = (MutableRepository) getRepository(); try {
RepositoryItem artistItem =
repository.getItem(pArtistid,"artist");

MutableRepositoryItem mutSongItem =
mutRepos.getItemForUpdate(pSongid,"song");

mutSongItem.setPropertyValue("artist",artistItem); mutRepos.updateItem(mutSongItem);

}
03/01/2011 Citrisys Solutions, Chennai 42

Mutable Repository updating an item


MutableRepositoryItem mutSongItem = mutRepos.getItemForUpdate(pSongid,"song"); mutSongItem.setPropertyValue("artist",artistItem); mutRepos.updateItem(mutSongItem); Fetch a mutable version of the repository item through the getItemForUpdate and getItemsForUpdate methods. These methods return instances of MutableRepositoryItem. This interface extends RepositoryItem and adds one method:setPropertyValue(String pPropertyName, Object pPropertyValu e) Use the setPropertyValue method of MutableRepositoryItem to change as many properties as you wish. These changes are not reflected in the repository until the final updateItem operation is invoked. Save the changes with the updateItem method. This method extracts all the changes required for the item and updates the item in the data store.
03/01/2011 Citrisys Solutions, Chennai 43

Mutable Repository removing an item


Removing an item from the repository is very easy. Pass the ID and ItemDescriptor name of the item you want to remove persistently to the removeItem method. The items property values are deleted and are no longer accessible from the repository: removeItem(String pId, String pDescriptorName)

03/01/2011

Citrisys Solutions, Chennai

44

Repository Queries
The most straightforward way of executing queries in a repository is using RQL using the RqlStatement class You can create an RQLStatement from a string using parseRQLStatement() RqlStatement statement = RqlStatement.parseRqlStatement( rql string); RQL statements are executed against a RepositoryView

03/01/2011

Citrisys Solutions, Chennai

45

Repository Queries - Parameterized RQL


public RepositoryItem findArtistByName(String pArtistName) throws RepositoryException {
1 2

Repository repos = getRepository(); RqlStatement findArtistRQL; RepositoryView artistView = repos.getView("artist"); Object rqlparams[] = new Object[1]; rqlparams[0] = pArtistName; findArtistRQL = RqlStatement.parseRqlStatement("name = ?0"); RepositoryItem [] artistList =
findArtistRQL.executeQuery (artistView,rqlparams);

if (artistList != null) {
return artistList[0];

} return null;

} 03/01/2011

Citrisys Solutions, Chennai

46

Named Queries (1)


You can also define a query in the SQL repository definition file
songs.xml

Example: a named <item-descriptor name="song"> query to return all jazz songs in the <named-query> repository <rql-query> <query-name>jazzSongs</query-name> <rql>genre = "jazz"</rql> </rql-query> </named-query> </item-descriptor>

Named Queries (2)


Two ways to execute a named query
- programmatically (use the NamedQueryView object)
SongsManager
jazzSongs

- in JSP (use the NamedQueryForEach droplet)

Named Queries: Programmatic Execution SongsManager.java


SongsManager jazzSongs

public RepositoryItem[] getJazzSongs() { try { RepositoryView songView = getRepository().getView("song"); 1 if(songView instanceof NamedQueryView) { NamedQueryView nameView = 2 (NamedQueryView)songView; Query namedQuery = nameView.getNamedQuery("jazzSongs"); RepositoryItem[] results = nameView.executeQuery(namedQuery); } return results; }

Named Queries: JSP


jazzsongs.jsp

<dsp:droplet name="/atg/dynamo/droplet/NamedQueryForEach"> <dsp:param name="repository" bean="/dynamusic/SongsRepository" /> <dsp:param name="queryName" value="jazzSongs" /> <dsp:param name="itemDescriptor" value="song" /> <dsp:oparam name="output"> <li> <dsp:a href="song.jsp"> <dsp:param name="itemId" param="element.id"/> <dsp:valueof param="element.title"/> </dsp:a> </dsp:oparam> </dsp:droplet>

Item-Descriptor Relationships
1. One-to-One Relationships: Lets see the Repository Definition file below; <item-descriptor name="user"> <table name="ctdc_user" type="auxiliary" id-column-name="user_id"> <property name="maxNoOfLoginAttempt" data-type="int" category="Login Attempts" column-name="max_no_of_login_attempts" display-name="Number of Login Attempts"/> </table> Explanation: We have to use the type=auxiliary for 1-1 relationship. Here, the property maxNoOfLoginAttempt of data-type int has been added to the item-descriptor user.

Item-Descriptor Relationships
dps_user
1-1 relationship

ctdc_user

03/01/2011

Citrisys Solutions, Chennai

52

Item-Descriptor Relationships
One-Many Relationship: Lets see the repository Definition File below: <item-descriptor name="user">
<table name="ctdc_user_interests" type="multi" id-column-name="user_id" multicolumn-name="sequence_num"> <property name="interests" data-type="list" category="User Interests" componentitem-type="ctdcInterest" column-name="user_interest" display-name="interests" /> </table> </item-descriptor> <item-descriptor name="ctdcInterest"> <table name="ctdc_interest" type="primary" id-column-name="id"> <property name="id" display-name="id"/> <property name="name" data-type="string" column-name="name" displayname="Name"/> </table> </item-descriptor>
03/01/2011 Citrisys Solutions, Chennai 53

Item-Descriptor Relationships
Explanation: 1. For one-to-many the type should be multi. 2. multi-column-name="sequence_num is used to maintain an order. It is used with list data-type. 3. Atg supports Set, List, Map, or array data-types. 4. component-item-type="ctdcInterest - the name of the item descriptor that defines the item type of the members of the collection of repository items. We can use the String array for storing the multi-valued properties like component-data-type=String. 5. You cannot establish a default value for multi-valued attributes. 6. In Code, we can get the multi-valued properties like: List l = (List) item.getPropertyValue(" interests ");
03/01/2011 Citrisys Solutions, Chennai 54

Cascade Operations
The SQL repository uses the cascade attribute in a <property> tag to better handle hierarchical properties, which is to say properties with the item-type or component- tem-type attributes. The cascade attribute can have one or more of the values insert,update, or delete. For example: <property name="scenarios" itemtype="scenario" cascade="update,delete"/> The item is created, added, updated, and deleted along with the parent item. Cascade Insert: A new item of the type declared by the item-type attribute is also created. The cascade="insert" attribute is typically used with cascade="update" and cascade="delete" so management of this item is completely automatic. The cascade="insert" attribute is ignored for properties that use component-itemtype.
03/01/2011 Citrisys Solutions, Chennai 55

Cascade Operations
Cascade update: When you call updateItem, any modified referenced items are automatically updated. Any referenced items that are new (transient) items are added. Cascade delete: If a repository item has a property with the cascade="delete" attribute set, when you remove the repository item, any items that are referenced by the property are also removed. Also, when you remove a reference to this item, the item is automatically removed.

03/01/2011

Citrisys Solutions, Chennai

56

Item Descriptor Inheritance


You can define an item descriptor that inherits properties from another item descriptor in the same repository. In the following example, a simple clothing store catalog offers coats and shorts. You can model this by creating independent item descriptors to represent coats and shorts and putting each in its own database table. The XML repository definition for this model looks something like: <!-- The "coat" item type --> <item-descriptor name="coat"> <table name="coat" id-column-names="id" type="primary"> <property name="name"/> <property name="description"/> <property name="color"/> <property name="shippingWeight"/> <property name="size"/> <property name="season"/> </table> </item-descriptor>
03/01/2011 Citrisys Solutions, Chennai 57

Item Descriptor Inheritance


<!-- The "shorts" item type --> <item-descriptor name="shorts"> <table name="shorts" id-column-names="id" type="primary"> <property name="name"/> <property name="description"/> <property name="color"/> <property name="shippingWeight"/> <property name="size"/> <property name="pleated" data-type="boolean"/> </table> </item-descriptor> And the database data model has two unrelated tables:

03/01/2011

Citrisys Solutions, Chennai

58

Item Descriptor Inheritance


This approach has several drawbacks: Coats and shorts have a lot of properties in common, which in the above model means duplicated database columns and probably duplicated code. This model does not allow you to easily perform a query like: find all the items of clothing (shorts and coats) that have Star Wars in their description

An object-oriented approach like that used by the SQL repository lets you define a base item descriptor class called clothing to hold the attributes common to coats and shorts. You can use simple inheritance to make coats and shorts subclasses of clothing. You can then model the data in your clothing catalog as follows:

03/01/2011

Citrisys Solutions, Chennai

59

Item Descriptor Inheritance


The corresponding XML repository definition (with changes in bold type) looks like this: <!-- The "clothing" item type, a base type --> <item-descriptor name="clothing" sub-type-property="type"> <!-- This is the primary table that holds clothing data --> <table name="clothing" type="primary" id-column-names="id"> <property name="type" data-type="enumerated"> <option value="coat"/> <option value="shorts"/> </property> <property name="name"/> <property name="description"/> <property name="color"/> <property name="size"/> <property name="shippingWeight"/> </table> </item-descriptor>

03/01/2011

Citrisys Solutions, Chennai

60

Item Descriptor Inheritance


<!-- The "coat" item type, now a subclass of "clothing" --> <item-descriptor name="coat" super-type="clothing" sub-typevalue="coat"> <table name="coat" type="auxiliary" id-column-names="id"> <property name="season"/> </table> </item-descriptor> <!-- The "shorts" item type, now a subclass of "clothing" --> <item-descriptor name="shorts" super-type="clothing" sub-typevalue="shorts"> <table name="shorts" type="auxiliary" id-column-names="id"> <property name="pleated" data-type="boolean"/> </table> </item-descriptor>

03/01/2011

Citrisys Solutions, Chennai

61

Derived Properties
This feature enables one repository item to derive property values from another repository item or from another property in the same repository item. For example, an organization might have divisions, departments, and employees, organized in a tree structure. A repository represents this tree structure with division, department, and employee item descriptors. Each of these item descriptors might define a property called spendingLimit. A business rule might specify that an employees spending limit comes from their department if it is not set for that employee. If the spending limit is not set for the department it should be derived from the spending limit for the division. This derived property relationship is represented in a repository definition file as follows:

03/01/2011

Citrisys Solutions, Chennai

62

Derived Properties
<item-descriptor name="employee"> <property name="department" item-type="department"/> <property name="empSpendingLimit" data-type="int"/> <property name="spendingLimit" writable="false"> <derivation> <expression>empSpendingLimit</expression> <expression>department.spendingLimit</expression> </derivation> </property> </item-descriptor> <item-descriptor name="department"> <property name="division" item-type="division"/> <property name="deptSpendingLimit" data-type="int"/> <property name="spendingLimit" writable="false"> <derivation> <expression>deptSpendingLimit</expression> <expression>division.divSpendingLimit</expression> </derivation> </property> </item-descriptor> <item-descriptor name="division"> <property name="division" item-type="division"/> <property name="divSpendingLimit" data-type="int"/> </item-descriptor>
03/01/2011 Citrisys Solutions, Chennai 63

SQL Repository Item Properties


Enumerated Properties <property name="transactionType" data-type="enumerated"> <option value="credit" code="0"/> <option value="debit" code="1"/> <option value="purchase" code="2"/> </property> Required Properties You can specify that a repository item property is required by setting a property tags required attribute: <property name="lastName" data-type="string" required="true" /> Unique Properties You may want a repository item property to require a unique value. <property name="login" data-type="string" required="true"> <attribute name="unique" value="true"/> </property>

03/01/2011

Citrisys Solutions, Chennai

64

SQL Repository Item Properties


Date and Timestamp Properties You can have a property whose value is set to the current time or date at the moment a repository item is created. You can do this by setting the feature descriptor attribute useNowForDefault. For example: <property name="creationDate" data-type="timestamp"> <attribute name="useNowForDefault" value="true"/> </property> Last-Modified Properties In some applications, it is useful to know when a repository item was last modified most recently. <item-descriptor name="article" last-modified-property="lastActivity"> <attribute name="updateLastModified" value="true"/> <table name=article type="primary> <property name="lastActivity" data-type="timestamp"/> ... </table> </item-descriptor When items of this type are added or updated, the lastActivity property is updated with the current time.
03/01/2011 Citrisys Solutions, Chennai 65

SQL Repository Item Properties


Transient Properties The SQL repository lets you define properties of a repository item that are transient. Transient properties are never stored or read from the persistent data store. They are readable and writable, but not queryable. Transient properties provide applications a hook for custom objects that are not persisted by the repository. <item-descriptor name="user" sub-type-property="userType"> <property name="loggedIn" data-type="boolean"> <table name="user" type="primary" id-column-names="id"> <property name="userType" data-type="enumerated" column-name="user_type"> ... Here, the property loggedIn is a transient property.

03/01/2011

Citrisys Solutions, Chennai

66

SQL Repository Item Properties


Linking between Repositories
A property value can refer not just to another type of repository item, but also to a repository item in another repository. <table name="employees" id-column-names="id"> ... <property name="work_address" item-type="workAddress" repository="/atg/userprofiling/LDAPRepository"/> </table>

03/01/2011

Citrisys Solutions, Chennai

67

SQL Repository Caching


Item and Query Caches Item caches hold the values of repository items, indexed by repository IDs. Item caching can be explicitly enabled for each item descriptor. Even if caching is explicitly disabled, item caching occurs within the scope of each transaction Query caches hold the repository IDs of items that match the given queries. Query caching is turned off by default.

03/01/2011

Citrisys Solutions, Chennai

68

SQL Repository Caching


Caching Modes Simple caching handles caches in each server locally; no attempt is made to synchronize updates across multiple server instances. This is the default cache mode. Locked caching uses read and write locks to synchronize access to items stored by multiple caches. Distributed TCP caching uses TCP to broadcast cache invalidation events to all servers in a cluster. Distributed JMS caching uses JMS to broadcast cache invalidation events to all servers in a cluster. Distributed hybrid caching uses TCP to send cache invalidation events only to those servers that are known to cache the target items.

03/01/2011

Citrisys Solutions, Chennai

69

ATG Servlet Bean (Droplet)


Most applications require a way to dynamically generate HTML from a Java object. The dsp:droplet tag lets you do this by embedding an ATG servlet bean. The servlet bean produces output that is included in the HTML page. Droplets will generate dynamic output at run time. There are OOTB droplets. Few are given below.
For ForEach RQLForEach Switch Range TargettingForEach RepositoryLookup IsEmpty IsNull

03/01/2011

Citrisys Solutions, Chennai

70

ATG Servlet Bean (Droplet)


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. Use of Droplet Separates Jsp code and java Code.

03/01/2011

Citrisys Solutions, Chennai

71

ATG Servlet Bean (Droplet)


How to Implement the Droplet in a Page? Import the Droplet <dsp:droplet name="/atg/dynamo/droplet/ForEach"> Implement the For Each to fetch the results. <dsp:droplet name=ForEach> <dsp:param name="array" bean="ClassroomService.enrolledStudents" /> <dsp:setvalue param=CurrentStudent paramvalue=element/> <dsp:oparam name=empty> No students in the class. </dsp:oparam>
03/01/2011 Citrisys Solutions, Chennai 72

ATG Servlet Bean (Droplet)


<dsp:oparam name=outputStart> Here is the list of students: </dsp:oparam> <dsp:oparam name=output> <dsp:valueof param=CurrentStudent.fullName/> </dsp:oparam> </dsp:droplet> Note:
The below code will fetch the results from an array. It is similar to for loop. It will loop through the array and display the results.

03/01/2011

Citrisys Solutions, Chennai

73

ATG Servlet Bean (Droplet)


Next, we can see how to extend the OOTB Droplets to add our custom requirements. Override the OOTB component and point it to your custom class. (The path of the component should be same as in the OOTB). For Example, lets try to override the ForEach Droplet. $class=com.test.MyCustomForEach. Create a class MyCustomForEach inside com/test, extends ForEach Droplet. public class MyCustomForEach extends ForEach { //include you custom requirements. }

03/01/2011

Citrisys Solutions, Chennai

74

ATG Servlet Bean (Droplet)


Next, we will see how to write a custom Droplet. Create a Nucleus component. For example: $class=com.droplet.CTDCPriceRangeDroplet $scope=request Create a class which extends DyanmoServlet like the below. public class CTDCPriceRangeDroplet extends DynamoServlet{ //override the service method public void service(final DynamoHttpServletRequest pRequest, final DynamoHttpServletResponse pResponse) throws ServletException, IOException { //set the results: pRequest.setParameter("minPrice", minPrice); pRequest.setParameter("maxPrice", maxPrice); pRequest.serviceLocalParameter("output", pRequest, pResponse); }
03/01/2011 Citrisys Solutions, Chennai 75

ATG Servlet Bean (Droplet)


Next, we will see how to display the custom Droplet in jsp. Import the droplet using importBean as we seen the previous section Implement the droplet like the below.

<dsp:droplet name=" CTDCPriceRangeDroplet"> <dsp:oparam name="output"> <dsp:valueof param="minPrice/> <dsp:valueof param=maxPrice/> </dsp:droplet> Note:
The minPrice and maxPrice are the custom parameters which we created in the customDroplet. Please see the previous slide.

03/01/2011

Citrisys Solutions, Chennai

76

FormHandlers
Atg Form handlers that can perform these tasks: Validate data before it is submitted. Detect missing information and display appropriate messages to the user. Direct users to different pages depending on form submission results. Read and write database or repository data. Form handlers are components that you typically build from one of the form handler classes provided by the ATG Adaptive Scenario Engine. All provided form handler classes are subclasses of atg.repository.servlet.GenericFormHandler, and inherit its properties and methods:

03/01/2011

Citrisys Solutions, Chennai

77

FormHandlers
ATG Relationship Management Platform includes the following form handler classes: SimpleSQLFormHandler for working with form data that is stored in a SQL database. RepositoryFormHandler for saving repository data to a database. ProfileFormHandler class to connect forms with user profiles stored in a profile repository. SearchFormHandler for specifying properties available to a search engine. You can also extend these and other form handler classes to handle the specific needs of your application.
03/01/2011 Citrisys Solutions, Chennai 78

FormHandlers - Form Error Handling


A Web application must identify and gracefully handle errors that might occur on form submission. For example, a user enters an alphabetic character in a field where an integer is required. Then, it should throws an error. If the form uses a form handler of class GenericFormHandler or one of its subclasses, exceptions that occur during form processing are saved to one of these form handler component properties: Property formError Purpose Boolean that is set to true if any errors occur during form processing. A vector of the exceptions that occur during form processing.
Citrisys Solutions, Chennai 79

formExceptions

03/01/2011

FormHandlers - Form Error Handling


propertyExceptions A read-only property that returns a Dictionary of subproperties, one for each property set by the form. For each property that generates an exception, a corresponding subproperty in the propertyExceptions Dictionary contains that exception. For each property that does not generate an exception, the corresponding subproperty in the propertyExceptions Dictionary is unset.

03/01/2011

Citrisys Solutions, Chennai

80

SimpleSQLFormHandler
Dynamo defines a class, atg.droplet.sql.SimpleSQLFormHandler, which implements a form handler for querying, inserting, updating, and deleting rows from a database table. This form handler requires that each row to be edited can be uniquely identified by a set of key columns. In other words, it cannot be used for queries, updates, or deletes that operate on more than one row at a time. The SimpleSQLFormHandler lets you interact with a SQL database directly, by specifying the table rows to query or update. This form handler relies only minimally on the repository layer, it requires you to know exactly which items are required.

03/01/2011

Citrisys Solutions, Chennai

81

SimpleSQLFormHandler Navigation Properties


Handler method handleLookup handleUpdate handleDelete handleInsert Success/failure URL properties lookupSuccessURL lookupErrorURL updateSuccessURL updateErrorURL deleteSuccessURL deleteErrorURL insertSuccessURL insertErrorURL

03/01/2011

Citrisys Solutions, Chennai

82

SQL Form Handler Example


$class=atg.droplet.sql.SimpleSQLFormHandler $scope=session connectionURL^=TableManager.connectionURL keyColumns=NAME tableName=SKIER DBErrorURL=sqlError.jsp Lets name the component as SkierHandler. You can use the SkierHandler component to look up or change the properties of skiers who are registered with an application. For example, skiers can change the value of their preferredActivity property with this portion of the editPerson.jsp page:

03/01/2011

Citrisys Solutions, Chennai

83

SQL Form Handler Example


<tr> <td align=right><b>Your preferred activity:</b></td> <td><dsp:select bean="SkierHandler.value.preferredActivity"> <dsp:option value="Skiing">Skiing</dsp:option> <dsp:option value="Snowboarding">Snowboarding</dsp:option> <dsp:option value="X-Country">X-Country</dsp:option> </dsp:select> </td> </tr>

When a user submits this form, the preferredActivity property of the value property of the SkierHandler is set to the selected option, and is inserted in the appropriate row of the SKIER database table.

03/01/2011

Citrisys Solutions, Chennai

84

Repository Form Handler


The atg.repository.servlet.RepositoryFormHandler class provides methods and properties for working with repository items. You can use a component of this class to add, update, and delete repository items that use the same item descriptor. The RepositoryFormHandler offers several benefits: Requires only the repository item type for updates. Supports all repository types: HTML, XML, LDAP, and SQL. Caches repository data .Optimizes data access.

03/01/2011

Citrisys Solutions, Chennai

85

RepositoryFormHandler Properties
checkForRequiredProperties A boolean, specifies whether the form handler checks that all required properties are present during operation. clearValueOnSet A boolean, specifies whether the value dictionary for an item is cleared and reset from the database when its repositoryId property changes. itemDescriptorName A string that specifies the item descriptor items handled by this RepositoryFormHandler. repository Specifies the repository where items are added, updated, and deleted. requireIdOnCreate A boolean, specifies whether an item ID must be user-supplied when an item is created. If set to true (the default), an error is thrown if no ID is provided. If set to false and no ID is provided, an ID is generated for the item on the fly.

03/01/2011

Citrisys Solutions, Chennai

86

RepositoryFormHandler Operations
Operation create Function Creates a repository item based on the value set in the form and adds it to the repository. If the repositoryId property is specified in the form, the new item is created with the given repository ID; otherwise, an auto-generated ID is used. Deletes from the repository the item specified by repositoryId. Updates the item described by repositoryId from the form values.

delete update

You associate one of these operations with a submit input tag. For example, the following input tag defines a submit button that creates a repository item: <dsp:input type="submit" bean="atg/dynamo/droplet/MyRepositoryFormHandler.create" value="Add CD"/>

03/01/2011

Citrisys Solutions, Chennai

87

ProfileFormHandler
Connects forms with user profiles stored in a profile repository. You can use the ProfileFormHandler to set user profile properties without writing any Java or SQL code. The ProfileFormHandler handles the following tasks: Profile creation and updates User login and logout. Assignment of existing roles and organizations to individual users and groups of users.

For example, when a user logs into a site, a form can invoke the login operation as follows: <dsp:input bean="ProfileFormHandler.login" type="submit" value="Submit"/>

03/01/2011

Citrisys Solutions, Chennai

88

Setting Profile Values


First Name: <dsp:input bean="ProfileFormHandler.value.firstname" maxlength="30size="25" type="text"/> Last Name: <dsp:input bean="ProfileFormHandler.value.lastname" maxlength="30 size="25" type="text"/> Email Address: <dsp:input bean="ProfileFormHandler.value.email" maxlength="30 size="25" type="text"/> <dsp:input bean="ProfileFormHandler.value.gender" type="radio" value="female"/>Female <dsp:input bean="ProfileFormHandler.value.gender" type="radio value="male"/>Male <dsp:input bean="ProfileFormHandler.create" type="submit" value=" Save "/>

03/01/2011

Citrisys Solutions, Chennai

89

Customizing ProfileFormHandler
You can extend the ProfileFormHandler in the same way you are extending the other FormHandlers. public class MyProfileFormHandler extends ProfileFormHandler. { protected void preCreateUser // invokes before the handlecreate() public boolean handleCreate()// create user. protected void postCreateUser // Invokes after the handleCreate() }

03/01/2011

Citrisys Solutions, Chennai

90

Writing Custom Form Handlers


Sometimes we need to create a custom form handler to meet our business requirements. The Custom FormHander should extend atg.droplet.GenericFormHandler . The GenericFormHandler class provides simple implementations of the DropletFormHandler interfaces methods and adds basic error handling logic. If errors occur in processing a form that uses GenericFormHandler, the errors are saved and exposed as properties of the form handler component. Form handlers use special handler methods for linking form elements with Nucleus components. A handler method has the name handleX, where X represents the name of the form handler property being set. For Example, public boolean handleCreate (javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) { }
Citrisys Solutions, Chennai 91

03/01/2011

Writing Custom Form Handlers


Form handlers typically implement an interface called DropletFormHandler. This interface has the following methods, which are called at specific points as the form is processed: Method beforeSet afterSet beforeGet afterGet handleFormExc eption
03/01/2011

When Called Before any setX methods are called After all setX methods are called Before any input tags that reference this component are rendered After page rendering is complete, before the socket is closed If an exception occurs when trying to call the setX method of a form
Citrisys Solutions, Chennai 92

Writing Custom Form Handlers


Now, let us look into creating a new custom formhandler. 1. Create a component for the formhandler. $class = path of the class. $scope= request. 2. Create a Formhandler on the same path mentioned by the component. public class customFormHandler extends GenericFormHandler. { public boolean handleRegister (javax.servlet.http.HttpServletRequest request,javax.servlet.http.HttpServletResponse response) { // this method can invoked through Jsp. } } 3. In Jsp, you can invoke this using the following code. <dsp:input type="submit" value="Register Now" bean=" customFormHandler.register"/>
03/01/2011 Citrisys Solutions, Chennai 93

Form Handler Scope


A form handler component should be either request- scoped or sessionscoped. Most of the case it will be request scope. But, in certain situation it has to be Session scope. For Example, if your registration page contains multi-page, then , it will be necessary to set the scope to session.

03/01/2011

Citrisys Solutions, Chennai

94

Request Handling pipeline


One of Dynamos most important tasks is handling HTTP requests Dynamo uses two request-handling pipelines: DAS servlet pipeline for JHTML requests DAF servlet pipeline for JSP requests Request handling can usually be broken down into a series of independent steps. In Nucleus-based applications, each of these steps is represented by a single Nucleus service that also implements the Servlet interface. Most requests handled by Nucleus are dispatched to the PageFilter filter or DynamoProxyServlet, either of which start the servlet pipeline. When the application server invokes PageFilter, it starts the DAF servlet pipeline by calling DynamoHandler, the first servlet in the pipeline. The last servlet in the pipeline is TailPipelineServlet.
Citrisys Solutions, Chennai 95

03/01/2011

Request Handling pipeline


Customizing Request handling Pipeline A standard servlet pipeline is invoked every time Dynamo handles a request The atg.servlet.pipeline package provides interfaces that provide various mechanisms for linking servlets to create a pipeline. The heart of the servlet pipeline is the PipelineableServlet interface. Dynamo also provides an implementation class PipelineableServletImpl that implements this interface; your own classes can implement PipelineableServlet by sub classing PipelineableServletImpl.

03/01/2011

Citrisys Solutions, Chennai

96

Request Handling pipeline


For example, suppose you have a servlet pipeline where a servlet called Servlet1 invokes a servlet called Servlet2. Now suppose you want to insert another servlet, Servlet1a, between these two servlets in the pipeline. If Servlet1a implements PipelineableServlet, you can reroute the pipeline by changing the value of the Servlet1.nextServlet property so it points to Servlet1a rather than Servlet2, and set Servlet1a.nextServlet to point to Servlet2. But if Servlet1a implements InsertableServlet, you only have to set Servlet1a.insertAfterServlet to point to Servlet1, and Servlet1a is automatically spliced into the pipeline right after Servlet1 and before Servlet2.

03/01/2011

Citrisys Solutions, Chennai

97

Request Handling pipeline


PipelinableServlet Servlets that implement the PipelineableServletImpl interface have an nextServlet property which tells the sequence where the servlet to be inserted. PipelineableServlet interface has two sub-interfaces DispatcherPipelineableServlet InsertableServlet InsertableServlet Servlets that implement the InsertableServlet interface have an insertAfterServlet property that enables the servlet to insert itself in a specific spot in the pipeline. The key advantage of this mechanism is that it does not require modifying any existing servlets in the pipeline. To implement the InsertableServlet interface, you can subclass InsertableServletImpl.
03/01/2011 Citrisys Solutions, Chennai 98

Request Handling pipeline


Steps to customize Request handling pipeline: Create a servlet which implements PipelinableServletImpl / InsertableServletImpl based on your implementation Create a component for the servlet created with property nextServlet or insertAfterServlet. Add the path of your servlet to the InitialServices Property of /atg/dynamo/servlet/Initial InitialServices+=/myServlet

Example for Insertable servlet: 1. Create a component $class=atg.dynamo.servlet.pipeline.URIPrinter insertAfterServlet=/atg/dynamo/servlet/pipeline/DynamoServlet

03/01/2011

Citrisys Solutions, Chennai

99

Request Handling pipeline


2.Create a class URIPrinter extends InsertableServletImpl on the same path mentioned in the component. public class URIPrinter extends InsertableServletImpl { public void service (DynamoHttpServletRequest request, DynamoHttpServletResponse response) throws IOException, ServletException { if(isloggingInfo) logInfo ("Handling request for " + request.getRequestURI ()); } passRequest (request, response); }

03/01/2011

Citrisys Solutions, Chennai

100

Request Handling pipeline


Example for Pipelinable Servlet 1.Create a component. $class=atg.dynamo.servlet.pipeline.URIPrinter nextServlet=/atg/dynamo/servlet/pipeline/DynamoServlet Also Change the components next property of servlet after which you are going to insert your servlet. 2. Create a class URIPrinter extends PipelineableServletImpl on the same path mentioned in the component. public class URIPrinter extends PipelineableServletImpl { public void service (DynamoHttpServletRequest request, DynamoHttpServletResponse response) throws IOException, ServletException { if(isloggingInfo) logInfo ("Handling request for " + request.getRequestURI ()); } passRequest (request, response); }

03/01/2011

Citrisys Solutions, Chennai

101

Transaction Management
A transaction is a set of actions that is treated as an atomic unit. Either all the actions take place , or none of them take place. When all the actions runs successfully the transaction commits, otherwise the transaction roll backs. For example transfer from one bank account to another. The transfer requires two separate actions. An amount is debited from one account, then credited to another account. Here either both the actions should take place or none. This means that both actions must take place within the same transaction. Each active transaction is represented by a transaction object, which implements the interface javax.transaction.Transaction. This object keeps track of its own status, indicating if it is active, if it has been committed or rolled back, and so on.

03/01/2011

Citrisys Solutions, Chennai

102

Transaction Management
TransactionManager A transaction Manager provides services to support the management of transactional resources. The Transaction Manager is a services provided by the application server. The service implements a java interface javax.transaction.TransactionManager. The detailed operation of the Transaction Manager is normally hidden from the developer. The programmer need only worry about setting up transactional boundaries within the code. ATG uses TransactionManager as nucleus components. These components can be difficult to use. Fortunately ATG provides TransactionDemarcation class that allows you to demarcate program areas.

03/01/2011

Citrisys Solutions, Chennai

103

Transaction Management
TransactionDemarcation This a a helper class that simplify the management of transaction boundaries. Transaction Demarcation is a term used to define the start and end points of a Transaction. This class contains two methods. 1.The begin() method is used to indicate the involvement of this process in the current transaction .Depending upon the arguments passed to this method,TransactionManager will decide whether to start a new transaction or have this process join in an existing transaction or produce an error. void begin(javax.transaction.TransactionManager pTransactionmanager,int pTransAtrribute)throws TransactionDemorcationExeception. 2. The end() method is used to indicate that the current process has completed its part of the transaction. Depending upon the mode, this may result in a commit or it may defer the commit to some other process. public int end() This method returns a status code indicating what happened to the transaction during the demarcated area.
03/01/2011 Citrisys Solutions, Chennai 104

Transaction Management
To use Transaction you need to understand the transaction demarcation modes: 1) Required: Indicates that a transaction must be in place in the demarcated area. If a transaction is already in place in the area, nothing further is done. If no transaction is in place, one is created when the demarcated area is entered and ended when the demarcated area ends. 2) RequiresNew: Indicates that all activity within the demarcated area must occur in its own separate transaction. If no transaction is in place in the area, a transaction is created at the beginning of the demarcated area and ended at the end of the demarcated area. If a transaction is in place when the demarcated area is entered, that transaction is suspended, and a new transaction is begun, at the end of the demarcated area, the new transaction is ended, and the original transaction is resumed. 3) NotSupported: Indicates that a transaction must not be in place in the demarcated area. If no transaction is in place in the area, nothing further is done. If there is a transaction in place when the demarcated area is entered, that transaction is suspended, then resumed at the end of the demarcated area.
03/01/2011 Citrisys Solutions, Chennai 105

Transaction Management
4) Supports: This mode does nothing. If a transaction is in place when the demarcated area is entered then that transaction remains in place. Otherwise, the area is executed without a transaction in place. 5) Mandatory: Throws an exception if a transaction is not in place when the demarcated area is entered. This mode does not create a transaction; it is used to verify that a transaction is in place where the developer expects 6 )Never: Throws an exception if there is a transaction in place when demarcated area is entered. This mode does not end or suspend any existing transactions; it is used to verify that a transaction is not in place where the developer does not expect one.

03/01/2011

Citrisys Solutions, Chennai

106

Scheduler Services
Most server-side applications have routine tasks that must be performed periodically. For example, a component in the application might need to clear a cache every 10 minutes. Dynamo includes a Scheduler service, atg.service.scheduler.Scheduler, for doing this job. Writing a Schedulable Component. 1. Configure a Schedulable Component. scheduler=/atg/dynamo/service/Scheduler schedule=every 10 seconds. scheduler points to a Scheduler such as the standard Dynamo Scheduler. schedule points to the standard Dynamo Scheduler. The schedule property can be set in a wide variety of formats. Please refer the Atg Programming Guide for different time settings.

03/01/2011

Citrisys Solutions, Chennai

107

Scheduler Services
Write a class which implements Scehdulable public class HelloJob extends GenericService implements Schedulable { // Scheduler property Scheduler scheduler; public Scheduler getScheduler () { return scheduler; } public void setScheduler (Scheduler scheduler) { this.scheduler = scheduler; } // Schedule property Schedule schedule; public Schedule getSchedule () { return schedule; } public void setSchedule (Schedule schedule) { this.schedule = schedule; } // Schedulable method public void performScheduledTask (Scheduler scheduler, ScheduledJob job) { System.out.println ("Hello"); }

03/01/2011

Citrisys Solutions, Chennai

108

Scheduler Services
// Start method int jobId; public void doStartService () throws ServiceException { ScheduledJob job = new ScheduledJob ("hello", "Prints Hello", getAbsoluteName (), getSchedule (), this, ScheduledJob.SCHEDULER_THREAD); jobId = getScheduler ().addScheduledJob (job); } // Stop method public void doStopService () throws ServiceException { getScheduler ().removeScheduledJob (jobId); }

03/01/2011

Citrisys Solutions, Chennai

109

Dynamo Message System

03/01/2011

Citrisys Solutions, Chennai

110

The Dynamo Application Framework includes a number of JMS-related tools, which are known collectively as the Dynamo Messaging System (DMS). The main parts of DMS are:
Two JMS providers, Local JMS and SQL JMS. Patch Bay - an API and configuration system layered on top of JMS.

03/01/2011

Citrisys Solutions, Chennai

111

Local JMS is built for high-speed low latency synchronous messaging within a single process. SQL JMS is more robust, and uses a SQL database to handle communication between components within the same Dynamo application, or components running in different processes.

03/01/2011

Citrisys Solutions, Chennai

112

Patch Bay is designed to ease the development of messaging applications in Dynamo. The Patch Bay API allows Nucleus components to send and receive messages. The configuration system uses an XML file to specify how these components should be connected. This file allows developers to change or add connections between components without changing code. Patch Bay also maintains a Message Registry that the Dynamo user interfaces use to present lists of possible notifications to users. Dynamo registers the messages that it sends with the Message Registry. Applications may also register their own messages, which will then appear in the Dynamo user interfaces.
03/01/2011 Citrisys Solutions, Chennai 113

The different pieces of the DMS can be use independently of each other. For example, we can use Local JMS, SQL JMS, or both, with or without Patch Bay. We can use a third-party JMS provider, or use the JMS implementation provided with our application server, also with or without Patch Bay.

03/01/2011

Citrisys Solutions, Chennai

114

Dynamo Message Conventions


Dynamos JMS providers use the following message format conventions, based on a subset of the JMS message options: Messages are of type javax.jms.ObjectMessage. The objects stored in the ObjectMessage are Serializable Java Beans whose properties contain the messages data. These Java Beans are called message beans. The class names for the Message Beans all end with Message (e.g., atg.nucleus.dms.DASMessage). The JMSType header is used to identify the type of message being fired. JMSType names follow package name conventions (e.g., atg.das.Startup). Note that the JMSType name doesnt need to be an actual Java class name; it follows the package naming conventions to avoid collisions with other JMS applications.

03/01/2011

Citrisys Solutions, Chennai

115

Each JMSType corresponds to exactly one Message Bean class. For example, a message of JMSType atg.das.Startup will always be an ObjectMessage containing a bean of type atg.nucleus.dms.DASMessage. Multiple JMSTypes may correspond to the same Message Bean class. For example, JMSType atg.das.Shutdown also corresponds to atg.nucleus.dms.DASMessage. Messages avoid the use of application-specific header values. All such values are instead represented as properties of the contained message bean.
03/01/2011 Citrisys Solutions, Chennai 116

Using Local JMS


Local JMS is a JMS provider supplied with Dynamo. Messages sent through Local JMS can travel only between components in the same Dynamo process. Local JMS delivers messages synchronously. This means that when a component sends a message, the sending component will block until the receiving components have received and processed the message. In fact, the entire message sending and receiving process occurs within a single thread. As a result, both the sending and receiving of the message occurs in the same transaction. Also as a result, Local JMS has extremely high performance, adding very little overhead to each message delivery.
03/01/2011 Citrisys Solutions, Chennai 117

Local JMS does no queuing. When a message is sent, Local JMS immediately finds out who the receivers are and calls the appropriate methods on the receivers to deliver the message, waiting for each receiver to process the message before delivering the message to the next receiver. Only when the message has been delivered to all receivers does control return to the sender. In this way, Local JMS works more like Java Bean events than like typical JMS implementations; when a Java Bean fires an event, it actually calls a method on several registered listeners. Local JMS is also non-durable; all messages are nonpersistent. If a message is sent to a queue destination that has no listeners, the message disappears. Also, durable subscriptions to topic destinations act exactly like nondurable subscriptions if a subscriber is not listening to a topic, it will miss any messages sent to that topic whether it is subscribed durably or not.
03/01/2011 Citrisys Solutions, Chennai 118

Local JMS is most often used to pass data around to various components within a single request. For example, a user might view content on a certain page, thereby causing a message to be sent. A listener might be configured to listen for that message and update a value in the users profile as a result. The profile must be updated in the same request, or the updated value might not take effect in time for the next request. To make sure the sender and receiver both carry out their actions in the same request, the message should be carried over Local JMS. The same effect could be achieved by using a single component to watch for the user to view content then update the database. But by decoupling the two actions into separate components joined by JMS, the system allows new senders or receivers to be added to the system without changing any existing code.
03/01/2011 Citrisys Solutions, Chennai 119

We can use the DMS configuration file to create Local JMS destinations. These destinations are specified by name, separated into topics and queues:
<dynamo-message-system> <patchbay> ... </patchbay> <local-jms> <topic-name>/MyApp/RegistrationEvents</topic-name> <topic-name>/MyApp/FinancialEvents</topic-name> ... <queue-name>/MyApp/Orders</queue-name> ... </local-jms> </dynamo-message-system>
03/01/2011 Citrisys Solutions, Chennai 120

When Dynamo starts, it create these destinations with the JNDI names localdms:/local/MyApp/RegistrationEvent s, localdms:/local/MyApp/FinancialEvents, and localdms:/local/MyApp/Orders. Remember that Local JMS keeps no state, so adding these topics and queues simply creates named locations for messages to be sent locally. Nothing is actually added to a back-end storage system.
03/01/2011 Citrisys Solutions, Chennai 121

Local JMS implements synchronous, extremely high-performance messaging. However, many messaging applications require messaging to be asynchronous. When a sender sends a message asynchronously, the message is handed off to the JMS provider, and the sender continues on with its work. Once the sender passes the message to the JMS provider, the sender does not need to be informed if or when the message has been delivered to its final recipients. Asynchronous messaging is useful for processes that can be broken down into separate stages, where each stage might take an unknown amount of time.
03/01/2011 Citrisys Solutions, Chennai 122

For example, ATG Commerce uses asynchronous messaging to process an order. Each stage in the order (calculating tax, checking inventory, sending orders to shipping houses, sending confirmation e-mail to the user) is a single action that is activated by an incoming message from the previous stage, and ends by sending a message to the next stage in the process. When the user submits an order, a message is sent to the first stage in the process. The user is told that the ordering process has started, but will not know about the completion of the process until a later e-mail is sent. Another key difference between Local JMS and SQL JMS is message persistence. Local JMS stores no state, so if the system fails, all messages are lost. SQL JMS uses an SQL database for persistence of messages.
03/01/2011 Citrisys Solutions, Chennai 123

This insures that messages will not get lost in the event of a system failure, and enables support for persistent queues and durable subscriptions. To deliver messages, SQL JMS polls the database periodically, checking the appropriate tables to see if any new messages have been written. If so, those messages are delivered to the appropriate message receivers and then removed from the database. This all occurs transactionally, so if a failure occurs or the transaction rolls back, the messages are all returned to the database, again guaranteeing that messages do not get lost. In SQL JMS, the sending of a message and the receiving of a message occur in separate transactions. A sender might send a message in a transaction that later commits successfully.
03/01/2011 Citrisys Solutions, Chennai 124

This doesnt mean that the receiver has successfully received the message. It just means that SQL JMS has successfully delivered the message to its destination. At some point in the future, the receiving of the message will place in another transaction. The message will then be removed from the database when that second transaction successfully commits. SQL JMS uses standard JDBC drivers to communicate with the database. This allows SQL JMS to operate in a distributed environment, where Dynamo and the database are located on different machines. SQL JMS can also run on multiple Dynamos at once, all utilizing the same database. By default, the connection factory for all SQL JMS topic and queue connections (including XA connections) is the Nucleus component /atg/dynamo/messaging/SqlJmsProvider.

03/01/2011

Citrisys Solutions, Chennai

125

From the developers perspective, very little changes when using SQL JMS instead of Local JMS. The message source and receiver components are still coded in essentially the same way whether they are using Local JMS or SQL JMS. The main difference is that the components are configured by pointing them at SQL JMS destinations rather than Local JMS destinations. In SQL JMS, destinations are represented by entries in the dms_queue and dms_topic tables, so adding new destinations is a matter of inserting new rows into these tables. However, this should not be done directly, as is difficult to coordinate this with the mechanism that generates new IDs for the destinations. Dynamo includes a browser-based application called as SQLJMSAdmin to administer and remove queues and topics.
03/01/2011 Citrisys Solutions, Chennai 126

Patch Bay

03/01/2011

Citrisys Solutions, Chennai

127

Patch Bay is designed to simplify the process of creating JMS applications. Patch Bay includes a simplified API for creating Nucleus components that send and receive messages, and a configuration file where we declare these components and your JMS destinations. When Dynamo starts up, it examines this file and automatically creates the destinations and initializes the messaging components. This means our code does not need to handle most of the JMS initialization tasks, such as obtaining a ConnectionFactory, obtaining a JMS Connection, creating a JMS Session, etc.
03/01/2011 Citrisys Solutions, Chennai 128

The Patch Bay is represented in Nucleus as the component /atg/dynamo/messaging/MessagingManager, which is of class atg.dms.patchbay.PatchBayManager. In addition to the properties file, the MessagingManager uses an XML file called the DMS configuration file to configure the individual parts of the Patch Pay system, such as JMS providers, message sources and sinks, and destinations. The definitionFile property of the MessagingManager component names the DMS configuration file whose value is /atg/dynamo/messaging/dynamoMessagingSyst em.xml
03/01/2011 Citrisys Solutions, Chennai 129

Messaging Components As with standard JMS, the Patch Bay API includes Java interfaces that messaging components must implement in order to send and receive messages. However, these interfaces differ from the standard JMS interfaces, and the terminology is somewhat different: A component that can send messages is called a message source. A message source must implement the atg.dms.patchbay.MessageSource interface. A component that can receive messages is called a message sink. A message sink must implement the atg.dms.patchbay.MessageSink interface. A component that implements both interfaces (and can thus both send and receive messages) is called a message filter. All message sources, sinks, and filters must have global scope.

03/01/2011

Citrisys Solutions, Chennai

130

Unlike standard JMS, Patch Bay does not have separate interfaces for objects that communicate with topics and those that communicate with queues. A message source can send messages to both topics and queues, and a message sink can receive messages from topics and queues. In addition to our sources and sinks, we must also define standard JMS destinations; Patch Bay cannot connect a message source directly to a message sink. Instead, the two must be connected through a JMS 03/01/2011 Citrisys Solutions, Chennai 131 destination.

Patch Bay Initialization


The Patch Bay defines a simple life cycle for message sources, sinks, and filters. When the Patch Bay is started, it resolves each of the Nucleus names. If the referenced components have not yet been created, they will be created at this time according to the standard Nucleus name resolution procedure (including a call to doStartService if the component extends GenericService). At this point, message sinks should be prepared to receive messages, which can start arriving at any time, possibly from multiple simultaneous threads.
03/01/2011 Citrisys Solutions, Chennai 132

Message sources follow a slightly more complicated protocol. After a message source is resolved in Nucleus, the Patch Bay calls MessageSource.setMessageSourceContext() on the component. This provides the component with a context object that it can use to create and send messages. However, the component should not begin to send messages yet. At this point, the Patch Bay initializes the various JMS providers and makes sure that the messaging infrastructure is up and running. It then walks through each of the message sources and calls MessageSource.startMessageSource() on each one.
03/01/2011 Citrisys Solutions, Chennai 133

After this call, the message sources can start sending messages. Depending on the message source, this method is where a message source will register itself with the scheduler, or start a server to listen for incoming messages, or just set a flag that gates the sending of messages. Message filters are combinations of message sources and message sinks. They implement both interfaces, and must follow the protocols for both.
03/01/2011 Citrisys Solutions, Chennai 134

Patch Bay Configuration File


One of the functions of the DMS configuration file is to name all of the message sources, sinks, and filters existing in the system. These elements are globally scoped Nucleus services that implement the appropriate interfaces. Each element should be declared with its Nucleus name. Once a message source, sink, or filter has been declared in the configuration file, it must be hooked up to JMS in order for its messages to go anywhere, or for it to receive messages. Messaging components communicate with each other by hooking up to the same destination - if message source A sends messages to destination D, and message sink B receives messages from destination D, then messages will flow from A to B.
03/01/2011 Citrisys Solutions, Chennai 135

Whenever a destination is specified in the DMS configuration file, it must specify which provider owns that destination. The destination must also be named by its JNDI name, using the prefix appropriate to that destinations provider.

03/01/2011

Citrisys Solutions, Chennai

136

<message-source> <nucleus-name> /com/vam/MyMessageSource </nucleus-name> <output-port><port-name>DEFAULT</port-name> <output-destination> <provider-name>local</provider-name> <destination-name>localdms:/local/MyMessages </destination-name> <destination-type>Topic</destination-type> </output-destination></output-port></message-source>

The output-port definition is described in the Using Messaging Ports section of this chapter. The important part of this example is the outputdestination definition. This definition says that messages coming out of this Nucleus component should be directed to the topic called /local/MyMessages managed by a local provider.
03/01/2011 Citrisys Solutions, Chennai 137

If you only have one port it must be called DEFAULT. One Port can map on to multiple destinations also The port name must be passed into the sendMessage() call otherwise the message will go to the DEFAULT port Input and output port names in atg\dynamo\messaging\dynamoMessagingSystem. xml can be different. It's the affinity to the destination object which creates the relationship. The input port names are only visible to the MessageSink object and the output port names are only used by the MessageSource object
03/01/2011 Citrisys Solutions, Chennai 138

Message Ports
In the Patch Bay configuration, a component can be configured to send its messages to a destination (or group of destinations), or to receive its messages from a destination (or group of destinations). Sometimes, however, we may want a component to have more control over where its messages are going. For example, a message filter might read in a message and then resend that message to one of several outputs based on some aspect of the message, such as its JMSType. Each of those outputs would then be configured in the Patch Bay to go to a separate set of destinations. In the Patch Bay, those outputs are called ports.
03/01/2011 Citrisys Solutions, Chennai 139

The author of a messaging component chooses the names of the ports that will be used by that component. Whenever a message source (or filter) sends a message, it must specify the name of the port through which the message will be sent. This means that the port names used by the component will be hard-coded into the component. In the Patch Bay, each of a components output ports can be attached to a different set of destinations.

03/01/2011

Citrisys Solutions, Chennai

140