Adding a new Profile

Intro

The X3D specification contains the ability to add new functionality, such as new "standard" node types through the use of components. Each component typically contains a small number of nodes and your average VRML files needs lots of different nodes. That, in turn, requires a number of components needing to be declared in the VRML file. To reduce the amount of text needed to be typed by the end user, and to also specify a set of known functionality, the X3D specification also introduces a shortcut mechanism called profiles.

A profile is a shorthand way of telling the VRML application of the list of components and the levels of components required for the rest of the file. A profile is no more and no less than this.

Profile Management in Xj3D

As a toolkit, Xj3D has to be much more flexible in its management of profile information compared to a traditional browser. The way the end user decides what capabilities are to be used needs to be ignored so that profiles and components always are used. So, to do this, we use one of the standard Java mechanisms - property files. Everything is managed by property files and the standard classes provided by Xj3D load and manage their information with these property files.

The codebase will automatically make use of profiles and components if you use the standard classes. The focus of this handling is the factory classes that produce node instances. The standard factories are used throughout the code, so the effects are consistent across the code. If you decide to use something other than our standard factory mechanism, and implementation, then you are on your own as you will need to implement your own profile/component manangement system.

Within the provided code, the class to focus on is org.web3d.vrml.renderer.DefaultNodeFactory. This implementation of the org.web3d.vrml.nodes.VRMLNodeFactory manages the full profile and component handling within the toolkit. We'll base the rest of this tutorial around how this class describes and works with profiles and components.

Writing a new Profile

Working with profiles in Xj3D is quite simple and there are plenty of example files you can copy to work with. Starting right at the top is the file xj3d.properties. In this file is the bootstrapping mechanism to find out what profile definitions are available on the machine. This file lives in the root of your CLASSPATH. By default, there will be one provided in the Xj3D JARS, but if you want to add your own information then you will need to provide another version in your classpath that will be found before the standard Xj3D JAR files. If you are running from source, then you can find the property file in $X3D_HOME/src. (Note: The location of this file may change prior to the M5 release).

After opening the property file in your favourite text editor, you should notice a line near the top that defines the property value xj3d.profiles. The value of the property is a whitespace separated list of the profile names. The names defined here must exactly represent the name that would be found in an X3D file (UTF8 and XML encodings use the same naming scheme), including capitalisation. Note that each name is a single word that does not contain any whitespace, as per the X3D specification. Come up with a new name for your profile and append it to the end of that list. Save the file and close the file.

Now you will need to provide a file that defines the content of that profile. That file that defines the profile is another Java property file. The name of this file is profile_name.properties and exists in the a directory that can be found by the CLASSPATH. One other requirement to the name is that the profile name is all lower case. This is to avoid problems with non-case sensitive operating systems. So, if your profile name is Interactive, your property file would be named interactive.properties.

The content of the property file is very simple one property defines a title string for the profile title. This string is just any free text you wish to supply. The second value is really a list of values. As you know, a profile is a list of components, so you need profiles. To declare each of the components you need, you create a list of properties that are declared as component.number. The number is a sequence number starting at zero. The squence must be unbroken. For the value, you provide a string that is the profile code, followed by a colon and then an integer that is the level of that component to use. For example:

component.0=core:1
component.1=time:1
component.2=group:2
component.3=geom:2
component.4=appear:1
The name to use is the formal profile code, according to the X3D specification. If your profile uses one of your custom components, it is that code you have assigned to the component declaration. Once you have finished the declarations, save the file and exit the editor. You are now finished.

Debugging

Of course, something will end up going wrong somewhere. Perhaps you have declared the use of a component or level of a component that Xj3D does not support. Another might be that the profile definition file cannot be found. There are many ways that profile handling can fail, so this section is a guide for where to look and when you might expect to see errors.

During startup of the DefaultNodeFactory it will look for the main property file xj3d.properties. At this point all it does is look for the property definition, but does not look for the property file for each profile. As part of the effort to keep startup times high and memory usage low, we don't load anything until it is needed.

Individual property files are loaded and processed at the point where the first call to setProfile() is called. When called, this method looks to see if the named profile has been loaded. If it has not, then it will load and process the property file. If the file is not found then you will see the first of the errors - an UnsupportedProfileException. The first thing to look for is whether your property file can be found as part of the runtime CLASSPATH. It probably isn't.

As the profile definition is loaded, the factory will check for each component that you have requested. If the component is already loaded, it will check for the request level being supported. If not, a UnsupportedComponentException will be generated. If the component hasn't been loaded yet, then it will go off and load that and then check for the required level. Any errors issued at this stage usually result in the same UnsupportedComponentException.

Once it makes it through all of these, you can be assured that at least the components and profiles have loaded correctly. You should see no more errors that are directly related to this process. Any errors after this point will be due to issues like the node class in a particular component is not found or some other construction issue.


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