---

JavaBoutique: Open Source Shopping Cart [Part 1]

by Lane Friesen,
JavaBoutique

Directives for Browser-based Memory and Multiple Merchants on
One Cart With a Dumb Server and No Cookies

Every browser contains a JAVA virtual machine that remains
unchanged no matter where the user jumps in cyberspace. I have
developed a way to link data and program elements to the JAVA
virtual machine so that they can be accessed from one HTML page to
another as a kind of HTML “memory.” In another technique, I
instantiate GUI elements that break free from the launching page
and persist until the browser is closed. Both methods use standard
JAVA, and respect security limits. I have combined these two
methods to write a shopping cart front end that I am releasing as
Open Source.

I watched, recently, as a small web service provider developed
commercial sites for small businesses. The biggest expense was a
shopping cart – a good one cost hundreds of dollars per site. It
placed large amounts of JavaScript on each HTML page. The
designer’s creativity was restricted. Some months later, I spoke
with a Seattle-based company that is preparing to host multiple
corporate sites on the same shopping cart. Large Sun computers
maintained memory at the server. Thousands of JAVA threads were
left open for up to an hour. Design freedom was available, but only
at the expensive cost of an superstructure beyond the financial
means of smaller corporations.

The Open Source shopping cart solves these problems. It comes in
two versions– one for the small web designer, the other for the
large company. We will first examine the small business
version.

Any existing web site can be transformed into a commercial site
through the addition of two lines of boilerplate code– the first
line loads an applet, the second line defines a JavaScript function
called ” buy.” These two lines launch a frame which persists for as
long as is desired, no matter where you browse, and which keeps a
running total of purchases, from page to page within a site. If
another merchant uses the same cart, then a separate frame is
launched. There are no delays when purchases are made, because
everything occurs on the client browser. Except for a one-time
initial download of the applet and its classes (14K of code), there
are also no delays when jumps are made from one commercial page to
another. This is because the applet (414 bytes in size) and its
memory are simply transferred without a reload. An optional
database of price updates is downloaded from the server, cached on
the browser, and also carried from page to page. Again, there are
no delays, except for the initial download. In the current version,
orders are finalized by sending them to a fixed address. Open
Source modifications could easily be made that allow the merchant
to process his own order.

The purchaser need not finalize his order straight off, since
the shopping cart travels with him throughout cyberspace. When he
finally does choose to check out his cart, he still has the option
of changing his mind; he can later restore the cart and send out
another finalization.

Items are sold by triggering a JavaScript event which calls the
pre-defined function “buy,” giving a web designer total freedom.
Suppose that a merchant has already spent several thousand dollars
on a web site and wishes to make it commercial. His web site
designer can now do this for him, using his existing pages,
probably in less than one hour. Since the shopping cart is Open
Source, an hour’s charge for labor will be the merchant’s only
cost. This design freedom is possible with a host that is
completely “dumb,” because memory is maintained on the browser,
through links to the JAVA virtual machine. The merchant will not
need to change his hosting or use active server pages.

The cart can be run off-line. For instance, large mail order
companies presently distribute expensive catalogs by mail. In place
of a $5 catalog, and associated mailing costs, these companies
could send out 50 cent CD-ROMs, for much lower mailing charges,
containing the artwork for their catalogs, converted to web pages
and then commercialized through the insertion of the two lines of
boilerplate code and appropriate event triggers. CD-ROMs for
different areas of the country could contain differing “update.txt”
files to allow for regional price variations. Since the CD-ROM
would be run on a local computer, large update files could be used
and would be loaded almost instantaneously. The customer could
browse at his leisure, on a fast local connection, and then
finalize his order by going on-line briefly and checking out.

I look forward to seeing commercial sites that are fast and
clever, and go beyond the grid-like lists that are currently
generated by our present shopping carts.

Persistence: Method 1

