Categories
frameworks

Growing Frameworks: Web Site Manager – Analysis, and Design

When you maintain a web site, it’s helpful to have tools. In this chapter and the next, we’ll develop an application that can serve as a framework for a number of tools to track and manipulate pages in a web site.
 
What tools might we have?
·        Viewers – to show pages
·        Editors – to change pages
·        Evaluators – to score pages on some attribute
·        Critics – to suggest improvements
 
For example, we might have a viewer for a page that shows its file characteristics: read/write attributes, name, path, size, etc. Another tool might be an HTML editor. Another tool might show characteristics of the page as a graph node: number of links in or out, local density. Some tools might work with both the file nature and web nature of a page: perhaps to estimate the download time for a page and all pages it includes.
 
The application will use the graph framework we already developed, and it will be a framework for site manager applications. The framework will give tools access to the pages of a site. In the long run, the framework would probably grow to do more. For example, looking at the HTML form of pages might be so common that it would make sense to build in an HTML parser.
 

Approach

In this chapter, we’ll develop:
·        use cases (scenarios)
·        high-level object model
·        screen designs
 
In the next chapter, we’ll implement this:
·        software design
·        simple implementation (using the Graph framework)
 
The resulting framework will demonstrate several key ideas, and we’ll come back to it in later chapters to explore other framework issues.

Sidebar: Use Cases

Use cases are a tool designed to help in the requirements/analysis stage of development. They are scenario-based: they describe typical and exceptional flow through the system, partitioned in a way that shows how the user benefits from using the system.
 
Actors are the active entities, that correspond to the roles that participate in a use case. For example, a User might be an actor; so might an external system. Actors can be arranged in a hierarchy, e.g.,
 
                      User
                           Order Processor
                           Administrator
An actor is usually shown with a stick-figure icon (TBD).
 
A use case represents a set of scenarios. It is usually described via a template like this:
               Use case name
               Pre-conditions
               Post-conditions
               Normal flow
               Alternate flows
               Exceptions
 
The icon for a use case is an oval, containing the use case name. (TBD).
 
Two relationships are used to link use cases: uses and extends. The uses relationship is sort of like a subroutine call; it lets you build a complex use case from simpler ones. The extends relationship holds when one use case is like another but with extra steps added in. This lets you deal with a simple case first, then extend it to handle more complexity. Neither of these relations corresponds to class inheritance. (Use cases can use an inheritance relationship; an abstract use case can be inherited by concrete use cases with compatible pre- and post-conditions.)
 
As the actors and use cases are identified, it’s useful to have a use-case diagram showing which actors use (and are used by) which use cases:
 
 
While the use cases are being developed, you’ll also want to consider an analysis object model, and sample screen designs.
 

Use Cases

Vision: Develop a system to help an author view and edit web pages
that form a site the reader can browse.
 
We can see three use cases implied by the preceding paragraph: View Page, Edit Page, and Browse Site. We have two actors: Author and Reader.
 
UC View Page
Normal flow:         
1.     User selects a page and a viewing tool.
2.     The tool analyzes some aspect of the page.
3.     The tool presents the information to the user.
 
 
UC Edit Page
Normal flow:         
1.     User selects a page and an editing tool.
2.     The user interacts with the tool to create a new version of the page.
3.     The user asks the tool to save the revised page.
4.     The tool saves the revised page.
 
Alternate flow:
·        Instead of steps 3 and 4, the user decides not to save any changes. The original page is left unchanged and in place.
 
Exceptions:
·        In step 4, if the system is unable to save the changes, it offers to let the user either store the page elsewhere or cancel editing.
·        In step 4, if the new page is not in an acceptable format, the tool notifies the user, and returns the user to editing without saving the page.
 
 
UC Browse Site
Normal flow:         
1.     The user uses a web browser to interact with a page.
2.     The user can move through a link to another page (on this site or elsewhere), and continue browsing from there.
 
 
We’ve made a simple start. Are we embarked on a bloodless process of turning a crank to produce the system? Not at all, it’s more an active process of moving between the various possibilities. We may have an initial screen design in mind. Similarly, we haven’t carried out any real object design, but we expect things like Page, File, and Tool to be part of the model. These preconceptions are not absolute guides – but if we reach the end of analysis without talking about some sort of Page object, we need to think more deeply.
 
