Home > Products > SophiaFramework UNIVERSE > Tutorial > Amazon E-Commerce > - 9 / 9 -

Some Important Processing

List of Products and the Factory Function

A list of products is declared as the following:

SFXArray<AWSProductPtr> _productarray;

_productarray is an array of pointers to objects of AWSProduct class. In fact, what we need is an array of objects such as Book or DVD. This is done by making AWSProduct an abstract class and Book and DVD are its derived classess.

In the application, we add the pointers to Book objects or to DVD objects to the _productarray as follows.

 // item is pointer to AWSProduct abtract class
 AWSProductPtr item;	
 // assign a pointer to Book object or DVD object to item
 item = AWSProduct::Factory(producttype);
 // then add the item to the array

Below are the declaration and implementation of the Factory function. They are straightforward.

// declaration of the factory function 
static AWSProductPtr Factory(SFXAnsiString producttype);
// implementation of the factory function 
AWSProductPtr AWSProduct::Factory(SFXAnsiString producttype) 
 if(producttype == BOOK_SEARCH) 
  return	::new AWSBook();
 if(producttype == DVD_SEARCH) 
  return	::new AWSDvd();
 return null;

Suspend and Resume


BREW is a single thread environment, when other applications (such as an incomming call) boot up, the current running application will be suspended.

If there is an opened socket and we are getting data, we must close the socket and free the received buffer when we are sent a suspend message. In the application with REST API, the OnSuspend handler is registered to the "Connecting..." dialog and is implemented as shown in the source code below.

HANDLER_IMPLEMENT_VOIDSUSPEND(SGRNetworkDialogSet, OnSuspend, reason, info)

 if (IsConnecting())

Similarly, if there is a running timer, the timer must be cancelled before suspending. In the application, a timer is running when the list of products window opens. The OnSuspend handler is registered to the SGRListboxControl class and is implemented as follows.

HANDLER_IMPLEMENT_VOIDSUSPEND(SGRListboxControl, OnSuspend, reason, info)
	StopTimer();	// stop timer


When the application resumes, we reopen the socket and continue getting data. In the application with REST API, the OnResume handler is registered to the "Connecting..." dialog and is implemented as shown in the source code below.

HANDLER_IMPLEMENT_VOIDRESUME(SGRNetworkDialogSet, OnResume, environment)
 if (IsConnecting())
  DBGPRINTF("Network start again...");

The timer which was canceled when being suspended needs to be restarted.

HANDLER_IMPLEMENT_VOIDRESUME(SGRListboxControl, OnResume, environment)


Search Input Window Event Handlers

1. The OnKey Event Handler

The OnKey event handler handles the "Left" (AVK_LEFT), "Right" (AVK_RIGHT), "Up" (AVK_UP), and "Down" (AVK_DOWN) directional keys.

If the "Left" or the "Right" key is pressed, the left pane or the right pane of the current pane will be selected regardless of what the focused component is. The source code for handling "Left" key and "Righ" key is shown below.

SearchPanePtr tmp;
case AVK_LEFT:
	tmp= static_cast<SearchPanePtr>(GetLeft(TYPE_WILDCARD,ATTRIBUTE_SFRTABPANE));
	if (tmp) tmp->Select();
	ret = true;
	tmp= static_cast<SearchPanePtr>(GetRight(TYPE_WILDCARD,ATTRIBUTE_SFRTABPANE));
	if (tmp) tmp->Select();
	ret = true;

If the "Up" or the "Down" key is pressed, the focus will be moved up or down. However, there is a slight difference between the handling of the "Up" key and the "Down" key as shown in the source code below.

SFRResponderPtr responder(null);
case AVK_UP:
	if (GetFocus()) 
	if (responder) 
		ret = true;

case AVK_DOWN:
	ret= true;

For the "Up" key, the focus should be moved to the tab pane if the current focused component is the top one (the combo box).

When moving by the directional key, the label of the third softkey also change accordingly. This is shown in the source code below.

