Figure 12.1: Creating the Data Source in ODBC
Before you can use the XML server, you need to create the database schema
and insert a few products in the database. This is what
XMLServerConsole
is
for. Point your browser to
localhost:81/console
. First click Create Tables,
(see Figure 12.2). Enter the product information, as shown in Figure 12.3.
385
Building XCommerce
Figure 12.2: Creating the database schema
14 2429 CH12 2.29.2000 2:25 PM Page 385
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Figure 12.3: Creating products in the database
The Middle Tier
As explained in Chapter 11, “N-Tiered Architecture and XML,” the middle
tier server is a servlet that manages various XML documents. There is a
document for the list of merchants or another for the list of products, and
more. The servlet applies style sheets to them.
The middle tier server is made of the
Shop
class, shown in Listing 12.5.
Shop
decodes the URL and routes the requests to the appropriate object.
Listing 12.5: Shop.java
package com.psol.xcommerce;
import java.io.*;
import java.util.*;
import org.w3c.dom.*;
import javax.servlet.*;
import javax.servlet.http.*;
/**
* Shop manages the shop, using XSL for any output.
*
* @version Sep 10, 1999
386
Chapter 12: Putting It All Together: An e-Commerce Example
14 2429 CH12 2.29.2000 2:25 PM Page 386
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
* @author Benoît Marchal <>
*/
public class Shop
extends HttpServlet
{
/**
* the merchant list and the shopping cart
*/
protected MerchantCollection merchants;
protected Comlet checkout;
/**
* return the list of merchants
*/
public MerchantCollection getMerchants()
{
return merchants;
}
/**
* initializes the servlet
*/
public void init()
throws ServletException
{
merchants = new MerchantCollection(this);
checkout = new Checkout(this);
}
/**
* handle GET request
* @param request the request received from the client
* @param response interface to the client
* @exception IOException error writing the reply
* @exception ServletException error in processing the request
*/
387
The Middle Tier
continues
14 2429 CH12 2.29.2000 2:25 PM Page 387
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
Comlet comlet = translateURL(request);
if(null != comlet)
comlet.doGet(request,response);
else
response.sendError(HttpServletResponse.SC_NOT_FOUND);
}
/**
* handle POST request
* @param request the request received from the client
* @param response interface to the client
* @exception IOException error writing the reply
* @exception ServletException error in processing the request
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
Comlet comlet = translateURL(request);
if(null != comlet)
comlet.doPost(request,response);
else
response.sendError(HttpServletResponse.SC_NOT_FOUND);
}
/**
* Returns the time it was last modified.
* @param request the request received from the client
* @return time in milliseconds since January 1, 1970 midnight
*/
protected long getLastModified(HttpServletRequest request)
{
try
388
Chapter 12: Putting It All Together: An e-Commerce Example
Listing 12.5: continued
14 2429 CH12 2.29.2000 2:25 PM Page 388
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
{
Comlet comlet = translateURL(request);
if(null != comlet)
return comlet.getLastModified();
else
return -1;
}
catch(ServletException e)
{
return -1;
}
}
/**
* decode the URL and select the Comlet that will
* handle the request
* @param request the request received from the client
* @return the Comlet identified in the request
* @exception problem loading one of the object
*/
protected Comlet translateURL(HttpServletRequest request)
throws ServletException
{
String merchantID = null,
pathInfo = request.getPathInfo();
StringTokenizer tokenizer = null;
if(null != pathInfo)
{
tokenizer = new StringTokenizer(pathInfo,”/”);
if(tokenizer.hasMoreTokens())
merchantID = tokenizer.nextToken();
}
if(null == merchantID)
return merchants;
if(merchantID.equals(“checkout”))
return checkout;
Merchant merchant = merchants.getMerchant(merchantID);
389
The Middle Tier
continues
14 2429 CH12 2.29.2000 2:25 PM Page 389
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
String productID = null;
if(tokenizer.hasMoreTokens())
productID = tokenizer.nextToken();
if(null == merchant || null == productID)
return merchant;
else
return merchant.getProduct(productID);
}
}
The objects that really handle the request are derived from
Comlet
, defined
in Listing 12.6.
Comlet
defines methods for the
GET
and
POST
requests.
Listing 12.6: Comlet.java
package com.psol.xcommerce;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
/**
* Comlet is a subset of the servlet interface, Shop
* delegates HTTP requests to Comlet descendants.
*
* @version Sep 10, 1999
* @author Benoît Marchal <>
*/
public class Comlet
implements ServletConfig
{
/**
* properties
*/
protected ServletConfig servletConfig;
protected long lastModified = -1;
protected Shop shop;
390
Chapter 12: Putting It All Together: An e-Commerce Example
Listing 12.5: continued
14 2429 CH12 2.29.2000 2:25 PM Page 390
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
/**
* creates a new Comlet
* @param shop the shop it is part of
*/
public Comlet(Shop shop)
{
this.shop = shop;
}
/**
* return the servlet config
*/
public ServletConfig getServletConfig()
{
return shop.getServletConfig();
}
/**
* return the shop it is part of
*/
public Shop getShop()
{
return shop;
}
/**
* convenience: implements ServletConfig
* @param name the parameter whose value is requested
* @return the parameter value
*/
public String getInitParameter(String name)
{
return shop.getInitParameter(name);
}
/**
391
The Middle Tier
continues
14 2429 CH12 2.29.2000 2:25 PM Page 391
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
* convenience: implements ServletConfig
* @return an enumeration of names
*/
public Enumeration getInitParameterNames()
{
return shop.getInitParameterNames();
}
/**
* convenience: implements ServletConfig
* @return the config object
*/
public ServletContext getServletContext()
{
return shop.getServletContext();
}
/**
* handle GET request
* @param request the request received from the client
* @param response interface to the client
* @exception IOException error writing the reply
* @exception ServletException error in processing the request
*/
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
}
/**
* handle POST request
* @param request the request received from the client
* @param response interface to the client
* @exception IOException error writing the reply
* @exception ServletException error in processing the request
392
Chapter 12: Putting It All Together: An e-Commerce Example
Listing 12.6: continued
14 2429 CH12 2.29.2000 2:25 PM Page 392
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
*/
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
}
/**
* return the time the data was last modified
*/
public long getLastModified()
{
return lastModified;
}
/**
* data has changed, update lastModified
*/
public void freshened()
{
lastModified = System.currentTimeMillis();
}
}
MerchantCollection
URLs in the form
/shop
are handled by
MerchantCollection
, which man-
ages a list of merchants in XML. See Listing 12.7. Listing 12.8 is the list of
merchants and Listing 12.9 is the style sheet.
Listing 12.7: MerchantCollection.java
package com.psol.xcommerce;
import java.io.*;
import java.util.*;
import org.w3c.dom.*;
import javax.servlet.*;
import javax.servlet.http.*;
393
The Middle Tier
EXAMPLE
continues
14 2429 CH12 2.29.2000 2:25 PM Page 393
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
/**
* represents a list of merchants
*
* @version Sep 10, 1999
* @author Benoît Marchal <>
*/
public class MerchantCollection
extends Comlet
{
/**
* properties
*/
protected Dictionary merchants = new Hashtable();
protected Document merchantsDocument = null,
merchantsXSL = null;
/**
* creates a new Merchant object
* @param shop the shop it is part of
* @param ServletException error reading the merchant list
*/
public MerchantCollection(Shop shop)
throws ServletException
{
super(shop);
String fname = getInitParameter(“merchants.xml”);
if(null != fname)
merchantsDocument = XMLUtil.parse(fname);
if(null == merchantsDocument)
throw new UnavailableException(shop,”merchants.xml”);
freshened();
Element topLevel = merchantsDocument.getDocumentElement();
Enumeration enumeration =
XMLUtil.extract(topLevel,”merchant”);
while(enumeration.hasMoreElements())
{
394
Chapter 12: Putting It All Together: An e-Commerce Example
Listing 12.7: continued
14 2429 CH12 2.29.2000 2:25 PM Page 394
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Element element =
(Element)enumeration.nextElement();
Merchant merchant =
new Merchant(element,shop);
merchants.put(merchant.getID(),merchant);
}
}
/**
* return a document with the list of merchants
*/
protected Document getDocument()
{
return merchantsDocument;
}
/**
* return the style sheet for the list of merchants
* @exception ServletException error reading the document
*/
protected Document getXSL()
throws ServletException
{
if(null == merchantsXSL)
{
String fname = getInitParameter(“merchants.xsl”);
if(null != fname)
merchantsXSL = XMLUtil.parse(fname);
}
return merchantsXSL;
}
/**
* return a given merchant.
* @param id merchant id
*/
public Merchant getMerchant(String id)
395
The Middle Tier
continues
14 2429 CH12 2.29.2000 2:25 PM Page 395
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
{
return (Merchant)merchants.get(id);
}
/**
* handle GET request
* @param request the request received from the client
* @param response interface to the client
* @exception IOException error writing the reply
* @exception ServletException error in processing the request
*/
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
XMLUtil.transform(getDocument(),
getXSL(),
response.getWriter(),
response.getCharacterEncoding());
}
}
Listing 12.8: Merchants.xml
<?xml version=”1.0”?>
<merchants>
<merchant id=”xmli”>
<name>XMLi</name>
<description>Your specialist for XML products!</description>
<products href=”./data/xmli.xml”/>
<stylesheet-all href=”./xsl/products.xsl”/>
<stylesheet href=”./xsl/product.xsl”/>
</merchant>
<merchant id=”emailaholic”>
<name>Emailaholic.com</name>
<description>The largest electronic shop.
All products delivered via email!</description>
<products update=”3600”
href=”http://localhost:81/xml”/>
396
Chapter 12: Putting It All Together: An e-Commerce Example
Listing 12.7: continued
14 2429 CH12 2.29.2000 2:25 PM Page 396
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
<stylesheet-all
href=”http://localhost:81/products.xsl”/>
<stylesheet
href=”http://localhost:81/product.xsl”/>
<post href=”http://localhost:81/xml”
user=”SYSDBA” password=”masterkey”/>
</merchant>
</merchants>
Listing 12.9: Merchants.xsl
<?xml version=”1.0” encoding=”ISO-8859-1”?>
<xsl:stylesheet xmlns:xsl=” />xmlns=” /><xsl:output method=”html”/>
<xsl:template match=”/”>
<HTML>
<HEAD>
<TITLE>Online Shop</TITLE>
</HEAD>
<BODY>
<P>Visit one of the following prestigious merchants:</P>
<xsl:for-each select=”merchants/merchant”>
<P><B><A><xsl:attribute name=”HREF”>shop/<xsl:value-of
select=”@id”/></xsl:attribute><xsl:value-of
select=”name”/></A></B><BR/>
<xsl:value-of select=”description”/><BR/></P>
</xsl:for-each>
</BODY>
</HTML>
</xsl:template>
</xsl:stylesheet>
Merchant
Requests to
/shop/emailaholic
are forwarded to
Merchant
objects. Listing
12.10 is the
Merchant
class. It uses style sheets similar to Listings 12.11
and 12.12.
397
The Middle Tier
EXAMPLE
14 2429 CH12 2.29.2000 2:25 PM Page 397
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Listing 12.10: Merchant.java
package com.psol.xcommerce;
import java.io.*;
import java.util.*;
import org.w3c.dom.*;
import javax.servlet.*;
import javax.servlet.http.*;
/**
* a merchant is a collection of products
*
* @version Sep 10, 1999
* @author Benoît Marchal <>
*/
public class Merchant
extends Comlet
{
/**
* properties
*/
protected Element merchantElement;
protected Dictionary products = null;
protected Document productsDocument = null,
productsXSL = null,
productXSL = null;
protected String id;
protected long expire = Long.MAX_VALUE;
/**
* creates a new Merchant object
* @param element the merchant element
* @param shop the shop it is part of
*/
public Merchant(Element element,Shop shop)
{
super(shop);
398
Chapter 12: Putting It All Together: An e-Commerce Example
14 2429 CH12 2.29.2000 2:25 PM Page 398
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
merchantElement = element;
}
/**
* return the element id
*/
public String getID()
{
return merchantElement.getAttribute(“id”);
}
/**
* return the post URL
*/
public String getPostURL()
{
Element postElement =
XMLUtil.extractFirst(merchantElement,”post”);
if(null != postElement)
return postElement.getAttribute(“href”);
else
return null;
}
/**
* return the post user
*/
public String getPostUser()
{
Element postElement =
XMLUtil.extractFirst(merchantElement,”post”);
if(null != postElement)
return postElement.getAttribute(“user”);
else
return null;
}
399
The Middle Tier
continues
14 2429 CH12 2.29.2000 2:25 PM Page 399
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
/**
* return the post password
*/
public String getPostPassword()
{
Element postElement =
XMLUtil.extractFirst(merchantElement,”post”);
if(null != postElement)
return postElement.getAttribute(“password”);
else
return null;
}
/**
* return the list of products
* @exception ServletException error reading the document
*/
protected Document getDocument()
throws ServletException
{
if(null == productsDocument ||
expire < System.currentTimeMillis())
{
Element productsElement =
XMLUtil.extractFirst(merchantElement,”products”);
if(null != productsElement)
{
String fname =
productsElement.getAttribute(“href”);
String update =
productsElement.getAttribute(“update”);
if(!XMLUtil.isEmpty(fname))
{
productsDocument = XMLUtil.parse(fname);
freshened();
productXSL = null;
productsXSL = null;
400
Chapter 12: Putting It All Together: An e-Commerce Example
Listing 12.10: continued
14 2429 CH12 2.29.2000 2:25 PM Page 400
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
}
if(!XMLUtil.isEmpty(update))
{
long u = Long.parseLong(update) * 1000;
expire = System.currentTimeMillis() + u;
}
}
}
return productsDocument;
}
/**
* return the style sheet for a list of products
* @exception ServletException error reading the document
*/
protected Document getXSL()
throws ServletException
{
if(null == productsXSL)
{
Element productsXSLElement =
XMLUtil.extractFirst(merchantElement,
“stylesheet-all”);
if(null != productsXSLElement)
{
String fname =
productsXSLElement.getAttribute(“href”);
if(!XMLUtil.isEmpty(fname))
productsXSL = XMLUtil.parse(fname);
}
}
return productsXSL;
}
/**
* return the style sheet for one product
* @exception ServletException error reading the document
401
The Middle Tier
continues
14 2429 CH12 2.29.2000 2:25 PM Page 401
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
*/
public Document getProductXSL()
throws ServletException
{
if(null == productXSL)
{
Element productXSLElement =
XMLUtil.extractFirst(merchantElement,”stylesheet”);
if(null != productXSLElement)
{
String fname =
productXSLElement.getAttribute(“href”);
if(!XMLUtil.isEmpty(fname))
productXSL = XMLUtil.parse(fname);
}
}
return productXSL;
}
/**
* return a given product
* @param id product index
*/
public Product getProduct(String id)
throws ServletException
{
if(null == products ||
expire < System.currentTimeMillis())
{
Document productsDocument = getDocument();
if(null != productsDocument)
{
Element topLevel =
productsDocument.getDocumentElement();
Enumeration enumeration =
XMLUtil.extract(topLevel,”product”);
products = new Hashtable();
402
Chapter 12: Putting It All Together: An e-Commerce Example
Listing 12.10: continued
14 2429 CH12 2.29.2000 2:25 PM Page 402
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
while(enumeration.hasMoreElements())
{
Element element =
(Element)enumeration.nextElement();
Product product =
new Product(element,this,shop);
products.put(product.getID(),product);
}
}
}
// re-test: reading the product may fail
if(null != products)
return (Product)products.get(id);
else
return null;
}
/**
* handle GET request
* @param request the request received from the client
* @param response interface to the client
* @exception IOException error writing the reply
* @exception ServletException error in processing the request
*/
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
XMLUtil.transform(getDocument(),
getXSL(),
response.getWriter(),
response.getCharacterEncoding());
}
}
403
The Middle Tier
14 2429 CH12 2.29.2000 2:25 PM Page 403
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Product
Requests for a specific product take the form
/shop/xmli/1
. They are
forwarded to
Product
objects, as shown in Listing 12.11.
Listing 12.11: Product.java
package com.psol.xcommerce;
import java.io.*;
import java.text.*;
import org.w3c.dom.*;
import javax.servlet.*;
import javax.servlet.http.*;
/**
* a product is various information like price
*
* @version Sep 10, 1999
* @author Benoît Marchal <>
*/
public class Product
extends Comlet
{
/**
* properties
*/
protected Element productElement;
protected Document productDocument;
protected Merchant merchant;
/**
* creates a new product
* @param element XML description of the product
* @param merchant merchant owning this product
* @param shop the shop it is part of
*/
public Product(Element element,
Merchant merchant,
Shop shop)
{
404
Chapter 12: Putting It All Together: An e-Commerce Example
14 2429 CH12 2.29.2000 2:25 PM Page 404
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.