From VisualWorks®, 7.2 of October 20, 2003 on October 20, 2003 at 1:15:30 pm
(Dialog confirm: 'You are filing-in a Parcel source file!\\While this is possible it will not have\the same effect as loading the parcel.\None of the Parcel''s prerequisites will\be loaded and none of its load actions\will be performed.\\Are you sure you want to file-in?' withCRs) ifFalse: [self error: 'Parcel file-in abandoned. Choose terminate or close.']
Item
Smalltalk
Core.Object
false
none
id name description picture price
ShoppingDemo
ShoppingDemo
Item
An item for sale.
Instance Variables:
id <Intger> a unique identifier
name <String> The short name of the item.
description <String> A longer description of the item.
picture <String> a path to the picture that shows this item
price <Number> The price of the item.
Customer
Smalltalk
Core.Object
false
none
id name creditCardNumber shoppingCart
ShoppingDemo
ShoppingDemo
Customer
This represents a customer
Instance Variables:
id <Integer> The unique identifier for the customer.
name <String> Customer's login name
creditCardNumber <String> The customer's credit card number for purchases.
shoppingCart <ShoppingCart> The purchases this customer has made.
ToyzInput
Smalltalk
VisualWave.SingleThreadModelServlet
false
none
model
ShoppingDemo
ShoppingDemo
ToyzInput
ToyzInput is the single servlet that handles all input, and delegates
to the ShoppingSite object (the model).
Instance Variables:
model <ShoppingSite> acts as a glue layer to the actual domain objects
ShoppingSite
Smalltalk
Core.Object
false
none
actions currentPage catalog shoppingCart tempId
ShoppingDemo
ShoppingDemo
ShoppingSite
This is the main class for the shopping example, it acts like an application model to tie together the various domain objects and to control the display. The typical flow of control is that input comes in via the ToyzInput servlet. The ShoppingSite maps the input to its various aspects. These aspects do not (currently) hold ValueModels as in a traditional ApplicationModel, but are simply get/set method pairs. Once the input has been accepted, the servlet asks the site for the appropriate action based on its input and performs the method. These methods may change the current page, in which case the result displayed back to the browser will change.
Instance Variables:
actions <Dictionary from: String to: Symbol> Mapping from HTML actions to methods to be performed on this object. e.g. Login->login.
currentPage <String> The name of the current HTML page being displayed.
catalog <Catalog> The current catalog being viewed.
shoppingCart <ShoppingCart> The current customer's shopping cart.
tempId <String> A temporary aspect for holding the id of an object to be operated on.
ShoppingCart
Smalltalk
Core.Object
false
none
id customer items
ShoppingDemo
ShoppingDemo
ShoppingCart
A standard shopping cart, the set of items this customer has put aside for purchase in this session.
Instance Variables:
id <Integer> A unique identifier.
customer <Customer> The customer who is buying these items.
items <Collection of: Item> The items being purchased.
Catalog
Smalltalk
Core.Object
false
none
id itemsForSale
ShoppingDemo
ShoppingDemo
Catalog
This class represents one of our multiple catalogs.
Instance Variables:
id <Integer> The unique identifier for this catalog.
itemsForSale <Collection of: Item> The items available in this catalog.
Item accessing
description
^description.
description: aString
description := aString.
displayPrice
^ (NumberPrintPolicy print: price using: '$ #,###.00;($ #,###.00);$ 0.00;$ 0.00') asString.
id
^id.
id: anInteger
id := anInteger.
name
^name
name: aString
name := aString.
picture
^picture
picture: aString
picture := aString.
price
^price
price: aNumber
price := aNumber.
Item printing
printOn: aStream
aStream nextPutAll: self name.
Item class examples
example1
^self new
id: 1;
name: 'Assault Penguin';
description: 'Authentic replica, in finest plastic, of a fully armed and armoured assault penguin';
picture: 'assault.gif';
price: 49.95.
example2
^self new
id: 2;
name: 'Wind-Up Penguin';
description: 'This beautiful penguin, hand-crafted from the finest plastic, will delight any child and be an ornament to any home';
picture: 'windup.gif';
price: 4.49.
example3
^self new
id: 3;
name: 'Stained Glass Penguin';
description: 'A stained-glass penguin to catch and reflect the light, or just sit on the bookshelf';
picture: 'stainedglass.gif';
price: 57.63.
example4
^self new
id: 4;
name: 'Penguin Pull-Toy';
description: 'A charming hardwood pull-toy, complete with wheels';
picture: 'pulltoy.gif';
price: 40.00.
example5
^self new
id: 5;
name: 'Racing Cockroach';
description: 'Fun for the whole family';
picture: 'cockroach.gif';
price: 3.95.
Customer initialize
initialize
shoppingCart := ShoppingCart new.
Customer accessing
name
^name.
name: aString
name := aString.
Customer class instance creation
named: aString
"It would be nice to remember who our customers are, but not necessary for today."
^self new name: aString.
new
^super new initialize.
ToyzInput executing
action
^model actionFor: (request method = 'POST'
ifTrue: [self submitAction]
ifFalse: [self queryAction])
doGet
self doStuff.
doPost
self doStuff.
doStuff
"We can answer gets or posts interchangeably"
model := session at: 'model' ifAbsentPut: [ShoppingSite new].
model getInputFrom: request parameters.
model perform: self action.
self forward: model currentPage.
"We have registered the Servlet using a logical name in the configuration file, so we can just use the file name for
the current page. If you do not register the Servlet, you must prefix the current page with ../ because we will
always be coming here from something which is /servlet, and the ssp pages are not /servlet."
forward: aString
"Forward the request. Here we'll use a redirect. This is slower than a true forward, because it makes the client go and get the other page, but it leaves the URLS looking correct, which otherwise is harder to deal with."
self redirectTo: aString.
"The alternative would be "
" (self getRequestDispatcher: aString) forward: request response: response."
ToyzInput private
queryAction
^(request parameters at: 'action') first.
submitAction
^(request parameters at: 'Submit') first.
ShoppingSite aspects
actionFor: aString
^self actions at: aString ifAbsent: [#doNothing].
actions
actions isNil ifTrue: [self initializeActions].
^actions.
catalogName
^ self catalog name.
catalogName: aString
catalog := self lookupCatalogByName: aString.
catalogs: aCollection
self catalogName: aCollection first.
itemId: aString
self tempId: aString.
lookupCatalogByName: aString
^Catalog named: aString.
tempId
^tempId.
tempId: aString
tempId := aString.
username
^shoppingCart customer name.
username: aString
shoppingCart customer: (shoppingCart lookupCustomerByName: aString).
ShoppingSite accessing
catalog
catalog isNil ifTrue: [
catalog := Catalog default ].
^ catalog.
catalogHeader
self catalog id = 1
ifTrue: [ ^ 'mainCatalogHeader' ].
^ 'clearanceCatalogHeader'.
currentPage
^currentPage.
displayTotalAmount
^ (NumberPrintPolicy print: (shoppingCart totalAmount) using: '$ #,###.00;($ #,###.00);$ 0.00;$ 0.00') asString.
items
^ self catalog items.
itemsInCart
^shoppingCart items.
totalAmount
^ shoppingCart totalAmount.
ShoppingSite actions
addToShoppingCart
shoppingCart addItem: (self catalog itemWithId: tempId).
currentPage := 'reviewcart.ssp'.
doNothing
self halt.
login
self username isEmpty ifFalse: [
shoppingCart clearItems.
currentPage := 'catalog.ssp' ].
loginAsGuest
self username: 'Guest'.
self login.
logoff
shoppingCart clearItems.
currentPage := 'main.ssp'.
reviewShoppingCart
currentPage := 'reviewcart.ssp'.
selectClearanceCatalog
self catalogName: 'ClearanceItems'.
currentPage := 'catalog.ssp'.
selectDefaultCatalog
self catalogName: 'Default'.
currentPage := 'catalog.ssp'.
ShoppingSite input
getInputFrom: aDictionary
aDictionary keysAndValuesDo: [:key :value |
self setAspectFor: key to: value].
setAspectFor: key to: value
| selector |
selector := (key, ':') asSymbol.
(self respondsTo: selector) ifTrue: [
self perform: selector with: value first].
ShoppingSite initialize
initialize
shoppingCart := ShoppingCart new.
currentPage := 'main.ssp'.
initializeActions
actions := Dictionary new.
actions at: 'Login as Guest' put: #loginAsGuest.
actions at: 'Login' put: #login.
actions at: 'logoff' put: #logoff.
actions at: 'add' put: #addToShoppingCart.
actions at: 'selectClearance' put: #selectClearanceCatalog.
actions at: 'selectDefault' put: #selectDefaultCatalog.
actions at: 'reviewCart' put: #reviewShoppingCart.
ShoppingSite class instance creation
new
^super new initialize.
ShoppingCart accessing
addItem: anItem
items add: anItem.
clearItems
items := OrderedCollection new.
customer
^customer.
customer: aCustomer
customer := aCustomer.
items
^items.
totalAmount
^items inject: 0 into: [:sum :each |
sum + each price].
ShoppingCart initialize
initialize
items := OrderedCollection new.
ShoppingCart lookup
lookupCustomerByName: aString
^Customer named: aString.
ShoppingCart class instance creation
new
^super new initialize.
Catalog accessing
addItem: anItem
itemsForSale add: anItem.
allCatalogs
"Return a list of all catalog names"
^#('Default' 'ClearanceItems').
id
^ id.
items
^itemsForSale.
itemWithId: anId
^self items
detect: [:each | each id displayString = anId]
ifNone: [nil].
Catalog initialize
initialize
itemsForSale := OrderedCollection new.
initializeClearance
self addItem: Item example5.
id := 0.
initializeDefault
self addItem: Item example1.
self addItem: Item example2.
self addItem: Item example3.
self addItem: Item example4.
id := 1.
Catalog class instance creation
clearanceitems
^Catalog new initializeClearance.
default
^Catalog new initializeDefault.
named: aString
| catalogName |
catalogName := aString asLowercase asSymbol.
^self perform: catalogName.
new
^super new initialize.
"Imported Classes:"
self error: 'Attempting to file-in parcel imports. Choose terminate or close'
Object
Core
false
none
Kernel-Objects
Kernel-Objects
SingleThreadModelServlet
VisualWave
VisualWave.HttpServlet
false
none
request response session
Web Toolkit-Servlet
Servlet