// change the label of the third soft key accoding to the selected component
SGRSoftkeyWindowPtr softkey;
if (event.GetP16() == AVK_LEFT || event.GetP16() == AVK_RIGHT) 
 if ((softkey = SGRSoftkeyWindow::GetInstance()) != null) 
  static_throw(softkey->Register(this, SGRSoftkeyWindow::SOFTKEY_3, "Select"));
  if (static_try()) 
else if (event.GetP16() == AVK_UP || event.GetP16() == AVK_DOWN) 
 if ((softkey = SGRSoftkeyWindow::GetInstance()) != null) 
  SFRResponderPtr responder;
  if ((responder = GetFocus()) != null) 
   // if the combo box is selected
   if (responder->GetAttribute() == ATTRIBUTE_SFRCOMBOBOXCONTROL) 
	softkey->Register(this, SGRSoftkeyWindow::SOFTKEY_3, "Select");
   // if the edit box is selected	
   else if (responder->GetAttribute() == ATTRIBUTE_SFREDITBOXCONTROL) 
	softkey->Register(this, SGRSoftkeyWindow::SOFTKEY_3, "Input");
   // if the button is selected	
   else if (responder->GetAttribute() == ATTRIBUTE_SFRBUTTONCONTROL) 
	softkey->Register(this, SGRSoftkeyWindow::SOFTKEY_3, "Search");
2. The OnSoftKey Event Handler

If the "soft key 1" is pressed, the application is terminated. If the "soft key 2" is pressed, a window of favorite products is displayed. If the "soft key 3" is pressed, the default handling assigned to the focused component is called. Therefore, in the following source code, only "soft key 1" and "soft key 2" need to be handled.