These initial three use cases suggest several issues.
 
The biggest issue is the relationship between Edit Page and Browse Site. We need to make it explicit that changing a page changes what the Reader sees. Do we really want immediate changes though? What about a change that affects two or more pages simultaneously? (For example, we might be moving information from one page to another, or changing the appearance of the site.) In such cases, we don’t want the user to see the partial changes. This suggests the need for a new use case “Publish Site” that updates a site with a whole set of changes.
 
A second issue is the distinction between View Page and Edit Page. We don’t really need this – we can require the tool to know whether it has made any changes. So, we’ll fold these two use cases together.
 
A third issue is the relationship between a page and its representation (e.g., as a file). This is barely on the horizon, but we’ll need to consider the problem eventually.
 
A final issue (ha!) is the relationship between actors. How many Authors and how many Readers will there be (especially at the same time)? For now, we’ll allow a single Author, and multiple simultaneous Readers.
 

Revised Use Cases

UC View Page is deleted; its functionality is folded into Edit Page.
 
UC Edit Page should make it clear that a tool may be read-only. Also, add step 5, “The page is added to the list of pages changed since the last ‘Publish Site’ operation.”
 
UC Publish Site
Normal flow:         
1.     For all pages changed since the last ‘Publish Site’, the system copies the changed files to where they belong on the web server.
2.     The system clears the list of changed pages.
 
Post-Conditions:
1.     ‘Browse Site’ sees the newly published pages.
 
Exceptions:
·        If the system is unable to publish all changes, it warns the user, and the use case aborts with the site and change list unchanged.
 
[KEY] We have captured the idea that editing happens to a separate set of pages from the main site, and that it takes an explicit action to synchronize the two sets of pages. This is an important insight.
 

More Use Cases

We’ve described ongoing maintenance of a site, but we’ve ignored the need to create a site in the first place. To do this, we’ll add use cases for Create Site, Create Page, and Import Pages.
 
 
UC Create Site
Normal flow:         
1.     The user tells the system where the site should be located, where the (editable) pages should be stored, and how to move pages to the web site.
2.     The system creates the list of changed pages, initially empty.
3.     The system creates the site.
 
 
UC Create Page
Normal flow:         
1.     The user selects a tool and a location for the page.
2.     The tool creates the page at the specified location.
3.     The new page is added to the list of changes.
 
Alternate Flow:
·        In step 2, if a page already exists at the specified location, the tool asks permission before overwriting it.
 
Exceptions:
·        In step 2, if the tool is unable to create the page, the system warns the user and the use case is aborted.
 
 
UC Import Pages
Normal flow:         
1.     The user specifies a set of pages to be imported, and where they should go.
2.     The system copies the pages into place.
3.     The system adds the copied pages to the list of changes.
 
Alternate Flow:
·        In step 2, if any pages already exist in any target location, the user is warned and given the chance to cancel before any pages are moved.
 
Exceptions:
·        If the system is unable to copy any page, it warns the user and continues.
 
 
 
 
 
 

Remaining Use Cases

Our set of use cases is filling out. There are some techniques to help see if they’re complete:
1.     Try scenarios (real or pretend). For this project, we could watch a real site owner at work, and see if everything’s covered.
2.     Consider things from a “lifetime” perspective: when things are created, used, and destroyed.
3.     Consider pairs of actions, e.g., create/delete.
 
By observation, we discover that real owners sometimes move pages, and Move Page is a plausible use case. We can also see that we can Create and Edit a Page, so we add Delete Page as well. Finally, we consider Delete Site, to match up with Create Site.
 
