Xj3D Networking Component

Intro

VRML, as file format and runtime system is very heavily dependent on networking interaction. Anything but the most trivial file will reference at least one external file, in the form of a texture, script, externproto or inline. In order to support the more advanced extensions to VRML, such as the Universal Media Library, we need to support URNs as well as the more common URLs. These are not supported in the core JDK toolkits, so this component provides all of the low-level interfaces for dealing with fetching and processing content at the lowest level.

Background

From the start of the VRML 2.0 process, there was a concerted push by various members to make sure the specification supported URNs in addition to the traditional URLs. URNs allow the application to nominate content to use without needing to know the location. This then allows the browser to locate the nearest resource, either from disk, cache or somewhere on a network without the end user ever needing to deal with missing files.

Motivation

The stock JDK APIs provide a facility for fetching content from URLs but not from URNs. That meant in developing this capability for VRML, we would need to include our own code and library. Because we may need to do this in many different places within the scene graph, the networking aspects can be separated out to a standalone component. In addtion, as there were already publically available libraries to do most of the grunt work, the contents of this compenent are designed to extend the existing library with VRML/X3D specific requirements rather than writing our own from scratch.


Structural Overview

Because this component is designed to extend the standard interfaces provided by a third-party library, there is not really that much architecture to the design. It is just a series of disparate classes that extend a collection of interfaces. These classes are described in Figure 1.


Figure 1: UML description of the static structure of classes in the network component.

When describing the process of going from a URN/URL to the form that we use internally it is easiest to think of it in terms of a pipeline with a number of stages. Some of these stages are taken care of by the underlying library, and other stages we can modify or supplement with our own code. A rough description of the stages would be:

  1. Check the string for correctness/resolve relative references
  2. Decide whether to resolve as URN or URL
  3. Resolve a URN into a specific location or ordered set of locations
  4. Determine protocol used to contact server
  5. Locate appropriate protocol handler
  6. Open connection and receive header/meta data
  7. Locate appropriate processor for the content of the stream
  8. Process content of stream
In all of these steps, we really only need to override three - 3, 5 and 7. In providing appropriate extensions at these steps, it means we can modify or provide other capabilities providing in the following steps.

Code Layout

As you can see in Figure 1, there are three separate packages within the component, where the component is represented in the real code by org.web3d.net package. Within the component, the separate packages represent the functionality at the various stages of processing a request to load a file.

URN resolution services

The first stage we get involved in the process is working within the URN resolution mechanism. If the URN starts with the Namespace ID of web3d, that's our cue to take control of the resolution and attempt to find the listed resource.

The current (non-spec-compliant) form of a web3d URN is

  urn:web3d:group:path
Our class tries to provide a generic handler for all of the web3d namespace. Because everything follows the same format, if we know the group and a path to root directory of the local installation of that functionality and/or remote locations, it is simple to process each request. To facilitate this, our class has a method registerPrefixLocation() for registering the group and the root path to find them. Once set, if any URN that matches the group keyword is asked to be resolved, we assemble the appropriate string representing the full location (IAW the relevant RFCs and request types) and return the values to the caller. If we don't know how to handle it, null is returned, as per spec.

Protocol Handling

Once it has been decided where to fetch a file from, the next step that we get involved with is the how. For most protocols like HTTP and files, we leave that to the underlying system. However, we do have one custom protocol type that we must handle so that we can be spec-compliant: Provision of inline ECMAScript code in the URL field of a script with the protocol name javascript. The implementation of the protocol handler takes the full "URL" string of the the inline javascript, strips the leading javascript: keyword and returns the rest of the string as a stream to the caller.

Content handling

At the end of the chain is the content handlers. These process the raw bytes from the stream independent of protocol used to fetch them. For our implementation we provide an instance of the factory that can then produce our custom content handlers as desired. From the public viewpoint, the actual content types handled are invisible. Our basic types are the VRML content itself (ie we're processing an inline)


Extending the Code

Adding new protocol types

Adding new URN namespaces

Adding a new file type


References


[ Xj3D Homepage | Xj3D @ Web3d | Screenshots | Dev docs | Dev Releases | Contributors | Getting Started ]
Last updated: $Date: 2004-04-30 04:50:26 $