Monday, 7 May 2012

Procedure to override Item PriceList using Calculator in ATG10:


Procedure to override ItemPriceListCalculator in ATG10:
Step-1:  implement your own pricing calculator class by extending “ItemListPriceCalculator “class
Sample code like below:
public class XxPriceCalculator extends ItemListPriceCalculator {
private static final String PERFORM_MONITOR_NAME = "XxPriceCalculator";
private static final String TRUE_STRING = "true";
public final static ComponentName SHOPPING_CART= ComponentName.getComponentName("/atg/commerce/ShoppingCart");
private XxRepositoryService priceService ;
/**
* Price a single item in a context. this method will only update the price if the monthlyOnlinePrice has been set, so it should only affect talkplan prices
*
* @param pPriceXx ItemPriceInfo representing the current price Xx for the item
* @param pItem The item to price
* @param pPricingModel A RepositoryItem representing a PricingModel
* @param pProfile The user's profile
* @param pExtraParameters A Map of extra parameters to be used in the pricing, may be null
*/
@SuppressWarnings("unchecked")
@Override
public void priceItem(ItemPriceInfo pPriceXx, CommerceItem pItem, RepositoryItem pPricingModel, Locale pLocale, RepositoryItem pProfile,
Map pExtraParameters) throws PricingException {
String perfName = "priceItem";
PerformanceMonitor.startOperation(PERFORM_MONITOR_NAME, perfName);
boolean perfCancelled = false;

try {
Object priceSource = getPriceSource(pItem);
if (priceSource == null) {
try {
if (!perfCancelled) {
PerformanceMonitor.cancelOperation(PERFORM_MONITOR_NAME, perfName);
perfCancelled = true;
}} catch (PerfStackMismatchException psm) {
if (isLoggingWarning()) {
logWarning(psm);
}}
throw new PricingException(MessageFormat.format(Constants.NO_PRICE_SOURCE, new Object[] { pItem }));
}
RepositoryItem skuItem = (RepositoryItem) priceSource;
if (skuItem != null) {
if (isLoggingDebug()) {
logDebug("Calculating price for " + priceSource);
}
OrderHolder shoppingCart = (OrderHolder) this.resolveName(SHOPPING_CART, false);
if (shoppingCart != null) {
String offerAvailStatus = null;
String priceValue = null;
String XxId = null;
try {
if(null != pProfile) {
XxId = (String) pProfile.getPropertyValue("XxId");
offerAvailStatus = this.priceService.queryOfferAvailabilityStatus
(XxRepositoryService.XX_MANAGEMENT_DESCRIPTOR_NAME, XxId);
priceValue = this.priceService.queryXxPrice
(XxRepositoryService.XX_MANAGEMENT_DESCRIPTOR_NAME, XxId);
if (isLoggingDebug()) {
logDebug("XxPriceCalculator : Xx ID " + XxId
+ "Profile ID" + pProfile.getRepositoryId());
}}
if(null == offerAvailStatus ||
(null != offerAvailStatus && offerAvailStatus.equalsIgnoreCase(TRUE_STRING))) {
if (priceValue != null) {
Double price = Double.parseDouble(priceValue);
//price is not null
if (null != price) {
pPriceXx.setCurrentPriceDetails(new ArrayList());
// only need to update the price if the monthly online price has been set
priceItem(price.doubleValue(), pPriceXx, pItem, pPricingModel, pLocale, pProfile, pExtraParameters);
if (isLoggingDebug()) {
logDebug("ItemPriceInfo for " + priceSource + "=" + pPriceXx);
}
if(null != XxId) {
this.priceService.updateOfferAvailabilityStatus(XxId, TRUE_STRING);
}}}}
} catch (RepositoryException repExec) {
// TODO Auto-generated catch block
repExec.printStackTrace();
}}}
} finally {
try {
if (!perfCancelled) {
PerformanceMonitor.endOperation(PERFORM_MONITOR_NAME, perfName);
perfCancelled = true;
}} catch (PerfStackMismatchException e) {
if (isLoggingWarning()) {
logWarning(e);
}}}// end finally
}
@Override
@SuppressWarnings(XxConstants.UNCHECKED)
public void priceItems(List pPriceXxs, List pItems, RepositoryItem pPricingModel, Locale pLocale, RepositoryItem pProfile, Order pOrder,
Map pExtraParameters) throws PricingException {

for (int i = 0; i < pItems.size(); i++) {
CommerceItem cItem = (CommerceItem) pItems.get(i);
ItemPriceInfo priceInfo = (ItemPriceInfo) pPriceXxs.get(i);
Object priceSource = getPriceSource(cItem);
RepositoryItem skuItem = (RepositoryItem) priceSource;

if (skuItem != null) {
if (isLoggingDebug()) {
logDebug("Calculating price for " + priceSource);
}
String priceValue = null;
String offerAvailStatus = null;
String XxId = null;
try {
if(null != pProfile) {
XxId = (String) pProfile.getPropertyValue("XxId");
offerAvailStatus = this.priceService.queryOfferAvailabilityStatus
(XxRepositoryService.XX_MANAGEMENT_DESCRIPTOR_NAME, XxId);
priceValue = this.priceService.queryXxPrice
(XxRepositoryService.XX_MANAGEMENT_DESCRIPTOR_NAME, XxId);
}
if(null == offerAvailStatus ||
(null != offerAvailStatus && offerAvailStatus.equalsIgnoreCase(TRUE_STRING))) {
if (priceValue != null) {
Double price = Double.parseDouble(priceValue);
//price is not null
if (null != price) {
priceInfo.setCurrentPriceDetails(new ArrayList());
// only need to update the price if the monthly online price has been set
priceItem(price.doubleValue(), priceInfo, cItem, pPricingModel, pLocale, pProfile, pExtraParameters);
if (isLoggingDebug()) {
logDebug("ItemPriceInfo for " + priceSource + "=" + priceInfo);
}}}
if(null != XxId) {
this.priceService.updateOfferAvailabilityStatus(XxId, TRUE_STRING);
}}} catch (RepositoryException repExec) {
// TODO Auto-generated catch block
repExec.printStackTrace();
}}}}
public XxRepositoryService getPriceService() {
return priceService;
}
public void setPriceService(XxRepositoryService priceService) {
this.priceService = priceService;
}}

