[ Team LiB ] Previous Section Next Section

15.2 RDF Gateway, a Commercial RDF Database

RDF Gateway is a database and integrated web server, utilizing RDF, and built from the ground up rather than on top of either an existing web server (such as Apache) or database (such as SQL Server or MySQL). At this time, it works only within the Windows environment, specifically Windows NT 4.0, 2000, or XP. The installation is extremely easy; I was able to download, install, and run the application in less than five minutes.

Download an evaluation version of RDF Gateway at http://www.intellidimension.com. This chapter was written with the beta version of the product, but Version 1.0 released as this went into production.

RDF Gateway is an application server providing web page template support similar to ASP or JSP. This includes data storage, support for a scriptlike data query language, and web services. Aside from the use of RDF, all aspects of the tool are proprietary, though many are based on current open source efforts, including the RDF parser associated with Redland (discussed in Chapter 11).

Once installed, an RDF Gateway icon is added to the system tray. Right-clicking on this opens a menu that can be used to start or stop the server or to open a properties window with information about the Gateway, such as port, database location, and so on. The properties page is informational only—unless there's a problem with the server, these settings shouldn't need to be changed.

The Gateway can be managed through an online interface, where you can do things such as add or remove users from access to the repository, as shown in Figure 15-1.

Figure 15-1. Adding a new user for RDF Gateway
figs/prdf_1501.gif

You can also view the data tables used for the RDF Gateway repository or add COM objects, web services, packages, and so on. These externally created extensions to the Gateway can then be accessed through the scripting language supported by the product: RDFQL, an ECMAScript-based scripting language. RDFQL is used within RDF Server Pages (RSP) similarly to how Java is used in JSP and VBScript in ASP. As do these embedded scripting page approaches, RDFQL supports several built-in and global objects to facilitate application development. Among the objects supported with the released version of RDF Gateway are:

DataSource

Provides access to RDF statements stored in an external file or within the database

Request

Contains HTTP request information, including environment variables

Response

To return response

Security

Access to RDF Gateway security features

Server

Access to server features

Session

Created for every session and used primarily for setting session variables

RDFNode

To access a specific piece of information from an RDF data source

Package

Access to an RDF Gateway package

There are other objects such as strings, enumerators, and so on, but this listing gives you an idea of the built-in capability associated with RDFQL. Example 15-1 is a simple RSP that does nothing more than read an external RDF/XML page into a DataSource object and then use that object's formatting capability to print the RDF/XML out to the page.