Examine the cart at http://209.87.142.42/shopcart/Page1.htm.
It uses JDK 1.1, and thus requires Explorer 4 or 5, or versions 4.5
and higher of Netscape. Try pressing Reset when the cart comes up.
On Explorer, the cart will even survive a Shift-Reset. You can
press Reset fast and repeatedly, and you probably won’t crash the
cart.

Let’s look at how it’s done. There are two methods, one that
involves applet reloading: JAVA applets are in an active state for
as long as the HTML page in which they are loaded is on the browser
screen. When a jump is made to another page, then the applets that
were loaded on the previous page become inactive.

Unless there is a shortage of memory, they are not unloaded.
Whenever the browser returns to an applet’s page, then the
particular applet for that page is not usually reloaded, but rather
it is changed from an inactive state back again to an active state.
Variables that were set in a previous active stage are remembered
during times of inactivity, and can be accessed when an applet
again becomes active.

Now, what happens if the same applet (same name, same codebase)
is loaded by two separate pages? An applet is identified only by
its name and codebase. Thus, if a page loads an applet with the
same name as one that was loaded by a previous page, and if this
involves a relative (in contrast to an absolute) call to the same
codebase, then the applet for the previous page becomes active
again – just as if it had been called by the previous page. A new
instance of the applet is not usually loaded. This feature is used
by the shopping cart to store information between HTML pages. It
works much better than cookies.

An applet, however, contains program code as well as variables.
Thus, since it is a program that is being re-activated, persistent
processing can be carried out on the persistent memory. A program
can thus be written that appears to live on from page to page: all
that is necessary is to reload the same code. When the user leaves
the applet’s page, this exit alters the page’s applet from an
active to an inactive state, and when the user enters a different
page that reloads the previous applet through a relative call. This
entry changes the applet back again to an active state
which uses its previous memory. The new page, as
part of the applet’s life cycle, calls the applet’s init() and
start() methods; apart from that, applet program function
picks up at the point where it left off on the previous
page.
If one desires to keep certain variables, then it is
enough to declare them as static, and make sure they are linked to
static entities – the garbage collector will then leave them
alone.

If an applet with the same name but a different codebase is
loaded, then, for security reasons, it is assigned a new address
space. The same shopping cart code, even when it is run
simultaneously on separate commercial sites from the same browser,
can therefore develop and maintain distinct shopping carts for the
separate merchants. JAVA security, which we exploit here to our
advantage, takes care of all the details!

If an HTML document in a subdirectory of a site wishes to
participate in the persistence, then it is sufficient to add the
line CODEBASE=../ to the APPLET tag. This technique can be extended
throughout a directory and subdirectory structure, so that
persistence spreads freely throughout any given site.
Alternatively, it is often possible to access the applet
absolutely, as in CODEBASE=http://www.myserver/myAppletDirectory
as long as the applet and the HTML pages are located on the
same server.
This absolute call is then treated as
relative. The boilerplate code now becomes independent of
directories and sub-directories.

Applet download time is of course decreased greatly when all
classes are placed into a single uncompressed .zip file. It is my
understanding that earlier versions of Explorer 4 can find .zip
files confusing; the solution is to place the unzipped classes in
the same directory as the .zip file. Most browsers simply ignore
these extra files, and they may in fact no longer be necessary.

Functionality

Since Active X, as implemented in Microsoft’s Dynamic HTML, is
based in the JAVA language, it turns out that it can also generate
persistence. The said applet has in fact been successfully ported
to an Active X object. The said “boilerplate code,” in the previous
section may be altered so that it is an <OBJECT> that is
loaded, rather than an <APPLET>. With a few minor
adjustments, there is the same functionality.

The applet or object that is continually being reloaded does not
need to be entirely identical from page to page. In particular, it
may have different parameters, as expressed in varying
<PARAM> tags under the <APPLET> tag. Clever use of
freedom with parameters can enable massive changes in the classes
that are instantiated from one page to the next, generating genuine
alterations in the code itself. The fact that init() and start()
are called when a page is entered, and stop() is called when the
page is left, can be used to do some very useful things: the
garbage collector is always there to get rid of discarded elements.
The program can vary in ways that would never be possible if it
were not being continually re-activated. Alternatively, boolean
variables can be set or cleared in an abstract class, or in some
other non-instantiated region, which also determine ways in which
the said applet or Active X object re-incarnates itself.