Step-2:  create ATG pricing calculator componend by using above implementation class
Ex: XxPriceCalculator.properties
#
# The ItemPricingCalculator which gets the differential handset price
#

$class=com.Xx.pricing.QuotePriceCalculator

loggingIdentifier=ItemListPriceCalculator

pricePropertyName=listPrice
requirePriceValue=false
priceFromCatalogRef=true

pricingTools=/atg/commerce/pricing/PricingTools

repository=/atg/commerce/catalog/ProductCatalog
priceListsRepository=/atg/commerce/pricing/priceLists/PriceLists

priceListService=/shop/service/PriceListService

priceService=/com/Xx/service/PriceMatchingRepositoryService
Step-3: configure your own pricing calculator component in bellow path /atg/commerce/pricing/ItemPricingEngine
EX: ItemPricingEngine.properties  
# @version $Id: //hosting-blueprint/B2CBlueprint/version/10.0.2/EStore/config/atg/commerce/pricing/ItemPricingEngine.properties#2 $$Change: 635969 $

# This set is used if you are using priceLists to store your
# prices.  This means the prices are retrived from the PriceLists
# repository.
preCalculators=\
        calculators/ItemPriceListCalculator,\
        calculators/ItemPriceListSaleCalculator,\
        /com/Xx/pricing/QuotePriceCalculator,\
        calculators/ConfigurableItemPriceListCalculator,\
        calculators/ConfigurableItemPriceListSaleCalculator
       
priceInfoClass=atg.projects.store.pricing.StoreItemPriceInfo
Step-4: configure PricingTools component in bellow path /atg/commerce/pricing/PricingTools
EX: PricingTools.properties
# @version $Id: //hosting-blueprint/B2CBlueprint/version/10.0.2/EStore/config/atg/commerce/pricing/PricingTools.properties#2 $$Change: 635969 $
$class=atg.projects.store.pricing.StorePricingTools

Step-5: configure PricingModelProperties component in bellow path /atg/commerce/pricing/PricingModelProperties
EX: PricingModelProperties.properties
# @version $Id: //hosting-blueprint/B2CBlueprint/version/10.0.2/EStore/config/atg/commerce/pricing/PricingModelProperties.properties#2 $$Change: 635969 $
# $Id: //hosting-blueprint/B2CBlueprint/version/10.0.2/EStore/config/atg/commerce/pricing/PricingModelProperties.properties#2 $
$class=atg.projects.store.pricing.StorePricingModelProperties





Tuesday, 14 February 2012

Spring Integration with ATG:

Spring Framework Integration with ATG Framework:
Spring:
About: Spring framework is developed to simplify the developed of enterprise applications in Java technologies. It is an open source framework begin developed by Spring source company. Spring framework is also available for .NET framework (Spring .NET).
The Spring is light weight, non-invasive IoC Container and AOP framework. It provides support for JPA, Hibernate, Web services, Schedulers, Ajax, Struts, JSF and many other frameworks. The Spring MVC components can be used to developed MVC based web applications. Spring framework provides many features that makes the development of enterprise application easy work.
Integration with spring:
Spring:”http://www.springsource.org/documentation ” is an open source component framework. Like Nucleus, Spring is based on JavaBeans.
The ATG platform lets you integrate existing Nucleus-based and Spring-based applications. For example, if you have a Spring-based Web application that needs to access a property of an ATG user profile, you can use the integration to enable that.
The integration includes two classes:
  1. atg.nucleus.spring.NucleusResolverUtil enables Spring configurations to refer to Nucleus components
  2. atg.nucleus.spring.NucleusPublisher enables Nucleus components to refer to Spring components.