Example 15-1. Reading in and writing out remote RDF/XML document
<%
// Create an in-memory data source
// connect to remote RDF/XML document using the Inet data service
var monsters = new DataSource("inet?url=http://burningbird.net/articles/monsters1.
rdf&parsetype=rdf");

//set the content type 
Response.ContentType = "text/xml"; 

//use the Format command on the datasource to generate an rdf+xml representation of the 
//contents of the datasource 
Response.Write(monsters.Format('application/rdf+xml')); 

%>

As you can see from the example, scripting blocks are separated from the rest of the page with angle bracket/percent sign enclosures.

RDF Gateway can be extended through the use of COM/COM+ objects, as well as through Gateway packages, which are distinct applications or libraries of functions, which can be used in any of the Gateway-managed pages. In addition, the underlying data repository for RDF Gateway can be accessed directly through JDBC from within Java applications and through ADO if you're programming Windows-based applications. RDFCLI, a Win32 library, also provides the fastest and most direct access to the RDF Gateway services.

At first glance RDF Gateway appears similar to IIS/COM+ and other application/web servers of similar make, until you take a closer glance at the data queries. This is where the product's RDF roots shine through.

I pulled an example of how data manipulation can work with RDF Gateway from the help files included with the application. Example 15-2 shows how to create and insert RDF statements into an in-memory data source and then how to print select predicate values out.

Example 15-2. Creating and then querying RDF data within memory datastore
foaf = new DataSource(  );

INSERT 
    {[http://www.w3.org/1999/02/22-rdf-syntax-ns#type] 
     [mailto:[email protected]] 
     [http://xmlns.com/foaf/0.1/Person]}
     
    {[http://xmlns.com/foaf/0.1/firstName] 
     [mailto:[email protected]] 
     "Derrish"}
     
    {[http://xmlns.com/foaf/0.1/knows] 
     [mailto:[email protected]] 
     [mailto:[email protected]]}
         
    {[http://www.w3.org/1999/02/22-rdf-syntax-ns#type] 
     [mailto:[email protected]] 
     [http://xmlns.com/foaf/0.1/Person]}

    {[http://xmlns.com/foaf/0.1/firstName] 
     [mailto:[email protected]] 
     "Geoff"}

    {[http://xmlns.com/foaf/0.1/knows] 
     [mailto:[email protected]]
     [mailto:[email protected]]}
     
    INTO #foaf;

var ary = foaf.getObjects(  );

for (var i = 0; i < ary.length; i++)
{
    dumpPerson(ary[i]);
}

function dumpPerson(node)
{       
    var s = node["http://xmlns.com/foaf/0.1/firstName"];
    
    var ary = node["http://xmlns.com/foaf/0.1/knows"]; 
    
    if (ary != null)
    {   
        s += " -> ";
    
        for (var i = 0; i < ary.length; i++)
        {
            if (i > 0)
                s += ", ";
                
            s += ary[i]["http://xmlns.com/foaf/0.1/firstName"];
        }
    }
    
    Response.write(s);  
}

After exposure to RDQL in Chapter 10, the insert statements based on an RDF triple in the first part of the code should be relatively familiar. Once the data's added to the store, the second part of the code example accesses the firstName property for both the FOAF resource, as well as all the resources that map to the knows predicate, resulting in an output of:

Derrish -> Geoff
Geoff -> Derrish

RDF Gateway also provides the ability to query against multiple datastores, merging the results as appropriate. For instance, you can access data from three different data sources with a query such as the following:

select ?p ?s ?o using #ds1, #ds2, #ds3 where {?p ?s ?o};

RDF Gateway also includes strong inferential support through two types of rules: statement and function. These allow incorporation of process logic within the semantics of the more traditional query. Again, using examples from the help file for the Gateway product, a statement rule would be like the following:

INFER {[acme:size] ?product_id "big"} FROM 
{[itd:size] ?product_id "large"} OR {[itd:size] ?product_id "x-large"};

That's a lot of strange syntax, but what this statement is really saying is that there is a rule, {[acme:size] ?product_id "big"}, that is true if the body, {[itd:size] ?product_id "large"} OR {[itd:size] ?product_id "x-large"}, evaluates to true, and which can then be used within an RDFQL query as follows:

SELECT ?acme_size FROM inventory WHERE {[acme:size] ?product_id ?acme_size};

The use of an inferential rule allows you to map one type of schema on to another and to then use these within the queries.

How rules work becomes even more apparent when one looks at a function rule, such as the following:

INFER GetLeadTime(?product_id, ?lead_time) FROM
	{[itd:assembly_time] ?product_id ?assembly_time} AND
	SWITCH
	(
	case {[itd:component] ?product_id ?component_id}:
		GetLeadTime(?component_id, ?lead_time_comp) 
			AND ?lead_time = ADD(?lead_time_comp,
?assembly_time)
	default:
		?lead_time = ?assembly_time
	)

Using this function rule within a query, such as the following, returns the lead time for large products. However, within the rule itself, the actual lead time is accumulated from summing all lead times for the individual components that make up the part:

SELECT ?lead_time USING inventory WHERE
	{[itd:size] ?product_id "large"} AND  GetLeadTime(?product_id, ?lead_time);

Learning to work with the inferential engine of RDF Gateway isn't trivial, but the potential of encapsulating complex logic into a form that can be used and reused within queries has considerable appeal. To enable this encapsulation, RDF Gateway provides support for a rulebase, a set of RDFQL rules that can be included within a query. Redefining the function statement into a rulebase would be as follows:

rulebase app_rules
{
	// ITD size to Acme size mapping rule
	INFER {[acme:size] ?product_id "big"} FROM 
	{[itd:size] ?product_id 'large'} OR {[itd:size] ?product_id "x-large"};

	// Lead time function rule

	INFER GetLeadTime(?product_id, ?lead_time) FROM
	{[itd:assembly_time] ?product_id ?assembly_time} AND
	SWITCH
	{
	case {[itd:component] ?product_id ?component_id}:
		getLeadTime(?component_id, ?lead_time) AND ?lead_time = ADD(?lead_time, 
?assembly_time)
	default:
		?lead_time = ?assembly_time
	};
};

The rulebase would then be used in a query in the following manner:

SELECT ?product_id USING inventory RULEBASE NONE WHERE {[itd:size] ?product_id "big"};

It is this inferential engine support, in addition to the RDF/XML base, that makes RDF Gateway unique among application servers.

    [ Team LiB ] Previous Section Next Section