[go: up one dir, main page]

CA2209265A1 - Apparatus and method for information retrieval via internet - Google Patents

Apparatus and method for information retrieval via internet

Info

Publication number
CA2209265A1
CA2209265A1 CA002209265A CA2209265A CA2209265A1 CA 2209265 A1 CA2209265 A1 CA 2209265A1 CA 002209265 A CA002209265 A CA 002209265A CA 2209265 A CA2209265 A CA 2209265A CA 2209265 A1 CA2209265 A1 CA 2209265A1
Authority
CA
Canada
Prior art keywords
request
user interface
interface agent
category
response
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Abandoned
Application number
CA002209265A
Other languages
French (fr)
Inventor
Robert Telford
Gary Evans
Brian Duncan
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
COMPUTER GROUP Inc
Original Assignee
COMPUTER GROUP Inc
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by COMPUTER GROUP Inc filed Critical COMPUTER GROUP Inc
Publication of CA2209265A1 publication Critical patent/CA2209265A1/en
Abandoned legal-status Critical Current

Links

Landscapes

  • Information Retrieval, Db Structures And Fs Structures Therefor (AREA)

Abstract

The present invention relates to apparatus and method for retrieving information via an interactive computer network such as the Internet. Apparatus and methods are provided that permit Web clients to intelligently search secondary Web servers that have data matching the Web client's search criteria and retrieve specified data from such secondary Web servers, without the need for the Web client to specify the uniform resource locators, (URL's) of the secondary Web servers. Furthermore, apparatus and methods are provided that enable users of an interactive computer network to search for information in a specific context rather than searching for information by merely matching words without regard to the context in which the words are used in the information.

Description

_ CA 0220926~ 1997-06-27 " PATENT
ATTORNEY DOCKET NO.: CGI-l TITLE OF THE INVENTION
APPARATUS AND METHOD FOR INFORMATION
RETRIEVAL VIA INTERNET
BACKGROUND OF THE INVENI'ION
The present invention relates to apparatus and method for retrieving information via interactive computer networks, such as the Internet for example.
Hypertext Markup Language (HTML) is a computer language that is used to describe textual information accessible via an interactive computer network such as the Internet. This information is formatted as a document that is composed of words, consecutive words forming phrases, consecutive phrases forming sentences, consecutive sentences forming paragraphs, consecutive paragraphs forming pages, consecutive pages forming chapters, and consecutive chapters forming books, etc.
A person desiring access to information on the Internet is known as a Web client. To access the Internet, the Web client must run on the client's computer, a computer program known variously as a viewer or a browser. Currently, (see Fig. 1) a Web client makes Hypertext Transmission Protocol (http) requests for information (files) to a Web Server.
The Web Server will return to the Web client, the HTML file specified in the client's request. Alternatively, the Web Server may invoke a Common Gateway Interface (CGI) program to obtain data satisfying the Web client's request, and then return this data to the Web client as a formatted HTML file.
Current search engines, like LYCOS for example, are full text search vehicles in that they compare the search request against the entire document, word-by-word, without regard to the context of the word in the search request.
These search engines are computer programs running on a primary Web server. When such current search engines locate CA 0220926~ 1997-06-27 the information satisfying the'Web client's search request, this information is retrieved from the secondary server where it is found, and transmitted to the primary server where the information becomes available for review by the Web client. Because the retrieved information is stored on the primary server for review by the Web client, the operator of the secondary server must be willing to permit a third party, i.e., the operator of the primary server, to have access to the information stored in the data base management system associated with the secondary server.
However, many such operators of secondary servers are reluctant to allow such access.
Moreover, the full text searching that is performed by such search engines results in retrieval of information that, while satisfying the search request, includes much information of a type that is not desired by the Web client.
Accordingly, visits to the web site do not necessarily indicate a true interest by the visitor. Nor is it possible to gather information that correlates such visits according to the specific web site characteristics that were sought by the visitor.
Another disadvantage with such search engines results from the way that most commercial enterprises collect and maintain their information. Most of the information that commercial enterprises make available on their Web servers, is originally collected and maintained in column/row structures or field/record structures. Thus, such information must be converted to the document structure of HTML files before such commercial information becomes searchable by conventional search engines.
OBJECTS AND SUMMARY OF THE INVENTION
It is a principal object of the present invention to provide apparatus and methods that permit Web clients to intelligently search secondary Web Servers that have data - CA 0220926~ 1997-06-27 .. !

matching the Web client's search criteria and retrieve specified data from such secondary Web Servers, without the need for the Web client to specify the Uniform Resource Locators (URLs) of the secondary Web Servers.
It is another principal object of the present invention to provide apparatus and methods that permit Web clients to intelligently search remote Web Servers that have data matching the Web client's search criteria and retrieve specified structured data from such remote Web Servers, without the need for the Web client to specify the Uniform Resource Locators (URLs) of the remote Web Servers.
It is still another principal object of the present invention to provide apparatus and methods that enable users of an interactive computer network to search for information in a specific context rather than searching for information by merely matching words without regard to the context in which the words are used in the information.
It is yet another principal object of the present invention to provide apparatus and methods that enable users of an interactive computer network to interact with a user interface that assists the user by intelligently providing descriptive content and constraints to facilitate formulation of a structured search query rather than allowing the user to specify a search query in a manner likely to return information outside the desired context sought by the user.
It is a further principal object of the present invention to provide apparatus and methods that enable users of an interactive computer network to search for information in a specific context and without regard to the structure of the format in which the information is stored.
It is a still further principal object of the present invention to provide apparatus and methods that enable operators of primary and secondary servers of an interactive CA 0220926~ 1997-06-27 " ' ,, computer network to subscribe with a URL hub without allowing the URL hub to have unfettered access the information stored on the server.
It is a still further principal object of the present invention to provide apparatus and methods that enable operators of primary and secondary servers of an interactive computer network to identify and collect information indicative of the specific characteristics of the information stored on the server, that was sought by the visitor to the server.
It is yet another principal object of the present invention to provide apparatus and methods that enable operators of primary and secondary servers of an interactive computer network to more effectively target commercial advertising that is transmitted through the network.
Additional objects and advantages of the invention will be set forth in part in the description which follows, and in part will be obvious from the description, or may be learned by practice of the invention. The objects and advantages of the invention may be realized and attained by means of the instrumentalities and combinations particularly pointed out in the explanation below.
The present invention includes apparatus configured to perform a method of collecting data from at least one searchable data base management system of an interactive computer network. The computer network includes servers, routers, and associated searchable data base management systems that are operated by the servers and accessible via the routers. Moreover, the interactive computer network is configured to be accessible via a viewer that is running on a first computer that functions as a client user workstation. As noted above, the viewer is a computer program of a type that is also known as a browser such as _ CA 0220926~ 1997-06-27 f Netscape's NAVIGATOR~ browser or Microsoft's EXPLORER~
browser.
To achieve the objects and in accordance with the purpose of the invention, as embodied and broadly described herein, the apparatus and method of the present invention guides the client's search for desired information that is available on a computer network. The present invention organizes the information that is available on the network, into as many central themes as are desired to characterize the available information. For example, each central theme may be a real estate listing or a product such as an auto, a refrigerator, or any other product that can be imagined.
The central theme also could be a service such as dentistry, photography or any other service that can be imagined.
Then for each central theme, the present invention defines categories that revolve around that central theme.
The categories will vary depending on the central theme.
However, each category will fall within one of several types of categories. There is a Single type of category, which has only one possible category value. There is a Range type of category, which has two possible category values, one at each end of the range. There is a StaticList type of category, which has an open-ended number of possible category values that are non-volatile (explained more fully below). There is a DynamicList type of category, which has an open-ended number of possible category values that are volatile (explained more fully below).
The present invention then allows the client to define the search request with greater specificity within each category. The present invention accomplishes this by prompting the client to _hoose from a list of available selections within that category. Thus, the present CA 0220926~ 1997-06-27 invention urges the client's search request to be formulated from the selections that are available for each category in the data base. As the client fills out a search request by choosing particular selections within each category, these particular selections combine to produce a sharply focused search request.
The present invention keeps track of the locations of information that fit each central theme. At each of these locations, the present invention can access the categories and identify information that matches the selections chosen by the client for each such category. Based on these matches, the present invention facilitates the client's inspection of the matching information.
According to the present invention, the information available at each location on the network is constantly updated in terms of the available themes and categories.
In accordance with the present invention, a user interface agent is provided. A user interface agent is a computer program that can be stored on a computer that is functioning as a server in a network environment. The user interface agent is configured to receive from a viewer, a start signal. For example, a JAVA applet would be considered a type of user interface agent that can communicate between a server and the client workstation.
Such JAVA applet would perform such communication via a router. As embodied herein, each router has been configured as a JAVA application.
The user interface agent is configured so that when it opens, it performs the job of making appropriate requests of the primary router to obtain the information needed to assist the client user in formulating a search request that is structured within the available categories. Accordingly, CA 0220926~ 1997-06-27 ,.i. .

when the user interface agent~opens, it performs the TYP
Request, the CAT Request, and the HUB Request. The primary router responds to the TYP Request, the CAT Request, and the HUB Request, by providing respectively to the user interface agent, the TYP Response, the CAT Response, and the ~3 Response. The user interface agent also performs the VAL
Request directed to the primary server. The primary router also responds to the VAL Request by providing the VAL
Response from the primary DBMS to the user interface agent.
The user interface agent then cedes control to the client user to allow the client user to define the scope of the search by selecting either the local mode or the global mode.
When the client user selects the local mode, the user 1~ interface agent is configured to allow the client user to build the user's search request. The user interface agent is configured to allow the client user to choose selections from among the selections that populate each of the categories specified by the primary router in the CAT
Response. Once the client user has built a desired search request, the user interface agent is configured to allow the client user to initiate the search. Then the user interface agent is configured to send a LST Request to the primary router, which collects all of the matching records from the primary DBMS and returns the matching records to the user interface agent in the form of a LST Response from which the user interface agent populates the Result Window. The user interface agent is further configured to send a request for more information than is contained in the matching record.
This request is sent in the form of a HOM Request to the primary router, which is configured to create a HOM Response and return it to the user interface agent, in order to permit the client user to view more information than is provided in the matching record.

CA 0220926~ 1997-06-27 ,' When the client user selects the global mode, the user interface agent is configured to send a VAL Request via the primary router to the Hub router and the Hub server. The Hub router collects the sélections from the Hub DBMS, which stores the selections from the secondary DBMS's, and returns the selections to the user interface agent via the primary router in a HU~3 Response from which the user interface agent populates the DynamicList and StaticList Categories. As in the case of the local search, the user interface agent allows the client user to build the search request and execute the search. Based on the search criteria selected by the client user, the user interface agent is configured to request advertising or other targeted messaging information, by issuing an ADV Request to the Hub router via the primary router. The requested advertising (or other targeted messaging information) is collected and returned by the Hub router in an ADV Response to the user interface agent via the primary router. The user interface agent is further configured to request in a PRO Request directed to the Hub router via the primary router, the URL for each server associated with a DBMS that possibly maintains listings applicable to the client user's search request.
The Hub router is configured to select such URL's from the profile list of the Hub DBMS and return the matching URL's in a PRO Response to the user interface agent via the primary router. The user interface agent is configured to make a LST Request via the primary router to each URL
returned in the PRO Response. The secondary router resident at each such URL, collects the matching records that satisfy the search request in the LST Request and returns such matching records to the user interface agent via the primary router in a LST Response, from which the user interface agent populates the Result Window. The user interface agent is further configured to send via the primary router a CA 0220926~ 1997-06-27 request for more information than is contained in the matching record. This request is sent in the form of a HOM
Request directed to the secondary router that collected the matching record of particular interest. The secondary router is configured to create a HOM Response and return it via the primary router to the user interface agent, in order to permit the client user to view more information than is provided in the matching record.
The router for each primary/secondary server is configured to periodically update its profile stored on the Hub DBMS. This is be done by periodically sending a COL
Request to the Hub router via the primary router.
The accompanying drawings, which are incorporated in and constitute a part of this specification, illustrate one embodiment of the invention and, together with the description, serve to explain the principles of the nventlon .
BRIEF DESCRIPTION OF THE DRAWINGS
Fig. 1 is a schematic representation of conventional apparatus and method for retrieving information via the Internet;
Fig. 2 is a schematic representation of apparatus and method according to a presently preferred embodiment of the present invention;
Fig. 3 is a schematic representation of apparatus and method according to a presently preferred embodiment of the present invention configured in the global mode of operation;
Fig. 4 is a GUI screen of the present invention showing a HOMESEEK~ Web (HTML) Page from a primary server that has been accessed by the NETSCAPE~ browseri Fig. 5 is a GUI screen of the present invention in a configuration in which control has been ceded to the client CA 0220926~ 1997-06-27 user to choose from the selections returned in the VAL
Response to create a search request for a data base management system having information about motor vehicles;
Fig. 6 is a GUI screen of the present invention showing matching records returned in the LST Response, which matching records only have in common the Chevrolet Make, out of the following seven categories used to structure the information involving motor vehicles: AutoType, Make, Model, Year, MilesperGallon, RetailPrice, and SalePrice; and Fig. 7 is a GUI screen of the present invention showing an HTML page containing the information in one of matching records retrieved from a search.
DETAILED DESCRIPTION OF THE PREFERRED EMBODIMENTS
Reference now will be made in detail to the presently preferred embodiments of the invention, one or more examples of which are illustrated in the accompanying drawings. Each example is provided by way of explanation of the invention, not limitation of the invention. In fact, it will be apparent to those skilled in the art that various modifications and variations can be made in the present invention without departing from the scope or spirit of the invention. For instance, features illustrated or described as part of one embodiment, can be used on another embodiment to yield a still further embodiment. Thus, it is intended that the present invention cover such modifications and variations as come within the scope of the appended claims and their equivalents. The same numerals are assigned to the same components throughout the drawings and description.
The present invention is intended for an environment that includes an interactive computer network, which is indicated generally in Fig. 2 by the designating numeral 18.
Some examples of such network can include a local area network, a wide area network, the Internet or the World Wide Web. For purposes of this explanation, the World Wide Web CA 0220926~ 1997-06-27 ~ f (hereafter Web or WWW) will be chosen as the environment of a presently preferred embodiment of the invention.
As schematically shown in Fig. 2, the basic hardware components of the interactive computer network are the client user workstation, which is designated by the numeral 20 and the network servers, which are variously designated by the numerals 22 for the primary server, 24 for the Hub server, 26 for a first secondary server and 28 for another secondary server.
A typical client user of the interactive computer network, accesses the network via a viewer running on a first computer functioning as a client user workstation. As used herein, a viewer is defined as a computer program capable of using a protocol format to communicate with a specific internet protocol address such as a tcp/ip address.
Examples of such protocol formats include the hypertext transfer protocol (http). As known, a viewer can be configured to use http to communicate using any of a number of protocol formats that ride on top of tcp/ip, and examples of such protocols include FTP, Gopher, Usenet and the like.
Thus, in accordance with the present invention, the client workstation must be provided with viewer software such as the NETSCAPE NAVIGATOR~ browser. As shown in Fig. 2 for example, a browser 30 running on a client workstation 20 would be considered a type of viewer that can communicate with servers that can translate HTML pages and execute programs in the genre of a user interface agent (described below) on the client user workstation.
As explained below and schematically in Fig. 2, one of the network servers is configured as a Hub server 24 in a preferred embodiment, and each of the other network servers is configured as a primary server 22 or a secondary server 26, 28. In order to function as a server in the present invention, at least certain computer hardware is required in . CA 0220926~ 1997-06-27 _ . ~ .

the form of Random Access Mem~ry (RAM), a hard disk, a monitor, and connectivity to the interactive computer network. As to the latter, a Tl line can provide connectivity between the server and the network. In some applications, a bank of modems (a.k.a., a modem bank) could be used to provide connectivity between client user workstations and a primary server of the network.
Each type of server of the interactive computer network of the present invention is configured so as to permit the searching methodology of the present invention to be executed. The software that should be provided for each server configured for the present invention, includes an operating system with a data source that is Open Data Base Connection (ODBC) compatible and that recognizes Transmission Control Protocol Internet Protocol (tcp/ip) addresses. A suitable operating system for each server of the present invention is the WINDOWS NT~ platform. A Data Base Management System (DBMS) is one type of data source that is ODBC compatible, and a suitable DBMS is provided by a Microsoft~ SQL server. Each server also must be provided with network software such as Microsoft~ Internet Information Server. Optional software for each server could include E-Mail, Firewall, Web Page/Registration, Internet Connection SW, Internet Service Provider Registration, and File Transfer Protocol (FTP) software.
In accordance with the present invention, a user interface agent is configured to structure the client user's search request according to predetermined categories that describe the information in the chosen theme. As embodied herein, the user interface agent is a program that is specified in an HTML file that originates from a server of the interactive computer network. Each primary/secondary server must be provided with the software that defines a user interface agent (described below) and the supporting CA 0220926~ 1997-06-27 __ software for the user interface agent. A presently preferred embodiment of this software is presented below in Appendix A.
The present invention presents the client user with one or more themes that describe generally one or more topics that might interest the client user. If client user wants to explore the information available for one of these themes, then the present invention guides the client user in the formulation of a search request to identify particular information within the desired theme. The present invention automatically performs the task of identifying the Uniform Resource Locator (URL) of each server that controls a DBMS
containing the requested information. The present invention then automatically retrieves the information that satisfies the search request formulated by the client user with the guidance of the present invention. Thus, the present invention accomplishes the retrieval of the desired information without requiring the client user to supply any such URL.
Each data base management system maintained by a primary/secondary server, has been configured in accordance with the present invention so that the DBMS stores its information according to one or more different themes of information. For example, a DBMS operated by a Fortune~ 500 manufacturer may contain information relating to the theme of heating and air conditioning systems. That same DBMS
also may contain information relating to the theme of elevator systems for skyscrapers. Moreover, the information pertaining to each such theme is further indexed according to the present invention into one or more categories of information. Each category of information describes the information according to characteristics that are deemed of interest to potential users of the information. For example, categories for the heating and air conditioning CA 0220926~ 1997-06-27 . _ theme may include the capacity'of each system described by the information in the DBMS, the price of each system described by the information in the DBMS, and the fuel that powers each system described by the information in the DBMS.
In another example, if the theme is residential real estate listings, one useful category for characterizing such information would be the house type (one story, two story or three story). Another useful category for the real estate listing theme would be the price range of the listed property. Yet another useful category for the consumer interested in a real estate theme would be the square footage of the residence on the listed property. Other categories could be used, depending upon the perceived desires of the client users deemed likely to be interested in the particular theme.
In accordance with the present invention, the data base management system of each primary/secondary server on the network, is configured to maintain an initialization file.
The initialization file contains an initialization list.
The initialization list specifies each theme that characterizes the information that is maintained on the server~s DBMS and that is available to be searched by users of the network. The initialization list also specifies information for accessing the server's DBMS and the URL of the Hub server.
In accordance with the present invention, a cross-reference file is maintained in a manner that is accessible by each primary/secondary server. In a preferred embodiment of the present invention, the cross-reference file is maintained on each primary/secondary server. The cross-reference file contains a category list that includes at least one category that structures at least some portion of the information stored on the DBMS operated by the primary/secondary server. The category list contains each CA 0220926~ 1997-06-27 category of information that is maintained on the server's DBMS and that the owner of the DBMS desires to make available to users of the network. For example, consider the case of the owner of a DBMS that contains information about real estate listings. In accordance with the present invention, that real estate listing information is structured according to categories. Such categories can include for example, the location of the property that is the subject of the listing, the asking price for the property, the type of building on the property (l-story, 2-story), and the number (e.g., one, two, three, four, five) of bedrooms in the building. The categories are preselected to limit their number and to ensure their relevance to consumers who might be interested in the information.
The cross-reference file further contains for each category at least such supporting information as the category header for the user to identify the category, the DBMS column for each category, the maximum length of a category value, and the category type. The category type must be one of at least a Single type, a Range type, a StaticList type, or a DynamicList type. A separate object is available to define the attributes of each of the possible types of categories. As known, an object is an entity, such as an element in a computer program, that has its own functionality and is provided with a standard set of public interfaces so that the object can interact with other objects that are not familiar with the particulars of how the object functions. The object has attributes in the form of data. The object also has attributes in the form of actions by which the object operates on data.
In accordance with the present invention, once a category type is assigned to a particular category, then the appropriate one of the four possible objects for a category type, is implemented for that category. An attribute of the CA 0220926~ 1997-06-27 ~

object for each category of the Single type, is that it can contain only one possible category value. Similarly, each category of the Range type can contain two possible category values, one at each end of the range. Each category of the StaticList type can contain any number of nonvolatile data selections. What is meant by nonvolatile is that the data is not likely to be subject to change. Thus, efficiency can be obtained by storing nonvolatile data in memory so that such data need not be retrieved from the DBMS as frequently as volatile data. The values that satisfy the StaticList type can be drawn from an open-ended number of possible category values. Each category of the DynamicList type has data selections that are volatile, which means that the data is likely to change frequently. The values that satisfy the DynamicList type also can be drawn from an open-ended number of possible category values.
In accordance with the present invention, and as noted above, an additional computer is provided and configured as a server to function as a URL Hub for the interactive computer network. In one sense, this so-called Hub server is the central server of the interactive computer network of the present invention. As schematically shown in Fig. 3, the Hub server 24 is configured to control access to a searchable Hub data base management system, which is designated by the numeral 32.
The Hub data base management system 32 is operated and controlled by the Hub server 24 and is configured to contain a profile list. This profile list is configured to specify for each primary/secondary DBMS in the network, each theme that character zes the information that is maintained on such DBMS and that is to be made available to users of the network. The profile list is configured further to contain for each theme, each category of information that is CA 0220926~ 1997-06-27 ', :

maintained on each DBMS operated by an additional computer functioning in the network as a primary/secondary server.
In accordance with the present invention, the user interface agent is configured to assist the client user to formulate a search request in terms of at least one category that characterizes the information available to the client user from a DBMS in which the information is stored. The user interface agent might be a JAVA applet, an ActiveX
component or a NetScape~ plug-in. In the presently preferred embodiment of the invention, a JAVA applet has been chosen for the user interface agent. A JAVA applet was chosen for the user interface agent because of considerations of security, viewer compatibility, and platform independence. As to security, the JAVA applet is limited as to what it can access. For example, the JAVA
applet cannot make a socket connection to any server other than the server from which the JAVA originated (its primary server); cannot access the client workstation; and cannot access certain properties of the client workstation. As to viewer compatibility, a JAVA applet is one of the technologies that can be executed by a viewer. As to platform independence, a JAVA applet can be run on the primary server, which can be running any one of a large number of the possible platforms that are supported by JAVA.
The HTML file that specifies the user interface agent, originates from a server that functions as the primary server during that particular session on the interactive computer network. Since any server (other than the Hub server) in the interactive computer network of the present invention, might be called upon to function as the primary server in any given session on the network, each server on the network must be configured with an HTML file that contains the user interface agent. As schematically shown in Fig. 2 for example, a user interface agent in the form of CA 0220926~ 1997-06-27 a Search Applet 34 has been down-loaded from the Primary Server and run on the Client Workstation. Search Applet 34 is stored on the Primary Web Server 22, which is configured so that activation of the present invention causes the user interface agent to be down-loaded from the Primary Server 22 to the Client Workstation 20. The primary server operates a searchable data base management system, which becomes the primary DBMS during that session on the network.
In accordance with the present invention, all tcp/ip communication with the user interface agent, which is running on the client workstation during a particular session on the interactive computer network, is processed by and through a primary router that is configured to run on the primary server. The user interface agent is configured to communicate with the primary router via a socket connection through a port other than the port (typically denoted 80) used by the primary router's web server to remain connected to the Web. In a presently preferred embodiment, the user interface agent uses the port of the primary server denoted 7777 for the purpose of communicating with the primary router. In this way, the owner/operator of the server functioning as the primary server during a particular session on the network, is assured that the user interface agent lacks direct access to the primary data base management system. In accordance with the present invention, only the primary router, which is running on the primary server, is permitted such direct access to the primary server.
As embodied herein and schematically indicated in Fig.
2 for example, the primary router 38 (as well as each router for each server in the network) has been configured as a JAVA application. In the JAVA language, a viewer cannot execute a JAVA application. Thus, in the present invention, and as schematically indicated in Fig. 2 for example, the CA 0220926~ 1997-06-27 ~_ ,~

viewer 30 running on the client user's workstation 20 cannot load and execute the primary router 38. The software responsible for the primary router is presented below in Appendix B.
In order to permit the router to make ODBC calls, the router software must be run on a server that supports ODBC.
An Intel~ platform is one example that supports ODBC. The server also must have tcp/ip installed. In embodiments employing a JAVA application as the router, the server also must have the JAVA application progr~mm;ng interface (API) installed and a JAVA ODBC API installed. As schematically indicated in Fig. 2 for example, an ODBC interface 40 is provided on the primary server 22 in order to permit the primary router 38 to make ODBC calls.
In further accordance with the present invention, all communication between the primary server and each additional computer that is functioning as a secondary server, is also processed through the primary router that is running on the primary server. Moreover, as schematically indicated in Fig. 2 for example, all communication with each secondary server 26, 28 iS also processed through a secondary router 46, 4 8, respectively running on the secondary server 26, 28.
The software responsible for the secondary router is presented below in Appendix B. As schematically indicated in Fig. 2 for example, an ODBC interface 50, 52 iS provided respectively on each secondary server 26, 28 in order to permit the respective secondary router 46, 48 to make ODBC
calls.
In still further accordance with the present invention, and as schematically shown in Figs. 2 and 3 for example, all communication with the Hub server 24 iS processed through a Hub router 44 running on the Hub server. The software responsible for the Hub router is presented below in Appendix B. As schematically indicated in Fig. 2 for CA 0220926~ 1997-06-27 ' example, an ODBC interface 54 ls provided on Hub server 24 in order to permit the Hub router 44 to make ODBC calls.
Moreover, as schematically shown in Fig. 2 for example, all communication between the Hub server 24 and the primary server 22 is also processed through the primary router 38 that is running on the primary server.
In accordance with the present invention, a number of different requests and associated responses are employed.
Each of these is explained more fully below. The present invention employs a Backus-Naur Form (BNF) specification, which is meta syntactic notation that is used to specify the syntax of programming language, command sets, and the like.
Both the user interface agent and each router are composed in accordance with the BNF specification to define each Request and each associated Response. The BNF specification defines the basic elements that are used to build each Request and each Response. The BNF specification also defines how to combine these basic elements to form each Request and each Response. In the following presently preferred embodiment of the BNF specification, all strings are handled in a case-insensitive manner.