UC Move Page
Normal flow:         
1.     The user selects a page and its new location.
2.     The system moves the page.
3.     The system adds the moved page to the list of changes.
 
Alternate Flow:
·        In step 2, if the new location doesn’t exist, the user is given the option of creating it or canceling the move.
·        If a file of the same name (as the new location) already exists, the user can choose whether or not to replace the existing file.
 
Exceptions:
·        If the file is not moved, the original is not deleted and no change is recorded.
 
 
UC Delete Page
Normal flow:         
1.     The user selects a page to delete.
2.     The system deletes the page.
3.     The system adds the deleted page to the list of changes.
 
Exceptions:
·        If the page cannot be deleted, the user is warned and no change is recorded.
 
 
UC Delete Site
Pre-Condition:
1.     No pages are in the site.
 
Normal flow:         
1.     The system makes the site no longer exist.
 
Post-Condition:
1.     A Reader is no longer able to see the site.
 
 
 
With these additional uses cases, we have a fairly complete set. The biggest “design decision” is the idea of keeping the working area separate from the site itself. Other than that, they are fairly free of requirements on the user interface. We could develop a Perl script that would provide a decent first cut.
 
[TBD – paragraph before is weak.]
 
Let’s briefly look at the lifetime of a site:
[ CreateSite (( CreatePage | ImportPage | EditPage | MovePage | DeletePage)* PublishSite)* DeleteSite] || BrowseSite
This expression tells us that a site is created, things happen to it, and the site is deleted. Any changes can be followed by PublishSite. The site is browsed in parallel.
 
We should rewrite the use cases to clean up the vocabulary, simplify the sentence structures, and see if we’ve missed anything.
 
Next, we’ll start developing an “analysis model” consisting of objects implied by the use cases. Then we’ll consider the user interface.
 
 
 

Analysis Model

We’ve developed a set of use cases; now we’ll build a conceptual object model that can support them. This model is at the analysis level: the objects described will be those in the use cases. (During design, we’ll take the analysis model as a starting point, but we’re not committed to mimicking it exactly.)
 
To build this model, we’ll bounce around between the use cases, the object model diagram, and scenario diagrams, looking for objects and their relationships.
 

UC Create Site

We have the web site itself: Site. We have the web pages: Page. We also have the location of the pages in the system; we’ll call that a WorkSite. The Site has some sort of upload() method that can move pages into the site. Finally, there is a list of changes: Change and ChangeList.
 
To help validate the model so far, we might walk through a scenario diagram:
 

In the scenario diagrams, we won’t worry about whether the actor or some manager object coordinates the series of steps.
 

UC Delete Site

It’s often easy to work in pairs, so we’ll look at Delete Site next. We see no new objects, but we do see a new operation: some sort of “delete.” Notice the ambiguity in the use case: when we talk about the site, are we talking about what we’ve called the Site or the WorkSite?
 
We can resolve this by saying that the WorkSite must be empty (to delete it), but the Site need not be. This lets us delete pages, and then delete the Site, without first requiring us to publish the newly empty site.
 
We need an isEmpty() method on WorkSite (so we can determine that it’s empty).
 

UC Edit Page

We add the idea of a Tool, with edit() and save() operations. We also see the use of a Change object, added to the ChangeList.
 
 
The current object model:
 
 

UC Publish Site

This use case doesn’t require new objects, but does add new operations. To let the site reflect the changes, we’ll add methods publish(ChangeList) and apply(Change). To ChangeList, we’ll add elementAt(int), getElementCount(), and clear() methods.
 
 

UC Create Page

The Create Page use case introduces the idea of a page location. In web terms, we already have a name for this: URL. An earlier draft of the use cases talked about “file” as well; we cleaned it up to only refer to pages and page locations. We should go back and use “URL” for page location, since it’s a well-understood domain term.
 
The use case is a little ambiguous – when it talks about the “specified location”, it’s really talking about putting the Page into the WorkSite. (The Site will pick up the new page upon a Publish Site.) The use case should make this clear.
 