It is not necessary to load an applet or object into every page
of a site in order to gain persistence. It is enough to load the
said applet or object into those pages in which access to the
accumulated information is necessary. Browser mechanisms and the
functionality of JAVA make sure that the information is maintained
(for as long as memory permits) until it is needed. The information
will persist even through extended access to pages or sites which
know nothing about the applet or object. The applet simply sleeps,
in an inactive state, until reloaded through a relative call by
some HTML page that desires access to its program code or
memory.

Of course, if the applet is inactive, and if memory is needed
for other JAVA programs, then the virtual machine will eventually
overwrite the inactive program. There is room on the web,
therefore, for only a limited number of programs that use this
technique. Any particular intranet of course would have its own
separate limitation.

To protect the functionality of the Open Source shopping cart, I
have taken out a patent on the techniques used to develop
persistence. As long as developers change the source code of the
Open Source shopping cart in such a way that the program
remains a shopping cart with an
associated database cache, then they have
permission to use these patented techniques. This should protect
the bandwidth, and I retain rights to any use of these techniques
elsewhere.

Persistence of memory throughout other pages or sites is not a
security issue because an applet or Active X object is resurrected
(or made accessible to other programs) only if it resides at the
same codebase, or at some relative offset.

Persistence: Method 2

Let us now look at the second method for developing persistence
between HTML pages. Although it uses abstract classes, we will see
that this limitation can be bypassed. In nature, we observe objects
like robins and crows, but never things such as “birds.” Robins and
crows are birds, but birds as such do not exist; they are an
abstraction. Similarly, abstract classes in JAVA are a tool for
dealing with things that are common to various objects (in nature,
for example, commonalities would be wings or beaks)– they are not
themselves instantiated. What we are going to do, in general terms,
is take an abstract class which is an abstraction of
nothing, and inject code into it, just as a virus
inserts its DNA into a cell and takes over the machinery for its
own purposes. An infected cell turns out copies of the virus; the
abstract class, in our case, simply chooses to “live forever.” It
is all done, as you will see, with completely standard JAVA coding.
The principle will then be extended through standard coding, to
classes which are not abstract.

If one looks at abstract classes in JAVA, one notices that they
are tied very closely to the JAVA virtual machine. If they could be
instantiated, then certainly they would persist; programs could
then be remembered along with data, even when the applet
was inactive
. However, abstract classes cannot contain
constructors.

Suppose that applet code is composed solely of pointers to
static variables defined in some abstract class (sample code is
presented further on). Suppose further that static components for a
frame (buttons, etc.), as well as the static name of the frame
itself, are also defined in the abstract class. Then, suppose that
init() or start() in the applet calls a static function in the
abstract class which instantiates the static frame and assigns the
static components to it. It then sets a flag in the abstract class
that tells it not to do this again. One now has a kind of
pseudo-constructor for the abstract class. The resulting frame and
its components, are tied through the abstract class, to the JAVA
virtual machine itself, and they persist from HTML page to HTML
page, even when the applet is not being loaded.
The applet that originally launched both the frame and the abstract
class may move back and forth from an active to an inactive state,
as the user browses from one HTML page to another. This makes no
difference to the frame itself, for it is no longer dependent upon
the applet.

Now, how do we enable events within this “terminate and stay
resident” frame so that it will carry out actions when “off site?”
It is done in the following manner (sample code follows):

Events must be caught in the frame itself, but all variables and
interrupt methods are contained as static variables and static
methods in the abstract class. The frame event handlers simply make
jumps to these static variables and methods. Through a use of these
two separate persistence techniques– loading a program repeatedly,
and forming a pseudo-constructor for an abstract class– we have
now created a program that lives beyond the page in which it was
launched. It also remembers data that is collected from page to
page for as long as a page accesses the launching applet through a
relative call, and carries out event handling within the frame
itself, on applet data, when off-site.

