Although the advantages of object-oriented (OO) programming are well-known none among the main distributed OO middlewares (DCOM [COM, DCOM], CORBA [OMG99], and Java RMI [RMI]) has been widely adopted for the developing of Internet applications. Developers seems to perceive these approaches as over-complex (COM and CORBA), proprietary (COM and RMI), and incompatible with current WWW development practices. Recognizing these difficulties more WWW-friendly proposals based on XML are starting to appear. This paper describes a simple OO middleware system that uses RDF as its Interface Definition Language (IDL) and HTTP ([HTTP]) as its transport protocol. This approach provides most of the advantages of object-orientation while mantaining full compatibility with the existing WWW infrastructure and requiring only modest changes to existing applications to allow them to partecipate to the Object Web.
The imminent advent of the OO Web has been announced many times in the last years. The advantages of OO programming with respect to more traditional approaches are so evident that most observers had assumed that it was only a question of time before it would become dominant in the field of Internet development. Marc Andreessen in 1996 [AND96] could confidently say:
The next shift catalyzed by the Web will be the adoption of enterprise systems based on distributed objects and IIOP (Internet Inter-ORB Protocol) ... The next version of Netscape Navigator and Netscape SuiteSpot Servers will be IIOP-compliant. IIOP will be integral to everything we do. Netscape Navigator will be able not only to browse content but also to browse objects. We expect to distribute 20 million IIOP clients over the next 12 months and millions of IIOP-based servers over the next couple of years. We'll put the platform out there so that people can start developing for it.
Marc Andreessen, 1996
While Netscape, Sun and other companies provided the basic tools the idea that the Object Web was just behind the corner had been widely popularized by the extremely successful books on this subject by Robert Orfali et al. (for ex: [ORF97]). The main question for most observers was not if the OO Web was going to happen but rather if it would have been dominated by CORBA or DCOM. Unfortunately after such a brilliant start the Object Web has not made much progress. The large majority of developers are still sticking to "traditional" techniques such as CGI scripts ([CGI]) or the, only slightly more advanced, Java Servlets ([SRVLT]). The Object Web is simply not happening: a simple delay or a major failure?
It's not easy to see why such a promising technology might have failed to capture the developers' imagination but some of these elements might have contributed:
Both CORBA and COM originate in the pre-Internet era and lack two essential characteristics:
Simplicity is probably nowhere as important as in the Internet environment. A good example is given by the WWW itself, an hypertext system that provides only the most basic form of hypertext linkage: the, often broken, uni-directional link. At the beginning of the Nineties, when the WWW was born, there were a number of much more sophisticated hypertext systems available but none of them has had an impact even remotely comparable to that of the "humble" WWW. We now live in a world that has been throughly changed by the effects of the marriage of the Internet with such a simple technology. OO development has the potential of propelling the Web to a new era but probably needs to go through a similar process of simplification.
Recently a number of new XML-based protocols have been proposed that might match these requirements. These protocols adopt some form of XML schema language as their IDL, encode their remote procedure calls (RPC) in XML and use HTTP as their main transport protocol. A substantial activity is taking place in this area expecially after the appearance of the influential SOAP ([SOAP]) proposal. The main problem now seems to be the sheer number of available alternatives (see [XMLPC] for a summary). The W3C is working on this problem ([XMLPA]) but it will probably take some time before a common standard is agreed upon and widely adopted.
There are two basic differences between the current "procedural" web and the Obiect-Oriented Web (OOW):
Explicit and typed interfaces can go a long way in simplifying WWW development and improving the WWW surfing experience.
For developers they mean:
For users the OOW would in particular mean browsers that can make sense of a more significant part of the information stored in the WWW and that could use this increased understanding to be more helpful. Consider for example an user that is looking for a person. He knows that this person works for some American university but doesn't know which one. Most university have a search facility on their WWW sites. A smart browser would be able to apply the user query in parallel to a number of different university sites. Unfortunately where an human user sees an academic WWW site with a search service a browser sees only another HTML page with a form to display. It has no way of knowing the 'meaning' of what it's displaying. This is exactly the problem that the Semantic Web concept proposed by Tim Berners-Lee is trying to solve and an OO framework is an indispensable part of it. In our example if the search services of the different sites where defined as objects of the same type the browser could easily recognize this fact and offer the user the possibility of searching them in parallel.
The Web is a (huge) set of connected objects. Each object has a unique ID and a (MIME) type. The objects are weaved together in a web by a special kind of object: the HTML page. The HTML page is a very versatile object indeed that provides: human-readable information, a user interface and the links that hold the WWW together. Not only HTML pages can be considered objects but the HTTP protocol itself, on which the WWW is based, was initially inspired by OO programming and this fact is reflected in its terminology. The HTTP standard specifies a set of methods (a typical OO term) that are applied to remote resources (objects). But if the WWW was originally influenced by the OO mindset it has not evolved as a proper OO system. The way WWW applications are currently designed and developed is much more reminiscent of "spaghetti programming" than of OO concepts.
Even if the WWW is not a proper OO system it's not hard to impose some OO principles on it. The OOM described in this paper aims to do exactly so: provide a distributed OO model that is as simple as possible and as compatible as possible with the existing WWW infrastructure. It has been developed for the European projects NESSTAR ([NESSTAR) and FASTER ([FASTER) and it's called NESSTAR Obiect Oriented Middleware (NEOOM) (2.1). Its basic characteristics are:
A formal definition of the RDF model can be found in the [RDF] and [RDFS] documents and won't be repeated here. The extensions defined for NEOOM are themselves defined using RDF schema. In this paper I will focus on providing an informal introduction to the framework. In the simplest terms the NEOOM object model can be defined as follows:
The properties are the attributes of an object, they can be either:
The methods are the operations that can be performed on an object, they may have 0 to N parameters. Methods are not present in the basic RDF model but they can be easily added by defining two classes, Method and Parameter:
<rdfs:Class rdf:about="&n;Method"> <rdfs:label>Method</rdfs:label> <rdfs:comment>A Method</rdfs:comment> </rdfs:Class> <rdfs:Class rdf:about="&n;Parameter"> <rdfs:label>Parameter</rdfs:label> <rdfs:comment>A Method Parameter</rdfs:comment> </rdfs:Class>
Object's methods are defined as classes that extend the basic Method class. Defining a method as a class might sound a bit unusual but has many advantages. The first advantage is that if a method is an object we can describe it using RDF. So, for example, methods can have methods. This is actually the case, the Method class has two methods, one to execute the method and one to cancel it (2.1.1):
<rdfs:Class rdf:about="&m;Execute"> <rdfs:subClassOf rdf:resource="&n;Method" /> <rdfs:label>Execute</rdfs:label> <n:label>Execute the method {&o;}</n:label> <rdfs:comment>Execute the method.</rdfs:comment> <rdfs:domain rdf:resource="&n;Method" /> <rdfs:range rdf:resource="&n;String" /> </rdfs:Class> <rdfs:Class rdf:about="&m;Cancel"> <rdfs:subClassOf rdf:resource="&n;Method" /> <rdfs:label>Cancel</rdfs:label> <n:label>Cancel the execution of the method {&o;}</n:label> <rdfs:comment>Cancel the execution of the method.</rdfs:comment> <rdfs:domain rdf:resource="&n;Method" /> <rdfs:range rdf:resource="&n;Void" /> </rdfs:Class>
Another advantage is that the actual invocations of the method can be represented very naturally as instances of the method class.
As an example of a method definition we can examine the Login method of the Server class:
<rdfs:Class rdf:about="http://www.nesstar.org/rdf/Server/Login"> <rdfs:subClassOf rdf:resource="http://www.nesstar.org/rdf/Method" /> <rdfs:label>Login</rdfs:label> <n:label>Authenticate user '{http://www.nesstar.org/rdf/Server/Login#userID}' with server {http://www.nesstar.org/rdf/Method/obj}</n:label> <rdfs:comment>Authenticate with the server.</rdfs:comment> <rdfs:domain rdf:resource="http://www.nesstar.org/rdf/Server" /> <rdfs:range rdf:resource="http://www.nesstar.org/rdf/Void" /> </rdfs:Class> <n:Parameter rdf:about="http://www.nesstar.org/rdf/Server/Login#userID"> <rdfs:label>userID</rdfs:label> <rdfs:comment>The user's ID</rdfs:comment> <rdfs:domain rdf:resource="http://www.nesstar.org/rdf/Server/Login" /> <rdfs:range rdf:resource="http://www.nesstar.org/rdf/String" /> </n:Parameter> <n:Parameter rdf:about="http://www.nesstar.org/rdf/Server/Login#userPassword"> <rdfs:label>userPassword</rdfs:label> <rdfs:comment>The user's password</rdfs:comment> <rdfs:domain rdf:resource="http://www.nesstar.org/rdf/Server/Login" /> <rdfs:range rdf:resource="http://www.nesstar.org/rdf/Password" /> </n:Parameter>
Login is defined as a class, subclass of the class Method and has two parameters: userID and userPassword. Method parameters are defined as instances of the Parameter class. Parameters are very similar to RDF properties. They have a domain property that specifies the method class that they apply to and a range property that specifies the type of the parameter value. In this case the range of userID is a String and that of userPassword is a Password.
An actual invocation of Login could be represented in RDF (with namespaces omitted) as follows:
<Login r:about="http://155.245.254.82:4000/obj/temp0"> <obj r:resource="http://155.245.254.82:4000/obj/Server"/> <userID>admin</n3:userID> <userPassword>my password</n3:userID> </Login>
The result of a method call is, just as in the case of a normal HTTP request, either an error or a MIME document. Complex objects or set of objects can be returned as XML elements or RDF descriptions. For example, in the NESSTAR system, we have Catalogs objects that contain Datasets objects. When a catalog is queried through the Query operation it will return an XML document containing the RDF descriptions of the Datasets that satisfy the query: perform an example query.
Each NEOOM object, just as any Web document, can be retrieved by performing an HTTP GET at its URL. When so accessed an object will return an XML/RDF description of its properties plus any additional information that the server might deem suitable to transmit together with it (for example the descriptions of objects that are linked to the requested object to spare the client the burden of multiple requests). As an example let's consider the object with ID: http://da1881.essex.ac.uk:4000/obj/Server. If we access this location clicking on the link we will receive an XML document that contains the following description:
<r:RDF xmlns:r="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:n4="http://www.nesstar.org/rdf/Server#" xmlns:n="http://www.nesstar.org/rdf/" xmlns:n5="http://www.nesstar.org/rdf/Catalog#" xmlns:n3="http://www.nesstar.org/rdf/Dataset#" xmlns:s="http://www.w3.org/TR/1999/PR-rdf-schema-19990303#"> <n:Server r:about="http://155.245.254.82:4000/obj/Server"> <n4:statEngine r:resource="http://155.245.254.82:4000/obj/NSDStatEngine" /> <n4:catalogs r:resource="http://155.245.254.82:4000/obj/catalogs" /> <n4:version>1.1</n4:version> <n4:revision>Thu Nov 09 19:21:34 GMT+00:00 2000</n4:revision> <n4:debug>off</n4:debug> <n4:services r:resource="http://155.245.254.82:4000/obj/services" /> <n:administrators r:resource="http://155.245.254.82:4000/obj/administrators" /> <s:comment>The UKDADEV Server.</s:comment> <n:accessCondition r:resource="http://155.245.254.82:4000/obj/serverCondition" /> <s:label>UKDADEV</s:label> </n:Server> </r:RDF>
This is an RDF description of an object of type http://www.nesstar.org/rdf/Server. The object has a set of properties. Some of them, such as version, are literals. Others, such as catalogs, are pointers to other objects. An RDF description works very much like a machine-understandable form of HTML. Just as an HTML page an RDF object provides both immediatly accessible information (the value of the literal properties) as well as links to other objects.
What this description doesn't tell us is what this object is for, what is the meaning of its properties (what does the version or catalogs properties stand for?) and what we can do with it, that's to say which methods we can apply to it. This information can be found at the URL of the object type: http://www.nesstar.org/rdf/Server. The object type is also an object and is accessible through its URL. What we get is another XML document that starts with a description of the class Server:
<rdfs:Class rdf:about="http://www.nesstar.org/rdf/Server"> <rdfs:label>Server</rdfs:label> <rdfs:comment>A server used to publish data and metadata.</rdfs:comment> </rdfs:Class>
The comment property informs us of the purpose of the Server objects: "publish data and metadata". The document continues by describing the properties and methods of the type. For example the version property is defined as follows:
<rdfs:Property rdf:about="http://www.nesstar.org/rdf/Server#version"> <rdfs:label>version</rdfs:label> <rdfs:comment>The server software version name.</rdfs:comment> <rdfs:domain rdf:resource="http://www.nesstar.org/rdf/Server" /> <rdfs:range rdf:resource="http://www.nesstar.org/rdf/String" /> <n:readOnly>true</n:readOnly> </rdfs:Property>
This description contains both human and machine-understandable information. The human-understandable information is mainly in the comment that tells us that the property value is "the server software version name". The machine-understandable part tells us that this is a property of all the instances of type http://www.nesstar.org/rdf/Server (domain property) and that the value of this property is of type http://www.nesstar.org/rdf/String (range property). Domain and range are standard RDFS properties defined in the standard RDFS namespace: http://www.w3.org/TR/1999/PR-rdf-schema-19990303#. The property readOnly is a NEOOM extension, defined in the NEOOM namespace http://www.nesstar.org/rdf/ and indicates that this property cannot be changed remotely.
Objects can be rendered in a more user-friendly way using an Object Browser that will automatically blend instance and class-level information.
How do we apply methods to an object or change its properties? The Object Model that we have briefly examined is abstract and completly protocol-independent. To be able to use it we need to map it to a concrete transport protocol. We have already seen how we can use HTTP to access an object description. In this section we will see how we can use it to execute objects methods. The basic principle is that every method call should be represented in the simplest and most compatible way. The standard WWW of performing operations is to use HTML forms ([HFORM]). The user types in the required information, his input is then packed up an sent to the server using an HTTP GET or POST method. We can perform OO calls using the same mechanism.
If the operation has only a few string parameters the client can perform it using a simple HTTP GET. This is the case of the Login operation: a login on the server object http://da1881.essex.ac.uk:4000/obj/Server could be executed using an ordinary Web browser in this way:
A look at the HTML source will clarify how it works:
<FORM ACTION="http://155.245.254.82:4000/obj/Server" METHOD=GET> <input type=hidden name=http://www.nesstar.org/rdf/method value="http://www.nesstar.org/rdf/Server/Login"> <input type=text size=40 name=http://www.nesstar.org/rdf/Server/Login#userID> <input type=password size=40 name=http://www.nesstar.org/rdf/Server/Login#userPassword> <input type=submit value=execute> </FORM>
It's a normal HTML FORM element that uses the HTTP GET method, whose action target is the object http://155.245.254.82:4000/obj/Server and that has three parameters:
If there are many parameters or if one of the parameters is a file an HTTP POST should be used. This is the case of the SaveFile operation, used to upload a file to the Server object. This is a slightly more complex FORM that uses the HTTP method POST with an encoding type of multipart/form-data:
<FORM ACTION="http://155.245.254.82:4000/obj/Server" METHOD=POST enctype="multipart/form-data"> <p><input type=hidden name=http://www.nesstar.org/rdf/method value="http://www.nesstar.org/rdf/Server/SaveFile"> <br><b>serverPath:</b> <input type=text size=40 name=http://www.nesstar.org/rdf/Server/SaveFile#serverPath> <br><b>file:</b> <input type=file size=40 name=http://www.nesstar.org/rdf/Server/SaveFile#file> <p><input type=submit value=execute></FORM>
Similarly to change the value of an object property:
Set property 'debug' to a new value:
The HTML source shows that we have again a simple HTML FORM whose target is the object whose property has to be changed. The FORM has a single parameter whose name is the URL of the property to change:
<FORM ACTION="http://155.245.254.82:4000/obj/Server" METHOD=GET> <input type=text size=40 name=http://www.nesstar.org/rdf/Server#debug> <input type=submit value=execute> </FORM>
To summarize: the object-oriented calls of NEOOM are mapped as directly as possible to normal HTTP methods. A method call can so be interpreted in two ways: as an OO method call as specified by NEOOM or as an ordinary, though slightly verbose, HTML FORM call (2.3.1).
An advantage of using such a simple and direct mapping to HTTP is that each method invocation corresponds to a URL that can be "bookmarked" and reapplied at a later time. For example the invocation of the Login method for an user with ID john and password sunny would correspond to the URL: http://155.245.254.82:4000/obj/Server?http%3A%2F%2Fwww.nesstar.org%2Frdf%2Fmethod=http%3A%2F%2Fwww.nesstar.org%2Frdf%2FServer%2FLogin&http%3A%2F%2Fwww.nesstar.org%2Frdf%2FServer%2FLogin%23userID=john&http%3A%2F%2Fwww.nesstar.org%2Frdf%2FServer%2FLogin%23userPassword=sunny (2.3.2).
Although NEOOM methods can be performed using a normal WWW browser in most cases final users will access NEOOM objects through specialised clients. In the NESSTAR project for example we have three different clients: two stand-alone Java clients respectively for power-users and data publishers and one WWW client for normal users. The clients operate by performing method calls on the NEOOM objects and presenting the output to the user in a convenient way. In addition of using NEEOM objects they can also be NEOOM objects in their own right. "Objectifying" the client can be quite useful, if a client is an object:
Let's analyze these two points in more detail.
Most applications offer some form of macro language to let users automate simple task. Unfortunatly macro languages are largerly ignored by novice users that tend to perceive them as too complex to use. There is a notable exceptions: WWW browsers' bookmarks. We do not normally think of bookmarks as macros but there are good reasons to consider them as such. A bookmark is an association between a (usually meaningful, often user assigned) name and a WWW action that can be replayed by a simple click. As it corresponds to a single action it's a kind of 'degenerated' macro (but from the user point of view it represents the result of a process that might have involved several steps, such as finding a particular piece of information traversing multiple pages). Notwhistanding its simplicity, or most likely because of it, the bookmarks are by far the most useful "macros" ever devised.
One limit of browser's bookmarks is that they can be used to replay WWW actions but not the browser's own actions. There are no bookmarks to set your browser preferences to a given value or to show a given HTML page in a window sized in a certain way and with the text font set to your preferred dimension. Bookmarks are used to provide quick access to server-side functionality but not to client-side functionality.
In the Java clients developed for the NESSTAR project we use bookmarks extensively. As the clients are objects all client-side operations can be bookmarked at will. Bookmarks can also be replayed in groups, sequentially or in parallel, so providing a simple way of automating tasks. Effectively the bookmarks window provides a simple visual macro language that can be used to quickly create test suites or PowerPoint©-like demos.
Consider the following NESSTAR scenario. A social resercher writes a paper to analyze the results of a recent election and publish it as an HTML document on the Web. In the document he inserts links to a number of statistical operations, for example a cross-tabulation that shows how different political parties have ben voted in different counties. He creates these bookmarks using a NESSTAR Java client. The operations URLs contain rendering information that specifies how the cross-tabulation is to be displayed (for example: as a table or in graphical form). Later another reseacher reads the paper and click on the cross-tabulation link. As he has the same Java client used by the authors it can display the result of the operation. A second researcher performs the same operation, he doesn't have the same client but he is offered the possibility of displaying the result of the operation on its normal WWW browser through a NESSTAR WWW client. This is possible because the NESSTAR Java and Web client implement the same NEOOM interface. If other clients are added at a later time (say: a client optimised for mobile access or for blind users) they will also be able to display the result of the operations even if they were originally created by a completely different client. Similarly if a new client with additional capabilities is made available it could still provide compatibility with the existing operations by implementing (and possibly extending) the previous clients' interfaces.
For an object to be the target of a method call it must have a fixed URL. This is clearly not true for client-side objects (what is the URL of the browser that you are using to read this page?). There are a number of possible solutions to this problem (2.4.2.1) the one we use is based on interface proxies. An interface proxy is a server side object that will catch all calls addressed to a client-side object and redirect them to the actual client for execution. The mechanims works as follow:
To summarize the steps needed to deploy a NEOOM object are the following:
Though the development of NEOOM objects is rather straighforward it's still useful to have a sofware development kit for your language of choice. We have developed a simple Java SDK that provides:
On the client side every RDF class is mapped to a corresponding Java class. This is an excerpt from the Server class (with only the version and catalogs properties and the Login method listed):
... /** *
A server used to publish data and metadata. *
Code automatically generated from APIMaker on Mon Nov 13 15:31:57 GMT+00:00 2000 **/ public class Server extends RDFObject { ... /** * @return The list of Catalogs that the servers hosts. **/ public RDFRef get_catalogs() {return _catalogs;} RDFRef _catalogs; public void set_catalogs(RDFRef catalogs) throws Exception {_catalogs=catalogs;} /** * @return The server software version name. **/ public String get_version() {return _version;} String _version; public void set_version(String version) throws Exception {_version=version;} /** *
Authenticate with the server. * @param userID The user's ID * @param userPassword The user's password * @return the bookmark that implements this operation **/ public Bookmark Login(String userID,String userPassword) throws Exception { Parameters pars = new Parameters(); pars.put("http://www.nesstar.org/rdf/Server/Login#userID",userID); pars.put("http://www.nesstar.org/rdf/Server/Login#userPassword",userPassword); return MethodInvocation.getOpBookmark(this,new url\("http://www.nesstar.org/rdf/Server/Login"),pars); } ... }
Similarly on the server side every method is mapped to a Java class that can be extended to provide the actual implementation.
More information on the Nesstar Software Development Kit is available at http://www.nesstar.org/sdk.
NEOOM is currently used in the NESSTAR and FASTER projects. These projects aims to provide an easy and flexible way of publishing statistical data. NESSTAR servers are currently being deployed in a number of Data Archives across Europe. The whole system is composed by a set of distributed NEOOM objects: Servers (as the Server object showed as an example in the previous sections), Catalogs (searchable repositories of statistical datasets), Datasets (the published data and metadata), etc.
Even if the basic NEOOM framework is in place there is still plenty of work to do:
The work reported has been done as part of the NESSTAR and FASTER projects funded by the European Commission's DGXII under the 4th and 5th Framework Telematics Applications Programmes.
1.1: This difficulty can be overcome using HTTP-tunneling, that's to say by mapping the OOM wire protocol on top of HTTP. Unfortunatly this adds extra-complexity and doesn't work particularly well as the uni-directional nature of the HTTP protocol (a typical Request-Reply protocol) is not a good match for OOM protocols that normally assume bi-directional communication among the objects.
2.1: The extreme ugliness of this acronym has the advantage of making it unique. Searching for it on the Internet returns no result. This should simplify the retrieval of related information. Suggestion for better, but still unique names are naturally welcome.
2.1.1: These methods are mainly used when performing an operation that is subject to access control. In this case the user, in order to get the right to execute the operation, might have to provide credentials, accept the terms of some agreement, pay some money, etc. While this steps are performed the operation originally requested has to be suspended. The execute and cancel methods are used to control the final execution or cancellation of the operation. NEEOM provides a simple but very flexible OO access control mechanism that for reasons of space is not discussed here.
2.3.1: The mechanism described can naturally be used only for methods that have parameters of one of the basic types (strings, integers, etc). What about parameters that are objects? In practice we have found out that there is surprisingly little need for this kind of parameters. Anyway they can be easily transferred by coding the objects as RDF or XML and transmitting them as a normal string parameter.
2.3.2: Notoriously this will not work for operations with file parameters. This problem can be solved by having the server return a partially filled form anytime it receive a request whose file parameters content is not present. The user can then execute the operation by simply confirming the presented form.
2.4.2.1: A particularly simple one would use the proposed data: protocol name. Unfortunatly this is currently implemented only by the latest versions of the Netscape browsers.
2.4.2.2: Multiple MIME type can be used to differentiate among different implementation of the same interface so that an user can execute an operation using different clients.
2.4.2.3: The way an association is established between a MIME type and an application is unfortunatly not standardized across different operating systems. In a Windows environment it's performed modifying the Registry, under Unix it will normally imply registering with all the installed WWW browsers.
[AND96] Marc Andreessen, 1996. IIOP and the distributed objects model http://home.netscape.com/columns/techvision/iiop.html
[CGI] The Common Gateway Interface, National Center for Supercomputing Applications at the University of Illinois at Urbana - Champaign, IL, USA. http://hoohoo.ncsa.uiuc.edu/cgi/.
[COM] COM; in Microsoft Developer Network Online Library (http://msdn.microsoft.com/library/default.htm), Platform SDK, Component Services. Microsoft, 1999.
[DCOM] C. Kindel. Distributed Component Object Model Protocol -- DCOM/1.0; in Microsoft Developer Network Online Library (http://msdn.microsoft.com/library/default.htm), Specifications, Technologies and Languages. Microsoft, 1997.
[FASTER] FASTER Project Home Page. http://www.faster-data.org.
[HTTP] R. Fielding, et. al. RFC 2616, Hypertext Transfer Protocol -- HTTP/1.1. Internet Society, June 1999.
[HFORM] HTML 4.01 Specification - Forms http://www.w3.org/TR/html4/interact/forms.html W3C, 1999.
[NESSTAR] NESSTAR Project Home Page. http://www.nesstar.org.
[OMG99] The Common Object Request Broker: Architecture and Specification; revision 2.3. The Object Management Group (OMG), Framingham MA, June 1999.
[ORF97] Rober Orfali, Dan Harkey, Jeri Edwards. Instant CORBA. New York, Wiley, 1997.
[RDF] Resource Description Framework (RDF) Model and Syntax Specification. http://web4.w3.org/TR/REC-rdf-syntax/. W3C, 1999.
[RDFS] Resource Description Framework (RDF) Schema Specification 1.0. http://web4.w3.org/TR/rdf-schema/. W3C, 2000.
[RMI] Java Remote Method Invocation. http://java.sun.com/products/jdk/rmi/. Sun Microsystems, 1999.
[SOAP] Simple Object Access Protocol (SOAP) 1.1. http://www.w3.org/TR/SOAP/ W3C, 2000.
[SRVLT] Java Servlet Specification 2.3 http://java.sun.com/aboutJava/communityprocess/first/jsr053/servlet23_PFD.pdf. Sun Microsystems, 2000.
[XMLPA] XML Protocol Activity. http://www.w3.org/2000/xp/ W3C, 2000.
[XMLPC] XML Protocol Comparisons. http://www.w3.org/2000/03/29-XML-protocol-matrix W3C, 2000.
[XMLS] XML Schema http://www.w3.org/XML/Schema. W3C, 2000.
[XMLSP] XML Schema Primitive Datatypes http://www.w3.org/TR/xmlschema-2/#built-in-primitive-datatypes. W3C, 2000.