Request Header Structure rq_hdr~ rq_dest>~rq_str>~rq_id>
rq_dest::=~url_record>" "
rq_str::=["RQ"¦"RHn]","
rq_id::=~4-digit ASCII-decimal number>","

Request Definitions (Coming from applet to router) request~ rq_hdr>~rq_body>
rq_body::=~category_request>l~value_request>¦<listing_reques t~l~
profil~_request>l~hub_request>l~product_type_request>¦<
individual_listing_request>l<collection_request>¦<

CA 0220926~ 1997-06-27 ad_request>

category_request::="cat"
value_request::="val" n ~ ~ { cproduct type>","}
[ccat_list>¦"all"]
listing_request::="lst"",ncsearch_rq_list>
profile_request::="pro"","cproduct type>","csearch_rq_list>
hub_request::="hub"
product type_request::="typ"
individual_listing_request::="hom"","~Unique Listing Identifier~
collection_request::="col"","~url_record>","~product type>","ccatvalue_list>
ad_request::="adv"","cproduct type>","~search_rq_list>

Response Definitions (Returned from the router to the user interface agent) response::=crs_hdr>~rs_body>
rs_hdr::=crs_str>crq_id>
rs_str::="RS"","
rs_body:=ccategory_response>¦cvalue_response>¦clisting_respo 20 . nse>¦
cprofile_response>¦chub_response>¦cproduct_type_response>¦c individual_listing_response>¦cerr_response>¦ccollection_ response>l~ad_response>

category_response::="cat~ ccattype_rs_list>
value_response::="val"","ccatvalue_list>
listing_response::="lst"",~clisting_rs_list>
profile_response::="pro~","curl_rs_list>
hub_response::="hub~ ,"[curl_record>¦~none~]
product_type_response::="typ~ cproduct type>
individual_list_response::="hom"",~'[curl_record>]

CA 0220926~ 1997-06-27 ' ;.,~

err_response::="err~ error_~ecord>
collection_response::="col"",""updated"¦"created"
ad_response::="adv"" "~ad_rs_list~

List Definitions cat_list::=~category_name>{"l"~categoryname>}O n"
search_rq_list::=~catvalue_list>
catvalue_list::=<category_name>"="~value_list>{"l"ccategory_ name~
~ <value_liSt~}O .n cattype_rs_list::=<category_record~{~¦''<category_record~}O

value_list::=[<value~{<tab~value>}O n" I "]
listing_rs_list::=~listing_record>{"¦¦"~listing_record>}O n url_rs_list::=<url_record>{'~ url record~}O n ad_rs_list::-~ad_record~{''l~<ad_record~}O n Record De~initions listing_record::=~catvalue_list>
url_record::=<scheme>"://"<hostname>{":"<port>} {"/"<path>}
error_record::=<3-digitASCII-numeric number~"¦"<Error message>
category_record::=<category_name><tab><category_header><tab>
<

length><tab><category_datatype>
ad_record::=<ad_description~<tab><url_record>

Other category_name::=letter{letterldigit¦punc}O n category_datatype::="Single"¦~Range~¦"DynamicList"¦"StaticLi st"
value::=[token¦token"-"token]

In accordance with the present invention when the user interface agent sends a Request to a router the responding CA 0220926~ 1997-06-27 router will either: a) return a corresponding Response to the user interface agent, or b) return an error response.
In accordance with the present invention, each Request from the user interface agent is issued via the primary router and is configured with the following format (anything surrounded within the square brackets is optional):
[<Routing Tag~-~RQ,~4-digit unique ID>,<Request Type>[,Data]
In a search conducted in the global mode (described below) of the present invention, the Routing Tag will be the URL
(including the port) of the server from which the user interface agent is requesting information. The primary router is configured to use this tag to route the Request to the appropriate destination. The primary router is configured to strip the routing tag from the Request before the Request is forwarded to the Request's final destination.
In the local mode (described below) of operation, the primary router does not require a routing tag. The 4-digit unique ID will be an identifier that is defined by the user interface agent and included as part of the header of any Request that the user interface agent sends to the primary router.
The primary router is configured so that the Response that the primary router returns to answer the Request, includes the ID as part of the Response to the Request. For example, the primary router can be configured to format the Response to each Request in the following manner:
RS,<4-digit unique ID>,<Response Type>,<Data>
If the router encounters a problem interpreting the Request, or if the router is unable to formulate a correct Response, the router is configured to return an error response to the user interface agent. For example, t~e router can be configured to format the error response as follows:
RS,<4-digit unique ID>,err,<3-digit error number>¦<Error Message>

CA 0220926~ 1997-06-27 A potential client user of the present invention is a person who is using a viewer running on a workstation. The viewer has retrieved an HTML page, and the monitor of the workstation contains a display of the HTML page such as depicted in Fig. 5. It is likely that this HTML page pertains to a general interest of the potential client user.
However, the potential client user may have accessed the particular HTML page in error. In any event, if this HTML
page originates from the DBMS of a primary/secondary server that is configured to form part of the interactive computer network of the present invention, then this server is provided with a user interface agent in accordance with the present invention. Once the client user's viewer has loaded an HTML from a DBMS operated by a server that forms part of the interactive computer network of the present invention, the user interface agent associated with that server is automatically activated and begins running on the client user's workstation. Moreover, that server from which the user interface agent was loaded, becomes the primary server during that particular session on the network. This condition is schematically shown in Fig. 2 for example, in which the client user's browser has loaded an HTML from a DBMS operated by the Primary Web Server that forms part of the interactive computer network of the present invention, and the user interface agent in the form of a Search Applet associated with that Primary Web Server is automatically activated and begins running on the client user's workstation.
As explained more fully below, when the user interface agent opens, the user interface agent must determine the location of the searchable information and determine how that information is characterized. In the present invention, the user interface agent prepares to make these determinations by sending to the primary router, the TYP

CA 0220926~ 1997-06-27 _ ., Request, the CAT Request, and'the HUB Request. The primary router responds to the TYP Request, the CAT Request, and the HUB Request, by providing, respectively, to the user interface agent, the TYP Response, the CAT Response, and the HUB Resp~nse. Then the user interface agent begins assisting the client user to formulate a search request. In assisting the client user to formulate a search request, the user interface agent initially sends the VAL Request to the primary router. The primary router responds to the VAL
Request by providing the VAL Response from the primary DBMS
to the user interface agent.
As noted above, each server that has information available to be searched by client users on its associated DBMS, has been configured according to the present invention, to structure the information according to broad themes of information. For example, Fig. 4 depicts a HOMESEEK~ Web (HTML) Page from a primary server that has been accessed by the NETSCAPE~ browser. The client user in this example may have been interested in real estate listings and may have supplied the browser with a Uniform Resource Locator (URL) of a particular Web Page. The browser retrieved this Web Page and displayed it on the monitor of the client user's workstation. In this particular example, the information that is available to the client user for searching on this primary server's DBMS, is divided into two themes. With this Web Page displayed as shown in Fig. 4 on the monitor of the client user's workstation, the client user is presented with two links.
These two links appear as two picture blocks. Each of these links pertains to one of the two themes of information on this primary server's DBMS. As can be seen in the example shown in Fig. 4, one theme is information about homes, and the other theme is information about products other than homes.

CA 0220926~ 1997-06-27 The presentation of theseitwo themes is the result of one of the initial procedures performed by the user interface agent. When the user interface agent first opens, the user interface agent has not been provided with the themes that the primary server can make available to the client user. Therefore, when the user interface agent first opens, the user interface agent is configured to begin the search protocol by requesting the primary router to specify each theme that the primary server will make available on the primary data base management system. It is information in one of these themes for which the present invention will assist the client user to structure the search to be run by the client user. As noted above, this theme request that is issued by the user interface agent to the primary router is a termed a TYP Request. An example of a TYP Request is:
http://basx.usconnect.com~RQ,OOOl,typ In this example of a TYP Request, the header is RQ,OOOl,typ, and the user interface agent is configured to define the header portion of the TYP Request.
In accordance with the present invention, the primary router is configured so that when the primary router receives the TYP Request from the user interface agent, the primary router parses the TYP Request and retrieves from the initialization file associated with the primary server, the information satisfying the TYP Request. The primary router formats the information satisfying the TYP Request, into a TYP Response, which identifies each theme in which a search can be conducted by the user interface agent on the primary DBMS.
An example of a TYP Response from a primary router that has been configured to make available real estate listings (the theme of this data base management system chosen by the client user) from its data base management system is:
http://basx.usconnect.com~RQ,OOOl,typ,l CA 0220926~ 1997-06-27 !

In accordance with the present invention, the available themes are provided to the client user via the viewer, which has accessed a primary server that has returned an HTML such as shown in Fig. 4. The client user can select one of the themes by clicking on the link, which is presented as a picture block. For example, in the embodiment shown in Fig.
4, the primary server returned two themes to the viewer.
One theme is indicated by the picture block labeled "Search for a Home," and the other theme is indicated by the picture block labeled "Search for Other Products." The client user can use the present invention by clicking on (selecting) either the picture block labeled "Search for a Home" or the picture block labeled "Search for Other Products." By so doing, the client user makes an initial choice of the theme of the search that is to be conducted.
After this selection of one of the available themes is made, the present invention guides the client user's formulation of a search request. Initially, the present invention ensures that the search request for the theme chosen by the client user, is framed in terms of the categories that define and characterize the information that is available to be searched by the client user in the selected theme. Accordingly, once the user interface agent has been provided with the theme of the search, the user interface agent must be provided with the categories that are pertinent to that theme.
As noted above, the primary DBMS maintained by the primary server, has been configured in accordance with the present invention so that the primary DBMS stores its information according to a number of different categories of information. When the user interface agent first opens, the user interface agent has not been provided with the categories that the primary server can make available for the purpose of enabling the client user to specify criteria CA 0220926~ 1997-06-27 !

for a search query of the DBM~ maintained by the primary server. Therefore, the user interface agent is configured to begin the search protocol by requesting the primary router to specify each category that the primary server will make available from the primary DBMS to structure the search to be run by the client user. This category request that is issued by the user interface agent to the primary router is termed a CAT Request and is specified in the BNF presented above. An example of a CAT Request made during the local mode of conducting a search is:
RQ,OOOl,cat An example of a CAT Request made during the global mode of conducting a search is:
http://basx.usconnect.com-RQ,OOOl,cat In each of the above examples of a CAT Request, the header is RQ,OOOl,cat, and the user interface agent is configured to define the header portion of the CAT Request.
In accordance with the present invention, the primary router is configured so that when the primary router receives the CAT Request from the user interface agent, the primary router parses the CAT Request and retrieves from the cross-reference file associated with the primary server, the information satisfying the CAT Request. The primary router formats the information satisfying the CAT Request, into a CAT Response. As specified in the BNF presented above, the CAT Response identifies each category on the primary DBMS
that the primary server will make available to the user interface agent. As specified in the BNF presented above, the CAT Response formatted by the primary router also includes for each specified category: the category header, the maximum length of a category value, and the category type. The type of each category specified in the CAT
Response is one of the possible types noted above, namely, StaticList, DynamicList, Single, and Range.

CA 0220926~ 1997-06-27 An example of a CAT Response from a primary router that has been configured to make available real estate listings (the theme of this data base management system chosen by the client user) from its data base management system is:
S RS,OOOl,cat,HouseType=StaticList~tab~20ctab>House Type¦City=DynamicList~tab>20~tab>City¦StreetName=Single~tab>
30<tab>Street Name¦PriceRange=Range<tab>lO~tab>Price Range In this real estate listing example of a CAT Response, the header is RS,OOOl,cat, and the user interface agent is configured to interpret this header. Four categories are present in this real estate listing example, and they are termed HouseType, City, StreetName and PriceRange. The HouseType category is a StaticList type, and as such has possible values that are preordained by the context of the category and are of a type that are not likely to change over time. The HouseType category has a maximum length of 20 and is called by the name "~ouse Type." The City category is a DynamicList type, and as such has possible values that are dependent on other attributes of the category, and as such are likely to change, as well as being likely to be useful for setting up cross-dependencies. For example, the city where a real estate listing resides, will depend on the state. Moreover, if the city is known, then that also narrows the possible zip codes for the desired listing. The City category has a maximum length of 20 and is called by the name "City." The StreetName category is a Single type, and as such has only one possible value. The StreetName category has a maximum length of 30 and is called by the name "Street Name." The PriceRange category is a Range type, and as such has one possible value at each end of the range. The PriceRange category has a maximum length of 10 and is called by the name "Price Range."
The primary router is configured to send the CAT
Response to the user interface agent. The user interface CA 0220926~ 1997-06-27 e , agent is configured to receive the CAT Response from the primary router. For each category in the CAT Response, the user interface agent is configured to create an object that corresponds to the type of the category. Since there are four possible types of categories, the user interface agent is configured to instantiate one of four objects for each category type in the CAT Response.
As noted above, when the user interface agent first opens, the user interface agent is configured to request the primary router to specify the URL of the Hub server. This request for the Hub server's URL is termed a HUB Request, which is specified in the BNF described above. An example of a HUB Request is:
http://basx~usconnect~com-RQ~oool~hub In this example of a HUB Request, the header is RQ,0001,hub, and the user interface agent is configured to define the header portion of the HUB Request. In this example of the HUB Request, the routing tag is denoted by:
http://basx.usconnect.com. The primary router is configured to receive the HUB Request, parse the HUB Request, and retrieve from the initialization file associated with the primary server, the information satisfying the HUB Request.
The primary router formats the information satisfying the HUB Request, into a HUB Response, which identifies the URL
of the Hub server, and returns the HUB Response to the user interface agent. The format of the HUB Response is specified in the BNF described above. The HUB Response can take one of two form, an example of each form being:
RS,0001,hub,http://bduncan:81 -OR-RS,0001,hub,none In the first example of a HUB Response, the URL of the Hub server is bduncan:81. The "none" response in the second example of the HUB Response, signifies that the primary _ CA 0220926~ 1997-06-27 router does not know the Hub ~RL, or that the primary router does not allow global requests.
After the user interface agent receives the categories in the CAT Response from the primary server, the user interface agent is configured to request the primary server to provide selections to be used to populate each StaticList category and each DynamicList category. This request issued by the user interface agent to the primary router is a VAL
Request and is specified in the BNF presented above. An example of a VAL Request made to the primary router of a primary server that has been configured to make available real estate listings (the theme of this primary data base management system chosen by the client user) is:
RQ,0001,val,HouseType¦City In this real estate listing example of a VAL Request, the header is RQ,0001,val, and the user interface agent is configured to define the header. The StaticList category is HouseType, and the DynamicList category is City.
In accordance with the present invention, the primary router is configured so that when the primary router receives the VAL Request from the user interface agent, the primary router parses the VAL Request and retrieves from the primary data base management system associated with the primary server, the information satisfying the VAL Request.
The primary router is configured to format the information satisfying the VAL Request, into a VAL Response. As specified in the BNF presented above, the VAL Response contains all possible selections for each StaticList category and each DynamicList category passed to the Primary router in the VAL Request.
An example of a VAL Response from a primary server that has been configured to make available real estate listings from its data base management system is:
RS,0001,val,HouseType=One Storyctab>Two Story<tab>ThreeStory CA 0220926~ 1997-06-27 . .

¦City=Columbia~tab~Lexington<~ab>Cayce~tab>Re~3ank~tab>Pelio n In this real estate listing example of a VAL Response, the header is RS,0001,val, and the user interface agent is configured to interpret the header. In this example, when the client user eventually begins formulating a particular search request, the possible selections that the user interface agent will make available to the client user in the HouseType category, which is a StaticList type, are: One Story, Two Story, and Three Story. Similarly, the possible selections that the user interface agent will make available to the client user in the City category, which is a DynamicList type, are: Columbia, Lexington, Cayce, RedBank and Pelion.
The primary router is configured to send the VAL
Response to the user interface agent, which is configured to receive the VAL Response, parse VAL Response, and call a populate function, which passes a set of values to a specified object, which in this case is either the StaticList object created for the HouseType category or the DynamicList object created for the City category. As known in the art, a function is a process or action that resides within a computer program and that is called for a specific purpose. In this case, the populate function is configured to fill the specified object with the values returned as the selections in the VAL Response.
In accordance with the present invention, the user interface agent is configured to permit the client user to define the scope of the search by choosing to have the user interface agent operate in one of two alternative modes. In a first mode of operation known as the local mode, the user interface agent is configured to conduct a local search, which is a search that is restricted to the DBMS operated by the primary server. In a second mode of operation known as CA 0220926~ 1997-06-27 ~," ., the global mode, the user interface agent is configured to conduct a global search, which is a search that is not restricted to the DBMS of the primary server.
As explained above, when the user interface agent first opens, the user interface agent immediately and automatically performs the HUB Request, the TYP Request, the CAT Request, and the ~AL Request and has been provided with the HUB Response, the TYP Response, the CAT Response, and the VAL Response by the primary router. After these preliminary Requests and Responses have been completed, then the user interface agent is configured to cede control to the client user to select whether to conduct a local search or a global search.
Referring to Fig. 4, for purposes of this explanation, it is assumed that the client user in this example has clicked on the picture block labeled "Search for Other Products" and has been presented with a number of different themes. Though the menu of other themes is not shown, it is assumed for purposes of this explanation that the client user has selected a motor vehicle theme. Moreover, as shown in Fig. 5, the client user has the option of searching for information satisfying this motor vehicle theme by choosing between a local search and a global search. The client user makes this choice in the Fig. 5 embodiment by either entering a check in the box next to the heading "Expanded Search" or leaving that box blank. In the view shown in Fig. 5, the "Expanded Search?" box has been checked, indicating that the client user desires to conduct a global search, which is the second mode of operation of the present invention. However, for purposes of explaining the local search mode of operation of the present invention, the following discussion proceeds on the basis that the client user has left the ~Expanded Search~ box unchecked, i.e., blank. The components and process steps for conducting such CA 0220926~ 1997-06-27 :

a local search according to a presently preferred embodiment of the present invention are described first. The global mode of operation, which is the second or alternative mode of operation of the present invention, is described thereafter.
After the user interface agent has determined that the client user has selected a local search, the user interface agent is configured to allow the client user to control the user interface agent to build the user's search request.
The user interface agent is configured to allow the client user to build a search request by allowing the client user to choose selections from among the selections that populate each of the categories specified by the primary router in the CAT Response. The user interface agent is configured to cede to the client user, control over the user interface agent for adding search entries to the client user's search request by choosing from among the category selections populating each category.
For example, as shown in Fig. 5, a graphical user interface (GUI) is depicted of a kind that can be presented to the client user by an embodiment of the present invention that the client user has activated via a NETSCAPE~ viewer to search for information satisfying a motor vehicle theme. In the GUI screen shown in Fig. 5, the user interface agent has ceded to the client user, control over the user interface agent to formulate the client user's search request. In this particular GUI screen, the information stored in the primary data base management system satisfies the motor vehicle theme, and the categories appear under the Menu Window that is titled "Features." The information stored under this motor vehicle theme has been characterized by the following categories: Auto Type, Make, Model, Year, Miles per Gallon, Retail Price and Sale Price, which are contained in the category list maintained in the cross-reference file CA 0220926~ 1997-06-27 -, ,:

of the primary server. These are the categories returned in the CAT Response to the user interface agent from the cross-reference file of the DBMS of the primary server. In the GUI screen shown in Fig. 5, the client user has highlighted the Make category, which is a StaticList type. In this example, the only possible selection for this StaticList category is Chevrolet, which appears in the Menu Window entitled "Options" in the GUI screen shown in Fig. 5. The "Options" window contains the display for each highlighted category. The values appearing in the "Options" window are the values returned in the VAL Response to the user interface agent from the DBMS of the primary server. In this example, the client user has selected "Chevrolet" for the search request, which appears in the Selection Window titled "Selected Features" in the GUI screen shown in Fig.
5. Similarly, for each category, the client user selects from among the values in the "Options" window, and each value selected by the client user, appears in the "Selected Features" window. The values appearing in the "Selected Features" window constitute the client user's search request that the user interface agent has helped formulate by defining the theme, the categories, and the values available for each category.
In the preferred embodiment of the present invention, the user interface agent is configured to cede to the client user, control over the user interface agent for tailoring the search request. The user interface agent is configured to allow the client user to add search entries to the user's search request by entering one user-desired category value for each single type category, and to add two user-desired category values for each range type category. Moreover, the user interface agent is configured to cede to the client user, control over the user interface agent for allowing the client user to delete any number of search entries from the CA 0220926~ 1997-06-27 ! !

user's search request, including the deletion of the entire search request.
In further accordance with the present invention, the user interface agent is configured to cede to the client user, control over the user interface agent for allowing the client user to initiate the search of the primary DBMS
according to the search request that the client user has built. In the embodiment shown in Fig. 5 for example, the client user can initiate the search request that appears in the Selection Window entitled "Selected Features," by clicking the button labeled "Search," which is located immediately to the right of the legend "Expanded Search./' In still further accordance with the present invention, when the client user initiates the search request in the local mode of operation, the user interface agent is configured to send to the primary router, a request for information that satisfies the search request specified by the client user. This request issued by the user interface agent to the primary router is a LST Request, which has a format that is specified in the BNF presented above. An example of a LST Request made to a primary ser~er that has been configured to make available real estate listings (the theme of the primary data base management system in this example) is:
RQ,OOOl,LST,HouseType=TwoStory<tab>ThreeStory¦City=Columbia<
tab>Lexington¦PriceRange=lOOOOO<tab>120000 In this real estate listing example of a LST Request, the header is RQ,OOOl,LST, and the user interface agent is configured to define the header. The selections made by the client user in the HouseType category, which is a StaticList type, are: TwoStory and ThreeStory. The selections made by the client user in the City category, which is a DynamicList type, are: Columbia and Lexington. The entries made by the CA 0220926~ 1997-06-27 -client user in the PriceRange category, which is a Range type, are: 100000 and 120000.
In an alternative example shown in Fig. 5, the LST
Request made to a primary server that has been configured to make available motor vehicles offered for sale (the theme of this primary data base management system chosen by the client user upon activating the present invention) is:
RQ,OOOl,LST,Make=Chevrolet In this motor vehicle example of a LST Request, the header is RQ,OOOl,LST, and the user interface agent is configured to define the header. The client user only made a selection in the Make category, which is a DynamicList type, and chose Chevrolet from among this one possible selection returned in the VAL Response.
In accordance with the present invention, the primary router is configured so that when the primary router receives the LST Request from the user interface agent, the primary router is configured to retrieve from the primary data base management system, each record that satisfies the LST Request. The Primary router is configured to organize each record of matching data as a separate row by placing a double pipe (e.g., ~ ¦ " ) between each matching record. The primary router is configured to format the information satisfying the LST Request, into a LST Response, which includes each matching record in the primary data base management system. As specified in the BNF presented above, the LST Response formatted by the primary router includes for each matching record: a unique identifier and a value for each category that was specified in the CAT Response.
Thus, each row in the LST Response includes a data element that uniquely identifies said row on the primary data base management system and data elements that cumulatively satisfy each of the categories that were specified in the CAT Response.

-' CA 0220926~ 1997-06-27 f--An example of a LST Respo~nse from a primary router that has been configured to make available real estate listings (the theme of the data base management system in this example) from the primary DBMS is:
RS,0OOl,LST,ListNum=960053¦HouseType=2 Story¦City=Lexington¦StreetName=Magnolia Circle¦PriceRange=llO000 ¦¦ ¦¦ListNum=960167¦HouseType=2 Story¦City=Columbia¦Street Name=Gamecock Place¦PriceRange=115000 In this real estate listing example of a LST Response, the header is RS,OOOl,LST, and the router is configured to define the header. Four categories are present in this real estate listing example, and they are termed HouseType, City, StreetName and PriceRange. In the first matching record, the HouseType category, which is a StaticList type, is satisfied by a 2 story house, the City category, which is a DynamicList type, is satisfied by the city of Lexington, the StreetName category, which is a Single type, is satisfied by Magnolia Circle, and the PriceRange category, which is a Range type, is satisfied by 110000. The unique identifier for the first matching record is 960053. In the second matching record, the HouseType category is satisfied by a two story house, the City category is satisfied by the city of Columbia, the StreetName category is satisfied by Gamecock Place, and the PriceRange category is satisfied by 115000. The unique identifier for the second matching record is 960167.
In an alternative example that might accompany the GUI
screen shown in Fig. 6, the highlighted entry and the first truck entry immediately underneath the highlighted entry, of the LST Response made from a primary server that has been configured to make available information about motor vehicles offered for sale (the theme of this primary data base management system) is:

CA 0220926~ 1997-06-27 -~

RS,OOOl,LST,ListNum=8754887¦AutoType=Car¦Make=Chevrolet¦Mode l=Lllm; n~ ¦ Year=1994¦MilesperGallon=38¦RetailPrice=26545¦SaleP
rice=24000¦¦¦¦ListNum=0074421¦AutoType=truck¦Make=Chevrolet¦Mo del=Tahoe¦Year=1996¦MilesperGallon=26¦RetailPrice=52000¦Sale Price=49999 In this motor vehicle example of a LST Response, the header is RQ,OOOl,LST. The client user only made a selection in the Make category, and this did little to limit the scope of the search. For each search request, the router is configured to return no more than a predetermined maximum number of records. For example, the router can be configured to return no more than 50 records from a server for a given request. Though as shown in Fig. 6, there would likely have been a large number of matching records, which only have in common the Chevrolet Make, only two of the matching records shown in Fig. 6 are given in the example in order to save space. In this example, seven categories are used to structure the information involving motor vehicles, and the seven categories are termed AutoType, Make, Model, Year, MilesperGallon, RetailPrice, and SalePrice. In the highlighted matching record, the AutoType category, which is a StaticList type, is satisfied by a car, the Make category, which is a DynamicList type, is satisfied by Chevrolet, the Model category, which is a DynamicList type, is satisfied by Lumina, the Year category, which is a Range type, is satisfied by 1994, the MilesperGallon category, which is a Range type, is satisfied by 38, the RetailPrice category, which is a Range type, is satisfied by 26545, and the SalePrice category, which is a Range type, is satisfied by 24000. In the first truck matching record, the AutoType category is satisfied by a truck, the Make category is satisfied by Chevrolet, the Model category is satisfied by Tahoe, the Year category is satisfied by 1996, the MilesperGallon category is satisfied by 26, the RetailPrice - CA 0220926~ 1997-06-27 .-category is satisfied by 52000, and the SalePrice category is satisfied by 49999.
The primary router is configured to send the LST
Response to the user interface agent. The user interface agent is configured to receive the LST Response, to clear out any pre-existing records in the free-floating Result Window on the client workstation, add a header to the Result window, and populate the Result Window on the client workstation with a display of the matching records. For example, in the GUI screen shown in Fig. 6, the user interface agent has added the header "Seek & Find Search Results" to the free-floating Result Window and populated the Result Window with each of the matching records sent from a primary server that has been configured to make available information about motor vehicles offered for sale.
In accordance with the present invention, the user interface agent is configured to cede to the client user, control over the user interface to permit the user to scroll through the matching records that are displayed by the user interface agent in the Result Window.
In further accordance with the present invention, the user interface agent is further configured to cede control to the client user to permit the client user to choose to view more information than is provided in the matching record. When the client user chooses to view additional information for a matching record, the user interface agent is configured to issue to the primary router, a request to return the specific URL of an HTML page that contains additional information than is contained in the matching record chosen by the client user. This request issued by the user interface agent to the primary router is a HOM
Request. As specified in the BNF presented above, the HOM
Request contains a unique listing identifier. An example of a HOM Request is:

-' CA 0220926~ 1997-06-27 ,~

RQ,0001,HOM,95065 In this example of a HOM Request, the header is RQ,0001,HOM
and is defined by the user interface agent. The unique listing identifier for the matching record in the LST
Response is 95065, which specifies the address of the matching record in the primary DBMS.
In accordance with the present invention, the primary router is configured so that when the primary router receives the HOM Request from the user interface agent, the primary router parses the HOM Request and is configured to query the primary data base management system for detailed information about the specific row specified in the HOM
Request. The primary server is configured to retrieve a pre-existing HTML file if such HTML file exists. However, if such HTML file does not exist, the primary server is configured to build an HTML file from the detailed information and to save the built HTML file on the primary server. The primary server is configured to format the information satisfying the HOM Request, into a HOM Response, which identifies the URL of the matching record that the client user has chosen to examine on the primary DBMS. As specified in the BNF presented above, the HOM Response contains the Universal Resource Locator of the individual listing.
An example of a HOM Response from a primary server that has been configured to make available information about motor vehicles offered for sale (the theme of the data base management system in this example) from the primary DBMS is:
RS,0001,HOM,URL=HTTP:/ /176.16.9.12: 80/auto/chevy/html/5.htm In this motor vehicle example of a HOM Response, the header is RS, 0001,HOM and is defined by the user interface agent.
The Universal Resource Locator (URL) in this motor vehicle example is: HTTP://176.16.9.12: 80/auto/chevy/html/5.htm.

- CA 0220926~ 1997-06-27 t~

The primary server is configured to send the HOM
Response to the primary router, which is configured to parse the HOM Response and to send the parsed HOM Response to the user interface agent. The user interface agent is configured to receive the HOM Response containing the specific URL for the matching record chosen for examination by the client user. The user interface agent is further configured to instantiate a second viewer and to set this second viewer location to the specific URL for the matching record chosen for ~x~m; n~tion by the client user. Fig. 7 depicts the GUI screen that displays from a primary server that has been configured to make available information about motor vehicles offered for sale (the theme of the primary data base management system in this example), the information in the first one of the matching records depicted in Fig. 6.
This concludes the description of the present invention when the user interface agent is configured to operate in the local mode.
As noted above, the user interface agent is configured to permit the client user to cause the user interface agent to operate in a second mode of operation known as the global mode. In the global mode, the user interface agent is configured to conduct a global search, which is a search that is not restricted to the primary server. In conducting a global search, the user interface agent is configured to broaden the scope of the search to encompass information stored on data base management systems controlled by servers other than the primary server. As shown schematically in Figs. 2 and 3 for example, each of these other servers is termed a secondary server during a given session of the client user on the interactive computer network of the present invention. The main distinction between the primary server and each secondary server is that the primary server - CA 0220926~ 1997-06-27 --' is the server from which the user interface agent originated during a particular session on the network. Thus, any server (except the Hub server described below) in the interactive computer network can function as a primary server or a secondary server, depending on the origin of the user interface agent.
As noted above, each secondary server operates a searchable data base management system (DBMS), which is a secondary DBMS and is configured to store data in a structured data format. The structured format of each secondary DBMS can be the same format as that used for the primary DBMS, but need not be the same format as that used for the primary DBMS or for any other secondary DBMS.
As explained above, when the user interface agent opens, the user interface agent performs the TYP Request, the CAT Request, and the HUB Request. The primary router responds to the TYP Request, the CAT Request, and the HUB
Request, by providing to the user interface agent, the TYP
Response, the CAT Response, and the HUB Response. The user interface agent also performs the VAL Request directed to the primary server. The primary router also responds to the VAL Request by providing the VAL Response from the primary DBMS to the user interface agent. The user interface agent then cedes control to the client user to allow the client user to define the scope of the search by selecting either the local mode or the global mode. In the view shown in Fig. 5, the client user has chosen the option of using a global search to find information satisfying this motor vehicle theme. The client user has made this choice in the Fig. 5 embodiment by entering a check in the box next to the heading ~Expanded Searchn rather than leaving that box blank.
When the client user selects the global mode, the user interface agent is configured to send a VAL Request to the CA 0220926~ 1997-06-27 ~-' Hub server to begin the process of populating the DynamicList and StaticList Categories from the secondary DBMS's. As shown schematically in Fig. 2 for example, the user interface agent is configured to request the Hub router, via the primary router, to provide selections to be used to populate each StaticList category and each DynamicList category for each secondary DBMS in the computer network. This request issued by the user interface agent to the Hub router via the primary router, is a VAL Request and is specified in the BNF presented above. An example of a VAL Request made to the Hub router of a Hub server for secondary DBMS's that have been configured to make available real estate listings (the theme of the secondary DBMS's chosen by the client user) is:
RQ,0OOl,val,HouseType¦City In this real estate listing example of a VAL Request, the header is RQ,OOOl,val, and the user interface agent is configured to define the header. The StaticList category is HouseType, and the DynamicList category is City.
In accordance with the present invention, the Hub router is configured so that when the Hub router receives the VAL Request from the user interface agent via the primary router, the Hub router parses the VAL Request and retrieves from the Hub data base management system associated with the Hub server, the information satisfying the VAL Request. The Hub router is configured to format the information satisfying the VAL Request, into a VAL Response.
As specified in the BNF presented above, the VAL Response contains all possible selections for each StaticList category and each DynamicList category passed to the Hub router in the VAL Request.
An example of a VAL Response from a Hub server for secondary DBMS's that have been configured to make available real estate listings from their DBMS's is:

CA 0220926~ 1997-06-27 !'~-RS,0001,val,HouseType=OneStory<tab>TwoStory<tab>ThreeStory<t ab>FourStory¦City=Columbia<tab>Lexington<tab>Cayce<tab>RedBa nk<tab>Pelion<tab>Dearborn<tab>GrossePoint<tab>Warren<tab>Wi ndsor<tab>HighlandPark In this real estate listing example of a VAL Response, the header is RS,0001,val, and the user interface agent is configured to interpret the header. In this example, when the client user eventually begins formulating a particular search request, the possible selections that the user interface agent will make available to the client user in the HouseType category, which is a StaticList type of category, are: One Story, Two Story, Three Story and Four Story. Similarly, the possible selections that the user interface agent will make available to the client user in the City category, which is a DynamicList type of category, are: Columbia, Lexington, Cayce, RedBank, Pelion, Dearborn, Grosse Pointe, Warren, Windsor and Highland Park.
The Hub router is configured to send the VAL Response to the user interface agent via the primary router. The user interface agent is configured to receive the VAL
Response, parse the VAL Response, and call a populate function, which fills the specified object with the values returned as the selections in the VAL Response. In this case, the specified object is either the StaticList object created for the HouseType category or the DynamicList object created for the City category.
After the user interface agent populates the selections of the categories that are of the StaticList type and DynamicList type, the user interface agent is configured to allow the client user to control the user interface agent to build the user's search request. The user interface agent is configured to allow the client user to build a search request by allowing the client user to choose selections from among the selections that populate each of the ~ CA 0220926~ 1997-06-27 t~-categories specified by the Hub router in the CAT Response.
The user interface agent is configured to cede to the client user, control over the user interface agent for adding search entries to the client user's search request by choosing from among the category selections populating each category. Referring again to Fig. 5 for example, the client user in this example has double-clicked in a previous screen to select the picture block labeled "Search for Other Products" and has selected a motor vehicle theme. As described above in connection with the local search, the client user similarly is building a search request, which appears in the Selection Window labeled "Selected Features,"
by selecting values corresponding to each category returned in the CAT Response to the user interface agent by the primary router.
The user interface agent is further configured in accordance with the present invention, to cede to the user, control over the user interface agent for allowing the user to initiate the client user's search request. For example, in the GUI screen shown in Fig. 5, the client user can depress the button entitled "Search" in order to initiate the search request appearing in the Selection Window entitled nSelected Features."
Once the client user has initiated the search in the global mode of operation, the user interface agent is configured to request advertising (or other targeted messaging information) to be displayed to the client user.
The user interface agent is configured to select such advertising or other targeted messaging information according to the search criteria selected by the client user. In order to request such advertising or other targeted messaging information, the user interface agent is configured to issue an ADV Request to the Hub router via the primary router. The purpose of this ADV Request is to ~ CA 0220926~ 1997-06-27 ,-receive advertising text, graphics and/or sound (or other targeted messaging informational text, graphics and/or sound) stored on the Hub data base management system. The advertising (or other targeted messaging information) returned by the Hub router to the user interface agent via the primary router, will be determined by the Hub router according to the search criteria selected by the client user. Desirably, the Hub router is configured to limit the number of ads (or the volume of other targeted messaging information) returned to the user interface agent, to a reasonable number, such as five URL's. The ADV Request is formatted according to the BNF described above. An example of an ADV Request is:
http://basx.usconnect.com-RQ,OOOl,ADV,HouseType=Two Story~tab>
ThreeStory¦City=Columbia<tab>Lexington¦PriceRange=lOOOOO<tab >120000 The Hub router is configured to receive the ADV Request from the user interface agent, parse the ADV Request, and return to the user interface agent, the appropriate advertising or other information. The Hub router is configured to format an ADV Response containing the appropriate advertising or other information to be returned to the user interface agent. The ADV Response is formatted according to the BNF
described above. An example of an ADV Response is:
RS,0001,ADV,The Computer Group - US
Connect<tab>http://teg.usconnect.com In this motor vehicle real estate listing example of an ADV
Response shown in Fig. 6, the header is RS,OOOl,ADV, and the user interface agent is configured to interpret the header.
The advertising text is The Computer Group - US Connect.
The URL of the HTML page containing the advertising text is http://teg.usconnect.com. As shown in Fig. 6, the advertising text is displayed to the client user in the bar - CA 0220926~ 1997-06-27 ~-space located near the bottom of the Result Window labeled "Seek & Find Search Results."
When the user interface agent determines that the client user has indicated a global search, the user interface agent is further configured to request the URL for each server associated with a data base management system that possibly maintains listings applicable to the search request formulated by the client user. As noted above, the Hub DBMS maintains a profile list that contains for each DBMS on the network, each theme and each category characterizing the information on such DBMS that is to be made available to client users of the newtork. As schematically indicated in Fig. 2 for example, the user interface agent is configured to request such URL's from the Hub router via the primary router. The Hub router is configured to select such URL's according to the client user's search request. In order to request such URL's, the user interface agent is configured to issue a PR0 Request to the Hub router via the primary router. Desirably, the Hub router is configured to limit the number of URL's returned to the user interface agent, to a reasonable number, such as five. The PRO Request is formatted according to the BNF
described above. An example of an PR0 Request is:
http://basx.usconnect.com~RQ,OOOl,PRO,HouseType=TwoStory<tab >ThreeStory¦City=Columbia<tab>Lexington¦PriceRange=lOOOOO~ta b>120000 The Hub router is configured to receive the PR0 Request from the user interface agent via the primary router and to parse the PRO Request. The Hub router is configured to compare the search request to the profile list maintained on the Hub DBMS. The Hub router is configured to select URL's that are listed as having data matching the criteria specified in the search request. The Hub router is conrigured to format a PRO Response containing the -- CA 0220926~ 1997-06-27 ~-' appropriate URL's to be returned to the user interface agent. The Hub router is configured to return the appropriate URL's to the user interface agent via the primary router. The PRO Response is formatted according to the BNF described above. An example of a PRO Response is:
RS,OOOl,PRO,http://mls.detroit.com:7777¦http://mis.seattle.c om:7777¦http://mls.miami.com:7777 In this real estate listing example of a PRO Response, the header is RS,OOOl,PRO, and the user interface agent is configured to interpret the header. The URL's for the servers associated with DBMS's that have been selected as possibly having information satisfying the search request formulated by the client user are:
http://mls.detroit.com:7777; http://mis.seattle.com:7777, and http://mls.miami.com:7777.
The primary router is configured to receive the PRO
Response, parse the PRO Response, and provide the PRO
Response to the user interface agent.
In accordance with the present invention, the user interface agent is configured to create server objects for each URL returned in the PRO Response. However, because of the manner in which the Hub router is configured to select URL's responsive to the PRO Request, it is possible that not each DBMS associated with a server identified by a URL
returned in the PRO Response, will definitely have a record that satisfies all of the search criteria of the search request. For example, the server identified by the URL
http://mls.miami.com:7777 might have listings for houses satisfying the "Two Storyn selection in the HouseType category, and listings for houses satisfying the ~Columbia~
selection in the City category. Although the Hub router is configured to determine the applicability of each category, the Hub router is not configured to cross-reference information between any two categories. Thus, in the -' CA 0220926~ 1997-06-27 iJ -example given, the Hub router is not configured to select only those servers associated with a DBMS having information satisfying both "Two Story" for the HouseType category and "Columbia" for the City category.
In this global mode of operation, the user interface agent is configured to use the search request built by the cllent user to search simultaneously, each DBMS maintained by a server returned in the PRO Response to the user interface agent by the Hub server. The user interface agent is further configured to use the LST Request to simultaneously query each such primary server and secondary server for HTML pages that match all of the search criteria in the client user's search request. In further accordance with the present invention, when the client user initiates the search request, the user interface agent is configured to send to the primary router, a request for information that satisfies the search request specified by the client user. This request issued by the user interface agent to the primary router is a LST Request, which has a format that is specified in the BNF presented above. An example of a LST Request made during a global search to a server (primary or secondary) that has been configured to make available real estate listings (the theme of the DBMS in this example) lS:
http://basx.usconnect.com-RQ,OOOl,LST,HouseType=TwoStory<tab >

ThreeStory¦City=Columbia<tab>Lexington¦PriceRange=lOOOOO<tab >

In an alternative example shown in Fig. 5, the LST
Request made during a global search to a server that has been configured to make available motor vehicles offered for sale (the theme of this data base management system chosen - CA 0220926~ 1997-06-27 j~

by the client user upon activa~ting the present invention) i s :
http://basx usconnect.com-RQ,OOOl,LST,Make=Chevrolet In accordance with the present invention, each secondary router is configured so that when the secondary router receives the LST Request from the user interface agent via the primary router in the global mode of operation, the secondary router is configured to retrieve from the secondary data base management system, each record that satisfies the LST Request. The secondary router is configured to organize each record of matching data as a separate row by placing a double pipe (e.g., " ~ ) between each matching record. The secondary router is configured to format the information satsifying the LST Request, into a LST Response, which includes each matching record in the secondary data base management system. As specified in the BNF presented above, the LST Response formatted by the secondary router includes for each matching record: a unique identifier and a value for each category that was specified in the CAT Response. Thus, each row in the LST Response includes a data element that uniquely identifies said row on the secondary data base management system and data elements that cumulatively satisfy each of the categories that were specified in the CAT Response.
2 5 An example of a LST Response from a secondary router that has been configured to make available real estate listings (the theme of the data base management system in this example) from the secondary DBMS is:
RS,OOOl,LST,ListNum=960053¦HouseType=2 Story¦City=Lexington¦StreetName=Magnolia Circle¦PriceRange=l10 ooo ¦¦ ¦¦ ListNum=960167¦HouseType=2 Story¦City=Columbia¦Street Name=Gamecock Place¦PriceRange=115000 - CA 0220926~ 1997-06-27 -In this real estate listing example of a LST Response, the header is RS,OOOl,LST, and the router is configured to define the header. Four categories are present in this real estate listing example, and they are termed HouseType, City, StreetName and PriceRange. In the first matching record, the HouseType category, which is a StaticList type, is satisfied by a 2 story house, the City category, which is a DynamicList type, is satisfied by the city of Lexington, the StreetName category, which is a Single type, is satisfied by Magnolia Circle, and the PriceRange category, which is a Range type, is satisfied by 110000. The unique identifier for the first matching record is 960053. In the second matching record, the HouseType category is satisfied by a two story house, the City category is satisfied by the city of Columbia, the StreetName category is satisfied by Gamecock Place, and the PriceRange category is satisfied by 115000. The unique identifier for the second matching record is 960167.
In an alternative example that might accompany the GUI
screen shown in Fig. 7, the first two entries of an LST
Response made from a secondary server that has been configured to make available information about motor vehicles offered for sale (the theme of this secondary data base management system) are:
RS,OOOl,LST,ListNum=8754887¦AutoType=Car¦Make=Chevrolet¦Mode l=Geo¦Year=1996¦MilesperGallon=45¦RetailPrice=8930¦SalePrice =870 0 ¦¦ ¦¦ ListNum=0074421¦AutoType=car¦Make=Chevrolet¦Model=Geo ¦Year=1995¦MilesperGallon=45¦RetailPrice=7000¦SalePrice=6500 In this motor vehicle example of the first two entries of a LST Response, the header is RQ,OOOl,LST. The client user only made a selection in the Make category, and this did little to limit the scope of the search. For each search request, the secondary router is configured to return no more than a predetermined maximum number of records. For -'- CA 0220926~ 1997-06-27 .~

example, the secondary router can be configured to return no more than 50 records from a server for a given request.
Though as shown in Fig. 6, there would likely have been a large number of matching records, which only have in common the Chevrolet Make, only the first two of the matching records shown in Fig. 6 are given in the above example in order to save space. In this example, seven categories are used to structure the information involving motor vehicles, and the seven categories are termed AutoType, Make, Model, Year, MilesperGallon, RetailPrice, and SalePrice. In the first matching record, the AutoType category, which is a StaticList type, is satisfied by a car, the Make category, which is a DynamicList type, is satisfied by Chevrolet, the Model category, which is a DynamicList type, is satisfied by Geo, the Year category, which is a Range type, is satisfied by 1996, the MilesperGallon category, which is a Range type, is satisfied by 45, the RetailPrice category, which is a Range type, is satisfied by 8930, and the SalePrice category, which is a Range type, is satisfied by 8700. The unique identifier for the first matching record is 9754887.
In the second matching record, the AutoType category is satisfied by a car, the Make category is satisfied by Chevrolet, the Model category is satisfied by Geo, the Year category is satisfied by 1995, the MilesperGallon category is satisfied by 45, the RetailPrice category is satisfied by 7000, and the SalePrice category is satisfied by 6500. The unique identifier for the second matching record is 0074421.
Each secondary router is configured to send its LST
Response to the user interface agent. The user interface agent is configured to simultaneously receive each LST
Response from each responding secondary router, to clear out the free-floating Result Window on the client workstation, add a header to the Result window, and populate the Result Window on the client workstation with a display of the - CA 0220926~ 1997-06-27 --matching records. Note, in the global mode, the primary router's LST Response is treated as an LST Response from a secondary router. For example, in the GUI screen shown in Fig. 6, the user interface agent has populated the Result Window with each of the matching records sent from the DBMS
of a secondary server that has been configured to make available information about motor vehicles offered for sale.
As noted above in connection with the description of the local search, the user interface agent is configured to cede to the client user, control over the user interface to permit the user to scroll through the matching records that are displayed by the user interface agent in the Result Window.
In further accordance with the present invention, the user interface agent is further configured in the global mode to cede control to the client user to permit the client user to choose to view more information than is provided in the matching record. When the client user chooses to view additional information for a matching record retrieved during a search conducted in the global mode, the user interface agent is configured to issue to the secondary router via the primary router, a request to return the specific URL of an HTML page that contains additional information than is contained in the matching record chosen by the client user. This request is a HOM Request. As specified in the BNF presented above, the HOM Request contains a unique listing identifier. An example of a HOM
Request made during a global search is:
http://basx.usconnect.com-RQ,0001,HOM
In this example of a HOM Request, the header is RQ,0001,HOM, and the unique listing identifier is:
http://basx.usconnect.com.
In accordance with the present invention, the secondary router is configured so that when the secondary router ~- CA 0220926~ 1997-06-27 ~--receives the HOM Request from the user interface agent via the primary router, the secondary router parses the HOM
Request and queries the secondary DBMS for detailed information about the specific row specified in the HOM
Request. The secondary router is configured to retrieve a pre-existing HTML file if such HTML file exists. However, if such HTML file does not exist, the secondary router is configured to build an HTML file from the detailed information and to save the built HTML file on the secondary DBMS. The secondary router is configured to format the information satsifying the HOM Request, into a HOM Response, which identifies the URL of the matching record that the client user has chosen to examine on the secondary DBMS. As specified in the BNF presented above, the HOM Response contains the Universal Resource Locator of the individual listing.
An example of a HOM Response from a secondary DBMS that has been configured to make available information about motor vehicles offered for sale (the theme of the secondary DBMS in this example) from the secondary DBMS is:
RS,0001,HOM,URL=HTTP://176.16.9.12:80/auto/chevy/html/5.htm In this motor vehicle example of a HOM Response, the header is RS,0001,HOM and is defined by the user interface agent.
The Universal Resource Locator (URL) in this motor vehicle example is: HTTP://176.16.9.12:80/auto/chevy/html/5.htm.
The secondary router is configured to send the HOM
Response via the primary router to the user interface agent.
The user interface agent is configured to receive the HOM
Response containing the specific URL for the matching record chosen for ex~;n~tion by the client user. The user interface agent is further configured to instantiate a second viewer and to set this second viewer location to the specific URL for the matching record chosen for examination by the client user. Fig. 7 depicts the GUI screen that ~- CA 0220926~ 1997-06-27 ,~"
,: . I

displays from a DBMS that has been configured to make available information about motor vehicles offered for sale (the theme of the DBMS in this example), the information in the first one of the matching records depicted in Fig. 6.
In further accordance with the present invention, the router for each primary/secondary server is configured to periodically update its profile stored on the Hub DBMS.
This will be done via the COL Request. As schematically shown in Fig. 2, each router associated with each server (other than the Hub server) on the network sends periodically, a COL Request to the Hub router via the primary router. As specified in the BNF presented above, an example of a COL Request is:
RQ,O001,COL,HouseType=lStory~tab>3Story¦City=Columbia<tab>Le xington<tab>Cayce<tab>Red Bank¦County=T.~;ngton<tab>Richland¦State=SC
In this example of a COL Request, the header is RQ,0001,COL, and the user interface agent is configured to define the header portion of the COL Request. In this example of the COL Request, the DBMS of the initiating server has lStory and 3Story data in the HouseType category, Columbia, Lexington, Cayce and Red Bank in the City category, Lexington and Richland in the County category, and SC in the State category.
In accordance with the present invention, the Hub router is configured so that when the Hub router receives the COL Request from the router of a primary server or a secondary server, the Hub router parses the COL Request and checks the COL Request for validity. If the COL Request is valid, the Hub router is configured to return a COL Response to the router from which the COL Request originated.
Otherwise, the Hub router will return an ERR Response to the router from which the COL Request originated. An example of - CA 0220926~ 1997-06-27 ~-a COL Response, which is formatted as specified in the BNF
described above, is: RS,OOOl,COL,updated If the COL Request is valid, the Hub router is configured to use the data in the COL Request to update the profile of the reporting server in the profile list that is maintained by the Hub server's DBMS.
This concludes the description of the present invention when the user interface agent is configured to operate in the global mode. While a preferred embodiment of the invention has been described using specific terms in an embodiment of the invention applied to the purchase and sale of real estate and the purchase and sale of other products, such description is for illustrative purposes only, and it is to be understood that changes and variations may be made without departing from the spirit or scope of the invention.

,-~~ CA 0220926~ 1997-06-27 ._ .
A ppen~
import tcg.homeconnection.*;
import tcg.tools.*;
import tcg.control.*;
import java.awt.*;
import java.applet.Applet;
import java.net.*;
import java.util.*;

/*******************************************************
* Class: SeekFind * WriKen by: Brian Duncan * Date:
* Purpose: This is the main class. This controls * everything.
*******************************************************/
public class SeekFind extends Applet implements Runnable {
I/Set the Version HERE
public fmal String version = "I.Oe (01/08/97)";
//Have we already ini~i~li7~d?
static boolean initi~li7~d = false;
static boolean firstReshape = true;
Il Main Thread, Animation thread Thread tMain, tAnimate;
//The Category Panel, shows all available categories CategoryPanel CatPanel;
//The Query Panel, shows selected search criteria QueryPanel QPanel;
//The Value Panel, holds all value panels in a card l/Layout.
Panel VPanel;
CardLayout VLayout;
//Various buttons.
Button SearchButton, HelpButton, ClearAllButton;
Button ClearItemButton, AboutButton;
- //Global/local mode checkbox Checkbox Globallnd;
//Result Panel - Floating Frame that holds search results ResultPanel ResultWin;
//Shows current status of applet StatusBox CurrStatus;
//Splash Screen 5 8 -CA 02209265 1997-06-27 ,--StartupCanvas Splash;
//About Box - Floating frame AboutPanel About;
//Small activiy anirnation WaitAnimate Animation;
//Headers for CatPanel, Value Panels, and QueryPanel //These needed to be t~Ytfiel~lc to keep the 3d border.
TextField CatHeader, ValueHeader, QueryHeader;
//Holds the port # of the Primary Router int primaryPort;
/mle currently selected ValuePanel.
int CurIndex = 0;
//Random # generated to give applet a semi-unique //ID.
String sessionID;
//Which product type is this applet U~JpOI li~g?
String ProductType;
//Local or Global.
String initialMode;
String CategoryArgs[l[l = new String[100][5];
//These two will change, based on contents, so they t/can't be final.
int CATPANELWIDTH = 100;
int VALUEPANELWIDTH = 165;
//Sizes of various components. Did this to //Allow items to be positioned relative to //each other.
final int PRIMARY = 0;
final int HUB = l;
final int CATPANELHEIGHT= 120;
final int HEADERHEIGHT = 20;
final int QUERYPANELWIDTH=CATPANELWIDTH+VALUEPANELWIDTH+2;
final int QUERYPANELHEIGHT = 85;
final int BUTTONHEIGHT = 20;
final int BUTTONWIDTH = 60;
final int BUTTONHOFFSET = 5;
final int BUTTONVOFFSET = 2;
Vector of all servers being requested, with the first ([0]) being the Code Base, the second ([I]) being the hub, and the rest being secondary servers.

CA 0220926~ 1997-06-27 ,-' Vector Servers;
1/ ServerRequest Servers[];

I*****************************************************************
* Applet initi~li7~tion method *****************************************************************l public void initO {
Random r~n~lomi7~r;
int iLoop;
URL tempURL;
String arg;
//Come up with unique idPntifiP- for this session. It will be used //as applet id in the BNF request/response structure.
r~nrlomi7Pr = new RandomO;
s~cionln = String.valueOf((int)(r~ndorni7~nnextFloatO * 9999));
s~ nm = new String(~oooo~).substring(o~4-s~c~ionTn.lengtho)+spc~ nm;
//Determine which port the applet will be talking to arg = this.getParameter("PORT");
if(arg != null) primaryPort = new Integer(arg).intValueO;
else primaryPort = 7777;
//Determine startup mode for the applet, Local or Global arg = this.getParameter("MODE");
if(arg != null) initialMode = arg.toUpperCaseO;
else initialMode= "LOCAL";
setLayout(null);
//Display Splash Screen Splash = new StartupCanvas(this);
add("SplashScreen",Splash);
Splash.reshape(O,O,sizeO.width, sizeO.height);
}

I**************************************************
* Start method of Applet's thread **********************************$******************************1 public void startO {
if (tMain != null && tMain.isAliveO) {
tMain.resumeO;
tAnim~te.resumeO;
} else if(tMain - IIUII){
tMain = new Thread(this);
tMain.setPriority(Thread.MIN_PRIORI~Y);
tMain.startO;
}

} 60 CA 0220926~ 1997-06-27 --/*****************************************************************
* Stop method of Applet's thread *****************************************************************/
public void stopO {
if (tMain != null && tMain.isAliveO) {
tM~in cl.cp~dO;
t~nim~t~ cucp~n(lo;
}

I*****************************************************************
* Destroy method of Applet - Overrode this to * allow for Netscape quirks.
*****************************************************************l public void destroyO {
if(tMain != null && tMain.isAliveO) {
tMain.resumeO;
tAnim~te resumeO;

}

/*****************************************************************
* Run method of Applet's thread *~***************************************************************/
public void runO {
Vector categories;
ValuePanel tempPanel;
if(! initi~li7~d) {
//Increment Splash Screen counter Splash.incCounterO;
//Tniti~1i7e Server Array Servers = new VectorO;
IlSet Primary Server Serverc ~dtlT~lernent(new ServerRequest(PRIMARY, this));
((ServerRequest)Servers.elementAt(PRIMARY)) cetT.oç~tion(getCodeBaseO.getHostO, primaryPort, getCodeBaseO.getFileO);
//create status box CurrStatus = new StatusBoxO;
//Create Category Panel CatPanel = new CategoryPanel(lO);
//Create Value Panel VPanel = new PanelO;
VLayout = new CardLayoutO;
VPanel.setLayout(VLayout); 6 1 - CA 0220926~ 1997-06-27 ~i-//Request the Category List from the primary server. Make this request modal.
initiateRequest("CAT", PRIMARY);
waitForCompletion(PRIMARY);
//Increment Splash Screen counter Splash.incCounterO;
}

//Increment Splash screen Splash.incCounterO;
//Add all value panels to the VPanel.
categories = CatPanel.getAllCategoriesO;
int iCount=0;
for (Enumeration e = categories.el~mentcO; e.hasMoreFlrm~ntc0; iCount++) {
tempPanel = ((ValuePanel) ((Category)e n~ytFl~m~nto).getpanelo);
VPanel.add("ValuePanel"+String.valueOf(iCount), tempPanel);
}

//Create and set up panel headers.
Font f= new Font("Helvetica", Font.BOLD, 12);
CatHeader = new TextField("Features",50);
CatHeader cetFfIit~hle(false);
CatHeader cetR~rl~ground(Color.white);
CatHeader.setFont(f);
ValueHeader= new TextField("Options", 50);
ValueHeader.setEditable(false);
ValueHeader cetR~r~ground(color.white);
ValueHeader.setFont(f);
QueryHeader = new TextField("Selected Features",100);
QueryHeader.cetFtlit~ble(false);
QueryHeader cetR~r~ground(Color.white);
QueryHeader.setFont(f);
//lncrement the splash screen counter.
Splash.incCounterO;
//Create query panel QPanel = new QueryPanel(this);
ResultWin = new ResultPanel("Seek&Find Search Results", this);
//Create controls SearchButton = new Button("Search");
HelpButton = new Button("Help");
ClearAllButton = new Button("Clear All");
ClearItemButton = new Button("Clear Item");
AboutButton = new Button("About");
GlobalInd = new Checkbox("Expand Search");
//If initial mode is Global, check the checkbox;
if( initialMode.equals("GLOBAL") ) 62 ;~ CA 0220926~ 1997-06-27 , Globallnd.setState(true);
//Create Animation thread, panel.
AnimAtion = new WaitAnimate(this);
tAnimate = new Thread(Animation);
t~nim~tf~.ct~tO;
//Increment the splash screen counter.
Splash.incCounterO;
//Request the Hub URL from the Primary Server initiateRequest("HUB", PRIMARY);
waitForCompletion(PRIMARY);
//Request the Product Type from the Primary Server Splash.incCounterO;
initiateRequest("TYP", PRIMARY);
waitForCompletion(PRIMARY);
//Increment the splash screen counter Splash.incCounterO;
//Request the Category values from the Primary Server if(GlobalTn~ getStateO && GlobalInd.isVisibleO ) {
initiateRequest("VAL", HUB);
waitForCompletion(HUB);
} else {
GlobalTn-l cet~t~te(false);
initiateRequest("VAL", PRIMARY);
waitForCompletion(PRIMARY);
}
//Increment the splash screen counter Splash.incCounterO;
// Display Data Panels.
add("ValueHeader",ValueHeader);
add("QueryHeader", QueryHeader);
add("CategoryHeader",CatHeader);
add("QueryPanel", QPanel);
add("Status", CurrStatus);
add("CategoryPanel",CatPanel);
add("ValuePanel",VPanel);
// Display controls add("GlobalInd", GlobalInd);
add("Search", SearchButton);
add("ClearAII", ClearAllButton);
add("ClearItem", ClearItemButton);
add("Help", HelpButton);
add("About", AboutButton);
// Create the Result Panel add("ResultWin", ResultWin); 63 ~- CA 0220926~ 1997-06-27 '-//Add the ~nim~ n to the applet add("~nim~tior~ nim~tion);
//Remove the splash screen from the applet.
//Need to keep it, however, to get images.
remove(Splash);
//Set flag so this only happens the first time.
initi~li7~d = true;
//reshape everything reshape(0,0,thi~ Qi7~0.width, this.sizeO.height);
while(tMain != null) repaintO;
}

I***************************************************
* Reshape everything, but just the first time.
***************************************************l public void reshape(int x, int y, int w, int h) {
int iLoop;
int catItemWidth, valueItemWidth, totalWidth, temp;
super.reshape(x, y, w, h);
if (initi~li7Pd && firstReshape) {
//Autosize the Catpanel & Valuepanel based on the //size of the items in each.
catItemWidth = CatPanel.getMaxCatWidthO+10;
//Allow for scrollbar, if more than 8 categories if(CatPanel countC~t~goriesO > 8) catItemWidth+= 1 5;
valueItemWidth = CatPanel.getMaxValueWidthO;
totalWidth = CATPANELWIDTH +
VALUEPANELWIDTH+BUTTONWIDTH+BUTTONHOFFSET+2;
CATPANELWIDTH = totalWidth * (catItemWidth/(catItemWidth+valueItemWidth));
VALUEPANELWIDTH = totalWidth - CATPANELWIDTH;
if(CATPANELWIDTH < catItemWidth) {
CATPANELWIDTH = catItemWidth;
VALUEPANELWIDTH = totalWidth - CATPANELWIDTH;
} else if (VALUEPANELWIDTH < 80) {
VALUEPANELWIDTH = 80;
CATPANELWIDTH = totalWidth - VALUEPANELWIDTH;
}

IlSet the flag so reshape never happens again firstReshape = false;
//Reshape all components (God, this is ugly!) 64 CA 02209265 1997-06-27 ,~-' int buttonStart = I +((CATPANELWlDTH+VALUEPANELWIDTH)/2)- -(((BUTTONWIDTH+2)JS)n);
CatPanel.reshape(l ,BUTTONHEIGHT+2+HEADERHEIGHT+I ,CATPANELWIDTH,CATPANELHEIG
HT);
QPanel.reshape(l ,CATPANELHEIGHT+(HEADERHEIGHT*2)+BUTTONHEIGHT+4,QUERYPANEL
WIDTH,QUERYPANELHEIGHT);
ValueHeader.reshape(CATPANELWIDTH+2, 1 +BUTTONHEIGHT+2,VALUEPANELWIDTH,HEADER
HEIGHT);
QueryHeader.reshape(l ,CATPANELHEIGHT+HEADERHEIGHT+BUTTONHEIGHT+4,QUERYPANE
LWIDTH,HEADERHEIGHT);
Cat~ r reshape( 1,1 +BUTTONHEIGHT+2,CATPANELWIDTH,HEADERHEIGHT);
Glob~lTn-l reshape(b..tton.~Prt, 1,BUTTONWIDTH*2,BUTTONHEIGHT);
SearchButton.reshape(button !~t~rt+((BUTTONWIDTH+2)*2), 1, BUTTONWIDTH,BUTTONHEIGHT);
HelpButton.reshape(buttonStart+((BUTTONWlDTH+2)*3), 1, BUTTONWIDTH,BUTTONHEIGHT~;
Abo~ltRutt~ln reshape(button!;;t~rt+((BuTToNwIDTH+2)*4)~ 1, BUTTONWIDTH,BUTTONHEIGHT);
ClearItemButton reshape(QUERYPANELWIDTH+BUTTONHOFFSET, ((BUTTONHEIGHT+2)*8)+BUTTONVOFFSET, BUTTONWIDTH,BUTTONHEIGHT);
ClearAllButton.reshape(QUERYPANELWIDTH+BUTTONHOFFSET, ((BUTTONHEIGHT+2)*9)+BUTTONVOFFSET, BUTTONWIDTH,BUTTONHEIGHT);
Animation.reshape(QUERYPANELWIDTH+4,CATPANELHElGHT+QUERYPANELHEIGHT+(HEAD
ERHEIGHT*2)+BUTTONHEIGHT+24 - 43, 73, 43);
CurrStatus.reshape(l, CATPANELHEIGHT+QUERYPANELHEIGHT+(HEADERHEIGHT*2)+BUTTONHEIGHT+4, QUERYPANELWIDTH, 20);
ResultWin.reshape(50,25,600,330);
//Show the first ValuePanel in the Card Layout.
VLayout.show(VPanel,"ValuePanelO");
VPanel.reshape(CATPANELWIDTH+2,BUTTONHEIGHT+2+HEADERHEIGHT+ 1, VALUEPANELWIDTH,CATPANELHEIGHT);

CatPanel.listl .select(0);
repaintO;
}
}

I***************************************************
* This switches the value panel when the category * selected in the CatPanel changes.
***************************************************l public void update(Graphics g) {
IlHas the CategoryPanel been inct~nti~ted yet? 65 CA 0220926~ 1997-06-27 ,-~

if(CatPanel instanceof CategoryPanel) {
/Met the current index int tempIndex = CatPanel.listl.getSelect~tlTnd~ YO;
//If the index is different...
if( tempIndex >= 0 && CurIndex != tempIndex) {
//Pull the selections from the current panel addCriteriaO;
//Change the category selection.
CatPanel.se!ectC~tPgory(tempIndex);
//This is now current.
CurIndex = tempIndex;
//Show the current panel ValuePanel tempPanel = CatPanel.getCategory(tPmrTndPY).getPanel0;
System out println("ValuePanel"+String.valueOf(CurIndex));
VLayout.show(VPanel,"ValuePanel"+String.valueOf(CurIndex));
Mf this panel needs nrfi~ting do the SUB call.
if(tempPanel.getNeedsRefreshO) getSubValues(tempPanel.getNarneO);
}
}

I**************************************************
* Did this to try and get rid of double-clicking **************************************************l public boolean mouseDown(Event evt, int x, int y) {
if(evt.clickCount < 2 && (evt.target in~t~nceof BuKon 11 evt.target instanceof Checkbox)) return false;
else return true;
}

I**************************************************
* Action event. Find out what happened, and act on it.
**************************************************l public boolean action(Event evt, Object arg) {
boolean returnValue = false;
Il Search buKon pushed. Check checkbox state, if true, perform Il global search, otherwise perform local search.
if(arg.equals("Search")) {
addCriteriaO;
returnValue = true;
if( QPanel.conntTt~ m~O > 0) {
ResultWin.clearA110; 6 6 - CA 0220926~ 1997-06-27 if(Globallnd.getStateO) {
initiateRequest("PRO", HUB);
} else {
getT ictingc(pRIMARY);
ResultWin .showO;
} else ~
showError("Can't Search","To search, you must select\nat least one feature.");
} else if(arg.equals("Help")) {
t/ Help button pressed. Attempt to inct~nri~te new Browser, Il Set URL to the Help URL page.
retumValue = true;
URL ThisURL;
tr,Y {
ThisURL = new URL(getCodeBase0,"/help/hçlphr htm");
getAppletContextO.showDocurnent(ThisURL, "Help");
} catch(Exception e) {
SystPm ollt println("oops! Couldn't connect to Help HTML!");
}

else if(evt.target in~t~nreof Checkbox) {
The checkbox was clicked. repopulate values retumValue = true;
/IWe need to clear out all existing values first.
CatPanel.deselectA110;
/IDo VAL request either Globally, or locally if( GlobalInd.getState0) initiateRequest("VAL",HUB);
else initiateRequest("VAL",PRIMARY);
//Kill the query panel entries.
QPanel.clearA110;
else if(arg.equals("About")) {
//About button pressed. Let's see if we can't /Imake it modal...
retumValue = true;
if(About=null) {
About = new AboutPanel("About Seek~Find", this);
add("AboutBox",About);
About.reshape(50,25,3 00,3 00);
About.showO;
else if(arg.equals("Clear Item")) { 6 7 -- CA 0220926~ 1997-06-27 ¢-//Clear Item Button - Clears selected Query Item returnValue = true;
CatPanel.getCategory(CurIndex).deselectAI10;
QPanel.clearCurrentO;
else if(arg.equals("Clear All")) {
//Clear All Button - Clears Query Panel returnValue = true;
QPanel.clearA110;
CatPanel desel~ctA110;

.
return returnValue;
}

/**************************************************
* Handle custom everlts **************************************************l public boolean handleEvent(Event evt) {
//Custom Event. Did this to directly link a select t/with the applet.
if( evt.id = 10001) {
//Add criteria from current value panel to //Query Panel addCriteriaO;
//Check to see if this category has any dependents.
checkForSubs(((ValuePanel)evt.target).getNameO);

}
return super.handleEvent(evt);
}

/**************************************************
* Clears out all categories that are prerequisite * to this one (argS).
**************************************************/
public void checkForSubs(String argS) {
String pl ~l c;~uisiL~, String catName = argS;
Category whichOne;
Vector Values;
/IGet a vector of all categories that are children Vector categories = CatPanel.getPrerequisites(catName);
//Loop through them all, clearing the selections out, //and killing the query selections.
for( int iLoop = 0; iLoop < categories.sizeO; iLoop~ ) {
whichOoe = (Category) categories.elementAt(iLoo~);
whichOne.clearA110; - 6 CA 0220926~ 1997-06-27 Ir~

QPanel.clearItem(whichOne.getNarneO);
//Need to do this recursively, because this child //may also have children.
checkForSubs(whichOne getNameO);
//If the prerequisite category has a user's selection, //the children need to be set to repopulate when //selected if(!((String)CatPanel.getCategory(catName).getValuesO.elementAt(O)).equals("None")) whichOne.setNeedsRefresh(true);
}

}
/**************************************************
* Add the criteria entered or selected in the current * value panel to the query panel.
**************************************************/
public void addCriteriaO {
//Only let this happen if everything has been initi~li7Pd if(initi~li7Pd) {
Vector Values;
String Name, Header;
Category CurCategory;
//Get the cus-rent category.
CurCategory = CatPanel.getCategory(CurIndex);
Nasne = CurCategory.getNameO;
Header= CurCategory.getHeaderO;
Values = CurCategory.getValuesO;
//Add the selections to the Query panel.
QParsel.addQuery(Name, Header, Values);
}
}

/**************************************************
* Set the status box with the ap~SuS"idt~ message, start or * stop tlle ~nim~tion ~s,,oysiat~ly~
**************************************************/
public void setStatus(String sArg) {
if (tArssmate != null) {
if (sArg.equals("Ready")) {
//Activity's done, give the users their //buttons back enableButtonsO;
//Turn the anisnation off Anim~tion cetMotion(false);
//Set the cursor back to a nos-mal cursor.
if (!(ResultWin = null)) {
ResultWin.setCursor(Frame.DEFAULT_CURSOR);

CA 0220926~ 1997-06-27 -
3 else {
//Activity's goin' on, take the buttons away.
disableButtonsO;
// ~nim~tion cetMotion(true);
//Set the cursor to a 'HOLD IT!' cursor if (!(ResultWin = null)) {
ResultWin.setCursor(Frame.WAIT_CURSOR);

}
}
CurrSt~hlc cet~tatus(sArg);
}

/********$*************
* Turns all the buttons off **************************************************/
public void disablf Ruttonc0 {
SearchB--tt-n ~lic~bleo;
HelpBntton ~lic~hleo;
Clear~llRutton tlic~hleO;
ClearTtPmR--tton 11ic~bleo;
Abo--tRulton ~lic~hleo;
Glob~lTnrl disableO;
}

/************************************************** :
* Turns all the buttons on **************************************************/
public void enableBuKons0 {
- SearchButton.enableO;
HelpButton ~n~h~leo;
ClearAllButton-enableO;
ClearItemButton-enableO;
AboutBntton en~hleo;
Glob~lTnfl en~hleO;
}
/**************************************************
* Pop up an error message.
**************************************************/
public void showError(String title, String message) {
ErrorDialog errorDialog;
if(message l~ctTn~l~YOf(~]~) > o) message = message.substring(message l~ctTn-le~cOf("]")+1)+
"\nPlease contact the Webm lct~r ~;
errorDlalog = new ErrorDialog(title, message);
add("ErrorDialog", errorDialog);
errorDialog.setResizable(false);
errorDialog.reshape(200,200,300, 1 50);
errorDialog-showO;
} 70 -- CA 0220926~ 1997-06-27 /**************************************************
* Parses the CAT response, and sets the CatPanel * categories.
**************************************************l void parseCategoryResponse(Shring ArgS) {
String name, header, length, type, prerequisite;
Vector vFlPmPntc, vCategories;
I/Is the response valid?
if (ArgS.lengthO > ~ ) {
//Split the response into Category-sized chunks vCategories = M~nirul~tion crlit(~ ArgS);
//Loop through the category chunks - for( Enumeration e = vC~tcgo-ics.elementsO;e.hasMoreElementsO;) {
//Split each category chunk into category info //chunks vF.lementc = Manipulation.split(~,(Sh-ing)e ne~tFlPmentO);
name = (String)vElements.elementAt(O);
header = (Sh ing)vFlementi elementAt(l);
length = (String)vFI~m~ntc el~mentAt(2);
type = (String)vElem~nt~ ~lPm~nt~t(3);
//If there's no prerequisite, set it to "".
if(vElement~ Ci7~'0 > 4) {
prerequisite = (Shing)vElements.elementAt(4);
} else {
prerequisite= "";
}
//Add a new category to the Category panel.
CatPanel.addCategory(name, header, length, type, prerequisite);
}
}

/**************************************************
* Makes the CAT request to the primary server ***********************$**************************/
public void getCategoriesO {
Shring outString, response;
setSt~hlc("Requesting Categories...");
//Build the request string.
outSh:ing = makeRouterSh ing("", "cat", false);
//Make the request response = ((ServerRequest)Servers.elementAt(PRIMARY)).getRouterResponse(outString);
//Get the response parseCategoryResponse(response); 7 1 - CA 0220926~ 1997-06-27 r'~

setStatus("Ready");

I**************************************************
* Makes the HUB request to the Primary Server **************************************************/
public void getHubO {
Strillg outString;
String response;
setStatus("Requesting the Hub URL...");
//Build the request string outString = makeRouterString("", "hub", false);
//Make the request response = ((ServerRequest)Servers.elementAt(PRIMARY)).getRouterResponse(outString);
//Parse the response parseHubResponse(response);
setStatus("Ready");
}

I**************************************************
* Makes the TYP request to the primary server **************************************************l public void getProductTypeO {
String outString;
String response;
setStatus("Requesting the Product Type...");
//Build the request string.
outString = makeRouterString("", "typ", false);
//Make the request response = ((ServerRequest)Servers.elementAt(PRIMARY)).getRouterResponse(outString);
//Parse the response parseTypResponse(response);
setStatus("Ready");
}

I**************************************************
* Makes the SUB request for a specific Category **************************************************l public void getSubValues(String argS) {

IlGet the category that matches this name Category category = CatPanel.getCategory(argS); 7 2 CA 0220926~ 1997-06-27 ,~

//lf Local, request to the Primary Router, //Otherwise request to the Hub if(GlobalInd.getStateO && Globallnd.isVisibleO ) {
initiateRequest("SUB", HUB, category);
waitForCompletion(HUB);
} else {
GlobalInd.setState(false);
initiateRequest("SUB", PRIMARY, category);
waitForCompletion(PRIMARY);
}
//This category no longer needs refreshing category.setNeedsRefresh(false);
}

I**************************************************
* Makes the VAL request **************************************************l public void populateValues(int ServerNum) {
Sh ing CatString = "";
String outSh ing = "";
String response = "";
String p,~ Ui:~itt;
String Type;
Category whichOne;
Vector categories;
setSPhlc("Requesting Category Selections ");
categories = CatPanel.getAllCategoriesO;
//Loop through all the categories, pulling out the //ones that are Dyn~mi~T ict or StaticList for(Enumeration e = categories.el~mPntc0; e.hasMoreElementsO; ) {
whichOne = (Category) e.nextElementO;
Type = whichOne.getTypeO;
if(Type equ~le("Dyn~micT ict") 1I Type.equals("StaticList")) /ADetermine if this category has a ~ equiaite //If it does, skip it.
if(whichOne.getPrerequisiteO.lengthO = O) CatShring = CatString + whichOne.getNameO + "I";
}

//Strip the last "I" off CatShing = CatStr ng cubstring(o~ CatString l~ngthO-I);
//If global, request from Hub, otherwise, request //from Primary router.
if (ServerNum = HUB) {
outString = makeRouterShing(ProductType+","+CatString, "val", h-ue);
} else {
outString = makeRouterShring(CatString, "val", false);
} 73 -- CA 0220926~ 1997-06-27 ,~
;: .

//Make request.
response = ((ServerRequest)Servers.elementAt(ServerNum)).getRouterResponse(outString);
//Parse response parseValueResponse(response);
set~t~ c("Ready");
}

I**************************************************
* Parse Sub response, and populate appl olJI idt~
* category **************************************************l public void populateSubValues(int ServerNum, Object category) {
String CatString = "";
String outString;
String response = "";
Vector values;
set~t~hlc("Requesting Selectionc- "+((Category)category).getHeaderO);
CatString = ((Category)category).getNameO+"=";
IlGet the values from prerequisite category values = CatPanel.getCategory(((Category)category).getPrerequisiteO).getValues0;
CatString = CatString + Manipulationjoin("~t",values);
IlIf global, request to hub, otherwise, request to //Prirnary router if (ServerNum = HIJB) {
outString = makeRouterString(ProductType+","+CatString, "sub", true);
} else {
outString = makeRouterString(CatString, "sub", false);
}

//Make request response = ((ServerRequest)Servers.elementAt(ServerNum)).getRouterResponse(outString);
//Parse response parseValueResponse(response);
setst~tllc("Ready");
}

/**************************************************
* Adds a request header to the request string.
**************************************************l public String makeRouterString(String reqData, String reqType, boolean isHub) {
String outString;
if (isHub) {
outString = "RH,";
} else {

- CA 0220926~ 1997-06-27 ;-outString= "RQ,";
}
outString += sessionlD+","+reqType+","+reqData;
return outString;

/**************************************************
* Parses the hub response, and creates hub object **************************************************l public void parseHubResponse(String ArgS) {
Il If response contains a URL, create the hub Server object, Il Otherwise hide Global checkbox, which will limit user Il to local searches.
if(ArgS != null && !ArgS.toLowerCaseO.equals("none")) {
Serv~s ~ Flprn~nt(new ServerRequest(HUB, this));
((ServerRequest) Servers elem~nt~t(HUB)) cet~.o~tion(ArgS);
} else {
Glob~lTn~l hide0;
}
I**************************************************
* Parses the Product Type response.
**************************************************l public void parseTypResponse(String ArgS) {
ProductType = ArgS;
} ::
I**************************************************
* Parses the VAL response, populating ap~ ylia~e * Categories **************************************************l public void parseValueResponse(String ArgS) {
Vector vCategories, vValues;
int BodyPos, EqualPos, iLoop;
String Narne, nextSection;
Category CurCategory;
//Break response into category-sized chunks vCategories = Manipulation.split('l',ArgS);
I/Loop through the category chunks for(Enumeration e = vCategories.elementsO;e.hasMoreElements0;) {
nextSection = (String) e.nextElementO;
EqualPos - riextSection indexOf("=");
Name = nextSection.substring(0,EqualPos);
/IBreak category into value-sized chunks vValues = Manipulation.split(~, nextSectinn cnh.~t~ing(EqualPos+1));
CurCategory = CatPanel.getCategory(Name);

~ CA 0220926~ 1997-06-27 ~-i~

CurCategory.clearAI10;
//Add the values to the category list.
CurCategory ~TtPmc(vvalues);
}

}
I**************************************************
* Parses the LST response, and populates the * result window **************************************************l public void pars~T ictingResponse(String ArgS, int ArgI) {
Vector vListing, vValues;
String n,oYtT.ictine;
if (ArgS.lengthO > ~) {
//Break ~ ullse into listing-sized chunks vListing = Manipul~tion cplit("ll",ArgS);
vValues = new VectorO;
/tBreak listing chunk into column-sized chunks for( Enumeration eListing = vl.ictinp elementsO; ~T.icting h~cMoreT~.lemPntcO; ) {
nPYtT ictine = (String) eT.icting neYtT-lPmentO;
vV~ s ~ Flpment(Manipulation.split(ll~>n~ytT ictinp));
//Add a listing to the result window.
ResultWin ~ Ttemc(vValues, ArgI);
} else {
showError("No results retumed", "Your search did not retum any results.\nTry selecting different features,\nor eYp~n-ling search.");

}
I************************************************** :' * Parses the PRO response **************************************************l public Vector parseProfileResponse(String ArgS) {
Vector vServers;
//Split response into server-sized chunks vServers = Manipulation.split('l',ArgS);
return vServers;
}

I**************************************************
* Parses the ADV response, adding the ads to the * Resultwindow for use on the tickertape.
**************************************************l public void parseAdResponse(String ArgS) {
Vector vSections, vURLs, vMessages, vTemp;
vSections = Manipulation.split('l',ArgS); 7 6 -- CA 0220926~ 1997-06-27 ~'-vURLs = new VectorO;
vMessages = new VectorO;
//Split all the messages and URL's out for(Enumeration e = vSections.elementc(); e.hasMoreElementsO;) {
vTemp = Manipul ition cplit(~t', (String)e n~YtFl~ment0);
vMessages.addElement((String)vTemp.elementAt(0));
vURT.c adrlFlement((string)vTemp elementAt(l));
}
//Pass the ads to the result window ResultWin.addAds(vMessages, vURLs);
}
I**************************************************
* Parses the HOM response, passing URL to the browser **************************************************l public void parseHomeResponse(String ArgS, int ArgI) {
URL ListingURL;
try {
ListingURL = new URL(ArgS);
this.getAppletContextO.showDocument(ListingURL, "Home Listing");
} catch (MalformedURLException e) {
System.out.println("Didn't connect to web page "+ArgS+"\n");
}

/
* Request profile from HUB, create server objects from response * request listings from all servers retumed.
**************************************************l public void getGlob~lT.i~tingc0 {
String response;
Vector ServerURL;
ServerThread tThread;
int iLoop;
//Get ads from Hub response = QueryForAds(HUB);
//Parse ad response parseAdResponse(response);
//Get servers to query from Hub response = QueryForProfile(HUB);
ServerURL = parseProfileResponse(response);
//Do this to kill any old Secondary Servers. 7 7 Servers .setSize(2);

-~ CA 0220926~ 1997-06-27 ,.-//Create server objects for all servers, and do LST
//request for each of them for( iLoop = 0; iLoop < ServerURL.sizeO; iLoop++) {
Servers.addElement(new ServerRequest( iLoop+2, this));
((ServerRequest)Servers.elementAt(iLoop+2)).setLocation((String)ServerURL.elementAt(iLoop));
get~ .ictinpc(iLoop+2);
}
}

/**************************************************
* Kick off LST request **************************************************l public void getT ictingC(int ArgI) {
initiateRequest("LST",ArgI);
}

I**************************************************
* Request listings from secondary server **************************************************/
public void QueryForListings(int ServerNum) {
String Request;
String outString = "";
String response= "";
setStatus("Requesting T .ictingc - //Get request from Query panel Request= QPanel.getRequest(true);
I/Build request string outString = makeRouterString(Request, "lst", false);
//Make request response = ((ServerRequest) Servers.elementAt(ServerNum)).getRouterResponse(outString);
I/Parse response parseListingResponse(response, ServerNum);
setStatus("Ready");
}

,, I * ***** ***************************************
* Make HOM request **************************************************/
public void QueryForHome(int ServerNum) {
String Request;
String outString= "";
String response = ""; 7 8 -- CA 0220926~ 1997-06-27 --setStatus("Requesting a Listing Page...");
/IGet the unique identifier for currently //selected listing.
Request = ResultWin.getCurrentNumberO;
//Build request string outString = makeRouterString(Request, "hom", false);
//Make request response = ((ServerRequest) Servers.elementAt(ServerNum)).getRouterResponse(outString);
//Parse response parseHomeResponse(response, ServerNum);
set~t~h-c("Ready");
}

I**************************************************
* Make PRO request ***********************$**************************/
public String QueryForProfile(int ServerNum) {
String Request;
Strulg outString = "";
String response = "";
set~t~t-lc("Querying for Servers...");
/IGet query from Query Panel Request = QPanel.getRequest(false);
//Build request string outString = makeRouterString(ProductType+","+Request, "pro", true);
//Make request response = ((ServerRequest) Servers.elementAt(ServerNum)).getRouterResponse(outString);

set~t~c("Ready");
return response;
}

/**********************************$***************
* Make ADV Request **************************************************l public String QueryForAds(int ServerNum) {
String Request;
String outString = "";
String response = "";
setStatus("Querying for Ads.. "); 7 9 CA 0220926~ 1997-06-27 IlGet query from Query Panel Request = QPanel.getRequest(false);
//build request string outString = makeRouterString(ProductType+","+Request, "adv", true);
//Make request response = ((ServerRequest) Servers.elementAt(ServerNum)).getRouterResponse(outString);
setStatus("Ready");
return response;
}
/*********************************************************
* ClearingHouse function for all requests, parameters are * Request Type and ServerNumber.
*********************************************************l public void initiateRequest(String ArgS, int ArgI, Object argO) {
ServerRequest tempServer = (ServerRequest) Serv~rs ~l~rn~nt~t(ArgI);
//Set inforrn~tion for server to make request.
tempServer.setType(ArgS);
tempServer.setArg(argO);
//Kick the request thread off.
tempServer.startThreadO;
}

/**************************************************
* Convenience method version of initiateRequest, w/o argument.
**************************************************/
public void initiateRequest(String ArgS, int ArgI) {
initiateRequest(ArgS, ArgI, "");
}

/**************************************************
* This method makes the Server Thread modal **************************************************/
public void waitForCompletion(int ArgI) {
while(!((ServerRequest) Servers.elementAt(ArgI)).getCompleteO) {
repaintO;
tMain.yieldO;

}

/**************************************************
* Get Seek&find's version ****~*********************************************/
public String getVersionO {
return version;
} 80 CA 0220926~ 1997-06-27 import java.awt.*;
import java.net.*;

I*****************************************************
* Class: WaitAnimate * Written by: Brian Duncan * Date:
* Purpose: This class ~nc~rs~ tes functionality of anirnation that moves * when the applet is is a wait state.
*******************************************************l public class WaitAnimate extends Panel implements Runnable {
protected int whichPic = -1;
boolean Animate = false;
boolean first = true;
int direction = l;
SeekFind cParent;
boolean finalDrawn = false;
public WaitAnimate(SeekFind ArgC) {
cParent = ArgC;
}

public void setMotion(boolean bArg) {
Animate = bArg;
}

public void runO {
int iLoop;
Il first=true;
// paint(this.getGraphicsO);
while (true) {
try {
Thread.sleep(1 50);
} catch (Interrupte~iFY~eption e) f};
if (Animate) {
whichPic~;
if( whichPic > 16 ) {
whichPic = O;
}

repaintO;
} else {
if(whichPic != 99) {
finalDrawn=false;
whichPic = 99;
repaintO;

} } 8 1 }
public void paint(Graphics g) {
g.setColor(Color.gray);
drawTopLeftLines(g, 0,0,73,43);
g.setColor(Color.gray);
drawBottomRightLines(g,0,0,73 ,43);
if(whichPic=99) {
finalD,aw~ ue;
for(int iLoop=0;iLoop < 17; iLoop++) {
cPar~nt ~pl~ch drawOverlay(iLoop, thic g~tl~raphics0, 3, 3, 67, 37);
}

} else {
cParent.Splash.drawOverlay(whichPic, this.getGraphicsO, 3, 3, 67, 37);
}
}

//Override update with this to stop flickering.
public void update(Graphics g) {
paint(g);
}
public void drawTopLeftLines(Graphics g, int x, int y, int width, int height) {
g.setColor(g.getColorO.brighterO.brighterO);
for(int i=0; i<3; i++) {
g.drâwLine(x+i~ y+i, x+width-(i+l), y+i);
g.drawLine(x+i, y+i+l, x+i, y+height-(i+l));

}
public void drawBottomRightT in~s(Graphics g, int x, int y, int width, int height) {
for(int i=l; i<=3; i++) {
g.drawLine(x+i-l, y+height-i, x+width-i, y+height-i);
g.drawLine(x+width-i, y+i-l, x+width-i, y+height-i);
}
}

CA 0220926~ 1997-06-27 import java.awt.*;
import java.util.*;
import java.io.*;
import java.net.*;
import tcg.tools.*;

/*************************************~*****************
* Class: StartupCanvas * Written by: Brian Duncan * Date:
* Purpose: This class provides splash screen fimctionality, as well as * Image ~nim~
*******************************************************l public class StartupCanvas extends Panel {
Vector destCoord, sourceCoord, sizeCoord, imageNames;
Image collage, startup;
SeekFind cParent;
int imageCounter= 0;
int left, top;
boolean first = true;
int mainHeight, mainWidth;
int lastDrawn--I;
public StartupCanvas(SeekFind ArgC) {
cParent = ArgC;
getImagesO;
}

- publicvoidpaint(Graphics g) {
int fLeft, frop;
if (first) {
first=false;
Font f= new Font("TimesRoman", Font.PLAIN, 26);
FontMetrics fm = getFontMetrics(f);
String fMessage = "Please wait, loading...";
left = (int)((cParent.sizeO.width-mainWidth)/2);
top = (int)((cParent.sizeO.height-mainHeight)/2);
fLeft = (cParent.sizeO.width - fm.stringWidth(fMessage)) /2;
fTop = (top + 180);
g.setFont(f);
g.drawString(fMessage, fLeft, fTop);
g.draw3DRect(le~- I ,top- I ,mainWidth+2,mainHeight+2,true);
drawBaseImage(this.getGraphicsO, left, top, mainWidth-1, mainHeight-l);
} 83 CA 0220926~ 1997-06-27 '~

1/ Override update with this to stop flickering.
public void update(Graphics g) {
// drawOverlay(imageCounter, g, left, top, mainWidth-l, mainHeight-l);
}

public void drawLogo(Graphics g, int lef~, int top, int width, int height) {
drawLogo(imageN~mec Ci71'0-1, g, left, top, width, height);
}
public void drawLogo(int whichImage, Graphics g, int le~, int top, int width, int height) {
this.draw~PTm~ee(g, left, top, width, height);
for( int Loop = 0; iLoop <= whichImage; iLoop~) {
this.drawOverlay(iLoop, g, left, top, width, height);
}

/I g.setPaintModeO;
// paint(g);
}
public void drawBaseImage(Graphics g, int left, int top, int width, int height) {
g.drawImage(startup, left, top, width, height, this);
};
public boolean incCounterO {
imageCounter++;
repaintO;
if(imageCounter > imageNames.sizeO-l) imageCounter= imageNames.sizeO-l;

drawOverlay(imageCounter, this.getGraphicsO, left, top, mainWidth-1, mainHeight-l);
imageCountert~;
repaintO;
if(imageCounter > imageNames sizeO-I) imageCounter= imageNames.size0-1;

drawOverlay(imageCounter, this.getGraphicsO, left, top, mainWidth-l, mainHeight-l);
return true;
}

public void drawOverlay(int whichImage, Graphics g, int argIl, int argI2, int argI3, int argI4) {
// public synchronized void drawOverlay(int whichImage, Graphics g, int argIl, int argI2, int argI3, int argI4) {
float widthPct = (float) argI3/(mainWidth-l);
float heightPct = (float) argI4/(mainHeight- I );
int x = argIl;
int y = argI2;
int iWidth, iHeight;
int iX, iY, iSX, iSY; 84 CA 0220926~ 1997-06-27 String imageName;
F~ect~ngle oldClip = g.getClipRectO;
repaintO;
if(lastDrawn<=O ¦¦ whichrm~Pe =O) this.drawR~cerm~ge(g, argII, argl2, argI3, argI4);
if(imageNames.sizeO < 16) whichImage=(int)(whichImage*((float)imageNames.sizeO/I 6));
// if(lastDrawn = imageNames ci~O l) // lastDrawn=0;
for(int iLoop=M~th m~y(lastDrawn~o);iLoop <=whichTm~ge;iLoop++) {
iWidth=((Point)ci7PCoorrl el~ment~t(iLoop)).x;
iHeight=((Point)sizeCoord.elementAt(iLoop)).y;
iX=((Point)dfftCoor~l el~ment~t(iLoop)).x;
iY=((Point)destCoord.elementAt(iLoop)).y;
iSX=iX-((Point)sourceCoord.elementAt(iLoop)).x+x;
iSY=iY-((Point)sourceCoord.elementAt(iLoop)).y+y;
g.clipRect((int)((float)iX*widthPct)+x, (int)((float)iY*heightPct)+y+1, (int)((float)iWidth~widWct), (int)((float)iHeight*heightPct));
// g.drawImage(collage,(int)((float)iSX*widWct), (int)((float)(iSY*heightPct)+2), (int)((float)collage.getWidth(this)*widthPct), (int)((float)collage.getHeight(this)*heightPct), cParent);
g.drawImage(collage,(int)((float)iSX*widthPct), (int)((float)(iSY*heightPct)+2),(int)((float)collage.getWidth(this)*widthPct), (int)((float)collage.getHeight(this)*heightPct), cParent);
}

g.clipRect(oldClip.x, oldClip.y, oldClip.width, oldClip.height);
lastDrawn = whichTm~ge;
}
public void getImagesO {
DataInputStream dIn;
String tempName, line;
Vector temp;
Point tempCoord;
MediaTracker tracker;
line= "First";
try {
dIn = new DataInputStream((new URL(cParent.getCodeBaseO,"startup.map").openStreamO));
imageNames = new VectorO;
destCoord = new VectorO;
sourceCoord = new VectorO;
sizeCoord = new VectorO;
line = dIn.readLineO;
temp = Manip~ tit~n cplit(',', line);
tempName = (Strirlg)temp.elementAt(0);
mainWidth=(new Integer((String)temp.elementAt(l)).intValueO);
mainHeight=(new Integer((String)temp.elementA8t~2)).intValueO);

_ CA 0220926~ 1997-06-27 whiletline != null && line.trimO.length()>O) {
line = dIn.readLineO;
if(line != null && line.trimO.lengthO>O) {
temp = Manipulation.split(',', line);
imageNames.addElement(temp.elementAt(O));
tempCoord = new Point(new Integer((String)temp.elementAt(l)).intValueO,new Integer((String)temp.elementAt(2)). intValueO);
destCoord.addElement(tempCoord);
tempCoord = new Point(new Integer((String)temp.elementAt(3)).intValueO,new Integer((String)temp.elementAt(4)).intValueO);
sizeCoor~ Flpment(tempcoord);
tempCoord = new Point(new Integer((String)temp.elementAt(5)).intValueO,new Integer((String)temp.elementAt(6)).intValueO);
sourceCoord.addElement(tempCoord);
}

collage = cParent.getImage(cParent.getCodeBaseO, "images/collage.gif ');
startup = cParent.getImage(cParent.getCodeBaseO, "images/startup.gif ');
tracker = new MediaTracker(cParent);
tracker ~ m~ge(collage,O);
tracker ~ Tm~pe(startup~
for(int Loop=O;Loop<2;iLoop++) {
cParent.showStatus("Loading Startup Image: "+String.valueOf(iLoop+l));
try {
tracker.waitForID(iLoop);
} catch(InterruptedException e) {};
catch(lOException e) {
SystPm ol.t println("lJnable to open Image map file!");
}

}

CA 0220926~ 1997-06-27 import tcg.homeconnection.*;
import java.io.*;
import java.net.*;

I**********************************************
* Class: SeverThread * Written by: Brian Duncan * Date:
* Purpose: This class is an ~Ytencion of Thread.
* The purpose of this is to allow a Server class * to receive a response from a server, without * tying the system up. This allows seek&fuld to * process multiple requests simultaneously.
**********************************************/
class ServerThread extends Thread {
SeekFind cParent;
int ServerNumber;

I**********************************************
* Constructor **********************************************l public ServerThread(SeekFind Main, int iArg) cParent = Main;
ServerNumber= iArg;
}

I**********************************************
* The runO method of this thread. Will process - * different request-builder methods of the SeekFind class * based on the type of request.
**********************************************l public void runO {
boolean Successful = false;
InputStream fResponse;
ServerRequest tempServer;
String requestType;
tempServer= (ServerRequest) cParent.Servers.elementAt(ServerNumber);
requestType = tempServer.RequestType;
1/ Call app.o~liale request function based on Type if(requestType.equals("CAT")) cParent.getCategoriesO;
else if(requestType.equals("HUB")) cParent.getHubO;
else if(requestType.equals("TYP")) cParent.getProductTypeO;
- else if(requestType.equals("VAL")) cParent.populateValues(ServerNumber);
else if(requestType.equals("SUB")) cParent.populateSubValues(ServerNumber, tem~Server.arg);
else if(requestType.equals("PRO")) 7 .:
cParent.getGlob~l~ .ictinecO;
else if(requestType.equals("HOM")) cParent.QueryForHome(ServerNumber);
else if(requestType.equals("LST")) cParent.QueryForListings(ServerNumber);
IlSet the server object completion status to true.
tempServer.setComplete(true);
}
}

~ CA 0220926~ 1997-06-27 _ , import tcg.homeconnection.*;
impor~ java.io.*;
import java.net.*;

1****~*******************~**************************
* Class: ServerRequest * Written by: Brian Duncan * Date:
* Purpose: This class .onc~rsul~t~s all the connection * and state inforrnation about a router (Server-side * ja~a application).
********$******************************************/
class ServerRequest {
SeekFind cParent;
//Unique serYer number - used system-wide int S~rverNumber;
//D~chn~tion URL
Strinv destin~tion;
//Host IP Address Strinv Host;
//Server Port #
int Port;
//Server file. Used to keep track of sub-directory info String File;
//The current request type in process.
String RequestType;
//Argument to be used when processing the request.
Object arg;
InputStream InStrearn;
OutputStream OutStream;
//Determines the state of the request to this server boolean Complete = false;
Socket Sock;

/*****~****************************************
* Constructor *****~************************Y***************/
public ServerRequest(int iArg, SeekFind aArg) {
ServerNumber= iArg;
cParent = aArg;

/*****~***************************************
* Sets the completion status of the current 8 9 CA 0220926~ 1997-06-27 ;

* request for this server.
*****$****************************************/
public void setComplete(boolean bArg) {
Complete = bArg;
}
I**********************************************
* Gets the completion status of the culrent * request for this server ********************$*************************/
public boolean getCompleteO {
return Complete;

/**********************************************
* Sets the request type for the current request * to the server.
**********************************************l public void setType(String ArgS) {
RequestType = ArgS;
setCnmplete(false);
}

/**********************************************
* Sets the argument (If any) to be used when * processing the current request or response.
***********************J******************/
public void setArg(Object ArgO) {
arg = ArgO;
}

/*$********************************************
* Sets the location url info for this server * This version takes a complete URL String as a parameter.
**********************************************l public void setT oc~on(String ArgS) {
Stin~tion = ArgS;
try {
URL tempURL = new URL(ArgS);
Host = templlRL.getHost0;
Port = tempURL.getPort0;
if( Port = - I ) Port = cParent pri~naryPort;
} catch (M~lformedURLException e) {
System.out.println("Well, couldn't set the location!\n");

/**********************************************
* Sets the location url info for this server * This version takes Host (String), Port (Int)~ and * File/pa~ (String) as parameters.
*************** * J

CA 0220926~ 1997-06-27 public void setLocation(String ArgS, int ArgI, String Ar~S2) {
Host = ArgS;
Port = ArgI;
File = ArgS2;
if( Port = - I ) Port= 80;
destination = "http://"+Host+": "~String.valueOf(Port)+File;
}
I**********************************************
* Returns the Host name/IP address of this server **********************************************/
public String getHostO {
return Host;
}
/**********************************************
* Retums the Port # of this server **********************************************l public int getPortO {
return Port;
} ~ :

* * *
* Returns the Input Stream of this server **********************************************/
public InputStream getInStreamO {
return InStream;
} :
/**********************************************
* Returns the Output stream of this server ***********************$**********************/
public OutputStream getOutString0 {
return OutStream;
}

/**********************************************
* Opens a connection to the server, and processes * a request. Parameter is the request string.
**********************************************/
public String getRouterResponse(String ArgS) {
String response = "";
boolean Body = false;
DataInputStream DStream;
ServerRequest tempServer;
try {
tempServer= (ServerRequest) cParent.Servers.elementAt(0);
Sock = new Socket(tempServer.getHostO,tempServer.getPort0);
DStream = new DataInputStream(Sock.getInputStreamO);
sendRouterRequest(ArgS); 9 1 CA 0220926~ 1997-06-27 .
, .

response = DStream.readLineO;
//Check for error if(responce,cl~kstring(8,1 I).toLowerCaseO.equals("err")) {
cParent.showError("Router Error: "+response.substring(12, 15), resp-~rl~ç ~uhstring(17));
response = "";

Sock.closeO;
catch (Exception e) {
cParent.showError("Router Not Responding", "Please try again later.");
response = "";
System.out.println(e+" (Error receiving Router Response)");
}

//Truncate the header of the response.
if( r~s~l-nc~ lengthO > 11 ) response = r~poncç ~ubst~ing(12);
else response = "";
return ~ onse;
}

1****~*****************************************
* Adds a routing tag to a request.
**********************************************l public String addRouterTag(String data, String location) {
String outString;
outString = location+"~"+data;
return outString;

/**********************************************
* Sends the request to the server.
**********************************************l public void sendRouterRequest(String ArgS) {
PrintStream dStream;
if(ServerNumber != 0) ArgS = addRouterTag(ArgS, d~-stin ition);
try {
dStream = new PrintStream(Sock.getOutputStreamO);
dStream.pri~tlll(ArgS);
} catch(IOException e) {
System.out.println(e+" (Error sending Router Request)");
}
}

/**********************************************
* Starts a thread for this server object, to allow * multiple servers to be cormected siml]lt~neo,,sly *************~********************************1 public void startThreadO { 92 ServerThread tThread;
tThread = new ServerThread(cParent, ServerNumber);
tThread.startO;
}
}

CA 0220926~ 1997-06-27 import tcg.control.StringGrid;
import tcg.homeconnection.*;
import tcg.tools.*;
import java.awt.*;
import java.net.*;
import java.util.*;

I***********************************************
* Class: ResultPanel * Written by: Brian Duncan * Date:
* Purpose: This class en~apsu1~t~s a floating frame * cont~ ing a String Grid and a scrolling Navigator * ticker.
***********************************************/
class ResultPanel extends Frame {
Vector CatList;
StringGrid F~Pcl~ltT.ict SeekFind cParent;
//These vectors keep track of the Originating servers, //and Unique i~l~ntifi~rs for all records.
Vector ListServer, ListNumber;
//This thread controls the ad scrolling.
Thread tScroll;
NavigatorTicker AdScroll;
Button showDetail, close;
/***********************************************
* Constructor ***********************************************/
ResultPanel (String Title, SeekFind cArg) {
super(Title);
Vector Headers;
int Lengths~];
cParent = cArg;
CatList = cParent.CatPanel.getAllCategoriesO;
Headers = new VectorO;
int iLoop;
setResizable(false);
for(Enumeration e=CatList.elementsO; e.hasMoreElementsO; ) Headers ~ 1Fl~ment(((category) e.nextElementO).getHeaderO);
Res~lltr ict = new StringGrid(Headers);
AdScroll = new NavigatorTicker(this);
showDetail = new Button("Show Detail"); 9 4 CA 02209265 1997-06-27 .-close = new Button("Close~');
//Start the thread for the ad scrolling, however, //we don't need it yet, so suspend it.
tScroll = new Thread(AdScroll);
tScroll.startO;
tScroll cnspen~1o;
//Set widths here, when implemented.
ListServer = new VectorO;
ListNumber = new VectorO;
setLayout(null);
add("E~Psl.ltT,ict", Rpsllltr ict);
add("AdScroll", AdScroll);
add("showDetail", showDetail);
add("close", close);
}

public void reshape(int x, int y, int w, int h) {
super.reshape(x, y, w, h);
if( cParent.GlobalInd.getState0 ) {
p~s--ltT ictreshape(2,22,w,h-81);
AdScroll-showO;
AdScroll.reshape(l,h-65+2,w-2,30);
showDetail.reshape(w- 155,h-25,75,20);
close.reshape(w-75,h-25,75,20);
} else {
AdScroll.hideO;
~S~ltr.ict reshape(2~22~w4~h-92);
showDetail.reshape(w- 165,~ es~ltr .ict ci~loo~height+3o~7s~2o);
close.reshape(w-85,~esll1tT.ict ci7~o~height+3o~75~2o);
}
}

public boolean handleEvent(Event evt) {
if(evt.id = evt.WINDOW_DESTROY 11 (evt.target = close && evt.id = Event.MOUSE UP)) {
cParent.requestFocusO;
thic,hideO;
this.clearAI10;
return true;
}

return (super.handleEvent(evt));
}

public void atl-lrt~mc(Vector ArgV, int Argl) {
for(Enumeration e = ArgV.elements0;e.hasMoreFI~?mentc0;) ~ oSnltT ict ~ Tt~nn(bllilrlT ichng((vector) e neYtFl~ml~nt0, ArgI));
}

public void clearA110 {
ResultList.clearO; 9 5 ListServer.removeAllElementsO;

.

ListNumber.removeAllElementsO;
}

public void addAds(Vector ArgVI, Vector ArgV2) {
AdScroll.addMessages(ArgVI, ArgV2);
tScroll.resumeO;
}

public void stopAdsO {
tScroll Cl-spenflO;
}
public Vector bnil.lT icting(Vector ArgV, int ArgI) {
Category ThisCat;
String CurrNumber = "";
Vector vParsed, values;
String nextEI, ell, el2;
int iCounP0;
Enumeration e;
values = new VectorO;
e = ArgV.elementsO;
while( e.hasMoreFlPm,-~tcO ) {
nextEI = (String) e.nextElementO;
vParsed = Manipulation.split('=', nextEI);
ell = (String)vParsed.elementAt(0);
if ~vParsed.sizeO > I) el2 = (String)vParsed.elementAt( I );
else el2 = "";

if(ell .equals("listnum") ) {
CurrNumber = el2;
} else {
values ~ nlent(el2);
}

ListServer ~d~lFlement(new Integer(Argl));
ListNumber.addElement(CurrNumber);
return values;
}

public String getCurrentNumberO {
return (String) ListNumber.elementAt(ResultLict celect~r10);
}

public int getCurrentServer(int WhichOne) {
int tempInt;

tempInt= ((Integer) ListServer.elementAt(WhichOne)).intValueO;
return templnt;

public boolean action(Event evt, Object arg) {
if((evt.target inct~nceof StringGrid && "Double".equals(arg)) 11 arg.equals("Show Detail")) {
int ThisServer;
ThisServer = getCurrentServer(F~f~cnltT.ict celecte~lo);
cPar~nt initi~t~,Request("HOM", ThisServer);
return false;
} }

CA 0220926~ 1997-06-27 ._ import tcg.homeconnection.*;
import tcg.tools.*;
import java.awt.*;
import java.util.*;

I*************************************************
* Class: QueryPanel * Written By: Brian Duncan * Purpose: A list extension that holds selections chosen by * the user. Contains methods that check to insure * that a category puts only one line in it.
* Parameter: Count of max possible query lines.
*************************************************l public class QueryPanel extends List {
//Holds all category names in the Query List Vector CurrentCat;
SeekFind cParent;

I*********************************************
* Constructor *********************************************l public QueryPanel(Seek~ind ArgC) {
super(5, false);
cParent = ArgC;
//Initialize the vector for the categories CurrentCat = new VectorO;
setRa~kground(Color.lightGray);
}

I**
* Adds a query line to the list. It first calls findQueryO
* to see if there is already a query from that category in * there.
* Accepts two parameters: Category Name and Value vector.
* Takes all the values from the value vector and separates * them with commas.
* (~see tcg.homeconnection.QueryPanel#findQuery *l public void addQuery(String Name, String Header, Vector Values) {
int IsThereOne;
IsThereOne = findQuery(Name);
if (IsThereOne > -1) { 9 8 CA 0220926~ 1997-06-27 ~_ /tRemove the category from the Query List delItem(IsThereOne);
/tRemove the category from the vector.
CurrentCat.removeElementAt(IsThereOne);
}

if( !((String) V~1UPC elementAt(0)).equals("None") 1I V5lI11eS Ci7P() > I) {
addItem(Header+" = "+ Manipulationjoin(",",Values));
CurrentC~t ~d~Fl~oment(Name);
th ic celect(this.countItemso- I );
cParent.CatPanel.selectCategory((String)CurrentCat.elementAt(getSelt~c~ Tn(leY()));
}

I**
* If selected a query, set the category panel selection accordingly.
*t public boolean handleEvent(Event evt) {
if (evt.id -- Event.LIST_SELECT) {
cParent.CatP~nel celectcategory((string)currentcat.elementAt(getselectedIndexo));
return false;
}

I**
* Checks to see if the category name passed already has an * entry in the query panel.
*l public int findQuery(String ArgS) {
int WhichOne = -1;
for(int iLoop = 0; iLoop < CurrentCat.size(); iLoop++) {
if( ((String)CurrentCat.elementAt(iLoop)).equals(ArgS)) {
~,VhichOne= iLoop;
break;
} }
return WhichOne;
}

/**
* Clears all query lines out of the query panel.
*/
public void clearA110 {
this.delItems(0,this.countItems()-l);
CurrentCat.removeAllElementsO;
} 99 - CA 0220926~ 1997-06-27 _ I**
* Clears currently selected query line out of the query panel.
*l public void clearCurrent() {
int curltem;
curltem = this.getSelecte~llnd~YO;
if(curltem > - I ) clearItem(curltem);
}

/**
* Clears query line out of the query panel, based on Name.
*l public void clearltem(String argS) int whichItem;
whichltem = this.findQuery(argS);
if(whirhTtenn >-1) clearItem(whichItem);
}

/**
* Clears query line out of the query panel, based on index.
*l public void clearItem(int argI) {
CurrentCat.removeElementAt(argI);
this.delItem(argI);
/I Selected the one above it, if one, or the one below Il it, if one if(thic countlt~nnc() > o) {
if(argl-l >= O) this.select(argI- I );
else if(argI <= this.countItemsO) this.select(argl);
}

**
* Builds a query string of all queries in the query panel, * in a format that's can be passed to the server via cgi * (sans the cgi header.) Parameter specifies whether to include * all columns (LST), or to only include DynamicList and StaticList * (PRO).
*l CA 0220926~ 1997-06-27 public String getRequest(boolean ArgB) {
int iLoop;
String Request;
String Part;
String type;
int WhereEqual;
Request= "";
for(iLoop=0; iLoop < countItemsO; iLoop++) {
Il If ArgB is false, only use the columns that are StaticList or DynamicList.
if( !ArgB ) {
type = new String( cParent.CatPanel.getCategory(((String)CurrentCat.elementAt(iLoop))).getTypeO );
if( !type.equals("DynamicList") && !type.equals("StaticList")) contin~
}

Part = getItem(iLoop);
Part= Part.replace(',',~t');
Part= Part.replace('-','\t');
WhereEqual = Part.indexOf('=');
Part = ((String)CurrentCat.elementAt(iLoop))+"="+Part.substring(WhereEqual+2);
Request = Request + Part+"l";
}

if( Request.lengthO > ~ ) {
Request= Request cl~hstring(o~ Request.lengthO-1);
}

return Request;
}

CA 0220926~ 1997-06-27 .~-import java.awt.*;
import java.lang.*;
import java.net.*;
import java.util.*;
I**
* NavigatorTicker by Ahmed Abdelhady <b>ahady(~idsc.gov.eg<b> <br>
A live Hypertext java applets.
* Modified by Brian Duncan:
* Now just a panel implementing runnable.
All Params are now either fixed or set with methods.
*l public class NavigatorTicker extends Panel implements Runnable {
ResultPanel cParent;
/** index for the active message */
public int messageIndex=0;
/** TOtal no of messages */
public int messageCount=0;
/** The message to be displayed. */
public String message;
/** The messages Vector. */
public Vector msgs=new Vector();
/** The Font to be displayed. */
public Font messageF;
/** x-position of message. */
public int messageX;
/** y-position of message. */
public int messageY;
/** Length of the Active message. */
public int messageW = 0;
/** Messages Lengths Vector */
public Vector msgsW= new Vector();
/** URL to switch to */
public URL url_ = null;
/** Target URLs Vector */
public Vector msgsURL=new Vector();
/** How far to skip across the screen. */ 10 2 ~ CA 0220926~ 1997-06-27 .-int speed;
/** State of the applet. */
public boolean active = false;
/** The Text-color. */
public Color txtCo;
/** The Link-color. */
public Color linkCo;
/** The backgroundcolor. */
public Color bgCo;

/** The Size used to calc the Font. */
public Dimension lastS = new Dimension(l,l);
/** The offscreen image. */
Image im = null;
/** The offscreen Graphics context */
Graphics gr = null;
/* A flag that indicate mouse movement over the Applet */
boolean display_URL=false;
/* Mouse x Position */
int mouseX=0;

I**
* Initialize: Read Parameters *
public NavigatorTicker (ResultPanel cArg) {
cParent = cArg;
// mcgc ~ Flement(new String("Microsoft's Home Page..."));
Il msgsURI, ~ArlFl~mPrlt(new String("http://www.microsoft.com"));
// mcgs ~rlF.lement(new String("Netscape's Home Page..."));
Il msgsURL.addElement(new String("http://www.netscape.com"));
// mcgc,~drlF.lement(new String("Yahoo (Search Engine Extraordinaire!)..."));
ll msgsURL.addElement(new String("http://www.yahoo.com"));
// mcgc ~F.lernent(new String("The Computer Group - USConnect..."));
ll msgsURL.addElement(new String("http://tcg.usconnect.com"));
// mcgc ~F.lement(new String("TCG's Home Link..."));
Il msgsURL.addElement(new String("http://176.16.9.12/homelink"));
speed= 10;
txtCo = Color.yellow;
linkCo = Color.red;

CA 0220926~ 1997-06-27 ~_ bgCo = new Color(0,0,128); l/Dark Blue }

/* * Applet Info. */
public String getAppletlnfoO {
return "HadyTickerjava, V bl, 114196 by Ahmed Abdel-Hady extending the original ticker by Thomas Wendt, http://www.uni-kassel.de/fb 1 6/ipm/mt/staff/thwendte.html";
}

* Create the image Parameters.
* Called, if just created or size has changed *l public void createParamsO {
ll Init some conct~ntc int w = sizeO.width;
int h = sizeO.height;
lastS.width = w;
lastS.height = h;
ll dispose old buffer etc.
if (gr != null) { gr.fina!ize0; }
if (im != null) { im = null; }
ll Calc the font and positions. Message must fit applets area.
int refH = 14;
Font tf = new Font("TimesRoman", Font.BOLD, reflH);
setFont(tf);
FontMetrics tfm = getFontMetrics(tf);
int fh = tfrn.getHeightO;
fh = refH*(h-10)/fh;
messageF = new Font("TimesRoman", Font.BOLD, fh);
FontMetrics fm = getFontMetrics(messageF);
fh = fm.getHeight();
messageX = w;
messageY = ((h-fh) >> I)+fm.getAscent();
messageW = 0;

for(int i=0; icmessagecount;i++){
msgsW.addElement( new Integer(fm.stringWidth((String) msgs.elementAt(i))+14 ) );messageW+=fm.stringWidth((String) msgs.elementAt(i));
}

im = createImage(w, h);
gr= im.getGraphics();
}

I**
Painting the applet calls the overriding update to elimentate flicker *l public void paint(Graphics g) { update(g); }
/** Show the stuff */
public synchronized void update(Graphics g) { 104 if (messageCount > 0) {

CA 0220926~ 1997-06-27 1/ Recalc params, if something has changed if ((size().height != lastS.height) 11 (sizeO.width != lastS.width)) { createParamsO; }
1/ fill area with bgcolor gr.setColor(bgCo);
gr.fillRect(0,0,1astS.wi~th l~ct.~.height);
gr.drawRect(O,O,lastS.width- 1 ,lastS.height- I );
gr.drawRect(l,l,lastS.width-3,1astS.height-3);
gr.setColor(bgCo);
gr.draw3DRect(2,2,1astS.width-5, lastS.height-5, true);
gr.draw3DRect(3,3,1astS.width-7, lastS.height-7, true);
gr.clipRect(5,4,1astS.width- l O, lastS.height-8);
Il show status .. track mouse position..
if(display_URL) {
int currX=0,x=mouseX;
if( x > messageX ){ 11 clicking Nonempty area x-=messageX; 11 compute displ~ment relative to start of the message for(int i =O; i< messageCount; i++){
currX+=((Integer) msgsW.elementAt(i)).intValueO;
Il compare to acumulated widths to get clicked message index.
if ( x < currX ) { messageIndex=i; break;}
}
}

Il draw the text gr.setColor(txtCo);
gr.setFont(messageF);
int disp=0;
for(int i=0;i<messageCount;i++){
if(i==messagelndex && display_URL) gr.setColor(linkCo);
else gr.setColor(txtCo);
gr.drawString((String) msgs.elementAt(i), messageX+disp, messageY); 11111111111111 disp+=((Integer) msgsW.elementAt(i)).intValueO;
//Added these two lines to test text separation.
if(i<messageCount-l) {
gr.setColor(new Color(128,0,0));
gr.fill3DRect(messageX+disp, 10, 10,12, true);
disp+=14;
}
}

Il finally show all together on the screen g.drawImage(im,0,0,this);
}
}

/** calc next position of message and call repaint */
public synchronized void nextPos() {
Il decrement position messageX -= speed; 10 5 CA 0220926~ 1997-06-27 .

ll and stay in the bounds if ((messageX + messageW) < O) {
} meSSageX = lasts.width;
ll indirectly call update repaint();
}

/** Run the loop. This method is called by class Thread. */
public void runO {
ll others might be more important Thread.currentThreadO.setPriority(Thread.MIN_PRIORITY);
while (true) {
ll do the job nextPosO;
ll pause try {Thread.sleep(lOO);}
catch (InterruptedException e){ }
}
}

/* * Switch to url, if url is given. */
public boolean mouseUp(Event evt, int x, int Y) {
try { url_ = new URL((String)msgsURL.elementAt(messageIndex)); }
catch (Exception e) { url_= null; }
if ( url_ != null) { cParent.cParent.getAppletContextO.showDocument( url~ (String) msgs.elementAt(messageIndex)); } ll might not work with some early browsers return true;
}

public boolean mouseEnter(Event evt, int x, int Y) {
display_URL = true;
retum true;
}

public boolean mouseExit(Event evt, int x, int Y) {
display_URL = false;
return true;
}

public boolean mouseMove(Event evt, int x, int Y) {
mouseX=x;
return true;
}

public void addMessages( Vector ArgV 1, Vector ArgV2 ) {
msgsW.removeAllElementsO;
msgs = ArgVI; 106 CA 02209265 l997-06-27 msgsURL = ArgV2;
messageCount = ArgVl.sizeO;
createParamsO;
}

CA 0220926~ 1997-06-27 import java.awt.*;
import tcg.tools.*;
import tcg.homeconnection.*;

/***********************************************
* Clacs: AboutPanel * Written by: Brian Duncan * Date:
* Purpose: To display a Sek&Find-specific about box with * the QnimQt~d image sequence displayed.
***********************************************l public class AboutPanel extends Frame {
SeekFind cParent;
Button bOk;
ImagePanel imagePanel;

/***********************************************
* Constructor ***********************************************/
AboutPanel (String title, SeekFind cArg) {
super(title);
/l String line = "";
ll //Build the 'line' string;
ll for(int iLoop=0;iLoop<30;iLoop++) Il line+= '\304';
cParent = cArg;
thic cetT ~yout(null);
this.setResizable(false);
bOk = new Button("OK");
imagePanel = new ImagePanel(136,74,this);
imagePanel.setLayout(new FlowLayout(FlowLayout.CENTER,15,15));
add("OK", bOk);
add("Image",imagePanel);
imagePanel.reshape(82,40,136,74);
bOk.reshape(140,225,30,20);

I***********************************************
* Allow the frame to close normally ***********************************************l public boolean handleEvent(Event evt) {
if(evt.id = evt.WINDOW_DESTROY 11 evt.arg.equals("OK")) {
this.hide();
return true; 1 0 8 CA 0220926~ 1997-06-27 , : ' .

return (super.handleEvent(evt));
}

I***********************************************
* Paint the image and the text ********************4*************/
public void paint(Graphics g) {
int fLeft, frop, fHeight, fWidth, fCurrentY;
//Need three different fonts for various text Font f= new Font("TimesRoman", Font.PLAlN, 12);
Font f2 = new Font("TimesRoman", Font.BOLD, 12);
Font f3 = new Font("TimesRoman", Font.PLAIN, 10);
String versionString;
fWidth = getFontMetrics(f).stringWidth("Copyright (c) 1996 The Computer Group");fLeft= (300 - fWidth)/2;
fTop= 105;
fHeight = getFontMetrics(f2).getHeightO;
versionString= "Version "+cParent.getVersion0;
g.setFont(f2);
g.drawString(versionString,78, fTop);
g .setColor(Color.black);
g.fillRect(fLeft,fTop+4,fWidth,3);
g.setFont(f3);
fCurrentY = fTop+fHeight+6;
g.drawString("Copyright (c) 1996 The Computer Group", fLeft,fCurrentY);
fCurrentY += getFontMetrics(f3).getHeightO;
g.drawString("All Rights Reserved.", fLeft, fCurrentY);
g.setFont(f);
g.drawLine(fLeft,fCurrentY+4,fLeft+fWidth,fCurrentY+4);
fCurrentY += fHeight+3;
g.drawString("Patent Pending", fLeft, fCurrentY);
g.drawLine(fLeft,fCurrentY+4,fLeft+fWidth,fCurrentY+4);
fCurrentY += fHeight+2;
g.setFont(f3);
g.drawString("Written by Brian Duncan", fLeft, fCurrentY);
fCurrentY += fHeight-2;
g.drawString("Data grid written by Curtis Keisler", fLeft, fCurrentY);
}
.

class ImagePanel extends Panel {
AboutPanel cParent;
public ImagePanel(int X, int Y, AboutPanel argC) {
cParent= argC;
reshape(0,0,X,Y);
} 109 .;

public void paint(Graphics g) {
cParent.cPar~nt !~pl~ch ~lrawBaseImage(this~getGraphicso~ 0, 0, 135, 73);
for(int iLoop=0;iLoop < 17;iLoop~) cParent.cParent.Splash.drawOverlay(iLoop, this.getGraphicsO, 0, 0, 135, 73);
} }

CA 0220926~ 1997-06-27 _ package tcg.control;
/l This example is from the book _Java in a Nutshell_ by David Flanagan.
l/ Written by David Flanagan. Copyright (c) 1996 O'Reilly & ~Csori~tes // You may study, use, modify, and distribute this example for any purpose.
// This example is provided WITHOUT WARRANTY either expressed or implied.
import java.awt.*;
import java.util.~;
public class MllltiT ineT ~hel extends Canvas {
public static final int LEFT = 0; // ~ nment conct~ntc public static final int CENTER= I;
public static final int RIGHT = 2;
protected String[] lines; // The lines of text to display ~" ot~ ~,t~,d int num lines; // The number of lines protected int margin width; // Left and right margins protected int margin height; // Top and bottom margins pl ~ d int line height; ll Total height of the font protected int line_ascent; ll Font height above baseline protected int[] line widths; /t How wide each line is protected int max width; l/ The width of the widest line protected int alignment = LEFT; ll The ~lignmPnt of the text.
ll This method breaks a specified label up into an array of lines.
// It uses the StringTokenizer utility class.
protected void newLabel(String label) {
StringTokenizer t = new StringTokenizer(label, "\n");
num_lines = t.countTokensO;
lines = new String[num lines];
line_widths = new int[num_lines];
for(int i = 0; i < num_lines; it t) lines[i] = t.nextTokenO;
}

// This method figures out how the font is, and how wide each // line of the label is, and how wide the widest line is.
protected void measureO {
FontMetrics fm = this.getFontMetrics(this.getFontO);
// If we don't have font metrics yet, just retum.
if (fm = null) retum;
line_height= fm.getHeightO;
line_ascent = fm.getAscentO;
max_width = 0;
for(int i = 0; i < num lines; i~) {
line_widths[i] = fm.stringWidth(lines[i]);
if (line_widths[i] > max_width) max_width = line_widths[i];
}

// Here are four versions of the cosntrutor.
// Break the label up into separate lines, and save the other info.
public MultiLineLabel(String label, int margin_width, int margin_height, int ~1 ignm~nt) {
newLabel(label); 11 1 CA 02209265 1997-06-27 ~_ this.margin_width = margin_width;
this.margin_heig_t = margin_height;
thic ~lignment = alignment;
}
public MultiLineLabeltString label, int margin_width, int margin_height) {
this(label, margin-widt-h-~ margin_height, LEFl~);
}
public MultiT ineT ~hel(string label, int alignment) {
this(label, 1O, lO, alignment);
}

public MultiT.ineT ~bel(String label) {
this(label, 10, 10, LEFT);
}

// Methods to set the various aLLI ibut~s of the CG. . .l~o public void setT ~ I(String label) {
newLabel(label);
IllLaSUl ~,0;
repaintO;
}

public void setFont(Font f) {
super.setFont(f);
measureO;
repaintO;
}

public void setFol~ol~nd(Color c) {
super.setFol~ d(c);
repaintO;
}

public void setAlignment(int a) { alignment = a; repaintO; }
public void setMarginWidth(int mw) { margin_width = mw; repaintO; }
public void setMarginHeight(int mh~ { margin_height = mh; repaintO; }
public int getAlignmentO { return alignmpnt; }
public int getMarginWidthO { return margin_width; }
public int getMarginHeightO { return margin_height; }
// This method is invoked after our Canvas is first created // but before it can actually be displayed. After we've // invoked our superclass's addNotifyO method, we have font // metrics and can succ~ossfil11y call measureO to figure out // how big the label is.
public void addNotifyO { super.addNotifyO; measureO; }
/I This method is called by a layout manager when it wants to Il know how big we'd like to be.
public Dimension preferredSizeO {
return new Dimension(max width + 2*margin_width, num_lines * line_height + 2*margin_height);
}

Il This method is called when the layout manager wants to know Il the bare minimum amount of space we need to get by.
public Dimension minimllm!~izeO {
return new Dimension(max_width, num_lines * line_height);

- CA 0220926~ l997-06-27 --Il This method draws the label (applets use the same method).
Il Note that it handles the margins and the alignment, but that Il it doesn't have to worry about the color or font--the superclass Il takes care of setting those in the Graphics object we're passed.
public void paint(Graphics g) {
int x, y;
Dirnension d = this.sizeO;
y = line_ascent + (d.height - num_lines * line_height)/2;
for(int i - O; i < num_lines; i++, y += line_height) {
switch(alignment) {
case LEFT:
x = margin_width; break;
case CENTER:
default:
x = (d.width - line_widths[i])/2; break;
case RIGHT:
x= d.width - margin_width - line_widths[i]; break;
}

g.drawString(lines[i], x, y);
}
}

CA 0220926~ 1997-06-27 ,-', ' "

package tcg.control;
import java.awt.*;
irnport java.util.*;

I***********************************************************
Java StringGrid Class Copyright 1996 by Curtis Keisler Modified by Brian Duncan for use in SeekFind.
***********************************************************/
public class StringGrid extends Panel {
Il Selection bar color public static final Color selçctionR~rcolor = new Color(0,0,127);
protected int 1I The number of pixels to use for the row height rowHeight= 10, Il Used in text drawString as the offset for the row rowAscent, Il The current row currentRow = 0, // The left most column leftColumn = 0, // The last sorted column lastSortCol = -1, // The currently selected row selecteA~ow = -1;
protected Vector 1I Vectors of Strings for the columns. The vector need // need not be valid or defined. If so, blanks just // display in the "holesn.
row = new Vector(6,6), // The original data data = new Vector(6,6), // Strings with the text for the column headings.
columnHeading = new Vector(6,6), // Integers for the order of the columns since colurnns can // be moved by the user, the physical order of the colurnns - CA 0220926~ 1997-06-27 -.

ll in the vector may be different than the logical, viewed ll order of the colums.
columnOrder= new Vector(6,6), Il Integers con~ining the current column widths. Initially ll set to the width of the header.
columnWidth = new Vector(6,6);
protected Scrollbar ll The scrollbars on the grid horizScrollbar = new Scrollbar(Scrollbar.HORIZONTAL, l ,0,0,0), vertScrollbar = new Scrollbar(Scrollbar.VERTICAL, l ,0,0,0);
protected~tatic final int columnWidthPad = 6, columnHeightPad = 4;~ont gridFont = new Font("Dialog",Font.PLAIN,l0);

1**********************************************************1 public StringGridO
l*
PROCEDURE
public StringGridO
PURPOSE
StringGrid class constructor { */
superO;
setLayout(new BorderLayout0);
ll Install the scroll bars horizScrollbar.setLineIncrement( l );
vertScrollbar cetT.ineTnrrement(l);
horizScrollbar.setPageIncrement( I );
vertScrollbar.setPageIncrement(l);
add("South",horizScrollbar);
add("East",vertScrollbar);
ll Set the default font setFont(gridFont);
ll Get the needed height of each row rowHeight = getFontMetrics(gridFont).getMaxAscentO+
getFontMetrics(gridFont).getMaxDescentO;
rowAscent = getFontMetrics(gridFont).getMaxAscentO;
} ll StringGrid 1**********************************************************1 public boolean handleEvent(Event e) /* 115 _. CA 0220926~ l997-06-27 PROCEDURE
public boolean handleEvent(Event e) PURPOSE
To handle the horizontal and vertical scroll bar events.
*l {

boolean handled = false;
// Clicked the horizontal scroll bar if (e.target = horizScrollbar) switch(e.id) {
case Event.SCROLL_LrNE_UP:
case Event.SCROLL_LINE_DOWN:
case Event.SCROLL_PAGE_UP:
case Event.SCROLL_PAGE_DOWN:
case Event.SCROLL_ABSOLUTE:
leftColumn = ((Integer)e.arg).intValue();
if (leftColumn < 0) leftColumn = 0;
else if (leftColumn > columnHea~ing Ci7~0 _1) leftColumn = columnHe~ling Ci7f'() -1;
repaintO;
handled = true;
break;
}

else if (e.target = vertScrollbar) switch(e.id) {
case Event.SCROLL _ LrNE_UP:
case Event.SCROLL_L~NE_DOWN:
case Event.SCROLL_PAGE_UP:
case Event.SCROLL_PAGE_DOWN:
case Event.SCROLL_ABSOLUTE:
currentRow = ((Integer)e.arg).intValueO;
if (currentRow < 0) currentRow = 0;
else if (currentRow > row sizeO - I) currentRow=row.sizeO- I;
repaintO;
handled = true;
break;
}

if (handled) return true;
else return super.handleEvent(e);
} // handleEvent /**********************************************************/
public boolean mouseDown(Event evt, int mx, int my) I*
*/
{ 116 CA 0220926~ 1997-06-27 -int x, ll Used to find the column r, ll The clicked row col, ll Search column width, ll The maximum width height; ll The bottom of the headings Integer cwi; ll Column width boolean done = false; ll Loop flag ll Compute the height of the column headings height = rowHeight + columnHeightPad;
width = sizeO.width - vertScrollbar.sizeO.width;
ll If the mouse was clicked within the column headings if ((my <= height) && (mx <= width) ) {
// Determine the column and sort on it.
// Start at the left side x=O;
// Start with the left column col = leftColumn;
done = false;
while (!done) {
ll Are we looking in a valid column?
if ((col < columnWidth.sizeO) && (x < width)) {
ll Get the current column width cwi = (Integer)columnWidth.elementAt(col);
ll Is the mouse on this column?
if (mx <= x + cwi.intValueO + columnWidthPad) {
ll Draw the column heading depressed ll so that the user knows that something ll is happening.
drawColumnHeading(getGraphicsO,x,col,false);
ll Then sort the column sortColumn(col);
done = true;
} else {
col++;
x = x + cwi.intValue() + columnWidthPad;
}

} else done = true;
}

return true;
ll Otherwise, see if we clicked on a row then select it } else //If we double clicked, pass the event up to the parent.
if ((my < sizeO.height - horizScrollbar.size().height) &&
(mx < width) && (my > height) ) {

CA 0220926~ 1997-06-27 --if(evt.clickCount>l) {
getParentO.postEvent(new Event(this,Event.ACTlON_EVENT,"Double"));
return true;
} else {
1/ Compute the selected row selectedRow = currentRow + (my - height) / height;
Il If greater that the max row then it is the max row if (selectedRow > row.size()- I ) selectedRow = row.sizeO-I;
Il Redraw to show the selected row repaint(0);
return true;
}

} else {
return false;
} 11 mouseDown 1**********************************************************1 public void setColumnHeadings(Vector pColumnHeading) PROCEDURE
public void setColumnHeadings(Vector pColumnHeading) PURPOSE
To set the column headings to the given vector of strings.
The widths of the columns are initialized to the width of the headings. Because of this, the procedure should be called before adding and rows to the ~rid.
INPUT PARAMETERS
pColumnHeadings - The Vector of strings containing the column headings.

{ *l FontMetrics fm = getFontMetrics(gridFont);
Il Set the new columns to the passed in ones columnHeading = pColumnHeading;
1/ Compute the column widths based on the column headings computeColumnWidthsO;
Il Set the horizontal scroll bar horizScrollbar.setValues(O,l,O,columnHP~fling.ci7,~0 1);
} 11 setColumnHeadings 1**********************************************************1 public void computeColumnWidths() 118 CA 0220926~ 1997-06-27 ,-i, ..

/*
PROCEDURE
public void computeColumnWidthsO
PURPOSE
To compute the column widths based soley on the widths of the column headings.
{ *l FontMetrics fm = getFontMetrics(gridFont);
Il Clear out any old column widths columnWidth.removeAllElementsO;
Il Loop through each and compute the column widths for (int i = 0; i < COlumnHP?~ neci7f~o;i++) Il Compute the width and insert it into the Il column widths vector.
columnWiflth ~ Fl~ment(new Integer(fm.stringWidth((String)columnHeading.elementAt(i))));
} 11 computeColumnWidths 1**********************************************************1 public void addColumnHeading(String heading) *l {

FontMetrics fm;
fm = getFontMetrics(gridFont);
Il Append the passed in column heading columnHe If line ~ IFIement(heading);
Il Compute the width and insert it into the column Il width vector.
columnWi-lth ~ F~lement(new Integer(fm.stringWidth(heading)));
Il Set the horizontal scroll bar horizScrollbar.setValues(horizScrollbar.getValue(), I, 0,columnHeading.size()-l );
} 11 addColumnHeading /***********************************$**********************/
public boolean addItem(Vector item) * *
{ int cw, 11 Column width i, 11 Loop counter p; 11 Tab position indicator Integer cwi; 11 Integer column width String s; 119 . CA 0220926~ 1997-06-27 ,-, Vector newRow = new Vector(6,6);
l/ Pull out each column for (i = O; i < columnHe~ing ci7~0;i++) newRow.addElement(item.elementAt(i));
row ad-lFlement(newRow);
if (columnWidth != null) {
for (i = O; i < columnWidth.size(); i++) {
cwi = (Integer)columnWidth.elementAt(i);
if (i < newRow.size()) {
s = (String)newRow.elementAt(i);
cw = getFontMetrics(gridFont).stringWidth(s);
if (cw > cwi.intValueO) columnWi-lth cetFl~mentAt(new Integer(cw),i);
}
}

Il Set the veritcal scroll bar vertScrollbar.setValues(vertScrollbar.getValueO, I ,O,row.sizeO- I );
if(sizeO.height > (row.sizeO*rowHeight)) repaintO;
return true;
} ll addItem //Add multiple rows, parm is a vector of vectors public void addltems(Vector item) ( for(int iLoop = O;iLoop < iS~m Ci7f'0; iLoop++) addltem((Vector) item.elementAt(iLoop));
}

public int countItemsO {
return row.sizeO;
}

public void clearO {
row.removeAllElements();
}

public void removeColumnHeadings() {
clear();
columnHeading.removeAllElements();
}

public int selectedO {
return selectedRow;

}

/*****$****************************************************/
private void reverseOrderO 120 CA 0220926~ 1997-06-27 ~-PURPOSE
Reverses the order of the rows. This simulates sorting in the opposite order.
{ */
int i,mid,max;
Vector v;
max = row.sizeO ~ I;
mid = max / 2;
for (i = 0; i <= mid; i++) // Don't swap the same row!
ll Swap the rows v = (Vector)row.elementAt(i);
row ~etF.lom~nt~t(row.elementAt(max- i),i);
row cetF.l~m~nt~t(v,max - i);
}

} ll reverseOrder 1**********************************************************1 public void sortColumn(int sortCol) PROCEDURE
public void sortColumn(int sortCol) PURPOSE
To sort the given column. If the given column was the last one to sort on, then the sort will be in the opposite direction of the previous sort i.e. it will toggle between ~cen~ing and descending order.
INPUT PARAMETERS
sortCol - The column on which to sort.
{

// If we are not sorting on the same column as the last // time, then start in ascending order.
if (sortCol--lastSortCol) reverseOrder();
else // Sort the column quickSort(sortCol,O,row sizeO-I);
// Start at the top of the list currentRow = 0;
// Unselect the selected row selectedRow = - l;

CA 0220926~ 1997-06-27 // Set the vertical scroll bar back to 0 vertScrollbar.setValue(0);
// Save the col number for next time lastSortCol = sortCol;
// Refresh the screen repaint(0);
11 sortColumn 1**********************************************************1 private int compare(int rl, String r2, int c) PROCEDURE
public boolean compare(int rl, int r2, int c);
PURPOSE
To compare the two rows for the given column using the columnType indicator. If a column type indicator is not defined for the column, the col..?al ison is done on a string basis.
INPUT PARAMETERS
rl - The row number of the row in the row vector to compare against r2.
r2 - The row number rl is compared against.
c - The column in the row to be compared.
RETURNS
<Oifrl <r2 0 if rl = r2 >Oifrl>r2 { */
int comparison = 0; /I The outcome of the comparison Il (assumes everything is equal) Vector rv; 11 The row vector.

String src l;
// Get the first row rv = (Vector)row .elementAt(r I );
// Get the column in the first row srcl = (String)rv.elementAt(c);
comparison = srcl.compareTo(r2);
return comparison;
} // Compare /**********************************************************/
private void quickSort(int sortCol, int p, int r) 12 2 CA 0220926~ 1997-06-27 PROCEDURE
private void quickSort(int sortCol, int p, int r) PURPOSE
Implements the famous "Quick Sort" algorithm for sorting the rows on a given column. See the compare function INPUT PARAMETERS
sortCol - The column on which to sort.
p - The first row number in the row Vector to be sorted.
r - The last row number in the row Vector to be sorted.
*l {

if(p<r) {
int q = partition(sortCol,p,r);
quickSort(sortCol,p,q);
quickSort(sortCol,q+ l ,r);
}

} ll quickSort 1**********************************************************1 private int partition(int sortCol, int p, int r) I*
PROCEDURE
private int partition(int sortCol, int p, int r, int dt) PURPOSE
Partitions the array for a quicksort.
INPUT PARAMETERS
sortCol - The column on which to sort.
p - The begining of the partition search.
r - The end of the partition search.
dt - The data type of the column.
RETURN
The row where all rows above are less than the rows below.
*l {

int i = p - l j=r+ I;
Vector v = (Vector)row.elementAt(p);;
String x = (String)v.elementAt(sortCol);
while (true) {
do j__;
while ((compare(j,x,sortCol) > 0));
do i++;
while (compare(i,x,sortCol) < 0); 123 . CA 0220926~ 1997-06-27 if (i <i) {
ll Swap the rows v = (Vector)row.elementAt(i);
row.setElementAt(row.elementAt(j),i);
row.setElementAt(v,j);
} else return j;
}

} ll partition 1**********************************************************1 public void drawCell(Graphics g, int x, int y, int width, int drawCol, int drawRow) /*
PURPOSE
To draw the given cell at the given location on the given graphics object.
*l {

Graphics cg; // Clipped graphics cell Vector v; // Temporary vector used to get the cell String s; // Contents of the cell int sw; // The drawing text width of the cell // used to compute ~lignm~nt offsets.
ll If this is a selected row then draw the selection bar if (drawRow = selectedRow) {
g.setColor(selectionBarColor);
g.fillRect(x,y,width,rowHeight+columnHeightPad-l);
}

ll Draw the grid box for the cell ll Draw the left side of the grid line g.setColor(Color.gray);
g.drawLine(x,y,x,y + rowHeight + columnHeightPad-l);
g.drawLine(x,y + rowHeight + columnHeightPad-l, x + width-l,y + rowHeight + columnHeightPad-l);
if(drawCol--columnWidth.size()- l) g.drawLine(x+width- l ,y,x+width- l, y + rowHeight + columnHeightPad- l );
ll Draw the left side on the left most column if (x == 0) g.drawLine(x,y,x,y + rowHeight + columnHeightPad-l);
ll Use a clipped graphics to draw the text cg = g.createO;
cg.setFont(gridFont);
cg.clipRect(x+l,y+l ,width-2,rowHeight+columnHeightPad-2);
if (row != null) {
ll Get the current row of vectors v = (Vector)row.elementAt(drawRow);

CA 0220926~ 1997-06-27 ~_ ~. ' .

if (v != null) {
Il Is there a value for the column we are on?
if (drawCol < v.size()) {
Il Get the value s = (String)v.elementAt(drawCol);
Il If it is valid, then draw the string if (s != null) {
Il Get the string width sw = cg.getFontMetrics().stringWidth(s);
Il Set the color to black non selected Il or white if selected if (drawRow = selectedRow) cg.setColor(Color.white);
else cg.setColor(Color.black);
cg.drawString(s, x+columnWidthPad/2, y+rowAscent+columnHeightPad/2- 1 );
}
}
}

} 11 drawCell 1**********************************************************1 protected void drawColumnHeading(Graphics g, int x, int drawCol, boolean raised) I*
PROCEDURE
protected void drawColumn(Graphics g, int x, int drawCol, boolean raised) PURPOSE
To draw the given column, starting at the given x position on the given graphics object.
rNPUT PARAMETERS
g - The graphics object on which to draw the column.
x - The x position where the column should be drawn.
drawCol - The index of the column to draw (0 - columnH~ing ci7e()-l) raised - True if the heading is raised, false if it is lowered.
*l {

int w,y,h,shift;
String s;
y=O;
h = rowHeight + columnHeightPad;
1/ Get the column width 12 5 CA 0220926~ 1997-06-27 w = ((Integer)columnWidth.elementAt(drawCol)).intVàiueO
+ columnWidthPad;
Il Draw the raised 3D header g.setColor(Color.lightGray);
g.fillRect(x, y, w, h);
if (raised) { I/ If raised shift= 0;
g.setColor(Color.white);
g.drawLine(x + I, y + 1, x + I, y + h - 3);11 Left g.drawLine(x+2,y+ I,x+w-2,y+ I);//Top g.setColor(Color.gray);
g.drawLine(x+ I,y+h-2,x+w- I,y+h-2);//Bottom g.drawLine(x + w - I, y + h - 3, x + w - I, y + I); // Right Side } else { /l otherwise depress shift= I;
g.setColor(Color.gray);
g.drawLine(x + I, y + I, x + 1, y + h - 3);11 Left g.drawLine(x + 2, y + I, x + w - 2, y + 1);1/ Top g.setColor(Color.white);
g.drawLine(x+ I,y+h-2,x+w- I,y+h-2);//Bottom g.drawLine(x + w - I, y + h - 3, x + w - I, y + I); // Right Side }

/I Draw a black rectangle around this g.setColor(Color.black);
g.drawLine(x,y,x+w- I ,y);
g.drawLine(x,y+h- I ,x+w- I ,y+h- I );
g.drawLine(x,y,x,y+h- I );
// If the last column then draw the right side if(drawCol==columnWidth.size()- I) g.drawLine(x+w- I ,y,x+w- 1 ,y+h- I );
// Draw the column heading text g.setColor(Color.black);
g.setFont(gridFont);
s = (String)columnHeading.elementAt(drawCol);
if (s != null) g.drawString(s,x+columnWidthPad/2+shift,y+rowAscent+columnHeightPad/2+shift-l);
else g.drawString("BAD ! ",x+columnWidthPad/2+shift,y+rowAscent+columnHeightPad/2+shift- 1 );
I/ drawColumnHeading 1**********************************************************/
protected void drawColumn(Graphics g, int x, int drawCol) /*
PROCEDURE
protected void drawColumn(Graphics g, int x, int drawCol) PURPOSE
To draw the given column, starting at the given x position on the given graphics object. 126 CA 0220926~ 1997-06-27 ~-rNPUT PARAMETERS
g - The graphics object on which to draw the column.
x - The x position where the column should be drawn.
drawCol - The index of the column to draw (O - COlumnHea~lillg Ci7PO-I) *l int width, ll The width of the table minus the Il vertical scrollbar width.
y, ll The current y position height, ll The height of the table minus the Il horizontal scrollbar height.
drawRow; ll The current drawing row String s; ll Temporary string Il Compute the drawing room height = sizeO.height - horizScrollbar.sizeO.height;
Il Start at the top y=O;
Il Ensure that the column is in the correct range if ( (drawCol >= 0) && (drawCol < columnWidth.sizeO)) {
Il Get the column width width = ((Integer)columnWidth.elementAt(drawCol)).intValueO
+ columnWidthPad;
Il Clear the background g.setFont(gridFont);
g.setColor(Color.white);
g.fillRect(x,rowHeight+columnHeightPad,width,height);
drawColumnHeading(g,x,drawCol,true);
Il Move to the next row y = y + rowHeight + columnHeightPad;
Il Loop through each row until we are at the bottom of the Il screen or out of rows.
drawRow = currentRow;
while ((drawRow < row.sizeO) && (y <= height)) {
drawCell(g,x,y,width,drawCol,drawRow);
Il Advance to the next row y = y + rowHeight + columnHeightPad;
drawRow++;

} ll drawColumn _ CA 0220926~ 1997-06-27 1**********************************************************1 public void update(Graphics g) PROCEDURE
public void update(Graphics g) PURPOSE
To override the default update so that screen is not erased before the new one is drawn.
{ *l paint(g);
} 1/ update /**********************************************************/
public void paint(Graphics g) PROCEDURE
public void paint(Graphics g) PURPOSE
To display the grid. If the column headings and alignment have not been specified, then nothing is displayed.
lNPUT PARAMETERS
g- The graphics object on which to draw.
{ */
int i, // Loop counters x, 1/ The current x position width, 11 The width of the table height, 11 The height of the table minus the Il horizontal scrollbar height.
drawRow, 11 The current drawing row drawCol; 1/ The current drawing column Image image; // Temporary drawing image so that redraws // are done cleanly.
Graphics ig; // Image's graphics object image = createImage(sizeO.width,size().height);
ig= image.getGraphicsO;
ig.setFont(gridFont);
Il If there are column headings and alignments then draw Il the grid, otherwise, don't bother.
if ( (columnHeading != null)) {
Il Start or, the left side x = O;
Il Loop through each column, until we have reached the Il right side of the screen or we have run out of Il columns. 12 8 CA 0220926~ 1997-06-27 _~

i = leftColumn;
while ((i < columnHe~ling ':i7~'0) && (x < sizeO.width)) {
drawColumn(ig,x,i);
ll Advance to the next column width = ((Integer)columnWidth.elementAt(i)).intValueO
+ columnWidthPad;
x += width;
i++;
}

ll Now, draw the new screen.
g.drawImage(image,O,O,null);
}

ll Compute vertical number of columns and adjust ll the horizontal scroll bar accordingly.
height = sizeQheight - horizScrollbar.sizeO.height -(rowHeight + columnHeightPad);height = Math.round(height / (rowHeight + columnHeightPad));
vertScrollbar ~etT inçTncrement(l );
vertScrollbar.setPageIncrement(height);
} ll paint } ll StringGrid CA 0220926~ l997-06-27 .' ' i ~.~, package tcg.control;
import java.awt.TextField;
import java.awt.Color;

/*******************************************************
* Class: StatusBox * Written by: Brian Duncan * Date:
* Purpose: Extends the TextField class. It is used as a status * window to display the current operation.
*

* The default message is 'Ready'.
*******************************************************/
public class StatusBox extends TextField {

/*******************************************************
* Constructor for StatusBox class. This one allows for * a default of "Ready"
*******************************************************/
public StatusBoxO {
this("Ready");
}

/*******************************************************
* Constructor for StatusBox class. Like other one, except that * it allows a parameter for the initial message.
*******************************************************/
public StatusBox(String sArg) {
super(sArg, 30);
this.setBackground(Color.lightGray);
this.setForeground(Color.blue);
thic cetF-lit~ble(false);

/*******************************************************
* Sets the statusbox message.
*******************************************************/
public void set~t~t lc(String sArg) {
this .setText(sArg);
}

CA 0220926~ 1997-06-27 _ package tcg.control;

import java.awt.*;

/*********************************************************
* Class: ErrorDialog * Written by: Brian Duncan * Date:
* Purpose: This class simulates a popup messagebox.
*********************************************************/
public class ErrorDialog extends Frame {

protected Button button;
protected MnltiT inel ~hel label;
int lines;

I*******************************************************
* Constructor *******************************************************/
public ErrorDialog(String title, String message) {
super(title);
thic cetT ~yout(new BorderLayout(5, 5));
label = new MultiLineLabel(message,30,30, Label.CENTER);
this.add("Center", label);

/lUsing a separate panel to center the button horizontally, llbut keep it at the bottom of the frame.
Panel p = new PanelO;
p.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
button = new Button("OK");
p.add(button);
this.add("South", p);
Il Resi~ the window to the preferred size of its components this.pack();
}

I*******************************************************
* Kill the window when the button is clicked *******************************************************l public boolean action(Event e, Object arg) {
if(e.target == button) {
this.hide();
((Component)getParentO).requestFocusO;
this.disposeO;
return true; 131 CA 02209265 1997-06-27 ~_ else return false;

- CA 0220926~ 1997-06-27 ~_ package tcg.control;

import java.awt.*;

I*********************************************************
* Class: ErrorDialog * Written by: Brian Duncan * Date:
* Purpose: This class simulates a popup messagebox.
*********************************************************/
public class ErrorDialog extends Frame {

protected Button button;
protected MnltiT in~oT ~bel label;
int lines;

I*******************************************************
* Constructor *******************************************************/
public ErrorDialog(String title, String message) {
super(title);
this.setLayout(new BorderLayout(5, 5));
label = new MultiLineLabel(message,30,30, Label.CENTER);
this.add("Center", label);

//Using a separate panel to center the button horizontally, /Ibut keep it at the bottom of the frame.
Panel p = new PanelO;
p.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
button = new Button("OK");
p.add(button);
this.add("South", p);
Il Resize the window to the preferred size of its components this.packO;
}

I*******************************************************
* Kill the window when the button is clicked *******************************************************/
public boolean action(Event e, Object arg) {
if(e.target == button) {
this.hide();
((Component)getParentO).requestFocusO;
this.dispose(); 13 3 return true;

else return false;

CA 0220926~ 1997-06-27 --t package tcg.homeconnection;
import java.awt.*;
import java.util.*;

I*******************************************************
* Class: ValueSingle * Written by: Brian Duncan * Date:
* Purpose: This class extends ValuePanel (Panel) to provide * a singleLineEdit panel.
*******************************************************l public class ValueSingle extends ValuePanel {
TextField Valuel;

I*******************************************************
* Constructor: Parameter is Category Name *******************************************************/
public ValueSingle(String argS) {
name = argS;
Valuel = new TextField(20);
Valuel cetRarkpround(color.white);
setR~rl~p.round(Color.lightGray);
add("Valuel", Valuel);
}

I*******************************************************
* Returns the value of the SLE. in a vector. If empty, * returns "None" in the vector.
*******************************************************l public Vector getValuesO {
Vector Values = new Vector(l);
if(Value I .getTextO.trimO.lengthO == 0) {
V~ s ~ Flrment("None");
} else {
Vall-es ad~F.lement(Valuel.getText());
return Values;
}

/************************************~**~***************
* Did this so the parent had a consistent method to call * between value panels.
*******************************************************l public void deselectAII0 clearAII0;
}

I*******************************************************
* wipes out the SLE. 13 5 CA 0220926~ l997-06-27 --~

*t***********************************$*********~********/
public void clearA110 {
Value I .setText("");
}

I*******************************************************
* If the mouse leaves the SLE, notify anyone who's listening **~****************************************************1 public boolean handleEvent(Event evt) {
if(evt.id -- Event.MOUSE_EXIT && evt.target instanceof TextField) {
this.postEvent(new Event(this,10001,"ue_selecte~itPrn"));
}

return super.handleEvent(evt);
}

I*******************************************************
* Reshapes and re-lays out the cont~inf~r *******************************************************l public void reshape(int x, int y, int w, int h) {
super.reshape(x, y, w, h);
getLayoutO.layoutContainer(this);
}
}

CA 0220926~ 1997-06-27 package tcg.homeconnection;
import java.awt.*;
import java.util.*;

I*******************************************************
* Class: ValueRange * Written by: Brian Duncan * Date:
* Purpose: This class extends ValuePanel (Panel) to provide * a range, comprising of two textFields.
*******************************************************/
public class ValueRange extends ValuePanel {
TextField LowLabel, ~TiphT abel;
RangeText Valuel, Value2;
int whichFocus = I;

I*******************************************************
* Constructor: Parameter is Category Name *******************************************************l public ValueRange(String argS) {
name = argS;
setLayout(null);
Valuel = new RangeText(5, this, 1);
Valuel cetRackground(Color.white);
Value2 = new RangeText(5, this, 2);
V~hl~.cPtR~rL ground(Color.white);
LowLabel = new TextField("Min:",4);
LowLabel cetRarkEround(color.lightGray);
LowLabel cetF~lit~hle(false);
HighLabel = new TextField("Max:",4);
HighLabel cetRarkground(color.lightGray);
HighLabel cetF~lit~ble(false);
setRIrkground(Color.lightGray);
add("LowText", LowLabel);
add("LowRange", Value I );
add("HighText", HighLabel);
add("HighRange", Value2);
}

I*******************************************************
* Override reshape, to force sizes of the labels and * textfields.
*******************************************************l public void reshape(int x, int y, int w, int h) {
super.reshape(x,y,w,h);
LowLabel.reshape(w/2 - 55,h/2 - 25, 40, 20); 13 7 . CA 0220926~ 1997-06-27 HighLabel.reshape(w/2 - 55, h/2+5,40,20);
Value I .reshape(w/2- 1 0,h/2 - 25, 60, 20);
Value2.reshape(w/2- 1 0,h/2+5 ,60,20);
}

I*******************************************************
* Override paint to draw a box around the panel.
*******************************************************l public void paint(Graphics g) {
super.paint(g);
g .setColor(Color.black);
g.drawRect(0,0,thic ci7~0 width-l, this.size().height-l);
}

I*******************************************************
* Returns the low and high values of the range in a Vector.
* If the low value is empty, it sets the value to the high value.
* If the high value is empty, it sets the value to the low value.
* If the low value is higher than the high value, it returns 'None'.
*******************************************************l public Vector getValuesO {
Vector Values = new Vector(l);
String Vall, Val2;
Val I = Value I .getTextO.trimO;
Val2 = Value2.getTextO.trimO;

Vall = (Vall.lengthO > 0) ? Vall: "O";
Val2 = (Val2.1engthO > 0) ? Val2: "0";
if (Vall.equals("O") && Val2.equals("0")) {
Valuçs ~ lFlpment(~None~
} else {
if(Val I .lengthO < V~l~ lengthO) {
String Spaces= " ";
Vall = Sp~ces cubstring(o~ Val2.1engthO - Vall.length())+Vall;
}

if(Val I .compareTo(Val2) <= O) {
Valll~s ~rlrlFlement(vall+"-"+val2);
} else {
Valu~s.~clrlF.lement("None");
}
return Values;

}

/*******************************************************
* Did this so that the calling method has the same call * for all value panels.
*******************************************************l public void deselectAllO { 13 8 CA 0220926~ 1997-06-27 ,f clearAI10;
}

I*******************************************************
* Clears out the textFields.
*******************************************************/
public void clearA110 {
Value I .setText("");
Value2 .setText("");
}

I*******************************************************
* Don't allow any keystrokes except A-Z, a-Z, Tab, * Rarl~r~re, delete, and 1-0 *******************************************************l public boolean keyDown(Event evt, int key) {
if((key > 31 && key < 48) 11 (key > 57 && key < 92) 11 (key > 92 && key < 127)) {
return true;
} else return false;
}

I*******************************************************
* Check for tab, if so, switch to the next textfield.
*******************************************************l public boolean keyUp(Event evt, int key) {
if((char) key == '\t') {
switchFocus();
this.postEvent(new Event(this,10001,"ue_selecte~item"));
}

return false;
}

I*******************************************************
* If the mouse moves out of the textfields, notify anyone * who cares.
*******************************************************l public boolean handleEven~(Event evt) {
if(evt.id = Event.MOUSE_EXlT && evt.target instanceof TextField) {
this.postEvent(new Event(this, 10001 ,"ue_selecte~lits~m ~
}

return super.handleEvent(evt);
}

I*******************************************************
* If Toggle focus between the textfields. This allows * Tabbing functionality.
*******************************************************l public void switchFocus() {
if (whichFocus = I) {
Value2.requestFocusO;
whichFocus = 2;
} else {
Value I .requestFocusO; 13 9 .. CA 0220926~ l997-06-27 -:.

whichFocus= I;
}
}

/*******************************************************
* Class: RangeText * Written by: Brian Duncan * Date:
* Purpose: This class extends TextField, and was written * to have a textfield that has a tag value.
*******************************************************l class RangeText extends TextField {
ValueRange cParent;
int ID;

I*******************************************************
* Constructor: Length, Parent, Tag #
*******************************************************l public RangeText(int length, ValueRange par, int argI) {
super(length);
cParent = par;
ID = argI;
}
}

CA 0220926~ l997-06-27 r_ package tcg.homeconnection;
import java.awt.*;
import java.util.*;

/****************************************************
* Interface: ValuePanel * Written by: Brian Duncan * Date:
* Purpose: This interface provides method declarations for the * value panels: ValueSingle, ValueRange, and ValueDynamicList.
****************************************************l public abstract class ValuePanel extends Panel{
protected String name;
//abstract method can handle these.
public String getNameO {
retum name;
};
/IJust stubbed these methods, some panels need 'em, some don't.
public void a~ Tt~mc(Vector ArgV) { }
public int getMaxWidthO { retum O; }
public void setNeedsRefresh(boolean argB){}
public boolean getNeedsRefreshO { retum false; }
//AII value panels need these, SeekFind relies on 'em.
public abstract void clearAI10;
public abstract Vector getValuesO;
public abstract void deselectAI10;
}

. CA 0220926~ 1997-06-27 package tcg.homeconnection;
import java.util.*;
import java.awt.*;

/*******************************************************
* Class: ValueDyn~micT ict * Written by: Brian Duncan * Date:
* Purpose: This class extends ValuePanel (Panel) to provide * A List with ~ ition~l filnction~lity, in- In~ling p~ uisile * Proc~c~in~.
*******************************************************l public class ValueDynarnicList extends ValuePanel {
//The listbox List Listl;
//Label to indicate to the user that there is a p.~ ui~
//Category.
Label preLabell, preLabel2;
//The Category Name of the pl ~,.e.~uiai~e (if any) String ~ ui ~
//Need this to toggle between the F~ ui~ panel and the //List panel CardLayout layout;
//~nrlic~t-lr that tells the calling method that this panel' //needs refreshing (IJpdating the list).
boolean needsRefresh = false;
//lndicates whether or not the message is being shown.
boolean messageShown = false;

/*******************************************************
* Constructor.
* argS: Category name of this panel's parent.
* argS2: l~.e~lui~ CategoryName *******************************************************/
public ValueDynamicList(String argS, String argS2) {
Panel messagePanel = new PanelO;
messagepal~cl.setLayout(new GridLayout(4, 1 ));
name = argS;
pl~ Uisil~ = argS2;
layout = new CardLayout(l, I);
setLayout(layout);
Listl = new List(lO, true);
setRacL-ground(Color.lightGray);
add("List", Listl);
//If there's a prerequisite, add prerequisite message.

CA 0220926~ 1997-06-27 -- .
' '..

if(prerequisite.lengthO > ~) {
preLabell = new Label("You must choose a ",Label.CENTER);
preLabel I .setFont(new Font("TimesRoman",Font.BOLD, 14));
preLabel2 = new Label(prerequisite+" first.",Label.CENTER);
prPT ~bel'~ cPtFont(new Font("TimesRoman",Font.BOLD,14));
I/Add a blank label to top and bottom, to center the l/two me~nineful ones.
messagePanel.add(new Label(""));
messageP~nPI a~l~l(preLabel I );
messageP~nPI ~I(preLabel2);
messageP~nPI ~d~1(new Label(""));
add("Message",messagePanel);
/lIf prerequisite, the prerequisite must be shown //initially, until the pie.~.luisiL~ caetgory is //chosen.
Iayout.show(this, "Message");
messageShown = true;
}
}

/*$*****************************************************
* Constructor. Use to default Prerequisite to "".
* argS: Category name of this panel's parent.
*******************************************************/
public ValueDynamicList(String Name) {
this(Narne, "");

}

/*******************************************************
* Adds a vector of items to the list.
*******************************************************l public void ~Al1Tt~prnc(vector ArgV) {
for(Enumeration e = ArgV.elementsO;e.hasMoreElements0;) Listl ad~lTtPm((String)e.nextElement0);
//If this is a child category, show the list, now that //the prerequisite category has been chosen.
if(prerequisite.lengthO > ~) {
layout.show(this, "List");
messageShown = false;
}

I*******************************************************
* Return a vector of the selected items, or "None" as the * only element if none are selected.
*******************************************************l public Vector getValuesO {
String[] Items;
Vector Values; 14 3 ~ CA 0220926~ l997-06-27 .

Items = Listl.getSelectedItemsO;
Values = new Vector(Items.length);
fo~int iLoop=O; iLoop < Tt~mclPn~th, iLoop++) V~l-.es ~d~Fl~ment(ItemstiLoop]);
if( V~lu~s Ci7f'0 = O) {
V~h-~s ~ Fl~ment(~None~
}

return Values;
}
/*******************************************************
* Sets the needsRefresh flag.
*******************************************************/
public void setNeedsRefresh(boolean argB) {
needsRefresh = argB;
/Mo ahead and switch to the list, because we know that //It will be populated as soon as the user sees this /tanyway.
if(needsRefresh) {
layout.show(this, "List");
messageShown = false;
}
}

I*******************************************************
* Returns the needsRefresh flag *******************************************************l public boolean getNeedsRefreshO {
return needsRefresh;
}

/*******************************************************
* Clears all items from the list. If this is a child * category, show the p~ ui~iLe message.
*******************************************************t public void clearAI10 {
Listl ~e!Tt~mc(O,Listl.cou,lLI~ sO-l);
if(prerequisite.lengthO ~ ~) {
layout.show(this,"Messagen);
messageShown = true;
}

setNeedsRefresh(false);
}

/*******************************************************
* Deselects all selected items from the list.
*******************************************************l CA 0220926~ 1997-06-27 :

public void deselectAll0 {
int iLoop;
for(iLoop = 0; iLoop < Listl countTtf~mc(); iLoop++) {
Listl .deselect(iLoop);
}
}

/*******************************************************
* Returns the String width of the widest item in * the list.
*******************************************************/
public int getMaxWidthO {
int temp, maxWidth = 0;
FontMetrics fm = getFontMetrics(this.getFontO);
for(int iLoop=0;iLoop<Listl .con~llT~ O;iLoop++) {
temp = fm.stringWidth(Listl.getItem(iLoop));
if( temp > maxWidth) maxWidth = temp;
}

return maxWidth;

}
I*******************************************************
* Implemented to notify anybody watching that an Item was * selected.
*******************************************************l public boolean handleEvent(Event evt) {
if (evt.id = Event.LIST_SELECT 11 evt.id -- Event.LIST_DESELECT) {
1/ ((Component)getParentO).handleEvent(new Event(this,lOOOl,"ue_selecterlitçm"));
this.postEvent(new Event(this,l0001,"ue_selectç~1it~r "));
}

return super.handleEvent(evt);
}

I*******************************************************
* Reshapes and re-lays out the container *******************************************************/
public void reshape(int x, int y, int w, int h) {
super.reshape(x, y, w, h);
getLayoutO.layoutContainer(this);
}
I*******************************************************
* Override paint to draw a box around the panel.
*******************************************************/
public void paint(Graphics g) {
super.paint(g);
//Only draw the box if the prerequisite message is //being shown.
if(messageShown) { 14 5 CA 02209265 l997-06-27 --g.setColor(Color.black);
g.drawRect(O,O,thic ci7~0 width 1, this.sizeO.height-l);
}
}

. CA 0220926~ l997-06-27 .-package tcg.homeconnection;

importtcg.homeconnecti-n *;
import java.awt.*;
import java.util.*;

/**********************************************************
* Class: CategoryPanel * Written by: Brian Duncan * Date:
* Purpose: A list eytrncion that displays a list of * category headers, keeping track of their ~csoci~tçd * category objects.
* along with an array of m~tr~lin~ lrd category * objects.
**********************************************************l public class CategoryPanel extends Panel {
public List listl;
Vector Ca~goliei, /**********************************************************
* CollaLI u~,lul for the CategoryPanel.
*
* Accepts one integer parameter that specifies how many * list items should be displayed on the screen at the s arne * time.
**********************************************************l public CategoryPanel(int ArgI) ~

setLayout(new BorderLayoutO);
listl = new List(10, false);
listl cetR~r~ground(Color.white);
add("Center",listl);
Categories = new Vector(ArgI);
}

I**************************************************
* Adds a category to the list. Creates a new category object **************************************************l public void addCategory(String ArgS1, String ArgS2, String ArgS3, String ArgS4, String ArgS5) {
listl .addItem(ArgS2);
Categories ~ Fl~rnent(new Category( ArgS1, ArgS2, ArgS3, ArgS4, ArgS5 ));

}

I**************************************************

CA 0220926~ 1997-06-27 * Returns the ~ccoci~tpd value panel of the category * name passed in.
**************************************************l public ValuePanel getValuePanel(String ArgS) {
Category whichOne;
ValuePanel pPanel=null;
whichOne = getCategory(ArgS);
if(whichOne != null) pPanel = whichOne.getPanelO;
return pPanel;
}

I**************************************************
* Returns a category object that collei~,onds to the item #
* passed in.
**************************************************l public Category getCategory(int ArgI) {
return (Category) Categories.elementAt(ArgI);
}

I********************************************************
* Returns a category object that corresponds to the category * name passed in.
********************************************************l public Category getCategory(String ArgS) {
Category whichOne = null;
for(int iLoop=0; iLoop < Categories.sizeO; iLoop++) {
whichOne = (Category) Categories.elementAt(iLoop);
if(whichOne.getNarneO .equals(ArgS)) break;
}

return whichOne;
}

/**
* Returns an array of all category objects in the list.
*/

public Vector getAllCategoriesO {
return Categories;
}

/**
* Sets the app. o~l ;at~ category List item based on index.

,_ CA 0220926~ 1997-06-27 ._ public void selectCategory(int argI) {

list l .select(argI);
}

/**
* Sets the dpl)lOIJlia~e category List item based on name.
*l public void selectCategory(String ArgS) {
String header;
Category whichOne;
for(int iLoop=0;iLoop < C~,go, ics.size(); iLoop++) {
if(getCategory(iLoop).getNameO.equals(ArgS)) listl .select(iLoop);
}

/**
* Unselects all selected items in all categories.
*l public void deselectAI10 {
for( Enumeration e = Categories.elementsO; e.hasMoreElementsO; ) ((Category) e nçYtFl~ment0) deselectAll0;
}

public int countCategoriesO {
return listl.conntTt~-mc0;
}

public int getMaxCatWidth0 {
int temp, maxWidth = 0;
FontMetrics frn = getFontMetrics(this.getFontO);
for( Enumeration e = Categories.elementsO; e.hasMoreFlementc0;) {
temp = fm.stringWidth(((Category) e n~ytFlemPnt()).getHeader0);
if( temp > maxWidth) maxWidth = temp;
return maxWidth;
}

public int getMaxValueWidth0 {
int temp, maxWidth = 0;
for( Enumeration e = Categories.elementsO; e.hasMoreElementsO;) {
temp = ((Category) e.nextElementO).getPanel0.getMaxWidth0;
if( temp > maxWidth) maxWidth = temp;
return maxWidth;
}

/**************************************************
* Returns a Vector of all categories that have a 14 9 CA 0220926~ l997-06-27 . , .

* prerequisite category of the one passed in **************************************************l public Vector getPrerequicites(String argS) {
Vector parents = new VectorO;
Category whichOne;
for(Enumeration e=Categories.elements(); e.hasMoreElementsO; ) {
whichOne = (Category) e.nextElement();
if(whichOne.getPrerequisiteO .equals(argS)) parentC ~d~ Pment(whichOne);
}

return parents;
}

public void reshape(int x, int y, int w, int h) {
super.reshape(x, y, w, h);
getLayout().layoutContainer(this);
}

/************************************************
* Removes all CaL~gOI ies from the CatPanel object.
************************************************/
public void removeAllCategoriesO {
Categories.removeAllElementsO;
listl .clearO;
}
}

CA 0220926~ 1997-06-27 _ package tcg.homeconnection;
import tcg.homeconnection.*;
import java.awt.*;
import java.util.Vector;

I***********************************************************
* Class: Category * Written by: Brian Duncan * Date:
* Purpose: This class represents a dynamic category object.
* A category is a search criterion that the user can use * to formulate a query.
* This object contains a value panel that's one of four types:
* Single, Range, DynamicList, StaticList ***********************************************************l public class Category {
//The value panel that's associated with this category ValuePanel pValuePanel;
//The category Name - Not to be confused with the Header String Name;
//Type of category - Single, Range, DynamicList, StaticList String sType;
//Max length of the category entry field(s).
int iLength;
//Header of this category - Shows up on the Category Panel.
String sHeader;
//The prerequisite Category name, if any, for this category.
String prerequisite;

I***************************************************
* Constructor for the Category Class * The first parameter of this Constructor specifies the Category Name, * 2nd is Header, 3rd is Length, 4th is type, 5th is pre-requisite category.
***************************************************l public Category(String ArgSI, String ArgS2, String ArgS3, String ArgS4, String ArgS5) {
Name = ArgS 1;
sHeader= ArgS2;
iLength = Integer.valueOf(ArgS3).intValueO;
sType = ArgS4;
prerequisite = ArgS5;
//Create the valuePanel object for this category, based //on category type.
if (sType.equals("Single")) pValuePanel = new ValueSingle(Name); 151 CA 0220926~ 1997-06-27 else if( sType.equals("Range")) pValuePanel = new ValueRange(Name);
else if( sType.equ~lc("Dyn~miçT ict'l) 1I sTyFe eql~lc("StaticList")) pValuePanel = new ValueDynamicList(Name, prerequisite);
else pValuePanel = new ValueSingle(Name);
}

I*************************************************
* Returns the maximum allowed length *************************************************l public int getT ~ngthO {
return iLength;
}

I*************************************************
* Returns the category type **~**~***********************
public String getTypeO {
return sType;

}

I*************************************************
* Returns the valuePanel object associated with this * category *************************************************l public ValuePanel getPanelO {
retum pValuePanel;
}

I*************************************************
* Returns the name of this category *************************************************l public String getNameO {
return Name;
}

I*************************************************
* Returns the display header for this category *************************************************l public String getHeaderO {
return sHeader;
}

I*************************************************
* Returns the values in the ValuePanel associated with this * category. It does this by calling the getValues() method * of the valuePanel 15 2 --. CA 0220926~ 1997-06-27 * ~see tcg.homeconnPction ValueSingle#getValues * ( ~see tcg.homeconnection.ValueRange#getValues * (~,see tcg.homeconnection.ValueDynamicList#getValues * (~see tcg.homeconnection.V~ eSt~ticList#getValues *************************************************l public Vector getValuesO {
return pValuePanel.getValues();
}

/*******************************************************
* Adds selection items to the a~"ol,lial~ valuepanel.
*******************************************************l public void ~dfl~t~rnc(Vector ArgV) {
pValuePanel ~d~l~t~rnc(Argv);
}

I*******************************************************
* Clears all selection items from the a~plopfiate v~l-lep~-lPI
*******************************************************l public void clearAIIO {
pValuePanel.clearAIIO;
}
I*******************************************************
* Deselects all selection items from the appropriate valuepanel.
*******************************************************l public void deselectAIIO {
pValuePanel dPce!~ctAIIO;
}

I********************************************************
* Sets the 'needsRefresh' flag.
* Does this by calling the appropriate valuepanel's setNeedsRefreshO
* method.
********************************************************/
public void setNeedsRefresh(boolean argB) {
pValuePanel.setNeedsRefresh(argB);
}

I****************************************************
* Gets the 'needsRefresh' flag.
* Does this by calling the appropriate valuepanel's getNeedsRefreshO
* method.
****************************************************l public boolean getNeedsRefreshO {
return pValuePanel.getNeedsRefresh();
}

I****************************************************
* Get's Prerequisite category narne, if any.
**************$*************************************/
public String getPrerequisiteO { 153 -~ CA 02209265 l997-06-27 --} return prerequisite;

-- CA 0220926~ 1997-06-27 ,~

package tcg.tools;
import java.io.*;
import java.util.*;
public class Manipulation {
/** This class works similar to Perl's 'join'. It takes a * separator string, and a vector, and joins them all * together, separating them with the separator. It * Retums them all as a string.
*l public static String join(String ArgS, Vector ArgV) {
Enumeration e = ArgV.elementsO;
String joined = "";
if(!ArgV.isEmptyO) {
joined = (String) e nPYtFlPrnent0;
while~ e.hasMoreElementsO ) joined += ArgS + (String) e.nextElement();
return joined;
}

/* * This class is just a front end for the above join method.
* It takes a character instead of a string as a separator.
*/
public static String join(char ArgC, Vector ArgV) {
return join( String.valueOf(ArgC), ArgV);

}

/** Front-end function for the Split method. This one takes character and converts it to string.
*/
public static Vector split(char ArgC, String ArgS) {
return split(String.valueOf(ArgC), ArgS);
}

/** This method imitates the perl 'Split' function . It splits * apart a string into a vector of strings based on a * particular separating character.
*l public static Vector split(String ArgS I, String ArgS2) {
Vector items;
int nextPos;
items = new VectorO;
while(ArgS2.1engthO > ~) {
nextPos = ArgS2.indexOf(ArgS l);
if(nextPos < 0) {
itPrnc ~rl(lF.lPrnent(ArgS2); 155 -- CA 0220926~ 1997-06-27 ArgS2 = "";
} else {
itPmC ~ArlF,lement(Arg~ cubstring(O,nextPos));
ArgS2 = Arg~ cnbstring(nextpos+Args I .length());
}
}

return items;
}

/*****************************************************
* This gets the value of a particular tag in the passed in * .ini file, and returns it.
* This version doesn't worry about group na~nes.
*****************************************************l public static String getINIString(String filPn~rne, String tag) {
File f;
FileInputStream ffn;
D~t~Tnrut.~tream dln;
String line;
f= new File(filename);
try {
fln = new FileInputStream(f);
dln = new DataInputStream(fIn);
//Look for tag in file. Don't come back until you get it or //EOF.
do {
line = dIn.readLine();
} while((line != null) && line.indexOf(tag) == -1);
if(line != null) line = line.substring(line.indexOf('=')+ I ).trimO;
if(line=null) Iine= "none";
return line;
} catch(lOException e) {
System.out.println("Unable to open INI File!\n");
return null;

}
I*****************************************************
* This gets the value of a particular tag in the passed in * .ini file, and returns it.
* This version does it based on group name.
*****************************************************l public static String getINlString(String filename, String group, String tag) {
File f; 15 6 - CA 0220926~ 1997-06-27 i-FileInputStream fln;
DatalnputStream dln;
String currGroup = "";
String line;
String returnValue = null;
f= new File(filename);
try {
fln = new FilelnputStream(f);
dln = new DatalnputStream(fln);
//Look for tag in file. Don't come back until you get it or //EOF.
while((line = dIn.readLineO) != null) {
if(line.startsWith("[") && line.endsWith("]")) {
//This is a group header.
if(!currGroup.equals(group)) {
currGroup = line.substring( I ,line.lengthO- 1 );
continue;
} else //The group header we needed is over, stop.
break;
}

if(line.indexOf(tag) != -I && currGroup.equals(group)) {
returnValue = line.substring(line. indexOf('=')+ I ) .trimO;
break;

if(returnValue=null) returnValue= "none";
return returnValue;
catch(lOException e) {
System.out.println("Unable to open INI File!\n");
return null;
}
}

/** This method pads the passed-in s~ing with spaces until * it is the specified length, then returns the modified string.
*l public static String padSpaces(String ArgS, int Argl) {
String Spaces = " ";
if(ArgS.lengthO > Argl) return ArgS;
else return ArgS + Spac~os cubstring(o~ Argl-ArgS.leng~);
}

-- CA 0220926~ l997-06-27 --/** This method pads the passed-in string with zeros until * it is the specified length, then returns the modified string.
*/
public static String padZeros(String ArgS, int Argl) {
return "000000000000000".substring(0,ArgI-ArgS.length())+ArgS;
}

/** This method counts the occurrences of a substring inside * a string, then returns the count.
*l public static int countOccurrences(String ArgS, String ArgS2) {
int next = 0;
int count = 0;
while (next != -1) {
next= ArgS.indexOf(ArgS2, next+l);
if (next != - I ) count++;
return count;
}

- CA 0220926~ 1997-06-27 ,~
~pe~lx B
import java.io.*;
import java.net.*;
import java.awt.*;
import java.util.*;
import tcg.tools.*;
import jet.connect.*;
public class SFServer extends Thread {
public final static int DEFAULT_PORT = 7777;
protected int port;
protected ServerSocket listen socket;
protected StartCol startCol;
public File f;
public RandomAccessFile lOut;
public Vector xrefCategory;
public Hashtable xrefColumn, xrefType, xrefLength;
public Hashtable xrefHeader, xrefColType, xrefPrerequisite;
public DbEnv dbenv = null;
public DbDbc dbcon = null;
public Hashtable iniParms;
public ThreadHandler handler;
public Frame frame;
public Label users, threads;
//Exit with an error message, when an exception occurs.
public static void fail(Exception e, String msg) {
System.out.println(msg+":"+e);
System.exit(1);
}

//Create a ServerSocket to listen for connections on; start the thread.public SFServer(int port, boolean isHub) {
//Create out server thread with a name.
super("Server");
if(port = 0) port = DEFAULT_PORT;
this.port = port;
f= new File("Usage.log");
try {
lOut = new RandomAccessFile(f, "rw");
lOut.seek(lOut.length0);
} catch(lOException e) {
System.out.println("Unable to open Usage file.\n");
}

//Populate the category information populateXRefO;
//Populate the database access variables;
populateDBlnfoO;
//Create and open an ODBC Connection while(true) {
try { 1 5 9 - CA 0220926~ 1997-06-27 ---dbenv = DbEnv.SQLAllocEnvO;
break;
} catch(DbSqlException e) {
}
}

//Call the odbc driver and populate the column data type hashtable if (!isHub) getColTypesO;
try {
listen socket = new ServerSocket(port);
} catch (IOException e) {
fail(e, "Exception creating server socket");
/I Create a thread group for our conn~ctionc System.out.println( Server: liseing on port " + String.valueOf(port));
//Create a window to display our connections in frame = new Frame("Seek&Find: "+String.valueOf(port));
f~rn~ setT ~yout(new GridLayout(2,2));
fiame.resize(200, l00);
users = new Label("");
threads = new Label(nn);
fr~me ~d-l("Label l",new Label("Connections:"));
frame.add("Users",users);
fr~me ~d~i("Label 2",new Label("Threads:"));
frame.add("Threads",threads);
handler = new ThreadHandler(this);
// f.add(handler);
// frame.showO;
// Create a thread to kickoffthe COL request at the // d~)plU~lidLe time.
if(!isHub && !(getINI("HUBURL").equals("none")) && !getINI("COLLECTTIME").equals("0")) startCol = new StartCol(this);
// Start the server listening for connections.
this.startO;
}

public void setStat(int iUsers, int i~hreads) {
users.setText(String.valueOf(iUsers));
threads.setText(String.valueOf(iThreads));
//The body of the server thread. Loop forever, listening for and //accepting conenctions from clients. For each connection, //create a Connection object to handle com~n--nic~tion through the //new Socket. When we create a new connection, add it to the //Vector of connections, and display it in the List. Note that we //use synchronized to lock the Vector of connections. The Vulture CA 0220926~ 1997-06-27 _ //class does the same, so the vulture won't be removing dead //connections while we're adding fresh ones.
public void run() {
try {
while(true) {
Socket clientSocket = listen_socket.acceptO;
while(!handler.startClient(clientSocket)) {
System.out.print("fail! ");
}
catch (IOException e) {
fail(e, "Exception while listening for connections");
}
}

/** This method populates the XREF vectors from the * XREF.DAT file.
*/
public void populateXRefO {
File f;
FileInputStream fIn;
DataInputStream dIn;
String line, category, column, type, length, header, prerequisite;
int Index, ColIndex, TypIndex, T . nTn~lex, HeadIndex;
f= new File("xref.dat");
line= "First";
try {
fIn = new FileInputStream(f);
dIn = new DataInputStream(fIn);
xrefCategory = new Vector();
xrefColumn = new HashtableO;
xrefType = new HashtableO;
xrefHeader = new HashtableO;
xrefLength = new HashtableO;
xrefColType = new HashtableO;
xrefPrerequisite = new Hashtable();
while(line != null) {
line = dIn.readLineO;
if(line != null) {
Index = line.indexOf('=');
if(Index > O) {
category= line.substring(O,Index).trim();
line = line.substring(lndex+l) trimO;
//Column, Type, Length, Header ColIndex = line.indexOf('l');
TypIndex = line.indexOf('l', ColIndex+l); 161 f CA 0220926~ 1997-06-27 r-T PnTndl?x = line indexOf('l', Typlndex+l);
Headlndex = line.indexOf('l', I .onTn~i~oy+l);
column = line.substring(0, ColIndex).trimO;
type= line.substring(Collndex+l, Typlndex).trimO;
length = line.substring(Typlndex+l, LenIndex).trimO;
if(H~Tn~x > 0) {
header= line.substring(l ~nTnd~x+l~ He~Tn~Y).trim0;
prerequisite= line.substring(He~lTn~lex+l).trim0;
} else {
header= line cubstring(T.Pnln~lPY+I) trimO;
prerequisite= "";
}

xrefCategory ~ F.l~ment(category);
xrefColumn.put(category, column);
xrefType.put(category, type);
xrefLength.put(category, length);
xrefHeader.put(category, header);
xrefPrerequisite.put(category, pl~ uisil~);

}
} catch(IOException e) {
System.out.println("Unable to open XReference File!\n");
}

/** This method determines the data type of each column in the * XREF.DAT file.
~1 public void getColTypesO {
int iCount;
String genType;
DbColDesc colDesc;
DbDbc dbcon = null;
DbStmt dbstmt = null;
DbVarChar data[] = new DbVarChar[20];
Vector columns;
String sqlString;
Enumeration eCat;
eCat = xrefCategory.elementsO;
columns = new Vector();
while( eCat.hasMoreElementsO ) colllnnnc ~ Flement(xrefcolumn~get((string)ecat~nextElemento));
sqlString = "SELECT DISTINCT "+getINI("lDCOLUMN")+",";
sqlString += Manipulationjoin(",",columns); 162 CA 0220926~ 1997-06-27 -' sqlString += " FROM "+getINl("DBTABLE");
//Connect to ODBC Driver while(true) {
try {
dbcon = dbenv.SQLAllocConnect0;
dbcon.SQLConnect(getINI("DATASOURCE"),getINI("USERID"),getINI("PASSWORD"));
dbstmt = dbcon.SQLAllocStmtO;
//Execute the SQL Statement dbstmt.SQLExecDirect(sqlString);
break;
} catch(DbSqlException e) {
}
}

//Bind the data into arrays, column by column.

iCount = 2;
for( eCat = xrefCategory.elem~ntc0;eCat.hasMoreElements0;) {
colDesc = dbstmt.SQLDescribeCol(iCount);
genType = getGeneralType(colDesc.getSqlTypeO);
xrefColType.put(eCat.nextElementO,genType);
iCount++;
}

colDesc = dbstmt.SQLDescribeCol(l);
genType = getGeneralType(colDesc.getSqlTypeO);
iniParms.put("IDTYPE",genType);

dbstmt.SQLFreeStmt(Db.SQL_DROP);
dbcon.SQLDisconnect();
dbcon.SQLFreeConnectO;
}

public String getGeneralType(int Type) {
String returnValue;
if(Type=Db.SQL_BlGINT 1I Type=Db.SQL_DECIMAL 1I Type=Db.SQL_FLOAT
Type==Db.SQL_INTEGER 1I Type=Db.SQL_NUMERIC 1I Type=Db.SQL_REAL
Type=Db.SQ~_SMALLINT 1I Type=Db.SQL_TINYINT) returnValue = "INT";
else if (Type---Db.SQL_CHAR li Type=Db.SQL_LONGVARCHAR 11 Type=Db.SQL_TlME 1I Type=Db.SQL_TIMESTAMP 1I Type=Db.SQL_VARCHAR) returnValue = "CHAR";
else if (Type==Db.SQL_DATE) returnValue= "DATE"; 163 else returnValue = "OTHER";
return returnValue;
/lStart the server up, listening on an optionally specified port public static void main(StringO args) {
int port = 0;
boolean isHub = false;
if (argC l~n~h >= l) {
try {
port = Integer.parseInt(args[0]);
} catch (NurnberForrnatException e) { port= 0;
}
}

if (arg~ l~ngth = 2) isHub = true;
new SFServer~port, isHub);
}

public String getINI(String ArgS) {
return (String) iniParrns.get(ArgS);
}

public void populateDBInfio0 {
String tempString;
iniParms = new HasbtableO;

iniParms.put("DATASOURCE", Manipulation.getINIString("HCINI.INI","DATASOURCE"));iniParms.put("DBTABLE", Manipulation.getINIString("HCINI.INI","DBTABLE"));
iniParrns.put("IDCOLUMN~ nirul~tiomgetINIstring(llHcINI~INpl~l~IDcoLuMN~
iniParms.put("USERID", M~nirul~tion.getINIString("HCINI.INI","USERID"));
iniParrns.put("PASSWORD", Manipulation.getINIString("HCrNI.INI","PASSWORD"));
iniP~nnc put("HUBURLn, Manipul~tion getINIString("HCINI.INI","HUBURL"));
iniParms.put("PRODUCTTYPE", Manipulation.getINIString("HCINI.rNI","PRODUCTTYPE"));
iniParms.put("HTMLTEMPLATE", Manipulation.getINIString("HCINI.INI","HTMLTEMPLATE"));
iniParms.put("HTMLREFRESH", Manipulation.getINIString("HCINI.INI","HTMLREFRESH"));
iniParrns.put("DEBUG", Manipulation.getlNIString("HCINI.INI","DEBUG"));
tempString = Manipulation.getrNIString("HCINI.INI","HTMLDIRECTORY");
Mlf htmlDirectory doesn't have ~r at end, add it.

if(!tempString.equals("nonen~) if(!tempString.endsWith("r')) tempString+="/";
iniParms .put("HTMLDIRECTORY",tempString);
iniParms.put("COLLECTTIME", Manipulation.getlNIString("HCINI.INI","COLLECTTIME"));
iniParms.put("SERVERADDRESS",Manipulation.getINlString("HCINI.INI","SERVERADDRESS"));

CA 0220926~ 1997-06-27 ,-' /IThis class is a timer thread, that kicks of at the appropriate /Itime and makes a COL request once a day.
class StartCol extends l~read {
protected SFServer cParent;
protected StartCol(SFServer ArgC) {
super("COL Kickof~');
cParent = ArgC;
this.startO;
}

public void runO {
Date currDate, kickDate;
String time = cParent.getlNl("COLLECTTlME");
long kickoff;
int index;
boolean first = true;
String inLine;
if(time.equals("none")) time = "00:00";
currDate = new DateO;
kickDate = new DateO;
index = time.indexOf(":");
kici;Date.setHours(lnteger.valueOf(time.substring(O,index)).intValueO);
kickDate.setMinutes(lnteger.valueOf(time.substring(index+l)).intValueO);
while (true) {
try {
sleep(30000);
currDate = new DateO;
if( currDate.getHoursO--kickDate.getHoursO && currDate.getMinutes() >=
kickDate.getMinutesO ) {
if(first) {
System.out.println("Started Profile Collection at~+Strin~.valueOf(currDate.getHoursO)+": "+String.valueOf(currDate.getMinutes()));
processCOLRequestO;
first = false;
}

} else if ( currDate.getHoursO > kickDate.getHours() ) {
if(first) {
inLine = processCOLRequest();
System.out.println("Profile Collection at "+Manipulation.padZeros(String.valueOf(currDate.getHours()),2)+":"+Manipulation.padZ:eros(String.valu eOf(currDate.getMinutesO),2)+" - "+inLine);
first = false; 16 5 - CA 0220926~ 1997-06-27 f~-} else {
first= true;
} catch(Interrupte~FYreFtion e) {};
}

/I Process the DATA Collection request (COL) public String processCOLRequestO {
DbStmt dbstmt = null;
DbDbc dbcon = null;
DbVarChar data[l = new DbVarChar[20];
String localHost;
String address;
Enumeration eCat;
String category, type, prerequisite, sqlString, tempSQL, currCat, outLine, inLine;
Vector where, currVals, allCatVal;
String routingTag;
int iLoop;
inLine = "";
eCat = cParent.xrefCategory.elementsO;
where = new VectorO;
while( eCat.hasMoreElementsO ) {
category = (String) eCat.nextElement();
type = (String) cParent.xrefType.get(category);
prerequisite = (String)(cParent.xrefColumn.get((String) cParent.xrefPrerequisite.get(category)));
if(prerequisite--I~ull) prerequisite = """;
if(type.equals("DynamicList") 1I type.equals("StaticList")) {
tempSQL = "SELECT DISTINCT "'+category+"', ";
tempSQL += cParent.xrefColumn.get(category);
tempSQL += ", "+prerequisite+" FROM ";
tempSQL += cParent.getINI("DBTABLE")+" WHERE ";
tempSQL += cParent.xrefColumn.get(category)+" IS NOT NULL";
if (cParent.xrefColType.get(category).equals("CHAR")) tempSQL += " and "+cParent.xrefColumn.get(category)+" O "";
where.addElement(tempSQL);
}
}

sqlString = Manipulationjoin(" UNION ",where);
try {
/lConnect to ODBC Driver 16 6 CA 0220926~ 1997-06-27 ,~' dbcon = cParent.dbenv.SQLAllocConnect();

dbcon.SQLConnect(cParent.getlNI("DATASOURCE"),cParent.getINI("USERID"),cParent.getINI("PASS
WORD"));
dbstmt = dbcon.SQLAllocStmtO;
/tExecute the SQL Statement dbstrnt.SQLExecDirect(sqlString);
//Bind the data into arrays, column by column.
for (iLoop=0;iLoop < dbstrnt.SQLNumResultColsO.intValue0;iLoop++) {
data[iLoop] = new DbVarChar(100);
dbstmt.SQLBindCol(iLoop+l, data[iLoop]);
}

currVals = new VectorO;
allCatVal = new VectorO;
currCat= "";
while (dbstmt.SQLFetch0) {
if (currCat.equals("") ) currCat = data[0].toString0;
if (data[0].toString().equals(curr~at)) {
currV;~lc ~d(lF.l~ment(data[ I ].toString0.trim0+"&"+data[2].toString().trim0);
} else {
allCatVal.addElement(currCat+"="+Manipulation join('\t',currVals));
currCat= data[0].toStringO;
currVals.removeAllElementcO;
currV~lc ~ Flement(data[ I ] .toStringO.trim());
} }
allCatV~ ment(currcat+~ +Manipulationioin(~\t~currvals));
if (cParent.getINI("SERVERADDRESS ") .equals("none")) {
try {
address = InetAddress.getLocalHost().toStringO;
localHost= addr~cc c~lbstring(address indexOf("/")+l);
} catch(UnknownHostException e) {
localHost = "";
} else {
localHost = cParent.getINI("SERVERADDRESS");
}

outLine = "RH,000 1 ,col,"+"http://"+localHost+":"+String.valueOf(cParent.port)+",";
outLine += ","+cParent.getINI("PRODUCTTYPE")+","+Manipulationjoin('l',allCatVal);
routingTag = cParent.getINI("HUBURL");
inLine = routeData(outLine, routingTag);

//Strip the Response header off the line. 16 7 - CA 0220926~ 1997-06-27 f if(inLine.lengthO > I l) inLine = inLine.substring(12);
else inLine = "";
} catch (DbSqlException e) {
if ( ! cParent.getlNI("DEBUG").equals("None")) {
System.out.println(" Error Trace: "+new DateO+" ");
System.out.println("SQL: "+sqlString);
e.printStackTraceO;
}

}
Il Shut everything back down.
dbstmt.SQLFreeStmt(Db.SQL_DROP);
dbcon.SQLDicconnectO;
dbcon.SQLFreeConnectO;
return inLine;
}

I**
* Re-route the data to the destination specified in the Routing Tag. Wait for and return a response.
*l public String routeData( String outLine, String routingTag) {
Socket destination;
DataInputStream serverln;
DataOutputStream serverOut;
String Request;
String response;
String host;
URL destURL;
int whichPort;
try {
destURL = new URL(routingTag);
host = destURL.getHostO;
whichPort = destURL.getPortO;
if(whichPol L--O) whichPort = cParent.DEFAULT_PORT;
destination = new Socket(host, whichPort);
try {
serverln = new DatalnputStream(destination.getInputStreamO);
serverOut = new DataOutputStream(destination.getOutputStreamO);
serverOut.writeBytes(outLine+"\n ");
response = WaitForResponse(serverIn);
return response;
}

catch (lOException e) { 16 8 - CA 02209265 l997-06-27 return "";
} catch (Exception e) {;
re~urn "Error";
} }
public String WaitForResponse(Dat~Tnrut.~tream inStream) {
boolean Body= false;
String line, CGIResponse;
CGIResponse = "";
try {
CGIResponse= inStream.readLirle0;
} ca~ch (IOException e) {
System.out.println("Error "+e+". Unable to obtain response.");
return "ERROR:0061Unable to obtain response from routed ~ tin~ti~n ~;
return CGIR~spon~e;
} }

CA 0220926~ 1997-06-27 /** Handles two vectors of Client objects, available * and in-use. When the startClientO method is * invoked, finds the next available Client object, * puts it in the in-use vector, and kicks it off.
**l import java.util.*;
import java.awt.*;
irnport java.net.*;
class ThreadHandler implements Runnable {
Vector availableThreads;
Thread handlerThread;
Cli~ntC~nnection tempThread;
SFServer cParent;
public ThreadHandler(SFServer argC) {
cParent = argC;
availableThreads = new Vector(5);
for(int iLoop=0;iLoop < 5; iLoop++) {
tempThread = new ClientConnection(this, cParent);
availableThr~A~ FI~rnent(tempThread);
}

public void startO {
if (handlerThread = null) {
handlerThread = new Thread(this);
handlerThread.setPriority(Thread.MAX_PRlORITY);
handlerThread.startO;
}

public void stopO {
if (handlerThread != null && handlerThread.isAliveO) handlerThread.stopO;
handlerThread = null;
}

public void run() {
while(true);
}

public synchronized boolean startClient(Socket argSo) {
boolean foundOne = false;
boolean returnValue = true;
int howManyUsed;
for(Enumeration e=availableThreads.elements();e.hasMoreElementsO;){
tempThread=(ClientConnection)e.nextElementO;
if(!tempThread.inUse) {
tempThread.setSocket(argSo); 17 0 CA 0220926~ l997-06-27 f ((ClientConnection) tempThread).start();
foundOne = true;
break;
}
}

if(!foundOne) {
if(availableThre~r~c Ci7PO C 10) {
System.out.println("Exceeded the pool. Adding a new Thread...");
tempThread=new ClientConnec~ion(this, cParent);
tempThread.setSocket(argSo);
tempThread.inUse = true;
((ClientConnection) tempThread).startO;
availableThrea~lc ~ FlPment(tempThread);
else {
returnValue = false;
}

howManyUsed = 0;
for(Enumeration e2=availableThreads.elementsO;e2.hasMoreElements();){
if(((ClientConnection)e~ nPYtF.IPment0) jnUse) howManyUsed++;
}

cParent.setStat(howManyUsed, availableThre~ ci7P0);
return returnValue;
}
}

-~ CA 0220926~ 1997-06-27 ~
-import java.net.*;
import java.io.*;
import java.util.*;
import tcg.tools.*;
import jet.connect.*;
irnport java.awt.*;

/**************************************************
* Class: ClientConnection * Written by: Brian Duncan * Date:
* Purpose: This class handles a connection from * a client. It receives and parses the request, * does whatever processing it needs, in~lu~in~ ODBC, * for~nulates and sends the response, and sl~ep~n~le itself.
**********************$***************************/
public class ClientConnection implements Runnable{
/IFlag including whether this thread is currently //conversing with a client.
public boolean inUse;
//Socket passed from the server, connection from Client protected Socket client;
//Datainput stream to the client protected DataInputStream clientIn;
//Dataoutput stream to the client.
protected DataOutputStream clientOut;
//This thread.
protected Thread clientThread;
//Parsed-out routing tag (if any) from the client.
protected String routingTag;
//Data passed from the client protected String data;
//lndicates whether or not the current request if for the //Hub protected boolean isHub;
protected SFServer cParent;
//The thread handler for this thread.
protected ThreadHandler handler;
//ODBC connection protected DbDbc dbcon = null;
//ODBC Statement 17 2 - CA 0220926~ l997-06-27 _ protected DbStmt dbstrnt = null;

/**************************************************
* Constructor **************************************************l public CIientconnection(Thre~ r argC l, SFServer argC2 ) {
handler = argC l;
cParent = argC2;
//Make an ODBC conn~cti-~n using the Server's ODBC
//Environrnent.
dbcon= cParent.dbenv.SQLAllocConnectO;
dbcon.SQLConnect(cParent.getINI("DATASOURCE"),cParent getINI("USERID"),cParent.getINI("PASS
WORD"));

}
/**************************************************
* Start method for this thread.
**************************************************l public void startO {
if (clientThread = null) {
//If thread hasn't been created, create it and start l/it.
clientThread = new Thread(this);
clientThread.setPriority(Thread.NORM_PRIORITY);
clientThread.startO;
} else {
/lIf already thread here, resurne it.
this.resumeO;
}

/**************************************************
* Start method for this thread.
**************************************************l public void stop0 {
if (clientThread != null && clientThread.isAliveO) clientThread.stopO;
clientThread = null;
}

/**************************************************
* Suspend method for this thread **************************************************/
public void suspendO {
clientThre~fl cllcp~n~l0;
}

/**************************************************
* Resume method for this thread.
**************************************************l - CA 0220926~ 1997-06-27 ~' public void resumeO {
clientThread.resumeO;
}
I**************************************************
* Run method for this thread. Checks to see if * socket is valid, if it is, processes request, * then suspends itself.
**************************************************/
public void runO {
String inLine, outLine;
//Loop forever while(true) {
I/Has the socket for this connection been set?
if~client != null) {
inUse = true;
try {
/I read in the data inLine = clientIn.readLineO;
// Parse out the string into routing tag and data.
if( ParseInput(inLine) ) {
//This request should be routed to another router.
outLine = routeData(data);
} else {
//This request should be processed by this router outLine = processRequest(data);
}

//Uh-Oh, we had some kind of error if( outLine.equals("Error") ) {
System.out.println("Unable to connect to client!");
} else {
//Pass the error to the client.
clientOut.writeBytes(outLine+"\n");
/ISave the error in the log file.
saveData(data, outLine);
} }
catch (lOException e) {
System.out.println("IOException with client - "+e.toStringO);
try {
client.closeO;
} catch(IOException e2) {}
} }
//Reset the Socket.
client = null; 174 -- CA 0220926~ 1997-06-27 _.

inUse = false;
//Suspend this thread. Server will resume it //when it has a connection for it.
~hic cucpendo;
}

/**************************************************
* Sets the socket for the next connection. Also * creates input and output streams.
**************************************************l public void set~o~t(Socket argSo) {
client= argSo;
//Create input and output streams for this client.
try {
Il clientln = new n~t~Tnrl~tstream(new BuffereflTnrutctream(client~getTnru~streamo));
1/ clientOut = new DataOutputStream(new BufferedOutputStream(client.getOutputStreamO));
clientln = new DataInputStream(client.getInputStreamO);
clientOut = new DataOutputStream(client.getOutputStreamO);
}

catch (IOException e) {
try {
client.closeO;
} catch (IOException e2) {};
System.out.println("Exception while getting socket streams: "+e);
}
}

1*********************~****************************
* Takes the string passed in, parses out the routing * tag and the data based on the ~ character.
**************************************************l public boolean ParseInput(String sInput) {
int whereTilde;
//If the request contains a "~", there's a routing lltag in it.
whereTilde = sInput.indexOf('~');
if( whereTilde == -I ) {
//No routing tag routingTag= "";
data = sInput;
return false;
} else {
//There's a routing tag in it.
routingTag = sInput.substrin~ .~,whereTilde);
data = sInput.substring(whereTilde+ I );
//Check to see if it's a Hub request.
if (f~t::l c~lbstring(O,2).equals("RH")) isHub = true;
else 17 5 -- CA 0220926~ 1997-06-27 ~-isHub = false;
return true;
}

I**************************************************
* Re-route the data to the destination specified in * the Routing Tag. Wait for and return a response.
****************************************~*********1 public String routeData( String outLine ) {
//Socket for the routed destination.
Socket destin~tion;
//DataInputStream for the routed rlestin~tior~
DataInputStream serverIn;
//DataOutputStream for the routed destin~tion DataOutputStream serverOut;
//Response string from the routed destination String response;
//Host name/IP address from destination.
String host;
URL destURL;
/IPort # from destination.
int whichPort;
//Attempt to connect to destination.
try {
destURL = new URL(routingTag);
host= destURL.getHostO;
whichPort = destURL.getPortO;
if(whichPort--0) whichPort= cParent.DEFAULT_PORT;
destination = new Socket(host, whichPort);
try {
//Create input/output streams for destination serverln = new DatalnputStream(new BufferedlnputStream(destination.getlnputStreamO));
serverOut= new DataOutputStream(new BufferedOutputStream(destination.getOutputStream()));
//Send the request to the destination serverOut.writeBytes(outLine+"\n ");
serverOut-flushO;
//Wait for the response response= WaitForResponse(serverln);
return response } catch (lOException e) { 176 - CA 0220926~ 1997-06-27 ,-try {
client.closeO;
} catch (lOException e2) {};
return "";
} catch (Exception e) {;
return "Error";
}

I**************************************************
* Sit and wait for a response from destin~tion **************************************************l public String WaitForResponse(Dat~Tnru'~tream inStream) {
boolean Body = false;
String line, CGlResponse;
CGIResponse = "";
try {
//Attempt to receive the response.
CGIResponse = inStream.readLineO;
} catch (lOException e) {
System.out.println("Error "+e+". Unable to obtain response.");
return CGlResponse;
}

I**************************************************
* processRequest(String) - This method deterrnines * which request to process, and processes it * appropriately.
**************************************************l public String processRequest(String inLine) {
String header, type, id, outLine;
boolean hub;
//lf debug mode is set to high, show the request //String.
if (cParent.getlNl("DEBUG").equals("High")) System.out.println("Request: "+inLine);
outLine = "";
//Parse out the header from the request.
header = inT ine c~lhstring(0, l l);
//Parse out the type from the request.
type = header.substring(8).toUpperCase();
//Parse out the session id from the request.
id= inLine.substring(3,7); 177 ~ CA 0220926~ 1997-06-27 //Parse out the Ini~i~1i7.or from the request.
Mf it's requesting to a hub, note that.
hub = header.substring(0,2).equals("RH") ? true: false;
//Strip out header info.
if(inLine.lengthO > I l) inLine = inT.inP cllhstring(l2);
else inLine = "";

Il Based on the type of request, call the ap~.. ~I)' iat~ method.
if(type.equals("CAT")) outLine = processCAT0;
else if (type.equals("TYP")) outLine = processTYP0;
else if (type.equals("HUB")) outLine = processHUB0;
else if (type.equals("VAL")) outLine = processVAL(inLine, hub);
else if (type.equals("SUB")) outLine = processSUB(inLine, hub);
else if (type.equals("LST")) outLine = processLST(inLine);
else if (type.equals("HOM")) outLine = processHOM(inLine);
else if (type.equals("ADV")) outLine = processADV(inLine);
else if (type.equals("PRO")) outLine = processPRO(inLine);
else if (type.equals("COL")) outLine = processCOLResponse(inLine);
else return "RS,"+id+","+"ERR,"+"004jlnvalid request type.";
//lf response from handler method start with "ERROR", Illt encountered an error (Probably ODBC).
if( outLine.startsWith("ERROR:")) {
outLine = "RS,"+id+","+"ERR"+","+outLine.substring(6);
} else outLine= "RS,"+id+","+type+","+outLine;
Illf debug mode is set to high, show response string if (cParent.getrNl("DEBUG").equals("High")) System.out.println("Response: "+outLine);
return outLine;
}

I**************************************************
* Process the CAT request from the Client **************************************************l public String processCAT0 { 17 8 - CA 0220926~ 1997-06-27 ---Vector categoryStuff, allCats;
String nextCategory;
allCats = new VectorO;
//Loop through all the categories in the XREF list.
for(Enumeration e = cParent.xrefCategory.elementsO; e.hasMoreElementsO;) {
categoryStuff= new Vector(5);
nextCategory = (String) ~ n~xtF~l~m.ont();
//Pull all info needed for this category into a vector.
categoryStllff ad-lF.lement(nextCategory);
categoryStnff ~rl(1Fl~oment(cparent.xrefHeader.get(nextcategory));
categoryStl-ff ~ Fl~ment(cparent~xrefLength.get(nextcategory));
categoryStllff ~ Fl~ment(cparent.xrefrype.get(n~ytc~fçgory));
categoryStllff~lrlFI~ment(cParent.xrefP~G.~lui~ get(n~YtC~tegory));
//Add tab-separated string of Category criteria.
allC~tc ~d-lF.lement(Manipulationjoin('\t',categoryStuff));
}

//Join all Cat criteria strings together separated by "I"
return Manipulation join('l',allCats);
}

I**************************************************
* Process the TYP request from the client.
**************************************************l public String processTYP0 {
return cParent.getINI("PRODUCTTYPE");
}

I**************************************************
* Process the HUB request from the client.
**************************************************l public String processHUB0 {
return cParent.getrNI("HUBURL");

}

I**************************************************
* Process the VAL request from the client.
**************************************************l public String processVAL(String inLine, boolean isHub) {
String sqlString;
//Build the SQL String to query the database.
sqlString = buildValSQL(inLine, isHub);
//Connect to ODBC Driver DbSqlException status = reConnect(isHub);
if(!(status = null)) return processERR(dbcon,dbstmt, status, "None");
return runValSQL(sqlString); 17 9 - CA 0220926~ 1997-06-27 I**************************************************
* Builds the SQL request string for the VAL request.
**************************************************l public String buildValSQL(String inLine, boolean isHub) {

String sqlString;
Vector categories,queries;
if(isHub) {
//Build SQL for querying the Hub int index = inLine.indexOf(',');
//Parse the Product type out of the string.
String productType = inLine.substring(0,index);
inLine = in~ ine ~bstring(index+l);
//Split the CAT request into Category-sized chunks categories = Manip~ tion ~plit('l', inLine);
//Build the SQL String sqlString = "SELECT t_category.category_name, t_value.value ";
sqlString += "FROM t_value, t_category ";
sqlString += "WHERE t_value.category_id = t_category.category_id and ";
sqlString += "t_category.product_id = "+productType+" and ";
sqlString += "t_category.category_name in ("'+Manipulationjoin("',"',categories)+"') ";
sqlString += "GROUP BY t_category.category_name, t_value.value ";
sqlString += "ORDER BY t_category.category_name, t_value.value";
} else {
//Build the SQL String for the Primary server //Split the request into Category-sized chunks categories = M~nir~ tion.split(~ inLine);
queries = new VectorO;
//Loop through the Categories requested for(Enumeration e = categories.elements();e.hasMoreElementsO;) {
String nextCategory = (String) e.nextElement();
String nextColumn = (String) cPa-ent.xrefColumn.get(nextCategory);
//Build a SELECT statement for each category String nextSQL = "SELECT distinct "';
nextSQL += nextCategory + "', ";
nextSQL += nextColumn + " FROM ";
nextSQL += cParent.getlNl("DBTABLE");
nextSQL += " WHERE "; 18 0 -~ CA 0220926~ 1997-06-27 -nextSQL += nextColumn + " IS NOT NULL";
//If it's a CHAR type field, check for empty-string.
if (cParent.xrefColType.get(nextCategory).equals("CHAR")) nextSQL += " and "+ nextColumn + " O "";
queries ~ F~lement(nextsQL);
//Join all select statements together with a "UNION"
sqlString = Manipulationjoin("\r\nUNION\r\n", queries);
}

return sqlString;
}

I**************************************************
* Runs the VAL SQL, parses the response into string.
**************************************************l public String runValSQL(String sqlString) {
DbVarChar data[] = new DbVarChar[20];
Vector currVals, allCatVal;
String currCat= "";
try {

//Execute the SQL Statement dbstmt.SQLExecDirect(sqlString);
//Bind the data into arrays, column by column.
for (int iLoop=0;iLoop < dbstmt.SQLNumResultColsO.intValue0;iLoop++) {
data[iLoop] = new DbVarChar(100);
dbstmt.SQLBindCol(iLoop+l, data[iLoop]);
}

currVals = new Vector();
allCatVal = new VectorO;
//Pull in result set, row by row.
while (dbstmt.SQLFetch0) {
//Doing a control break on Category name if (currCat.equals("") ) currCat = data[0].toString0.trim0;
if (data[0].toStringO.trim().equals(currCat)) {
//Add all the data from one particular category //into the same vector.
if(data[ I ] = null) currVals.addElement("");
else currV~lc ~ Fl~rnent(data[ l ].tostring().trim());
} else {
//When the category changes, build a response //for that category from the values collected.
allCatVal.addElement(currCat+"="+Manipulat8onjoin('\t',currVals));
currCat = data[0].toString0.trim0;

- CA 0220926~ 1997-06-27 ~-currVals.removeAllElements();

//lf the result set contains a null value, //replace it with empty-string if(data[ I ] = null) currValc ~d-lF.I-oment("");
else currValc ad~lF.lenlent(data[ I ].toStringO.trimO);
}
}

//Build a response for the final category.
allCatV ~ lFlpnlent(currcat+~ +Manipulationioin(~tl~currvals));
} catch (DbSqlFY~eption e) {
return processERR(dbcon,dbstmt, e, sqlString);
}

1/ Shut everything back down.
dbstmt.SQLFreeStmt(Db.SQL_CLOSE);
//Join all category values responses into the same string.
retum Manipulationjoin('l', allCatVal);
}
/**************************************************
* ~ocei~ts the SUB request from the Client **************************************************/
public String processSUB(String inLine, boolean isHub) {
String sqlString;
sqlString = buildSubSQL(inLine, isHub);
//Connect to ODBC Driver DbSqlException status = reConnect(isHub);

if(!(status = null)) return processERR(dbcon,dbstmt, status, "None");
//Sub SQL and val SQL return the same format of result //set~ so why not use VAL's execute routine.
return runValSQL(sqlString);
}

I**************************************************
* Builds the SQL request string for the SUB request.
**************************************************l public String buildSubSQL(String inLine, boolean isHub) {
Vector depValues, catParts;
String sqlString, category, column, prereq;
category= "";
if(isHub) { - 18 2 ~ CA 0220926~ 1997-06-27 .

//Build SQL for querying the Hub int index = inLine.indexOf(',');
/IParse the Product Type out of the Request string String productType = inLine.substring(0,index);
inLine = inBine cubstring(index+l);
IlParse the Category name and values into two separate //Elements catParts = M~nirul~tion ~plit('=', inLine);
category = (String) catParts.elementAt(0);
//Parse the dependent values into a vector.
depValues = Manipulation.split("\t",(String) catParts.elementAt(l));
//Build the sql String.
sqlString = "SELECT t category.category_name, t_value.value ";
sqlString += "FROM t_value, t_category ";
sqlString += "WHERE t_value.category_id = t_category.category_id and ";
sqlString += "t_category.product_id = "+productType+" and ";
sqlString += "t_category.category_name = "'+category+"' and ";
sqlString += "t_value.prerequisite_value in ("'+Manipulationjoin("',"',depValues)+"') ";
sqlString += "GROUP BY t_category.category_name, t_value.value ";
sqlString += "ORDER BY t_category.category_name, t_value.value";
else {
//Build the SQL String for querying the primary server //Parse the Category name and values into two separate //Elements catParts = Manipulation.split('=', inLine);
category = (String) catParts.elementAt(0);
/IParse the dependent values into a vector depValues = Manipulation.split("\t",(String) catParts.elementAt(l));
//Get the actual column name for this category column = (String) cParent.xrefColumn.get(category);
//Get the prerequisite column name for this category.
prereq = (String) cParent.xrefColumn.get((String) cParent.xrefPrerequisite.get(category));
//Build SQL string for the Primary Router sqlString = "SELECT distinct "'+category+"', "+column;
sqlString += " FROM "+cParent.getlNl("DBTABLE");
sqlString += " WHERE "+column+" IS NOT NULL";
sqlString += " AND "+prereq+" in ("';
sqlString += Manipulationjoin("',"',depValues)+"')";
//lf this category is a CHAR type, don't allow 18 3 - CA 0220926~ 1997-06-27 //empties.
if (cParent.xrefColType.get(category).equals("CHAR")) sqlString += " and "+ column + '' O '''';
return sqlString;
}
I**************************************************
* Processes the LST request from the Client **************************************************l public String processLST(String inLine) {
String sqlString;
sqlString = buil~T.ct~QL(inLine);

//Connect to ODBC Driver DbSqlF.Yre~tion status = reConnect();
if(!(status = null)) return processERR(dbcon,dbstmt, status, "None");
return runLstSQL(sqlString);
}

I**************************************************
* Builds the SQL request string for the LST request.
**************************************************l public String buildLstSQL(String inLine) {
Vector where, inSections, inTokens, inValues, columns;
String sqlString, needQuote, category, nextSection;
where = new VectorO;

//Split the request string into category-sized chunks inSections = Manipulation.split('l', inLine);
//Build a column vector from the XREF Category vector.
columns = new VectorO;
for(Enumeration e = cParent.xrefCategory.elementsO; e.hasMoreElements(); ) colllmnc ~ Flpment(cparenLxrefcolummget((string)e n~tFl~mentO));
//Build the SELECT and FROM clauses of the SQL String sqlString = "SELECT "+cParent.getINl("IDCOLUMN")+",";
sqlString += Manipulationjoin(",",columns);
sqlString += " FROM "+cParent.getINI("DBTABLE");
sqlString += " WHERE ";
//Loop through the Category Chunks, and build where clause //for each one.
for(Enumeration e = inSections.elementsO; e.hasMoreElements(); ) {
nextSection = (String) e.nextElementO;
inTokens = Manipulation.split('=', nextSection), -- CA 0220926~ 1997-06-27 ~-~

//Split the values for this category where into a //vector inValues = Manipul~tion cplit(~t', (String) inTo~nc elem~ntA.t(l));
category = (String)inTokens.elementAt(0);
.
//Determine if the value needs "'s around it based on //The column type.
needQuote = cParent.xrefColType.get(category).equals("CHAR") ? ""':"";
//Build either a 'Between' or an 'In' clause, based //on the type on category if( cParent.xrefType.get(category).equals("Range")) where ~ IFI~Pnt((String)cParent.xrefColumn.get(category) + " between "+needQuote+
inValues.elementAt(0) + needQuote+" and "+needQuote + inValues.elementAt(l) + needQuote);
else {
where ~(MFle~ent((string)cparent.xrefcolumn.get(category) + " in ("+needQuote +
Manipulationjoin(needQuote+","+needQuote,inValues) + needQuote+")");
}
}

//Join all the where clauses together, tack them on //the end of the SQL String.
sqlString += lvl~nipul~tionioin(~ and ", where);
return sqlString;
}

/**************************************************
* Runs the LST SQL, parses the response into string.
**********************************~***************/
public String runLstSQL(String sqlString) {
DbVarChar data[] = new DbVarChar[20];
Vector outValues, outRows;
int iCount;
try {
//Execute the SQL Statement dbstmt.SQLExecDirect(sqlString);
//Bind the data into arrays, column by column.
for (int iLoop=O;iLoop < dbstmt.SQLNumResultCols().intValueO;iLoop++) data[iLoop] = new DbVarChar(100);
dbstmt.SQLBindCol(iLoop+l, data[iLoop]);
}

outRows = new VectorO;
outValues = new VectorO;
iCount= 0;
//Loop through the Result set, row by row, //until you reach the end, or read 50 rows, //whichever comes first. 18 5 while (dbstmt.SQLFetchO && iCount <51) {
iCount++;
t/Assume the first column is the unique identifier.
//We" always call the first column "listnum", I/So that the client applet can rely on it.
outV~Iut?s a~rlFlement(~listnum~+~ +data[0].toString0~trim0);
//Add the rest of the data to the vector.
for(int iLoop=l; iLoop < dbstmt.SQLNumResultColsO.intValue0;iLoop++) outV~hl~s ~drlF.l~ment((String)cParent xrefCategory.elementAt(iLoop-l )+"="+data[iLoop] .tostring0.trim0);
//Join all the data for a row together, s~aL,d //with "I"'s.
outRowc ~ Flement(Manipulationioin(~ outvalues));
outvalues~remove~llFl~nnentco;
}

} catch (DbSqException e) {
retum processERR(rlbcon~lhstmt~ e, sqlString);
}

//Release the ODBC ~ e~L
dbstmt SQLFreeStmt(Db.SQL_CLOSE);
if (!outRows.isEmpty0) mf there was something in the result set, //Join all the row data strings together into a //big string.
return Manipulationjoin("ll", outRows);
else //If there was nothing in the result set, return //empty-string.
return "";
}

1******************~*******************************
* Processes the HOM request from the Client ************************~*************************1 public String processHOM(String inLine) {
RandomAccessFile fTemplate, fOutHTML;
Vector columns, vNameValues, names, sections;
Hashtable values;
String sqlString, line;
boolean keepIt;
String needQuote, TemplateExt, oString;
//Determine template extension. We will use this as lla basis to ~l~tt nnine whether to build an HTML page, //or a get request.
TemplateExt= cParent.getINI("HTMLTEMPLATE");

- CA 0220926~ 1997-06-27 ~ , if( TemplateFY~ in~l~xOf(" ") > 0) {
TemplateExt = TemplateFYt cllhstring(Templ~teFYt indpyof(~ll)+l)~touppercaseo;
} else TemplateExt= "HTM";
//If the Template file has an extension of "HTM" or "HTML", IfConfli~ion~lly build the HTML file. Otherwise, formulate lla CGI 'GET' request.
if( TemplateExt.equals("HTM") 1I TemplateExt.equals("HTML")) {
//Check to see if the file already exists.
keepIt= isCurrentHTML(inLine, TemplateExt);

if(!keepIt) {

/IWe need to create a new HTML file.
try {
fTemplate = new RandomAccessFile(cParent.getlNI("HTMLTEMPLATE"), "r");
columns = getHTMLTemplateTags(fTemplate);
//Determine if the ID column is Char, if so, //put quotes around it.
needQuote = cParent.getlNI("IDTYPE").equals("CHAR") ? ""':"";
//build the SQL String based on all the //unique columns in the template file.
sqlString= "SELECT "+Manipulationjoin(',',columns);
sqlString += " FROM "+cParent.getINI("DBTABLE");
sqlString += " WHERE "+cParent.getlNI("IDCOLUMN")+"="+needQuote+inLine+needQuote;
//Connect to ODBC Driver DbSqlException status = reConnect();
if(!(status = null)) return processERR(dbcon,dbstmt, status, "None");
//Run HOM SQL, parse response into a hashtable.
try {
values = runHomHTMLSQL(sqlString, columns);
catch (DbSqlException e) {
return processERR(dbcon, dbstmt, e, sqlString);
}

//Create new HTML file handle.
fOutHTML = new RandomAccessFile("htmV/"+inLine+"."+TemplateExt,"rw");
//Reset the position of the Template file back llto the top fremplate.seek(O);
IlPut the appropriate data into the //new HTML file. 18 7 - CA 0220926~ 1997-06-27 -buildHTMLFile(fTemplate, fOutHTML, values);

//Close the two files.
fTemplate.closeO;
fOutHTML.closeO;
retum cParent.getlNI("HTMLDIRECTORY")+inLine+"."+TemplateExt;
catch(lOException e) {
System.out.println("Couldn't read the template file.");
retum "ERROR:0041Couldn't read the template file.";
}

} else {
retum cParent.getlNl("HTMLDlRECTORY")+inLine+"."+TemplateExt;
} else {
//Build a Get Request URL.
//Deterrnine and open the template file.
try {
fTemplate = new RandomAccessFile("template.get", "r");
line = "first";
columns = new VectorO;
names = new VectorO;
//Chug through the template file, finding all column tags, and putting them in a basket.
while( line != null) {
line = fr~mpl~te readLine0;
if (line != null && line.trimO.length() > 0) {
sections = Manipulation.split("=",line);
nam~s ~d~FI~ment((String)sections.elementAt(0));
colnmnc ~dAFlement((String)cectionc elementAt(l));
}
}

fTemplate.closeO;
needQuote = cParent.getlNl("lDTYPE").equals("CHAR") ? ""':"";
sqlString = "SELECT "+Manipulationjoin(',',columns);
sqlString += " FROM "+cParent.getlNl("DBTABLE");
sqlString += " WHERE "+cParent.getlNl("lDCOLUMN")+"="+needQuote+inLine+needQuote;
//Connect to ODBC Driver DbSqlException status = reConnect();
if(!(status = null)) retum processERR(dbcon,dbstmt, status, "None");
try { 1 8 8 -- CA 0220926~ 1997-06-27 --- ' vNameValues = runHomCGlSQL(sqlString, names);
oString =
cParent.getINl("HTMLDIRECTORY")+cParent.getlNI("HTMLTEMPLATE")+"?"+Manipulation join("&
",vNameValues);
oString = oString.replace(",'+');
return oString;
} catch(DbSqlException e) {
fTemplate.closeO;
return processERR(dbcon, dbstmt, e, sqlString);
}
} catch(IOException e) {
System.out.println("Couldn't read the template file.");
return "ERROR:0041Couldn't read the template file.";
}
}

I**************************************************
* Deterrnines whether or not the HTML file requested * in the HOM request is there, and if so, if it's $ still current.
**************************************************/
public boolean isCurrentHTML(String inLine, String TemplateExt) {
Date date, oldDate;
int htmlRefresh;
boolean keepIt = true;
File oldFile;
//Open a file object to the Existing HTML file.
oldFile = new File("html//"+inLine+"."+TemplateExt);

I/ls it already created?
if( oldFile.exists0) {
//Should we consider the page static?
if( Integer.valueOf(cParent.getlNl("HTMLREFRESH")).intValueO > 0) {
//If no HTMLREFRESH setting has been specified, //Default it to I hour.
if(cParent.getINI("HTMLREFRESH ").equals("none")) htmlRefresh= I;
else htmlRefresh = Integer.valueOf(cParent.getlNI("HTMLREFRESH")).intValueO;
//Compare the current date/tirne with the existing //HTML file's date/time.
oldDate = new Date(oldFile.lastModifiedO);
date = new DateO;
if(oldDate.getDateO != date.getDate()) {
//The two days are different, create a new 18 9 - CA 0220926~ 1997-06-27 .-//file.keepIt= false;
else if ((date.getHoursO - oldDate.getHoursO) > htmlRefresh) {
/rrhe time between the old file and he new file //is greater than the allowed amount. Create //a new file.
keepIt = false;
else {
//Everything checks out Keep the file.
keepIt = true;
}

} else {
//HTMLRefresh setting = 0. This means, keep it if l/it exists at all. This is used for static pages.
keepIt = true;
}

} else {
//The file has never been created. We must create it keepIt = false;
}

return keepIt;
}

/**************************************************
* Pulls all the column tags out of the template * htrnl file.
**************************************************/
public Vector getHTMLTemplateTags(RandomAccessFile fTemplate) throws IOException {
Vector sections;
Vector columns = new VectorO;
Enumeration eFragments;
String line, nextColumn;

try {
//Chug through the template file, fnding all column //tags, and putting them in a basket.
while( (line = fremplate.readLine0) != null) {
sections = M~nipul~tion cplit(~ sEEKDBcoL=\llll~line);
eFragments = sectionC ele~nentsO;
//Skip first element;
if( eFragments.hasMoreElementsO ) eFragmPn~c n~ytFlemento;
while( eFr~gm~tc h~cMoreElementso ) {
nextColumn = (String) eFMgrn~ntc n~ytFlemento;
nextColurnn = nextColumn.substring(0,nextColnmn ind~xOf(""));
if(!columns.contains(nextColumn)) colnmnc ~r1Flement(nextcolumn);
}
}

} catch(IOException e) {
//Re-Th~ow the exception, because we want the called method to _ CA 0220926~ 1997-06-27 /Ihandle it.
throw e;
return columns;
}

I**************************************************
* Runs the SQL for the HOM request (HTML version), * returns a hashtable **************************************************l public Hashtable runHomHTMLSQL(String sqlString, Vector columns) throws IOException {
DbVarChar data[] = new DbVarChar[20~;
Enumeration eColumns;
Hashtable values;
try {
/IExecute the SQL St~tPnlpnt dbstmt.SQLExecDirect(sqlString);
IlBind the data into arrays, column by column.
for (int iLoop=0;Loop < dbstmt.SQLNumResultColsQintValue0;iLoop++) {
data[iLoop] = new DbVarChar(100);
dbstmt.SQLBindCol(iLoop+l, data[iLoop]);
}

/IBuild a hashtable from the columns and corresponding values.
values = new HashtableO;
eColumns = columns.elementsO;
IlOnly one row in the result set, so no need for a //Loop per row.
dbstmt.SQLFetchO;
for (int iLoop=0;iLoop < dbstmt.SQLNumResultColsO.intValue0;iLoop++) values.put( (String) eColumns.nextElement(), data[iLoop].toStringO.trim0 );
//Close the ODBC connection.
dbstmt.SQLFreeStmt(Db.SQL_CLOSE);
} catch(DbSqlException e) {
throw e;
return values;
}

I**************************************************
* Runs the SQL for the HOM request (CGI version), * returns a Vector **************************************************l public Vector runHomCGISQL(String sqlString, Vector names) throws DbSqlException {
DbVarChar data[] = new DbVarChar[20];
String sName, sValue; 191 - CA 0220926~ l997-06-27 --' Vector vNameValues;
tr,Y {
//Execute the SQL Statement dbstmt.SQLExecDirect(sqlString);
//Bind the data into arrays, colurnn by column.
for (int iLoop=0;iLoop < dbstmt.SQLNumResultColsO.intValue0;iLoop++) {
data[iLoop] = new DbVar{ har(100);
dbstrnt.SQLBindCol(iLoop+l, data[iLoop]);

//Fetch the first and only row in this result set dbstrnt.SQLFetchO;
vNameValues = new VectorO;
//Loop through the colurnns in the result set row, //making name/value pairs out of them.
for (int iLoop=0;iLoop < dbstmt.SQLNumResultCols0.intValue0;iLoop++) {
sName = (String)n~mPs elPmPnt~t(Loop);
sValue = data[iLoop].toString0.trim0;
vNameVal-lPc ~ pment(sName+~ +svalue);
}

dbstmt.SQLFreeStmt(Db.SQL C~OSE);

} catch (DbSqlException e) {
throw e;
return vNameValues;
}

/**************************************************
* Build the new HTML file based on the Template file **************************************************/
public void buildHTMLFile(RandomAccessFile fTemplate, RandomAccessFile fOutHTML, Hashtable values) throws IOException {
String line, nextColumn;
int index;
try {
/IGo back through the template file, re-find the l/tags, and copy over the template code to the //new HTML file, swapping the tags for data.
while( (line = fremplate.readLine0) != null) {
index = line.indexOf("!--SEEKDBCOL");
while (index > - I ) {
nextColurnn = line.substring(index+l4,1ine.indexOf("",index+14));
line = line ~nhstring(o~index-l)+values.get(nextColurnn)+line snbstring(line.indexOf("",index+14)+4);

CA 0220926~ 199i-06-27 __ index = line in~exof(~ -sEEKDBcoLll);
}

fOutHTML.writeBytes(line+ \n );

} catch (IOException e) {
throw e;
}

//This method pl ocesses the ADV request.
public String processADV(String inLine) {
DbVarChar data[] = new DbVarChar[80];

Vector where, inSections, inTokens, inValues, columns;
Vector outRows;
String sqlString, n~Yt~ection nextColumn, nextSQL, category;
Enumeration eSecti~nc;
String productType;
int index;
where = new VectorO;
index = inLine inf~YOf(',');
productType = inLine.substring(0,index);
inLine = inLine.substring(index+ I );
inSections = Manipulation.split('l', inLine);
sqlString = "SELECT ad_text, ad_url ";
sqlString += "FROM t_advertisement, t_value, t_category ";
sqlString += "WHERE t_advertisement.product_id = "+productType+" and ";
sqlString += "t_advertisement.category_id *= t_value.category_id and ";
sqlString += "t_adverticPm~nt value *= t_value.value and ";
sqlString += "t_advertisement.category_id *= t_category.category_id and ";
sqlString += "(t_advertisement.category_id IS NULL";
eSections = in~ectjonc elementsO;

while(eSectiorlc h~cMoreElementsO) {
nextSection = (String) eSections.nextElementO;
inTokens = Manipulation.split('=', nextSection);
inValues = Manipulation.split('\t', (String) inTokens.elementAt(l));
category = (String)inTokens.elementAt(0);
where.addElement(" (t_category.category_name = "'+category+"' and t_value.value in ("'+
Manipulationjoin("',"',inValues) + "'))");
}

if (!where.isEmpty()) {
sqlString += " or "; 193 - CA 0220926~ 1997-06-27 sqlString += Manipulationjoin(" or ",where);
}

sqlString += ")";
try {
//Connect to ODBC Driver DbSqlException status = reConnect(true);

if(!(status--null)) return processERR(rlbcon llhst~nt, status, "None");
//Execute the SQL Statement dbstmt.SQLExecDirect(sqlString);
t/Bind the data into arrays, column by column.
for (int iLoop=0;iLoop < dbstmt.SQLNumResultColsO.intValue0;iLoop++) {
data[iLoop] = new DbVarChar(80);
dbstmt.SQLBindCol(iLoop+l, data[iLoop]);

outRows = new VectorO;
while (dbstmt.SQLFetch0) {

outRows.addElement(data[O].toString().trim()+'\t'+data[l].toStringO.trimO);
} catch (DbSqlException e) {
return processERR(dbcon,dbstmt, e, sqlString);

dbstmt.SQLFreeStmt(Db.SQL_CLOSE);
return Manipulationjoin("l", outRows);

}

//This method processes the PRO request.
public String processPRO(String inLine) {
DbVarChar data[] = new DbVarChar[50];

Vector where, inSections, inTokens, inValues, columns;
Vector outRows;
String sqlString, nextSection, nextColumn, nextSQL, category, tempSQL;
String productType;
int index;
Enumeration eSections;
where = new VectorO; 19 4 --- CA 0220926~ 1997-06-27 __ index = inT.ine indexOf(',');

productType = inT.ine cnbstring(0,index);
inLine= inT ine ~lbstring(index+l);
inSectjon~ = Manipulation.split('l', inLine);
sqlString = "SELECT url ";
sqlString += "FROM t_server ";
sqlString += "WHERE ";
tempSQL= "t_server.server_id IN ";
tempSQL += " (SELECT t_server.server_id ";
tempSQL += "from t_server, t_category, t_value ";
tempSQL += " where t_server.server_id = t_value.server_id and ";
tempSQL += " t_category.category_id = t_value.category_id and ";
tempSQL += " t_category.product_id = " + productType+" and ";
tempSQL += " t_server.product_id = " + productType+" and ";
eSection~ = in~ecti-~n~ elementsO;
while(eSections.hasMoreElementsO) {
n~Yt~ection = (String) eSection~ npxtElemento;
inTokens = l~nip~ tion.split('=', neYt!~ection);
inValues = Manipulation.split('\t', (String) inTokens.elementAt(l));
category = (String)inTokens.elementAt(0);
where.~lF.l~rnent(tempSQL + "t_category.category_narne = "'+category+"' and t_value.value in ("'+ Manipulationjoin("',"',inValues) + "'))");
}

if(!where.isEmptyO) {
sqlString += Manipulationjoin(" and ",where);
} else {
sqlString += " t server.product id = " + productType;
}
try {
//Connect to ODBC Driver DbSqlException status = reConnect(true);
if(!(status = null)) return processERR(dbcon,dbstrnt, status, "None");
//Execute the SQL Statement dbstmt.SQLExecDirect(sqlString);
//Bind the data into arrays, column by column. 19 5 CA 0220926~ 1997-06-27 for (int iLoop=0;iLoop < dbstmt.SQLNumResultColsO.intValue0;iLoop++) {
data[iLoop] = new DbVarChar(100);
dbstmt.SQLBindCol(iLoop+l, data[iLoop]);
}

outRows = new VectorO;
while (dbstmt.SQLFetch0) {
outRowc ~d-lFlPment(data[0].toString().trim0);

} catch (DbSqlException e) {
return processERR(dbcon,dbstmt, e, sqlString);
}

dbstmt.SQLFreeStmt(Db .SQL_CLOSE);

return Manipulationjoin("l", outRows);
}

public String processCOLResponse(String inLine) {

DbValue tempValue;
DbInteger DBCatID, DBServerID;
DbChar DBValue, DBPrerequisite;
String sqlString, category, serverURL, serverID, categoryID;
String productType;
Vector categories, tempVector, values, vBoth;
Enumeration eCat, eVal;
int index;
String returnString = "Updated.";
index = inLine.indexOf(',');
if(index > 0 ) {
serverURL = inLin~ cubs~ring(0,index);
inLine = inLine.substring(index+2);
} else serverURL= "";
index = inLine.indexOf(',');
if(index > 0 ) {
productType = inT ine cubstring(0,index);
inLine = inLine.substring(index+ l );
} else productType= "";
sqlString = "SELECT server_id from t_server where url = "'+serverURL+""';
//Connect to ODBC Driver try {

CA 0220926~ 1997-06-27 .~
t , DbSqlException status = reConnect(true);

if(!(status = null)) return processERR(dbcon,dbstmt, status, "None");
//Execute the SQL Statement dbstmt.SQLExecDirect(sqlString);
serverID = "";
//Pull out the Server ID
if~dbstmt.SQLFetchO) {
tempValue = new DbValueO;
dbstmt.SQLGetData(l ,tempValue);
serverID = tempValue toStringO;
retumString= "Updated.";
Mf it came back with a server ID, Cool, delete all //their current values out of the value table.
dbstmt.SQLFreeStmt(Db.SQL_CLOSE);
sqlString = "delete from t_value where server id = "+serverID;
dbstmt.SQLExecDirect(sqlString);
} else {
//Otherwise, create new server record with a~.l,. up, iat~
t/URL, and product type.
//Determine next ID code.
dbstmt.SQLFreeStmt(Db.SQL CLOSE);
sqlString = "SELECT max(server_id)+l FROM t_server";
dbstmt.SQLExecDirect(sqlString);
if(dbstmt.SQLFetchO) {
tempValue = new DbValueO;
dbstmt.SQLGetData(l ,tempValue);
serverID = tempValue.toString();
dbstmt.SQLFreeStmt(Db.SQL_CLOSE);
sqlString = "INSERT into t_server (server id, product_id, server_name, url) ";
sqlString += "VALUES ("+serverlD+","+productType+","'+"Created: "+new DateO.toStringO+"',"'+serverURL+"')";
returnString = "Created. ";
dbstmt.SQLExecDirect(sqlString);
dbstmt.SQLFreeStmt(Db.SQL_CLOSE);
}

dbstmt.SQLFreeStmt(Db.SQL_CLOSE);

CA 0220926~ 1997-06-27 __ ~ //Ok, now trudge through the passed in COL request, ~arsing llout category names, and associated values and prerequisite values.
categories = Manipul~tion cplit(~ inLine);
eCat = categories.elementsO;
while(eCat.hasMoreElementsO) {
tempVector= Manipulation.split('=', (String) eC~t nPyt~nlento);
category = (String) tempVector.elementAt(0);
values = Manipulation.split(~t', (String) tempVector.el~m~nt~t(l));
/tFind out the category ID that corresponds with the category name //parsed out.
sqlString = "SELECT category_id FROM t_category ";
sqlString +="WHERE category_name = "'+category+""';
sqlString +="and product_id = "+productType;
dbstmt.SQLExecDirect(sqlString);
categoryID = null;
if (dbstmt.SQLFetch0) {
tempValue = new DbValue();
dbstmt.SQLGetData(l ,tempValue);
categoryID = tempValue toStringO;
}

dbstmt.SQLFreeStmt(Db.SQL_CLOSE);

if(categoryID!=null) {
/tSet up a statement to do multiple inserts dbstmt.SQLPrepare("INSERT INTO t_value values (?,?,?,?)");

DBCatlD = new DblntegerO;
DBServerID = new DbIntegerO;
DBValue = new DbChar(100);
DBPrerequisite = new DbChar(100);
dbstmt.SQLBindParameter(l,Db.SQL_PARAM_INPUT, DBServerlD);
dbstmt.SQLBindParameter(2,Db.SQL_PARAM_INPUT, DBCatlD);
dbstmt.SQLBindParameter(3,Db.SQL_PARAM_INPUT, DBValue);
dbstmt.SQLBindParameter(4,Db.SQL_PARAM_INPUT, DBPrerequisite);
DBCatID.set(categoryID .toString());
DBServerID.set(serverID toStringO);
for (eVal = values.elementsO; eVal.hasMoreElementsO;) {
vBoth = Manipulation.split('&',(String)eVal.nextElementO);
DBValue.set((String) vBoth.elementAt(0));
if(vBoth.sizeO ---2) DBPrerequisite.set((String) vBoth.elementAt( I ));
else 19 8 CA 0220926~ 1997-06-27 r~

DBPrereqllicite ~et("");
dbstrnt.SQT .FY~C~I~e();
} else {
return "ERROR: Category not found in Hub Database";
}

dbstmt.SQLFreeStmt(Db.SQL_CLOSE);
}

} catch (DbSqlException e) {
return processERR(dbcon,dbstmt, e, sqlString);
}

dbstrnt.SQLFreeStrnt(Db.SQL_CLOSE);
retum returnString;
}

public DbSqlException reConnectO {
return reConnect(false);
}

1/ Method to test the current ODBC connection.
1/ The Parameter is used to determine whether this // is a Hub or not.
public DbSqlException reConnect(boolean argB) try {
dbstmt = dbcon.SQLAllocStrntO;
if(argB) dbstmt.SQLExecDirect("select 2 from t_server");
else dbstmt.SQLExecDirect("select 2 from "+cParent.getINI("DBTABLE"));
dbstmt.SQLFreeStrnt(Db.SQL_CLOSE);
} catch(DbSqlException e) {
try {
dbcon.SQLFreeConnectO;
} catch(DbSqlException e2) {
}
try {
dbcon = cParent.dbenv.SQLAllocConnect();
dbcon.SQLConnect(cParent.getINI("DATASOURCE"),cParent.getINI("USERlD"),cParent.getINI("PASS
WORD"));
dbstmt = dbcon.SQLAllocStrnt();
Syst~m out println("ODBC: Reconnected");
} catch(DbSqlException e3) {
return e3;
} 199 _ CA 0220926~ 1997-06-27 return null;
}

public String processERR(DbDbc dbcon, DbStmt dbstmt, DbSqlException e, String sqlString) {
String returnValue;
returnValue = "ERROR:"+"0051"+e.toStringO;
dbstmt.SQLFreeStmt(Db.SQL CLOSE);
if(!cParent.getINI("DEBUG").equals("None")) {
System.out.println(" ErrorTrace: "+new DateO+" ");
System.out.println("SQL: "+sqlString);
e.printStackTraceO;
}

return returnValue;
}

ll Take input string, output string, pull data into a string that will be //saved to the end of the log file.
public void saveData(String ArgS 1, String ArgS2) {
String oDestination, oType, oDate, oTime, oListings, oClientAddress;
Date d = new DateO;
int count = 0;
oClientAddress = Manipulation.padSpaces(client.getInetAddressO.toString0, 30);
oDestination = Manipulation.padSpaces(routingTag, 22);
oType = ArgSl.substring(8,11);
oDate =
Manip~ tion p~A7~ros(String.valueOf(d.getMonth()+1),2)+"/"+Manipulation.padZeros(String.valueOf(d.
getDateO),2)+"/"+String.valueOf(d.getYear());
oTime =
Manipulation.padZeros(String.valueOf(d.getHoursO),2)+":"+Manipulation.padZeros(String.valueOf(d.get MinutesO),2);
oType = oType.trimO.toLowerCase0;
if(oType.equals("lst")) {
count = Manipulation.countOccurrences(ArgS2, "11");
ll If there are no "ll"'s in the string, check to see if that's ll because there was only one listing.
if(ArgS2.1ength() > 12) count++;
oListings = Manipulation.pad_eros(String.valueOf(count), 4);
} else {
oListings = " ";
}

try {
//Go to the end of the file cParent.lOut.writeBytes(oClientAddress);
cParent.lOut.writeBytes(oDestination); 2 0 0 CA 0220926~ l997-06-27 f cParent. IOut.writeBytes(oType);
cParent.lOut.writeBytes(oDate);
cParent.lOut.writeBytes(oTime);
cParent.lOut.writeBytes(oListings);
cParent.lOut.writeBytes('~r\n");
catch (IOException e) {
System.out.println("Unable to write to Usage.log\n");
}
}

Claims (39)

WHAT IS CLAIMED IS:
1. A method of collecting data from at least one searchable data base management system of an interactive computer network including servers, routers and associated searchable data base management systems operated by the servers and accessible via the routers, the interactive computer network being accessible via a viewer running on a first computer functioning as a client user workstation, the method comprising the steps of:
activating from the viewer, a user interface agent associated with a primary server;
processing all communication with said user interface agent through a primary router running on said primary server;
processing all communication between said primary server and the client workstation through said primary router;
said user interface agent determining the location of each router capable of accessing a searchable data base management system;
said user interface agent determining each category characterizing the information stored in each searchable data base management system; and said user interface agent assisting the client user to formulate a search request in terms of at least one said category.
2. A method as in claim 1, wherein said step of said user interface agent determining each category characterizing the information stored in each searchable data base management system, includes the step of:
maintaining a cross-reference file accessible by said primary server, said cross-reference file containing a category list including at least one category that identifies the information stored by the data base management system that is operated by said primary server.
3. A method as in claim 1, wherein said step of said user interface agent determining each category characterizing the information stored in each searchable data base management system, includes the step of:
said user interface agent sending a TYP Request to said primary server operating said primary data base management system, said TYP Request requesting for said primary data base management system, the theme type that characterizes the information that is maintained by said primary data base management system.
4. A method as in claim 3, wherein said step of said user interface agent determining each category characterizing the information stored in each searchable data base management system, further includes the step of:
said primary router receiving said TYP Request, retrieving from an initialization file maintained by said primary server, the information satisfying said TYP Request, formatting the information satisfying said TYP Request into a TYP Response, and returning said TYP Response to said user interface agent, said TYP Response including each theme type that characterizes the information that is maintained by said primary data base management system.
5. A method as in claim 1, wherein said step of said user interface agent determining each category characterizing the information stored in each searchable data base management system, includes the step of:
said user interface agent sending a CAT Request to said primary server operating said primary data base management system, said CAT Request requesting for said primary data base management system, each category that characterizes the information that is maintained by said primary data base management system.
6. A method as in claim 5, wherein said step of said user interface agent determining each category characterizing the information stored in each searchable data base management system, further includes the step of:
said primary router receiving said CAT Request, retrieving from a cross-reference file maintained by said primary server, the information satisfying said CAT Request, formatting the information satisfying said CAT Request into a CAT Response, and returning said CAT Response to said user interface agent, said CAT Response including each category type that characterizes the information that is maintained by said primary data base management system.
7. A method as in claim 6, wherein said step of said user interface agent assisting the client user to formulate a search request in terms of at least one said category, further includes the step of:
said user interface agent receiving said CAT Response and for each category in said CAT Response, said user interface creating an object corresponding to the type of said category.
8. A method as in claim 7, wherein said object corresponding to the type of said category is one of an object for a DynamicList type of category, an object for a StaticList type of category, an object for a Single type of category, and an object for a Range type of category.
9. A method as in claim 8, wherein said step of said user interface agent assisting the client user to formulate a search request in terms of at least one said category, includes the step of:
said user interface agent sending a VAL Request to said primary server operating said primary data base management system, said VAL Request requesting for said primary data base management system, each selection to be used to populate each said StaticList category and each said DynamicList category specified in said CAT Response.
10. A method as in claim 6, wherein said step of said user interface agent assisting the client user to formulate a search request in terms of at least one said category, includes the step of:
said user interface agent sending a VAL Request to said primary router, said VAL Request requesting for said primary data base management system, the selections to be used to populate at least one category object for a category specified in said CAT Response.
11. A method as in claim 10, wherein said step of said user interface agent assisting the client user to formulate a search request in terms of at least one said category, further includes the step of:
said primary router receiving said VAL Request, retrieving from said primary data base management system, the information satisfying said VAL Request, formatting the information satisfying said VAL Request into a VAL Response, and returning said VAL Response to said user interface agent, said VAL Response including each selection to be used to populate at least one category object for a category specified in said CAT Response.
12. A method as in claim 11, wherein said step of said user interface agent assisting the client user to formulate a search request in terms of at least one said category, further includes the step of:
said user interface agent receiving said VAL Response and for each category in said VAL Response, said user interface agent populating each category object according to the type of said category.
13. A method as in claim 6, wherein said step of said user interface agent assisting the client user to formulate a search request in terms of at least one said category, includes the step of:
said user interface agent sending a VAL Request to a Hub server operating a Hub data base management system, said VAL Request requesting for all secondary data base management systems, the selections to be used to populate at least one category object for a category specified in said CAT Response.
14. A method as in claim 13, wherein said step of said user interface agent assisting the client user to formulate a search request in terms of at least one said category, further includes the steps of:
a Hub router receiving said VAL Request, said Hub router retrieving from said Hub data base management system operated by said Hub server, the information satisfying said VAL Request, formatting the information satisfying said VAL
Request into a VAL Response, and returning said VAL Response to said user interface agent via said primary router, said VAL Response including each selection to be used to populate at least one category object for a category specified in said CAT Response.
15. A method as in claim 14, wherein said step of said user interface agent assisting the client user to formulate a search request in terms of at least one said category, further includes the step of:
said user interface agent receiving said VAL Response and for each category in said VAL Response, said user interface agent populating each category object according to the type of said category.
16. A method as in claim 1, wherein said step of said user interface agent determining each category characterizing the information stored in each searchable data base management system, includes the step of:
said user interface agent sending a HUB Request to said primary router, said HUB Request requesting the URL for a Hub server.
17. A method as in claim 16, wherein said step of said user interface agent determining each category characterizing the information stored in each searchable data base management system, further includes the step of:
said primary router receiving said HUB Request, retrieving from an initialization file maintained by said primary server, the information satisfying said HUB Request, formatting the information satisfying said HUB Request into a HUB Response, and returning said HUB Response to said user interface agent, said HUB Response including the URL of said Hub server.
18. A method as in claim 1, further comprising the step of:
said user interface agent retrieving information satisfying the client user's search request formulated with the assistance of said user interface agent, wherein said information is retrieved from one of said primary data base management system alone or said primary data base management system and other data base management systems operated by secondary servers.
19. A method as in claim 18, wherein said step of said step of said user interface agent retrieving information satisfying the client user's search request, further comprising the steps of:
said user interface agent sending to said primary router, a LST Request for information that satisfies the client user's search request; and said primary router receiving said LST Request, retrieving from said primary data base management system, the information satisfying said LST Request, formatting the information satisfying said LST Request into a LST Response, and returning said LST Response to said user interface agent, said LST Response including at least a predetermined number of matching records that satisfy the client user's search request.
20. A method as in claim 19, further comprising the step of:
said user interface agent presenting on the client workstation, a display of said matching records in said LST
Response.
21. A method as in claim 20, further comprising the step of:
said user interface agent retrieving and displaying on the client workstation, additional information than is provided in one of said matching records chosen by the client user.
22. A method as in claim 21, wherein said step of said user interface agent retrieving and displaying on the client workstation, additional information than is provided in one of said matching records chosen by the client user, comprises the step of:
said user interface agent issuing to said primary router, a request to return the specific URL of an HTML page that contains additional information than is contained in said one matching record chosen by the client user.
23. A method as in claim 21, wherein said step of said user interface agent retrieving and displaying on the client workstation, additional information than is provided in one of said matching records chosen by the client user, comprises the steps of:
said user interface agent issuing to said primary router a HOM Request for the specific URL of an HTML page that contains additional information than is contained in said one matching record chosen by the client user;
said primary router receiving said HOM Request and querying said primary data base management system for detailed information about said one matching record specified in said HOM Request;
said primary router building an HTML file from said detailed information and saving said built HTML file on said primary server;
said primary router formatting said detailed information satisfying said HOM Request, into a HOM Response and sending said HOM Response to said user interface agent;
and said user interface agent opening a second viewer and setting said second viewer location to the specific URL of said built HTML file in said HOM Response.
24. A method as in claim 18, wherein said step of said user interface agent retrieving information satisfying the client user's search request, includes the step of:
supplying said user interface agent with a profile list containing the server URL for each of a predetermined number of secondary servers that operates a data base management system with data applicable to the client user's search request and accessible to the client user via said user interface agent.
25. A method as in claim 24, wherein said step of supplying said user interface agent with a profile list, includes the steps of:
said user interface agent sending a PRO Request to a Hub router running on a Hub server operating a Hub data base management system, said PRO Request containing the client user's search request and requesting the addresses of less than a predetermined number of secondary routers that have access to data base management systems that are listed on a profile list of said Hub data base management system as having data matching at least one of the selections that compose the client user's search request;
said Hub router receiving said PRO Request from said user interface agent via said primary router;
said Hub router comparing the client user's search request to said profile list maintained on said Hub data base management system;
said Hub router selecting URL's that are listed in said profile list as having data matching at least one of the selections in the client user's search request;
said Hub router formatting a PRO Response containing said URL's selected by said Hub router; and said Hub router returning said PRO Response to said user interface agent via said primary router.
26. A method as in claim 25, wherein said step of said user interface agent retrieving information satisfying the client user's search request, further includes the step of:
said user interface agent receiving said PRO Response and creating a server object corresponding to each URL in said PRO Response.
27. A method as in claim 26, wherein said step of said step of said user interface agent retrieving information satisfying the client user's search request, further comprising the steps of:
said user interface agent sending to said primary router, a LST Request for information that satisfies the client user's search request; and said primary router sending said LST Request to each said secondary router associated with each secondary data base management system associated with each URL in said PRO
Response.
28. A method as in claim 27, wherein said step of said user interface agent retrieving information satisfying the client user's search request, further comprising the steps of:
each said secondary router receiving said LST Request, retrieving from said secondary data base management system associated with said secondary router, the information satisfying said LST Request, formatting the information satisfying said LST Request into a LST Response, and returning said LST Response to said user interface agent via said primary router, said LST Response including at least a predetermined number of matching records that satisfy the client user's search request.
29. A method as in claim 28, further comprising the step of:
said user interface agent presenting on the client workstation, a display of said matching records in said LST
Response.
30. A method as in claim 29, further comprising the step of:
said user interface agent retrieving and displaying on the client workstation, additional information than is provided in one of said matching records chosen by the client user.
31. A method as in claim 30, wherein said step of said user interface agent retrieving and displaying on the client workstation, additional information than is provided in one of said matching records chosen by the client user, comprises the step of:
said user interface agent issuing to said primary router, a request to return the specific URL of an HTML page that contains additional information than is contained in said one matching record chosen by the client user.
32. A method as in claim 30, wherein said step of said user interface agent retrieving and displaying on the client workstation, additional information than is provided in one of said matching records chosen by the client user, comprises the steps of:
said user interface agent issuing to said primary router a HOM Request for the specific URL of an HTML page that contains additional information than is contained in said one matching record chosen by the client user;
said primary router receiving said HOM Request, querying said primary data base management system for detailed information about said one matching record specified in said HOM Request;
said primary server building an HTML file from said detailed information and saving said built HTML file on said primary server;
said primary server formatting said detailed information satisfying said HOM Request, into a HOM Response and sending said HOM Response to said primary router;
said primary router sending said HOM Response to said user interface agent;
said user interface agent opening a second viewer and setting said second viewer location to the specific URL of said built HTML file in said HOM Response.
33. A method as in claim 1, further comprising the step of:
said user interface agent retrieving targeted messaging information related to the client user's search request.
34. A method as in claim 33, wherein said step of said user interface agent retrieving targeted messaging information related to the client user's search request, includes the steps of:
said user interface agent sending an ADV Request to a Hub router running on a Hub server operating a Hub data base management system, said ADV Request containing the client user's search request and requesting the URL's of a predetermined number of HTML files stored on said Hub data base management system and containing targeted messages that relate to at least one of the selections that compose the client user's search request;
said Hub router receiving said ADV Request from said user interface agent via said primary router;
said Hub router comparing the client user's search request to said targeted messages maintained on said Hub data base management system;
said Hub router selecting HTML files that contain targeted messages relating to at least one of the selections in the client user's search request;
said Hub router formatting an ADV Response containing the URL's of said HTML files selected by said Hub router;
and said Hub router returning said ADV Response to said user interface agent via said primary router.
35. A method as in claim 34, wherein said step of said user interface agent retrieving targeted messaging information related to the client user's search request, further includes the step of:
said user interface agent receiving said ADV Response and displaying to the client user at least a portion of the retrieved targeted messaging information in said ADV
Response.
36. A method as in claim 35, wherein said step of said user interface agent retrieving targeted messaging information related to the client user's search request, further includes the step of:
said user interface agent responding to a request of the client user for more of said retrieved targeted messaging information in said ADV Response by providing to the client user the URL in said ADV Response corresponding to the desired targeted messaging information;
said user interface agent permitting the client user to open a separate viewer; and said user interface agent setting said separate viewer to said URL in said ADV Response corresponding to the desired targeted messaging information.
37. A method as in claim 33, further comprising the step of:
each said secondary data base management system updating said profile list.
38. A method as in claim 37, wherein said updating step, includes the steps of:
each secondary router sending via said primary router, a COL Request to a Hub router running on a Hub server operating a Hub data base management system, each said COL
Request containing each category characterizing said secondary data base management system associated with each said secondary router and each selection in each said category;
said Hub router receiving each said COL Request from said primary router;
said Hub router checking each said COL Request for validity;
said Hub router updating said profile list according to each said valid COL Request;
for each said valid COL Request, said Hub router formatting and sending a COL Response to said primary router; and said primary router returning each said COL Response to each said secondary router from which a valid COL Request was received.
39. A method of making a selection from a plurality of data base management systems each housed on a computer connected by an interactive computer network and accessible to the client user, based on a data request formatted by the client user via a user interface agent, the method comprising the steps of:
configuring at least one computer on the interactive computer network as a Hub server functioning as a URL Hub for said interactive computer network, said Hub server serving a searchable Hub data base management system maintaining on the Hub data base a server profile containing for each primary and secondary server information listing each theme type that characterizes the information that is maintained by each data base management system available to said client user served by an additional computer functioning as a server, said profile information containing each theme type, and for each theme type each category of information that is maintained on each said data base management system served by an additional computer functioning as a server;
maintaining on said primary server an initialization file containing an initialization list that includes information for accessing the data base management system of said server, said Hub server's URL, and each theme type that characterizes the information that is maintained on the primary data base management system available to said user interface agent;
maintaining on each said secondary server an initialization file containing at least initialization information for accessing the data base management system available to said user interface agent;
processing all communication between said primary server and said Hub server through a Hub router running on said Hub server; and processing all communication between said user interface agent through a primary router running on said primary server.
CA002209265A 1997-02-27 1997-06-27 Apparatus and method for information retrieval via internet Abandoned CA2209265A1 (en)

Applications Claiming Priority (2)

Application Number Priority Date Filing Date Title
US80747497A 1997-02-27 1997-02-27
US08/807,474 1997-02-27

Publications (1)

Publication Number Publication Date
CA2209265A1 true CA2209265A1 (en) 1998-08-27

Family

ID=25196458

Family Applications (1)

Application Number Title Priority Date Filing Date
CA002209265A Abandoned CA2209265A1 (en) 1997-02-27 1997-06-27 Apparatus and method for information retrieval via internet

Country Status (1)

Country Link
CA (1) CA2209265A1 (en)

Cited By (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
WO2001003003A1 (en) * 1999-06-30 2001-01-11 Synerges Oy System for internationalization of search input information
WO2001046856A1 (en) * 1999-12-20 2001-06-28 Youramigo Pty Ltd An indexing system and method
EP1330736B1 (en) * 2000-09-06 2016-04-13 Oracle International Corporation Providing content from multiple services

Cited By (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
WO2001003003A1 (en) * 1999-06-30 2001-01-11 Synerges Oy System for internationalization of search input information
WO2001046856A1 (en) * 1999-12-20 2001-06-28 Youramigo Pty Ltd An indexing system and method
EP1330736B1 (en) * 2000-09-06 2016-04-13 Oracle International Corporation Providing content from multiple services

Similar Documents

Publication Publication Date Title
US7062475B1 (en) Personalized multi-service computer environment
US6278993B1 (en) Method and apparatus for extending an on-line internet search beyond pre-referenced sources and returning data over a data-packet-network (DPN) using private search engines as proxy-engines
US7856453B2 (en) Method and apparatus for tracking functional states of a web-site and reporting results to web developers
US5953732A (en) Hypertext information retrieval using profiles and topics
US8631036B2 (en) Associative search engine
US7076453B2 (en) System and method for designing and operating an electronic store
US5862330A (en) Technique for obtaining and exchanging information on wolrd wide web
US6041326A (en) Method and system in a computer network for an intelligent search engine
US6253208B1 (en) Information access
CN101228521B (en) Integration of personalized portals with WEB content syndication
US7158986B1 (en) Method and system providing user with personalized recommendations by electronic-mail based upon the determined interests of the user pertain to the theme and concepts of the categorized document
US7085997B1 (en) Network-based bookmark management and web-summary system
US5778367A (en) Automated on-line information service and directory, particularly for the world wide web
EP0718784A1 (en) Personalized information retrieval
EP0918424A2 (en) Automatic association of predefined user data with query entry fields
US20100185599A1 (en) Exposing rich internet application content to search engines
US20030103090A1 (en) Ephemeral list for object-action navigation
US6175864B1 (en) Method and apparatus for storyboard scripting of application programs running on a computer system
JP2003501725A (en) Generation and presentation of server-side WEB summary
JP2004516579A (en) Method and system for requesting information from a network client
AU2007203146A1 (en) Use of extensible markup language in a system and method for influencing a position on a search result list generated by a computer network search engine
JP2002073678A (en) System and method for sharing retrieval engine inquiry web base
CA2299035A1 (en) System and method for sharing bookmark information
KR20070007131A (en) System and method for responding to a search request in a computer network
CA2209265A1 (en) Apparatus and method for information retrieval via internet

Legal Events

Date Code Title Description
FZDE Dead