If we think of the tool as an editor, we don’t strictly need the location until we’re ready to save the new page. Perhaps we can combine Create Page with Edit Page.
 
 

UC Browse Site

We see that the site needs to serve up pages: get(URL). A Page needs to be able to report the URLs it links to: URL[] getLinks().
 

The Model So Far

This is a good point to stop and assess our model. We have a few use cases we haven’t covered yet: Import Pages, Move Page, and Delete Page. We’ll look at them later, and see what they do to the model.
 
 
Walk through the use case scenarios again to ensure that we can support all the needed behavior. (Notice that we added links from the WorkSite to the Tools and the ChangeList.)
 
Where is our model weak?
·        We need to make sure the Site object supports the transactions it needs. The publish(ChangeList) method lets it do that.
·        The idea of Change and ChangeList is reminiscent of the Command pattern. This should make us wonder – can we use this fact to provide some sort of undo capability? It’s worth taking the idea back to the use cases.
·        Page and URL have a more complicated relationship, especially when we consider “who knows what”:

·        WorkSite and URL need to be related and aligned somehow. We rely on being able to match up pages between Site and WorkSite.
·        The Tool defines methods for editing and saving Pages, but it can’t really alter the page without the cooperation of the Site.

 
 

Remaining Use Cases

Import Pages: There’s not much difference between importing a page and creating a new one; we can treat “import” as just another Tool.
 
Delete Pages: We need an operation on the site deletePage(URL).
 
Move Pages: We could treat this as a combination delete/create/delete, but instead we’ll add a single Site operation: movePage(fromURL, toURL).
 

Synchronizing Sites

What is the relationship between the ChangeList and the WorkSite? The ChangeList is mentioned explicitly in the use case, but it is really an artifact. The point of using it is to make the Site synchronize its contents with the WorkSite.
 
The idea of synchronizing sites is a broader notion than copying things from the ChangeList: it will also help us talk about mirror sites, multiple versions of a site, and other things.
 
[Key] Approach: Eliminate the ChangeList from our model (and from the use cases as well).
 
We may re-introduce the ChangeList later as a design element; that’s all right – that’s what it is.
 
So, add a synchronize(Site) operator to Site, and eliminate the distinction between Site and WorkSite.
 
In some ways, this is a radical change, but it’s one enabled by the use cases. Had we been buried in code, we might not have noticed this possible approach.
 
 
 [TBD Page level vs. site level]

What Have We Accomplished?

We have:
·        Developed an analysis object model coherent with our use cases. This model builds on concepts our users can understand and discuss.
·        Explored the interaction between Site and Tool, to balance responsibilities, and make it clear that the Site manages the pages.
·        Introduced site synchronization. Instead of the ChangeList, which had a very specific form, we’ve introduced the more powerful idea of site synchronization. This simplified both the use cases and the model.
 
This is a good opportunity to back through the use cases and the model, ensuring that they’re in synch with each other, and that the model supports the behaviors we need.
 

The Latest Analysis Model

 
This is a much trimmer model than we started with.
 

Screen Design

A screen design should also be part of our analysis. You shouldn’t focus on this too strongly in the initial stages: seeing a screen can shut out useful ideas for the use case and the model. The user interface is often a volatile part of the system, so you want to depend more on the use cases and the object model, which are more stable.
 
Here’s a possible screen:
 
 
 
With these menus:
 
                File         Edit         Site                    Page                            Tool                                        Help
                                                  Publish                  Delete                    New
                                                  Create    Move       Save
                                                  Delete                                    Save As…
                                                  Select…
 
We need to make sure that the screen can support each use case. We also need to do usability testing, to ensure that users can work with the proposed software.
 

Likely Changes

Finally, it’s helpful to acknowledge that some changes are more likely than others. In the spirit of “identifying risks to the project,” we’ll list changes from more to less likely:
·        new tools
·        variety of web servers
·        variety of target systems
·        new types of pages (e.g., XML)
·        multiple concurrent authors
 
