| By Hal Helms, Ben Edwards, Matthew Woodward | Article Rating: |
|
| January 31, 2006 05:45 PM EST | Reads: |
26,339 |
Examining the M2PetMarket
There is, of course, a DTD available for the mach-ii.xml file, but the set of elements and sub-elements is fairly simple. Let's look at the individual elements in the configuration file for the M2PetMarket application. We start with properties.
<properties>
<!-- Standard Mach-II application settings. -->
<property name="applicationRoot" value="/M2PetMarket" />
<property name="defaultEvent" value="home" />
<property name="eventParameter" value="event" />
<property name="parameterPrecedence" value="form" />
<property name="maxEvents" value="10" />
<property name="exceptionEvent" value="exceptionEvent" />
<!-- PetMarket application settings. -->
<property name="dsn" value="M2PetMarket" />
<property name="locale" value="en_US" />
</properties>
The applicationRoot is set to /M2PetMarket, indicating that a directory, M2PetMarket, should be a subdirectory of your Web root. The defaultEvent is home. When users initially come to the site, this is the entry point to the application. We won't change the properties, eventParameter, parameterPrecedence, maxEvents, and exceptionEvent and, for the sake of brevity, won't go into in this article.
Two additional properties, dsn and locale, are specific to this application and aren't part of the standard Mach-II properties (as the others are). Once set, these properties are available to all registered Mach-II components (listeners, plug-ins, etc.). Placing properties in the configuration file allows us to change their values, if needed, without changing any existing (and tested) code.
Next, we register listeners in their section of the configuration file:
<listeners>
<listener name="StoreListener"
type="M2PetMarket.m2components.StoreListener">
</listener>
<listener name="CheckoutListener"
type="M2PetMarket.m2components.CheckoutListener">
</listener>
</listeners>
Here, we've decided to use separate listeners to handle functions related to the basic store and the check out process. Remember, listeners are CFCs and different methods in those CFCs will be called depending on the event and how we wish to handle that event. We'll look at those methods when we get to the section on event handlers.
Our event-filters section is empty - this simple application requires no event filters.
We have two entries in the plugins section, PetMarketPlugin and TracePlugin. The configure method of a plugin is called automatically by Mach-II when the application is first initialized and allows us to write any initialization code. In the case of PetMarketPlugin, configure creates an instance of the Store CFC and calls its superclass, MachII.framework.Plugin, to keep this object in persistent memory.
The Store CFC has the following capabilities:
- init acts as a pseudo-constructor. It accepts a data source name (DSN) and makes it an instance variable.
- getCategory accepts a category ID and returns a properly instantiated Category object.
- getProduct accepts a product ID and returns a properly instantiated Product object.
- getProductItem accepts a product item ID and returns a properly instantiated ProductItem object.
- placeOrder accepts a User object and a ShoppingCart object and completes the placement of an order.
- queryCategories returns a recordset of all categories.
- queryProductItems returns a recordset of product items, optionally limited if an argument, productoid, is passed to this method.
- queryProducts returns a recordset of products, optionally limited if an argument, categoryoid, is passed to this method.
- searchProducts returns a recordset of products based on a keyword passed into this method.
- getDSN returns the instance variable, DSN.
- setDSN sets the instance variable, DSN.
- preProcess is called before any event processing.
- preEvent is called before each event is handled. (A single HTTP request may encompass several events.)
- postEvent is called after each event is handled.
- preView is called before any view (i.e., display) page is rendered.
- postView is called after any view page is rendered.
- postProcess is called after all event processing.
- handleException is called when an exception occurs (before any exception event is processed).
The TracePlugin is used for debugging purposes and provides information about the events processed and the time each took.
In the event-handlers section, we specify how the application should respond to various events (see Listing 1).
These events encompass the entire functionality of the PetMarket application. Let's quickly look at how each event is processed.
The home event uses a page-view element. When a page-view is specified, Mach-II looks for the appropriate display page registered in view-pages (another section in the configuration file) and displays the file(s).
The preferences, about, legal, affiliate, category, product, showCart, and search events are similarly handled, including display pages registered in the view-pages section of the configuration file.
The updateUserPreferences event is a bit more interesting. It notifies a listener, StoreListener, that an event has occurred and passes the Event object to that listener's updateUserPreferences method. Before this, though, it specifies an event-mapping. This requires some explanation (see Sidebar).
To understand what event-mappings are and how they operate, look at the updateUserPreferences method of the StoreListener shown in Listing 2.
This method receives an argument of type, Event. In fact, virtually all listener methods receive this argument. The method then sets the User object's email, favoritepet, mailings_sales, and mailing_tips instance variables. When this is done, the listener places a status message in the event and is done with its work.
Where do we go from here? The original Pet Market application returns the user to the preferences page. Given this, we could announce a new event, preferences, from within the listener, since Listener objects can announce events. But to do so would tightly couple this listener with the flow of the application - something that would violate the very sound principle of loose coupling. Instead, the Listener object announces something quite generic, userPreferencesUpdated.
However, we have no userPreferencesUpdated event registered in our configuration file, nor do we wish to. Instead, we want to substitute our previously registered preferences event for the announced userPreferencesUpdated event, and that's just what using event-mapping allows us to do. When the StoreListener announces userPreferencesUpdated, Mach-II intercepts the event announcement, substituting in its place the event, preferences.
The event handler for addItemsToCart notifies the StoreListener object, calling its addItemsToCart method. The addItemsToCart method within the listener announces a cartUpdated event, for which we have a corresponding registered event.
The event handler for updateCart notifies the StoreListener object, calling its updateCart method. Again, the listener announces an event, cartUpdated. We have a registered cartUpdated event that introduces a new Mach-II XML configuration element, redirect. The redirect tag acts like the ColdFusion tag, cflocation, causing the browser to make a new HTTP request. The redirect tag is used to ensure that if the user clicks the "refresh" button on their browser, the updateCart method will not be called again.
Published January 31, 2006 Reads 26,339
Copyright © 2006 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
- ColdFusion Developer's Journal Special Focus Issue: Frameworks
- "Frameworks" Focus Issue: TheHUB
- ColdFusion Developer's Journal Special "Frameworks" Focus Issue: Model-Glue
- ColdFusion Developer's Journal Special "Frameworks" Focus Issue: ColdSpring
- ColdFusion Developer's Journal Special "Frameworks" Focus Issue: Fusebox
- ColdFusion Developer's Journal Special "Frameworks" Focus Issue: SAM
- ColdFusion Developer's Journal Special "Frameworks" Focus Issue: onTap
More Stories By Hal Helms
Hal Helms is a well-known speaker/writer/strategist on software development issues. He holds training sessions on Java, ColdFusion, and software development processes. He authors a popular monthly newsletter series. For more information, contact him at hal (at) halhelms.com or see his website, www.halhelms.com.
More Stories By Ben Edwards
Ben Edwards is a Sun Certified Java Programmer and holds a degree in
computer science from the Georgia Institute of Technology. He
currently trains developers on software engineering practices
focusing on Java, object-oriented programming, and software
architectures. Ben is also cofounder of the Mach-II project.
More Stories By Matthew Woodward
Matt Woodward is Principal Information Technology Specialist with the Office of the Sergeant at Arms at the United States Senate. He was until recently a Web application developer for i2 Technologies in Dallas, Texas. A Macromedia Certified ColdFusion Developer and a member of Team Macromedia, he has been using ColdFusion since 1996. In addition to his ColdFusion work, Matt also develops in Java and PHP.
- Adobe’s Aiming ColdFusion at Multiple Clouds
- Cloud Computing Journal: Adobe to Deliver ColdFusion in the Cloud
- Adobe May Cooperate with Apple to Transplant Flash Player to iPhone
- Adobe Flex Developer Earns $100K in New York City
- Adobe LiveCycle Enterprise Suite 2 for Cloud Computing
- Adobe Betas Target RIAs and Cloud Computing
- Adobe Cans Another 9% of its Workforce
- Moyea DVD4Web Converter V2.0 Converts DVD to FLV Fast and Synchronously with Watermarks
- Adobe Fiddles with its Web Apps
- Adobe & Salesforce Cut Cloud Deal
- Hosting.com Launches ColdFusion 9 in the Cloud
- The Real Time Infrastructure Ultimatum
- Adobe’s Aiming ColdFusion at Multiple Clouds
- Eval JavaScript in a Global Context
- Fig Leaf Software to Exhibit at Government IT Conference & Expo
- Cloud Computing Journal: Adobe to Deliver ColdFusion in the Cloud
- Is Microsoft as Free as Open Source?
- Adobe Reader Sued
- The Planet Named “Bronze Sponsor” of Cloud Computing Expo
- Microsoft Expression Web Has Got Game
- Adobe May Cooperate with Apple to Transplant Flash Player to iPhone
- Adobe Flex Developer Earns $100K in New York City
- Bruce Chizen Joins Voyager Capital as Venture Partner
- My Top Seven Wishes From Adobe MAX 2009
- The Next Programming Models, RIAs and Composite Applications
- Where Are RIA Technologies Headed in 2008?
- Constructing an Application with Flash Forms from the Ground Up
- AJAX World RIA Conference & Expo Kicks Off in New York City
- CFEclipse: The Developer's IDE, Eclipse For ColdFusion
- Personal Branding Checklist
- Adobe Flex 2: Advanced DataGrid
- Has the Technology Bounceback Begun?
- Building a Zip Code Proximity Search with ColdFusion
- i-Technology Viewpoint: We Need Not More Frameworks, But Better Programmers
- The Asynchronous CFML Gateway
- Web Services Using ColdFusion and Apache CXF

