The JAVA program has now broken away from the launching page,
and it “lives forever.” It is interesting to reduce the browser to
a partial window, and to place the shopping cart frame on the
desktop beside it. Browse from page to page, and watch the frame:
it doesn’t flicker, and the buttons continue to work. JAVA in the
frame is fully enabled at all times.

There appears to be a small restriction. If you are running JAVA
off-site (if you force the cart to do something by pressing a
button), and if the resulting event-handling uses “new” to create a
variable, and if at the same time the browser is
working very hard at carrying out programming in a page, then it is
theoretically possible to crash the browser. In plain language,
suppose that the shopping cart frame breaks free of the launching
site and you go to some other point in cyberspace, such as the Mars
Lander site, starting some big VRML program. Then, as it is
in the middle of calculations, and things are
changing on the screen, if you bring up the persistent shopping
cart frame and begin pushing buttons, you can probably provoke a
crash. However, it takes a good deal of careful manual
dexterity.

The solution here is simple: Avoid the use of “new” in any JAVA
programming that is triggered when off-site. I have tested this,
and it appears to make it impossible for even the most obnoxious
person to crash the cart. This step has not been taken in the
current code because it can involve the use of global static
variables, and these make further program development very
difficult. Also, the slight potential instability off-site does not
appear to be a problem at all for this shopping cart in every-day
usage.

An Illustration of These Techniques

The following code will place a frame on a web page, and then
save its position as it is moved, so that it appears at the altered
position when a new page is loaded. This demonstrates
persistence.

An Applet Example

import java.awt.*;
import java.applet.*;

public class Applet1 extends Applet{
  public void init(){
    if(Constants.frame == null){
      Constants.frame = new Frame();
      Constants.frame.reshape((int)Constants.framex.intValue(),
        (int)Constants.framey.intValue(),300,300);
    }
    Constants.frame.show();
  }

  public void stop(){
    Constants.framex = new Integer(Constants.frame.bounds().x);
    Constants.framey = new Integer(Constants.frame.bounds().y);
    Constants.frame.dispose();
    Constants.frame = null;
    }
}

abstract class Constants{
  static Frame frame;
  static Integer framex = new Integer(225);
  static Integer framey = new Integer(150);
}

Compiling this code will generate the two files Applet1.class
and Constants.class.

Place the following code in HTML Page 1:

<HTML>
<HEAD>
</HEAD>
<BODY>
        <applet code=Applet1.class name=Applet1 width=1 height=1> </applet>
<A HREF="Page2.htm">Page2.htm</A>
</BODY>
</HTML>

Place the following code in HTML Page 2:

<HTML>
<HEAD>
<TITLE></TITLE>
</HEAD>
<BODY>
        <applet code=Applet1.class name=Applet1 width=1 height=1 id=Applet1> </applet>
<A HREF="Page1.htm">Page1.htm</A>
</BODY>
</HTML>

When the applet is loaded, method init() is called. This creates
a frame, and places it at the (x,y) position defined by variables
framex and framey. A look at class Constants tells us that these
are initialized at 225 and 150 respectively. Suppose that while
Page1 is up, the user moves the frame. Method stop() is called
automatically when Page1 is left by the user, and this determines
the (x,y) position to which the frame was moved by the user, and
remembers it by changing variables framex and framey. When the page
is reloaded, method init() is called again. It seems obvious that
the frame should be placed again at coordinates (225,150), as
defined in class Constants, however, the values of variables framex
and framey, when a reload occurs, are those set by method stop()
when the previous page was left. The initialization in
class Constants is ignored by a reload
. Why? The program
is not being restarted; it is simply being re-activated. That is
the essence of persistence as generated by applet reloading.