We can use this knowledge to help build a little extra flexibility into the design.
 

Non-Functional Requirements

We also should define requirements that don’t fit under the use case umbrella. This might include things like:
·        performance
·        reliability
·        cost
·        environment
·        etc.

What’s Next?

We’ve developed:
·        vision statement
·        use cases
·        object model
·        screen design
·        list of likely changes
 
These form the analysis.
 
In the next chapter, we’ll develop a framework to meet these requirements.

Web Site Manager – Design and Implementation

In the previous chapter, we developed a use-case analysis of the Web Site Manager. In this chapter, we’ll use that analysis to guide a design and implementation.
 
Our approach:
·        Flesh out the design model
·        Implement the graph and tool models, then their user interfaces
·        Add in the tree system, and its user interface
·        Discuss how we’ve used an old framework, and defined a new framework.
 
We’ll develop the model before the user interface, because the user interface is almost always “most likely to change.” (Should it be a GUI? Should it use Swing or AWT? Should the current node be on top? Is green the right color for this?) The object model is more stable: the system will still be a web site manager if it doesn’t use Swing, but not if it no longer deals with web sites.
 

Design Model

The screen design reflects three parts of the program:
 
 
We have three models to merge:
·        Analysis object model
·        Selection model
·        Graph framework
 
We’ll begin by adopting the object model from analysis, and see how it looks.
 
 
 
The Tool needs to know its Site. Also, we’d like to know the Tool’s name. We didn’t identify this as a property before. (So, we’ll add a method “String getName()” to Tool.)
 

Design Model – Selection

“A page is selected, and tools operate on it.” The page is important, and so is the tool, but realizing that a selection relates the two together is key.
 
[KEY] The analysis model didn’t emphasize the idea of a “current page”, but it is crucial to the design. The current page represents the focus of all three screen areas.
 
One approach to defining how selection might work would be to define a PageSelectionModel, a PageSelectionListener, and a PageSelectionEvent, suitable for use with JavaBeans. It might not be a bad approach. But, even while designing one framework, we keep our eyes out for other frameworks.
 
Selection is generally useful, so we’ll introduce a “micro framework” for selection:
                SelectionModel: tracks a selected object.
                SelectionListener: listens for changes in selection.
                SelectionEvent: notification of change in selection. [TBD needed?]
                DefaultSelectionModel: an implementation
 
These objects will connect like this:
 
 
When an object is selected, the model notifies the listeners of the change.
 
This object, focused on generic selection, may not be as type-safe as a version focused on pages, but it enables generic components to hook together with fewer adapters and fewer types overall.
 
Once we have these objects, we are following the JavaBeans version of the Observer pattern.
 
 
How did we know to use this pattern? By sweat work: trying a number of configurations, until it became obvious that all three screen areas were viewing the same thing. This is a classic arrangement that can make use of the Observer pattern.
 

Design Model – Graph

We’d like to use our Graph framework to support the graph nature of the web. The first step is to identify the relationships between Graph classes and web site manager objects:
                Graph: Site
                Node: Page
                Edge: Links to other pages
 
 
[TBD]
In Graph, do we need some sort of invalidate() command? (caching)
 
 

Design Model – Putting It All Together

[TBD] A. Unified model
 
[TBD] B. Mapping to Java
These could be mapped as classes or interfaces.
 
[KEY] Use interfaces for interesting objects, and classes for blobs of data.
 
In our case, a URL is mostly a “data bag”, so we’ll make it a simple class. (We might decide to just use java.net.URL.)
 
public class URL {
      private String name;
      public URL(String name) {this.name = name;}
      public String toString() {return name;}
}
 
Site, Page, and Tool have more interesting behavior, so they will be interfaces.
 
 
 
[TBD] C. Interconnection model
 
The model for interconnecting the pieces:

User Interface, V1

At this point, we can turn two teams loose in parallel: one for implementation of the model, the other to develop the user interface. At the end, we’ll integrate their efforts.
 
 
It’s helpful to “burst” this view apart, to see what could build it in terms of UI widgets.
 
 
 