// softkey handler
 switch (event.GetP16()) {
 case SGRSoftkeyWindow::SOFTKEY_1:
  // terminate application
 case SGRSoftkeyWindow::SOFTKEY_2:
  // display list of favorite products
  SFXAnsiString filename;
  SFCError error;
  load the favorite product and display the favorite window
3. The OnButtonControl Event Handler
HANDLER_IMPLEMENT_VOIDCONTROL(SearchPane, OnButtonControl, result, control) 
 SFRMultiDialog::ParamRec param;
 SFXWideString utf16str;

 SFXAnsiString _browsenode;
 SFXAnsiString _string, _keyword;

 // get browsenodes
 SInt16 ind = _combobox->GetValue();
 _browsenode = BrowseNodesValue[ind];

 _string = _textcontrol->GetText().Trim(); // trim spaces
 _string = _string.TrimRight("\r").TrimRight("\n"); // trim cariage return and linefeed

 // Convert to UTF8
 SFXTextEncoding::ShiftJISToUTF16LE(_string, &utf16str);
 SFXTextEncoding::UTF16LEToUTF8(utf16str, &_keyword);

 // if no brosenode is selected, keyword must be supplied
 if(_keyword.IsEmptyCString() && _browsenode =="All")
  _errorDialog.Open("Keyword Error", "Please input keyword", DIALOG_OK, this);
 // connect to AWS to get information using REST request
  _networkDialog.Open(AWSProduct::GetUrlForKeyWordSearch(_searchindex, _browsenode, _keyword), true, OnNetworkEntry, this, "Confirm", "Connect to the Internet?", "Yes", "No" );

Favorite Facility

A product can be saved so that the user can view this product later without the need to connect to the internet again.

Saved products are called favorites.

Favorite data are kept in "data" folder. For each favorite, there is a corresponding XML file that keep the product information, and an entry in a ".dat" file that holds the filename and title of all products of same type.

In the application the favorite window and the list of product window share the same class as shown below.

class ListProductsWindow : public SFRPlainWindow {
 // 0: search result, 1: favorite list
 SInt16 _windowtype;
 // product type such as Books or DVD
 SFXAnsiString _searchindex; 
 // List of products
 AWSListProductsPtr _products;
 // List control to display produc
 SGRListboxControlPtr _list;

The ListProductsWindow class displays the products in the _products variable in a SGRListboxControl list box.

The only difference between the favorite window and the list of product window is the handling of the sofkey window. In case of the favorite window, if the "soft key 2" is pressed, a menu for managing the favorite list will be displayed.

 softkey->Register(this, SGRSoftkeyWindow::SOFTKEY_1, "End");
 softkey->Register(this, SGRSoftkeyWindow::SOFTKEY_2, 
 (_windowtype == 0)? "Back" : "Menu");
 softkey->Register(this, SGRSoftkeyWindow::SOFTKEY_3, "Detail");

The source code below shows how to create the menu (error handling is obmitted).

SFRTextMenuPtr menu;
// create menu
menu = ::new SFRTextMenu(SGRSoftkeyToolbox::GetMenuPosition(OPERATION_LIMIT), "Menu", null, 0) ;

menu->AppendItem("Delete", AVK_1, 0xFBF6);
menu->AppendItem("Delete All", AVK_2, 0xFCF6);
menu->AppendItem("Back", AVK_3, 0x40F7);
SGRSoftkeyToolbox::OpenStandardMenu(menu, HANDLER_FUNCTION(FromSoftkey));

Searching in Different Locales

Every REST request to ECS begins with a base URL that is specific to the locale in which you want to make the request.

For Amazon.com (US), the base URL is:


For Amazon.co.jp (JP), the base URL is:


The browsenodes for each product type vary according to the locale. In this sample application, the locale base URL and the browsenodes are stored in an XML file. If you want to search on a different locale, just edit this file. Below is the structure of that XML file for the US locale.

<?xml version="1.0" encoding="UTF-8"?>
	<Title id="All">Amazon.com</Title>
	<Title id="1">Arts & Photography</Title>
	<Title id="2">Biographies & Memoirs</Title>
	<Title id="3">Business & Investing</Title>
	<Title id="4">Children's Books</Title>
	<Title id="4366">Comics & Graphic Novels</Title>
	<Title id="5">Computers & Internet</Title>
	<Title id="6">Cooking, Food & Wine</Title>
	<Title id="13643">Engineering</Title>
	<Title id="86">Entertainment</Title>
	<Title id="301889">Gay & Lesbian</Title>
	<Title id="10">Health, Mind & Body</Title>
	<Title id="9">History</Title>
	<Title id="48">Home & Garden</Title>
	<Title id="49">Horror</Title>
	<Title id="10777">Law</Title>
	<Title id="17">Literature & Fiction</Title>
	<Title id="13996">Medicine</Title>
	<Title id="18">Mystery & Thrillers</Title>
	<Title id="53">Nonfiction</Title>
	<Title id="290060">Outdoors & Nature</Title>
	<Title id="20">Parenting & Families</Title>
	<Title id="173507">Professional & Technical</Title>
	<Title id="21">Reference</Title>
	<Title id="22">Religion & Spirituality</Title>
	<Title id="23">Romance</Title>
	<Title id="75">Science</Title>
	<Title id="25">Science Fiction & Fantasy</Title>
	<Title id="26">Sports</Title>
	<Title id="28">Teens</Title>
	<Title id="27">Travel</Title>
	<Title id="All">Amazon.com</Title>
	<Title id="163296">Action & Adventure</Title>
	<Title id="538708">African American Cinema</Title>
	<Title id="712256">Animation</Title>
	<Title id="517956">Anime & Manga</Title>
	<Title id="163313">Art House & International</Title>
	<Title id="163345">Classics</Title>
	<Title id="163357">Comedy</Title>
	<Title id="466674">Cult Movies</Title>
	<Title id="508532">Documentary</Title>
	<Title id="163379">Drama</Title>
	<Title id="290738">Educational</Title>
	<Title id="578324">Fitness & Yoga</Title>
	<Title id="301667">Gay & Lesbian</Title>
	<Title id="163396">Horror</Title>
	<Title id="163414">Kids & Family</Title>
	<Title id="586156">Military & War</Title>
	<Title id="163420">Music Video & Concerts</Title>
	<Title id="508528">Musicals & Performing Arts</Title>
	<Title id="512030">Mystery & Suspense</Title>
	<Title id="163431">Science Fiction & Fantasy</Title>
	<Title id="163448">Special Interests</Title>
	<Title id="467970">Sports</Title>
	<Title id="163450">Television</Title>
	<Title id="163312">Westerns</Title>	

Go back  1   2   3   4   5   6   7   8   9