There will be stability problems with the frame in some
browsers, for it is constantly being destroyed and recreated again
(our later examples remove this problem). This is associated with
the Abstract Windows Toolkit, and is not linked to persistence. The
said instability is present even when the applet is not being
continually reloaded, and is caused by the fact that the applet
must interact with a peer, which does the actual work of
constructing the frame. The said instability is removed in three
ways: the first is to adjust the order of frame operations so as to
minimize pressure on the peer. The second is to follow every frame
operation with a call to pack(). This appears to place a modal stop
on further execution until the peer has completed its task. The
third is to introduce delay loops at critical points. For instance,
one might define the method pause(200), in which pause(time) is
defined as follows:

void pause(int time){
  long startTime = System.currentTimeMillis();
  while(System.currentTimeMillis() < startTime + time){
    //infinite loop: time slicing creates a pause to give the peer an opportunity to finish
  }

Notice in the applet code that the frame name is defined in the
abstract class Constants. This is absolutely essential for
stability. Notice also that the class Constants is never
instantiated. You can see already, in this example, that we have
started to manipulate an abstract class.

Illustration: Example 2: An Active X Example

In contrast to the applet example, which uses the Abstract
Windows Toolkit, there appears to be no stability problem at all in
the Active X implementation of persistence, which uses Windows
Foundation Classes. This demonstrates graphically that persistence
can be used to generate very dependable code.

import com.ms.wfc.html.*;
import com.ms.wfc.ui.*;

public class Class1 extends DhDocument{
  public Class1() {
    if(Constants.form == null){
      Constants.form = new Form();
      Constants.form.setBounds((int)Constants.formx.intValue(),
        (int)(Constants.formy.intValue()),300,300);
      Constants.form.setVisible(true);
      }
    Constants.form.bringToFront();
  }

  public void dispose() {
    Constants.formx = new Integer(Constants.form.getBounds().x);
    Constants.formy = new Integer(Constants.form.getBounds().y);
    Constants.form.dispose();
    Constants.form = null;
    super.dispose();
    }
  }

  abstract class Constants{
    static Form form;
    static Integer formx = new Integer(225);
    static Integer formy = new Integer(150);
  }

This code is interpreted by Microsoft Visual J++ Version 6, and
is used to form an Active X object which will be loaded by the
following two HTML pages. The first, or something similar to it, is
generated automatically by the said Visual J++ compiler and saved
as HTML Page1.htm. Notice that we have inserted, into the said
automatically generated code, a hyperlink to a Page2.htm.

<HTML>
<HEAD>
<TITLE></TITLE>
</HEAD>
<BODY>
<OBJECT classid="java:com.ms.wfc.html.DhModule"
        height=0 width=0 ... VIEWASTEXT id=OBJECT1>
<PARAM NAME=__CODECLASS VALUE=Class1>
<PARAM NAME=CABBASE VALUE=Project3.CAB>
</OBJECT>
<A HREF="Page2.htm">Page2.htm</A>
</BODY>
</HTML>

Page2.htm is produced by copying the contents of Page1.htm into
an empty HTML page, naming this said page Page2.htm, and altering
the hyperlink to Page2.htm, in the said copied code from Page
1.htm, into a return link to Page1.htm:

<HTML>
<HEAD>
<TITLE></TITLE>
</HEAD>
<BODY>
<OBJECT classid="java:com.ms.wfc.html.DhModule"
        height=0 width=0 ... VIEWASTEXT id=OBJECT1>
<PARAM NAME=__CODECLASS VALUE=Class1>
<PARAM NAME=CABBASE VALUE=Project3.CAB>
</OBJECT>
<A HREF="Page1.htm">Page1.htm</A>
</BODY>
</HTML>

The previous two examples can be tested in the following manner.
1) Place all relevant files into the same directory. 2) Load Page 1
into a browser. 3) Use the mouse to move the frame (or in the case
of Active X, the form) to a different location. 4) Use the browser
to jump to Page 2. Notice that the frame does not come up in the
original location but rather retains its new position. 5) Use the
browser to jump to an unrelated page and then reload either Page 1
or Page 2. You will notice that the frame returns and maintains its
latest position. 6) Repeat steps 3) to 5) as often as you wish.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends, & analysis