The Tool needs an on-screen representation (as a JComponent in this case).
 
The easy way out is to add a method to Tool: public void JComponent getComponent(). Then the user interface could ask for a tool, and ask the tool for its component.
 
[KEY] Couple the user interface to the model, not the model to the user interface.
 
We don’t want to depend “up”. So, we’ll temporize, and assume there is a ToolComponentMap object, with a method getComponent(Tool) that will find the component for us.
 
[TBD – defer commitment – Thimbleby]
 
The code for the panels is straightforward if tedious:
[TBD – keep?]
 
public URLPanel() {
      setLayout(new BorderLayout());
      add(new Jlabel(“URL”), “West”);
      add(textfield, “Center”);
      add(button, “East”);
      button.addActionListener(new ActionListener() {…});
      textfield.addActionListener(new ActionListener() {…});
}
 
public ToolPanel() {
      setLayout(new BorderLayout());
      add(Tool[0], “Center”);
}
 
public WSMPanel() {
      setLayout(new BorderLayout());
      add(new URLPanel(), “North”);
      add(new ToolPanel(), “Center”);
}
 


Current Node

We’re trying to support this piece:
                [TBD – current node, in, & out]
 
This is really just a view on the Node object.
 
Notice that we can access the current page name (via toString()), and the in and out nodes (and their names). Thus, we can entirely display these items without even caring that they’re Pages (or Nodes).
 
[NOTE Box] Wait a minute!
We’ve talked about the display, the file tree, and the current node. None of them cared that these were web pages! Can this be right?
 
Yes, it is, and it reflects a philosophical goal: keep things decoupled. At some point, yes, we must deal with HTML. But by avoiding the dependency as much as possible, we let other pieces continue development in parallel.
 

Node selection

JList inList = list of Node
JList outList = list of Node
 
setCellRenderer (ListCellRenderer)
setNodeRenderer (Renderer)
                (with defaults)
 
See CellRendererPane.
 
Setup list listeners. On click, make the selection be the current node.
 
                setSelection(Object)
                                (is null ok? Yes – can deselect all nodes)
 
TBD – more on design.
 
 
 

WebGraph Implementation

 
                URL   File  Edges
 
Relative to a “base” that defines a prefix for the URL and the file.
 
Given a file, relative to “base,”  find its Edges. We’ll let Graph take File. Each File will generate a node. We’ll use a StreamTokenizer to look for “<A HREF=”…”>” occurrences. This is not full HTML parsing by any stretch. It’s just a quick-and-dirty way to get the easy 95%.
 
WebBase
                String filePrefix
                String webPrefix
 

Tools

File Info Viewer
                name-value pairs
                Readable: true
                Writable: true
                Length: int
 
HTML Viewer
                []
Need: ability to change node.
 
 
The tool display is where we see this application acting as another framework. The idea is that we’ll provide a design that can accommodate a number of tools.
 
 
Each tool will provide a panel that we can add to the tab pane.
 
What does the tool look like?
 
We’ll require it to be a subclass of JComponent, so it can be put in the tab pane. We’d also like to know its name, and a tooltip name for it.
[TBD ??]
 
What does the tool need to know? It needs to know which page it’s working on.
 
[Later – revoke the subclass idea – provide a method to return JComponent.]
 
[Design with no central object – revoke later]
 
 
A tool now has these characteristics:
                name
                tooltip text (long name) (description)
                ObjectSelectionListener
                (and it’s a JComponent)
 
Wait! Is a tool a component, or does it have a component?
 
[TBD – no]
It’s almost certainly better to make the tool provide the component when asked. This will let us keep “being a tool” an interface. It will let us use existing components rather than forcing them to be in a particular spot in the class hierarchy.
 
                public interface Tool extends ObjectSelectionListener {
                                public String getName();
                                public String getDescription();
                                public JComponent getComponent();
                }
 
[TBD – easier to wrap]
 
