Pass an extra parameter to store Custom data while add to cart by using UserData Noun extenstion (SOI based Service)
Pass an extra parameter to store Custom data while add to
cart by using UserData Noun extenstion (SOI based Service)
Step1: Register your new Client API
Open struts-config-ext.xml.
Copy the following text into the bottom of the file,
before the </struts-config> tag:
<plug-in
className="com.ibm.commerce.struts.ComponentPlugIn">
<set-property property="componentId"
value="order"/>
<set-property
property="clientFacadeClassName"
value="com.mycompany.commerce.customization.order.ExtendedOrderFacadeClient"/>
</plug-in>
step 2: Write the new client class which
extends OrderFacadeClient.Modified to send the value of field1 as part of
the BOD request using userdata using field1 column
public class ExtendedOrderFacadeClient extends
OrderFacadeClient {
protected
com.ibm.commerce.order.facade.datatypes.OrderType buildOrder(Map parameters,
String actionName) throws
OrderException {
OrderType order =
super.buildOrder(parameters, actionName);
String field1[] =
resolveParameter(parameters, "field1");
UserDataType orderUserData =
order.getUserData();
if(orderUserData == null){
orderUserData =
getCommerceFoundationFactory().createUserDataType();
order.setUserData(orderUserData);
}
if(field1 != null &&
field1.length > 0 && field1[0] != null){
order.getUserData().getUserDataField().put("field1", field1[0]);
}
return order;
}
}
Step 3:Update CMDREG table for
extending the comopose command which will for the response
UPDATE CMDREG SET CLASSNAME
='com.mycompany.commerce.customization.order.ExtenedComposeOrderDetailsCmdImpl'
WHERE
INTERFACENAME='com.ibm.commerce.order.facade.server.commands.ComposeOrderCmd
+IBM_Details';
INSERT INTO CMDREG(STOREENT_ID, INTERFACENAME, CLASSNAME,
TARGET)
VALUES
(0,'com.ibm.commerce.orderitems.commands.ExtendOrderItemProcessCmd',
'com.mycompany.commerce.customization.order.ExtExtendOrderItemProcessCmdImpl
','Local');
Step 4:Write the Compose Comand which forms the response
and put the value for field1
public class ExtenedComposeOrderDetailsCmdImpl extends
ComposeOrderDetailsCmdImpl {
protected OrderItemType
composeOrderItem(OrderItemAccessBean aabOrderItem) throws ECException {
OrderItemType orderItem = super.composeOrderItem(aabOrderItem);
String orderItem_id=aabOrderItem.getOrderItemId();
UserDataType userData = orderItem.getUserData();
if (userData == null) {
userData =
CommerceFoundationFactory.eINSTANCE.createUserDataType();
orderItem.setUserData(userData);
}
userData.getUserDataField().put("field1",
"yes");
}
return orderItem;
}
}
Step 5: step, ExtendOrderItemProcessCmdImpl is the
component command that is required to be changed to handle the new information
inside the extended UserData. The new command takes the new filed1
parameters persists them to the database.
public class ExtExtendOrderItemProcessCmdImpl extends
ExtendOrderItemProcessCmdImpl {
private TypedProperty myRequestProperties;
public void performExecute() throws ECException{
private TypedProperty myRequestProperties;
public void performExecute() throws ECException{
//since field1 is part of OOB extension,below code
is enough to persist filed1 info
super.performExecute();
}
}
}
}
Step 6: Update the JSP which will display the new field
using userdata
<c:forEach var="userDataField"
items="${orderItem.userData.userDataField}">
<c:if test="${userDataField.typedKey eq
'field1'}">
<c:out value="${userDataField.typedValue}"
/>
<c:if>
The design pattern for Get services is the basic design
pattern to be used for retrieving and displaying information from Web services.
The class diagram demonstrates the classes that are
involved to create a Get service. One master controller command is created for
each Get service for each noun. This command, which uses the
com.ibm.commerce.foundation.server.util.oagis.SelectionCriteriaMapper utility
class, extracts the Get information from the request BOD. It then breaks the
work into two tasks, delegating to the command framework to run a Fetch command
and a Compose command. The Fetch command fetches the data, while the Compose
command composes the response.
Fetch
The Fetch command returns a list of data beans that
matches the expression. Extensions of this Fetch command are associated with a
particular XPath expression. They must implement the search expression only to
return the appropriate list of data beans that matches the expression.
The command framework can use the XPath expression and
Fetch task command to resolve the Get request to a particular implementation by
using the existing WebSphere Commerce command registry (CMDREG) data. Instead
of having one implementation for a Fetch business task, the command framework
uses the XPath as the selector to resolve the implementation. If a specific
implementation is not defined for the given XPath, then a default Fetch is
used.
The main principle behind this design pattern is
customization. This pattern promotes reuse of the Fetch command, so supporting
a new search expression is a matter of implementing a new Fetch command to
return a list of populated databases that represent that new expression. By
using the XPath and command configuration, you can associate one XPath
expression with one command implementation, or multiple XPath expressions with
the same command implementation. You do not need to modify the Compose tasks
just to support a new search expression.
Note: The member subsystem uses a slightly different
approach where the master controller command always delegates to a single
default Fetch command. The fetch command parses the XPath expression directly
and selects the necessary data.
Compose
The Get command then takes that list and for each data
bean, it calls a Compose task to transform the data bean into the appropriate
logical model (noun).
Access profile
It is recommended that an access profile be used to scope
the response data. Using an access profile makes it easier to extend the
service at a later time, using different profiles to allow different access or
data being returned. For example, to return a specific view of the data (such
as a search view of a catalog entry), or to return the data in all languages
for authoring purposes. As an extension to the XPath syntax, the access profile
name-value pair must be prepended to the XPath expression in curly brackets
({}). For example, to specify the access profile:
{_wcf.ap=$accessProfile$}/CatalogGroup[Name='MyCatalogGroupName']
When the Get command calls the Compose command, it uses
the access profile of the request as the key to select the appropriate Compose
implementation. Because the access profile is just a superset of another access
profile, the Compose commands delegates to the parent access profile to first
populate the logic model and add any required information. This results in a
chain of Compose commands that are called for the data bean, each populating a
set of the logical model.
To customize the amount and type of data that is returned
in the response, you can use different Compose tasks without changing the Fetch
task, by using a different access profile as the key. Supporting a new access
profile consists of creating a new Compose command for that access profile and
registering the implementation. Also, this chaining pattern ensures that
customization of the compose command at a particular access profile is
reflected in all dependent access profiles. If the customization adds more data
at the summary access profile, then all child access profiles also include this
summary data. If you override one command, all dependent code gets this new behavior.
Access profile names that are prefixed with IBM_ are
reserved for IBM predefined access profiles. This prevents naming collisions
between access profiles that are defined by WebSphere Commerce components and
your custom access profiles.
Access profile names that are prefixed with IBM_Admin_
are for services that are intended to be used by admin/CMC based services
calls.
Access profile names that are prefixed with IBM_Store_
are for services that are intended to be used by the storefront.
To achieve consistency across different service modules,
the IBM_Admin_Summary and IBM_Admin_Details profile names are used when
retrieving summary and detail level information about the entity object.
The recommended way to support Get operations is to use
the existing WebSphere Commerce data beans to reuse the existing business logic
and access control policies.
In the below example we are trying to create a
custom access profile using IBM SOI Framework
Extending wcf:getData to get more
data for a new access profile Using Compose
Command
To customize the amount and type of data that is returned
in the response, you can use different Compose tasks without changing the Fetch
task, by using a different access profile as the key. Supporting a new access
profile consists of creating a new Compose command for that access profile and
registering the implementation. Also, this chaining pattern ensures that
customization of the compose command at a particular access profile is
reflected in all dependent access profiles. If the customization adds more data
at the summary access profile, then all child access profiles also include this
summary data. If you override one command, all dependent code gets this new
behaviour.
The following example uses a new access profile for the wcf:getdata service using SOI as follows
Step1: Register the new accessprofile EXTOrder_Summary
in CMDREG table
insert into cmdreg (storeent_id, interfacename,
classname)
values(0,'com.ibm.commerce.order.facade.server.commands.ComposeOrderCmd+EXTOrder_Summary',
'com.test.order.facade.server.commands.ExtComposeOrderSummaryCmdImpl');
Step2: Extend the compose command which will form the
extra response for the access profile in user data section
public class ExtComposeOrderSummaryCmdImpl extends
ComposeOrderSummaryCmdImpl {
public void execute() throws CommandException {
super.execute();
}
protected OrderType composeOrder(OrderAccessBean
aabOrder,boolean abIncludeOrderItems) {
OrderType order = null;
try {
order = super.composeOrder(aabOrder,
abIncludeOrderItems);
UserDataType userData = order.getUserData();
if (userData == null) {
userData =
CommerceFoundationFactory.eINSTANCE.createUserDataType();
order.setUserData(userData);
}
order.getUserData().getUserDataField().put("info", "test
Order");
}
catch (Exception e) {
}
return order;
}
}
Step3: Jsp related changes using new access profile
EXTOrder_Summary and fetch data from user data elements
<wcf:getData
type="com.ibm.commerce.order.facade.datatypes.OrderType[]"
var="extOrderList"
varShowVerb="ShowVerbAllOrdersInThisCategory"
expressionBuilder="findByOrderStatus"
maxItems="${pageSize}" recordSetStartNumber="${beginIndex}"
recordSetReferenceId="orderstatus">
<wcf:param name="status" value="M"
/>
<wcf:param name="accessProfile"
value="EXTOrder_Summary" />
</wcf:getData>
<c:forEach var="extOrder"
items="${extOrderList}" varStatus="status">
<c:choose>
<c:when test="${!empty
extOrder.userData}">
<tr>
<c:forEach var="userDataField"
items="${extOrder.userData.userDataField}">
<c:if test="${userDataField.typedKey eq
'info'}">
<c:out value="${userDataField.typedValue}"
/>
</c:if>
</c:forEach>
</c:when>
</c:choose>
</c:forEach>
In the below example we are trying to create a Create
Custom Expression builder using IBM SOI Framework.
Extending wcf:getData service call to
get more data for an existing access
profile(IBM_Details)
Using customFetch Command and new custom
expression builder
Step 1: Create the extended
get-data-config.xml for the custom expression builder
Create a folder called
com.ibm.commerce.order-ext inside
WebContent\WEB-INF\config\com.ibm.commerce.order-ext
Create get-data-config.xml under this
directory as shown below
<_config:get-data-config
xmlns:_config="http://www.ibm.com/xmlns/prod/commerce/foundation/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.ibm.com/xmlns/prod/commerce/foundation/config
../../xsd/get-data-config.xsd ">
<data-type>
<name>Order</name>
<type>com.ibm.commerce.order.facade.datatypes.OrderType</type>
</data-type>
<client-facade>
<data-type-name>Order</data-type-name>
<class>com.ibm.commerce.order.facade.client.OrderFacadeClient</class>
<method>getOrder</method>
</client-facade>
<data-type>
<name>Quote</name>
<type>com.ibm.commerce.order.facade.datatypes.QuoteType</type>
</data-type>
<client-facade>
<data-type-name>Quote</data-type-name>
<class>com.ibm.commerce.order.facade.client.OrderFacadeClient</class>
<method>getQuote</method>
</client-facade>
<expression-builder>
<name>findByOrderUserPlacedDatesAndStatus</name>
<data-type-name>Order</data-type-name>
<expression-template>{_wcf.ap=$accessProfile$}/Order[BuyerIdentifier[(UniqueID='$userId$')]
and
OrderStatus[(Status='$status$')]
and PlacedDate>= '$from$' and
StoreIdentifier[UniqueID='$store$']]</expression-template>
<param>
<name>accessProfile</name>
<value>IBM_Details</value>
</param>
</expression-builder>
</_config:get-data-config>
Step 2: Insert CMDREG entries for the custom fetch
command as below.
select * from cmdreg where interfacename
like '%com.ibm.commerce.order.facade.server.commands.FetchOrdersCmd%';
insert into cmdreg(storeent_id, interfacename, classname)
values
(0,
'com.ibm.commerce.order.facade.server.commands.FetchOrdersCmd+/Order[BuyerIdentifier[(UniqueID=)]
and OrderStatus[(Status=)] and PlacedDate>= and
StoreIdentifier[UniqueID=]]',
'com.test.order.facade.server.commands.ExtFetchOrderByStoreIdPlaceDateMemberIdAndStatusCmdImpl')
;
Step 3:JSP related changes for the custom expression
builder
<wcf:getData
type="com.ibm.commerce.order.facade.datatypes.OrderType[]"
var="extOrderList"
varShowVerb="ShowVerbAllOrdersInThisCategory"
expressionBuilder="findByOrderUserPlacedDatesAndStatus”maxItems="${pageSize}"
>
<wcf:param name="status"
value="M,B,C,R,S" />
<wcf:param name="accessProfile"
value="IBM_Details" />
<wcf:param name="from"
value="2014-10-16T00:00:00" />
<wcf:param name="to"
value="2014-12-10T23:59:59" />
<wcf:param name="store"
value="${WCParam.storeId}" />
<wcf:param name="userId"
value="${CommandContext.userId}" />
</wcf:getData>
Step 4:Write the custom fetchcmd class
ExtFetchOrderByStoreIdPlaceDateMemberIdAndStatusCmdImpl which extends
FetchOrderByStoreIdPlaceDateMemberIdAndStatusCmdImpl.Overide the fetchOrders()
method to add the custom data in the fetch result.
public class
ExtFetchOrderByStoreIdPlaceDateMemberIdAndStatusCmdImpl extends
FetchOrderByStoreIdPlaceDateMemberIdAndStatusCmdImpl {
String CLASSNAME="ExtFetchOrderByStoreIdPlaceDateMemberIdAndStatusCmdImpl";
protected Collection fetchOrders(GetType getVerb)
throws Exception {
String METHODNAME = "fetchOrders";
if(LoggingHelper.isEntryExitTraceEnabled(LOGGER))
LOGGER.entering(CLASSNAME, "fetchOrders");
}
}
Comments
Post a Comment