NucleusResolverUtil

The NucleusResolverUtil class contains a single static resolveName method, which attempts to resolve the specified Nucleus path. Because Spring is unaware of Nucleus component scope, NucleusResolverUtil first attempts to resolve the name in the current request of the current thread (which should succeed if the component is request- or session-scoped) and if that fails, it then attempts to resolve the name in the global Nucleus scope.
To make a Nucleus component available in Spring, you declare it in your Spring configuration XML file. For example, to resolve the current user profile as a Spring component:
<bean name="/Profile" class="atg.nucleus.spring.NucleusResolverUtil"
    factory-method="resolveName" singleton="false">
  <constructor-arg value="/atg/userprofiling/Profile"/>
</bean>
Note: Nucleus components that do not have global scope should be specified with the singleton attribute set to false. If singleton is set to true, Spring caches the component, which can result in the wrong instance of a request- or session-scoped component being exposed.

NucleusPublisher

The NucleusPublisher class publishes a Spring configuration (that is, a Spring ApplicationContext) to a Nucleus path. The NucleusPublisher appears in the specified location as a Nucleus NameContext (a Nucleus folder) containing the JavaBeans from the Spring ApplicationContext. You can view these Spring components in the Component Browser in Dynamo Administration.
For example, you can have the NucleusPublisher publish an ApplicationContext to /atg/spring/FromSpring by including the following in the Spring configuration XML:
<bean name="/NucleusPublisher" class="atg.nucleus.spring.NucleusPublisher"
    singleton="true">
  <property name="nucleusPath">
    <value>/atg/spring/FromSpring</value>
  </property>
</bean>
This enables Nucleus components to refer to Spring components in this ApplicationContext. For example, a Spring component called SpringBean has this Nucleus address:
/atg/spring/FromSpring/SpringBean
Because the NucleusPublisher itself is a Spring component, it can be referred to within Nucleus as:
/atg/spring/FromSpring/NucleusPublisher
The NucleusPublisher class is not in the main ATG CLASSPATH, but is included in a separate JAR file, <ATG9dir>/DAF/spring/lib/springtonucleus.jar. NucleusPublisher requires access to the Spring classes, so the springtonucleus.jar must be added to the WEBINF/lib directory of the Web application containing the Spring configuration to be exported.
Note: The Nucleus NameContext created by the NucleusPublisher is not be available until the Web application containing the Spring configuration has been started, so any Nucleus components that depend on Spring components must be started up after NucleusPublisher. Therefore, NucleusPublisher has an initialServicePaths property, which can be configured with the paths of Nucleus components to start up after NucleusPublisher has published the Spring ApplicationContext. This property must be configured through the Spring configuration XML file, not through a Nucleus .properties file.

Nucleus: Organizing JavaBean Components

Nucleus is the Dynamo Application Framework’s component model for building applications from JavaBeans. 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. The ATG Control Center Components window provides a handy way to create, modify, and manage Nucleus components.
Nucleus by itself provides no application-specific functions. The JavaBean components implement all of an application’s functionality. Nucleus is the mechanism that gives those components a place to live, and a way for those components to find each other.
Nucleus also takes on the task of creating and initializing components. An application does not need to contain the code that creates a component and adds it to the Nucleus namespace. Instead, you can write a configuration file that specifies the class of the component and the initial values of the component’s properties. The first time that component is referenced by name, Nucleus finds the component’s configuration file, creates the component based on the values in that configuration file, and adds the component to the Nucleus namespace.
Nucleus provides a simple path for writing new components. Any Java object with an empty constructor can act as a component in Nucleus, so writing a new Nucleus component is as easy as writing a Java class. By adhering to JavaBeans standards for defining properties and events, a Java class can take advantage of Nucleus’s automatic creation and configuration mechanism. By implementing various interfaces, a Nucleus component can also take advantage of Nucleus services and notifications.
The Components window in the ATG Control Center provides a graphical user interface for creating, viewing, linking, and changing the states of application components. This lets you walk through the structure of a running application.

Note: This spring integration with ATG is exactly same as spring integration with Struts frame work only difference in configurable classes (licensers/ components/class) name.
To establish bridge between to two different frames works to make wiring between components sitting in different frame works .For this we have configure licensers/ components in frame work configuration to exchange configuration information from other frame work configuration to exchange components.
configuration as same as above sample example code.