Now the toolbox:
                public interface Toolbox extends ObjectSelectionListener {
                                public void add(Tool);
                                public void remove(Tool);
                }
 
 
                Toolbox <> —- Tool
 
Quickie implementation: use Vector & JTabbedPane.
 
 

Tree Model

For the moment, let’s ignore all the stuff about graphs, webs, and HTML, and take a detour. We’ll develop a component we might have had lying around: a tree of Files, corresponding to a directory hierarchy. (Many applications could use a tree widget based on the file system.)
 
The Swing library has an interface we will use: TreeModel. We’ll conform to that interface, and provide a concrete implementation focused on files. (As we’ll see later, Swing has been a bit sloppy about package dependencies; this forces us to depend on a GUI library for a basic data structure.)
 
To build a tree of files using Swing, it’s most natural to put them in a JTree object. The JTree requires a TreeModel, which is the data model (as in model-view-controller). This will correspond to the directory hierarchy.
 
The TreeModel is a Tree of File objects, corresponding to the structure on disk. (Notice that we need this – not all pages are linked together, and a tree view is often convenient.)
 
[TBD G – model]
 
We want to work with File objects, but a TreeModel works with TreeNodes. We will wrap our files into a TreeNode by implementing that interface:
 
[tbd]
 
We want to be somewhat careful in creating the tree. Since filesystems can be large, we don’t want to load the whole tree all at once. Instead, we only want to load the nodes as needed. Thus, the first step of most routines will be to ensure that the children (if needed) are present.
We want to be lazy in creating trees. Since a file system is potentially large, we don’t want to load it all at once. Instead, we’ll load nodes as needed. Thus, most routines will instantiate their children on demand.
 
[TBD] check isDirectory() once
 
Here’s a sample listener to verify our widget.
 
Here’s a demo GUI for it. [TBD JTree]
 
Problem: TreeModel and its base.
 
We can put it in the JTree like this:
[Code tbd]
 
Here’s simple driver code so you can test this:
[Code tbd]
 
We can add a SelectionListener to print the current file:
[Code tbd]
 
So – we have one part “done”!
 
Backtrack – TreeModel knows “base”.
 
We could define the display for those items, and let subclasses override the display methods if they want to be different. That would be a white-box approach. Instead, we’ll take a more black-box approach, and have the idea of renderers, small pieces of code that handle the display of a single item. (Swing does this for lists, tables, etc.)
 
[TBD – picture]
 
We’ll provide default renderers that just do “node.toString()” to get the value.
 
 
 

The Adapter

[TBD]
 
The file structure wasn’t really mentioned before, but we need to deal with pages not just as they’re linked, but also as they’re stored.
 
We have to relate the files contained in the tree to the pages in our web.
 
The adapter will have to know a relationship, e.g.,
                http://node/dir == /home/web/dir
(to realize that http://node/ maps to /home/web/.) On the web side, the Nodes will be Pages.
 
 
 
 

HTML (At Last!)

How do we find HTML nodes?
 
Files ending in .htm, .html, or .shtml.
 
<A HREF=”string”>
                capture the filename using StringTokenizer
 
<[Aa][ t]+[Hh][Rr][Ee][Ff][ t]*=[ t]*”[^”]*”>
 
HTMLGraph package  ——–à Graph package
HTMLGraph ->                     Graph
HTMLEdge ->                      Edge
HTMLNode ->                      Node
 

Design Revisited

 
Earlier, we described the notification from Graph to FileTree to toolbox, etc.
 
A useful technique for evaluating designs is to consider the most likely changes, and see how well the design stands up to them.
 
The most likely change is a new tool. We handle this fairly well – all that’s required is a new Tool subclass. Another Java application could be adapted fairly easily.
 
Another change might be a new web representation. We have three already: FileTree, Graph, and Tool. There’s an old design rule “0, 1, infinity.” It tells you that once you have two or more of something, then you need to consider the possibility of even more.
 
Another change might be moving to XML. [etc]