Building your own contextualised B2B registry
Note: Return to tutorial view.
This tutorial explains how to configure, install and write applications using GRIA's contextualised registry component
Introduction
Introduction to this tutorial
The purpose of this tutorial is to show developers, how to install, configure and use GRIA's Contextualised B2B Registry Component. The Registry Component (RC) provides common functionality inherent to all registries and a query translation functionality that supports mapping of ooXmlQL queries into corresponding XQuery queries.

Overview: How to build your own registry service.
The RC can be used for instance to create your own specialized registry service, which provides a set of specific registry functions and is configured using a service-specific Registry Domain Model (RDM).
Registry Component - Background
A description of the interfaces of the registry component
Architecture
The Registry Component (RC) encompasses three main layers: the Registry Core Component (RCC), the Registry Management Facility (RMF) and the Registry Database Connectivity (RDC).
The RDC provides a collection of interfaces for accessing and storing XML data as well as managing users and access rules on the underlying database. These interfaces are implemented using a specialised database connection. Currently the preferred implementation is based on an XML:DB API[1] connection.

Architecture of the registry component
The RCC includes interfaces for registration and discovery of XML documents, an interface for the Registry Domain Model (RDM) as well as an OWL-based implementation of this interface, and an implementation of the XML-based query language ooXmlQL.
The RDM specifies the concepts and relationship between these concepts that can be used by a specific registry instance. XML documents are stored and can be retrieved with respect to these concepts. Relationships define dependencies between concepts that can be used for specifying join queries and sub queries. A special is-a relationship is introduced for specifying hierarchies of concepts. Sub concepts inherit relationships from their super concepts. Currently only simple inheritance is supported by the RDM[2].
ooXmlQL is a query language designed to support join queries and sub queries based on the underlying RDM. Thereby the selection and filter statements are language independent, and can for instance be defined by XPath or XQuery. For execution, ooXmlQL queries will be translated to a language supported by the RDC. In the current realisation this is XQuery. However, ooXmlQL is not limited to XQuery.
The configuration of a concrete registry instance is done by the RMF. This module provides interfaces for configuration and for user management. User management encompass creation and deletion of users as well as groups, users can belong to. The configuration interface allows setting up the RDM as well as to dynamically adding new concepts and relationships. Furthermore it supports the registration of predefined queries that can be executed by name through the discovery interface of the RCC[3].
Interfaces
In the following we give a brief overview of the different interfaces used by the RC.
Registration

Registration interface
Method description:
- registerEntity: allows the user to register an entity under a specific concept.
- deleteEntity: removes an entity from a given concept.
- deleteAllEntities: removes all entities accessible by the user.
- insertRelationship: creates a relationship between two entities. Precondition: the used relationship is defined within the RDM between the concepts the two entities belong to. If the relationship has an inverse relationship (owl:inverseOf) the inverse relationship will be automatically added.
Discovery

Discovery interface
Method description:
- getRegistryDomainModel: return the RDM of the registry.
- lookup: looks up an entity by its concept and identifier.
- lookupByConcept: looks up entities by a specified concept.
- getIdentifier: returns the identifier of a document/entity.
- query: queries the registry using a Java class (XmlQuery.java) representing ooXmlQL queries (see appendix).
- queryBySpecificQL: queries the registry using a specified query language. If the query language is not supported by the concrete registry, an exception will be thrown.
- executePredefinedQuery: executes a predefined query, stored in the registry.
Configuration

Configuration interface
Method description:
- setRegistryDomainModel: sets up the RDM of the registry and configures the registry accordingly.
- getRegistryDomainModel: return the RDM of the registry.
- createConcept: creates a new concept in the RDM and updates the registry.
- insertBidirectionalRelationship: adds a new bidirectional relationship between two concepts (using owl:inverseOf).
- insertRelationship: adds a new relationship between two concepts.
- registerPredefinedQuery: registeres a new predefined query under a concrete name.
- setPredefinedQueries: registers a set of predefined queries using the XML representation of predefined queries (see appendix).
User Management

User Management interface
Method description:
- addUser: adds a new user to the list of registry users.
- removeUser: removes a user from the list of registry users.
- addGroupToUser: adds a new group to the list of groups a user belongs to.
- removeGroupFromUser: removes a group from the list of groups a user belongs to.
- listUsers: lists all users of the registry.
- listGroups: lists all groups used within the registry.
Implementation Details - Constants
Several interfaces provides constants used within the registry component. The following list summarises these interfaces.
- PropertyConstants: general identifiers used in ‘registry.properties’ file, e.g. ‘registry.conf.dir’ (package uk.ac.soton.itinnovation.registry.icomponent.util)
- QueryLanagueNS: namespaces of query languages (package uk.ac.soton.itinnovation.registry.icomponent.namespace)
- XmlPropertyConstants: identifiers used in ‘registry.properties’ file, specific for an XML based implementation of the registry (package uk.ac.soton.itinnovation.registry.component.xml.util)
- XmlDatabaseConstants: constants used internally like queries.xml for predefined queries (uk.ac.soton.itinnovation.registry.component.xml.db)
- XmlPropertyConstantsXmlDb: constants used within the XML:DB connector implementation of the registry (package uk.ac.soton.itinnovation.registry.component.xml.db.xmldb)
[2] Future enhancements could contain multiple inheritance and restrictions on relationships like arity.
[3] In the current realisation only XQuery queries can be stored and executed. In future the specification of predefined queries should support different query languages, and the query processor should evaluate if it can process a predefined query. Especially ooXmlQL queries should be supported.
Building your own registry
This section explains how to install, configure and use the registry component for building your own registry applications.
Initialisation
Install eXist
Install eXist in Tomcat or
standalone, following the instructions of the eXist documentation. It is
recommended to change and memorize the “admin” password using the eXist admin
HTML client.
Registry Properties
After installing
eXist you have to create and setup a ‘registry.properties’
file. This file contains information about the eXist database location,
administrator details and standard access rules applied by the registry on
concepts and entities registered with the registry. See the appendix for an example of the properties file.
Implementation Factory Properties
The ‘implementationfactory.properties’ file used MUST contain the
following setting:
# Communication channel to registry database
uk.ac.soton.itinnovation.registry.component.xml.db.XmlDbAccessManager
= uk.ac.soton.itinnovation.registry.component.xml.db.xmldb.XmlDbAccessManagerXmlDb
This file defines the actual implementation class of the db connection. Currently this is based on XML:DB.
Write an Install Client
Having the ‘registry.properties’ file correctly defined, you now can write a
simple Java client for installing the registry. You have to start the client by
providing the location where to find the properties file. This is done by using
the command line parameter
–Dregistry.conf.dir=<directory>
The following code is an example
install client.
import java.util.Properties;
import uk.ac.soton.itinnovation.registry.icomponent.util.PropertyConstants;
import uk.ac.soton.itinnovation.registry.icomponent.util.PropertyManagement;
import uk.ac.soton.itinnovation.registry.management.runtime.Install;
public class InstallRegistryClient {
/**
* Install the registry...
*/
public static void main(String[] args){
/*
* Setup registry properties...
*/
Properties systemProps = System.getProperties();
String configDir = systemProps.getProperty(PropertyConstants.registryConfigurationDir);
if(configDir==null){
String msg = "Configuration directory is not specified, "+
"e.g. -Dregistry.conf.dir=... ";
throw new RuntimeException(msg);
}
PropertyManagement.configurationDirectory = configDir;
System.out.println("Installation the registry...");
Install.init();
System.out.println("Finish installation.");
PropertyManagement.resetProperties();
}
}
Configuration
Configuration of the registry can be
done before usage of the registry or dynamically during runtime. However, in
principle there are two possibilities to configure the registry using the Configuration interface: using external
documents (based on OWL and XML) or using the appropriate Java methods (like createConcept).
Writing a configuration client using OWL and XML
The following Java class describes an
example how to use OWL and XML to configure the RDM as well as the predefined
queries specified in XML. For more information see the appendix.
import java.io.File;
import java.net.MalformedURLException;
import java.util.Properties;
import uk.ac.soton.itinnovation.registry.component.xml.db.XmlDatabaseConstants;
import uk.ac.soton.itinnovation.registry.component.xml.model.RegistryDomainModelJenaConnector;
import uk.ac.soton.itinnovation.registry.icomponent.model.RegistryDomainModel;
import uk.ac.soton.itinnovation.registry.icomponent.search.parser.ParsingException;
import uk.ac.soton.itinnovation.registry.icomponent.util.PropertyConstants;
import uk.ac.soton.itinnovation.registry.icomponent.util.PropertyManagement;
import uk.ac.soton.itinnovation.registry.management.factory.RegistryManagementFactory;
import uk.ac.soton.itinnovation.registry.management.factory.StartupRegistryManagementFactory;
import uk.ac.soton.itinnovation.registry.management.factory.SupportedTechnology;
import uk.ac.soton.itinnovation.registry.management.icomponent.configuration.Configuration;
import uk.ac.soton.itinnovation.registry.management.icomponent.configuration.ConfigurationException;
public class ConfigurationRegistryClient {
/**
* Configuration client...
*/
public static void main(String[] args) throws ConfigurationException, MalformedURLException, ParsingException {
/*
* Setup registry properties...
*/
Properties systemProps = System.getProperties();
String configDir = systemProps.getProperty(PropertyConstants.registryConfigurationDir);
if (configDir == null) {
String msg = "Configuration directory is not specified, " +
"e.g. -Dregistry.conf.dir=...";
throw new RuntimeException(msg);
}
PropertyManagement.configurationDirectory = configDir;
System.out.println("Configuration the registry...");
/*
* Get a configuration object...
*/
RegistryManagementFactory factory = StartupRegistryManagementFactory.createRegistryFactory(SupportedTechnology.XML);
Configuration configuration = factory.createConfigurationFacility();
/*
* load predefined queries...
*/
System.out.println(" setup predefined queries...");
File f = new File(configDir+"/"+XmlDatabaseConstants.queriesFile);
if (!f.canRead()) {
System.out.println(" no predefined queries specified.");
System.out.println(" file " + f.toString() + " not found.");
} else {
configuration.setPredefinedQueries(configDir+ "/" +XmlDatabaseConstants.queriesFile);
}
/*
* load registry domain model (RDM)...
*/
System.out.println(" setup domain model...");
f = new File(configDir +"/"+ XmlDatabaseConstants.registryDomainModelName);
if (!f.canRead()) {
System.out.println(" no registry domain model specified.");
System.out.println(" file " + f.toString() + " not found.");
} else {
RegistryDomainModel model = RegistryDomainModelJenaConnector.loadRegistryDomainModelFromURL(f.toURL().toString());
configuration.setRegistryDomainModel(model);
}
System.out.println("Finish configuration.");
PropertyManagement.resetProperties();
}
}
Using dynamic configuration
Using the dynamic adaptation of the
RDM is illustrated in the following Java class.
import java.util.Properties;
import uk.ac.soton.itinnovation.registry.icomponent.util.PropertyConstants;
import uk.ac.soton.itinnovation.registry.icomponent.util.PropertyManagement;
import uk.ac.soton.itinnovation.registry.management.factory.RegistryManagementFactory;
import uk.ac.soton.itinnovation.registry.management.factory.StartupRegistryManagementFactory;
import uk.ac.soton.itinnovation.registry.management.factory.SupportedTechnology;
import uk.ac.soton.itinnovation.registry.management.icomponent.configuration.Configuration;
import uk.ac.soton.itinnovation.registry.management.icomponent.configuration.ConfigurationException;
public class DynamicConfigurationRegistryClient {
/**
* Configuration client...
*/
public static void main(String[] args) throws ConfigurationException {
/*
* Setup registry properties...
*/
Properties systemProps = System.getProperties();
String configDir = systemProps.getProperty(PropertyConstants.registryConfigurationDir);
if (configDir == null) {
String msg = "Configuration directory is not specified, "
+ "e.g. -Dregistry.conf.dir=... ";
throw new RuntimeException(msg);
}
PropertyManagement.configurationDirectory = configDir;
System.out.println("Dynamic configuration of the registry...");
/*
* Get a configuration object...
*/
RegistryManagementFactory factory = StartupRegistryManagementFactory.createRegistryFactory(SupportedTechnology.XML);
Configuration configuration = factory.createConfigurationFacility();
/*
* concepts to be added under 'Reference'...
*/
String[] billingConcepts = { "SLAConversation", "TradeAccountConversation", "RemoteSLAService" };
for (String concept : billingConcepts) {
if (!configuration.getRegistryDomainModel().containsConcept(concept)) {
// add concept as a sub concept of concept 'Reference'
configuration.createConcept(concept, "Reference");
}
}
/*
* concept added under 'ManagerResource'
*/
if (!configuration.getRegistryDomainModel().containsConcept("MegaAccount")) {
// add concept as a sub concept of concept 'Reference'
configuration.createConcept("MegaAccount", "ManagerResource");
}
/*
* add a owner/owned relationship between 'MegaAccount' and 'Account'
*/
String fromConcept = "MegaAccount";
String toConcept = "Account";
if (!configuration.getRegistryDomainModel().containsRelationship(fromConcept, "owner", toConcept)) {
System.out.println("add relationship...");
configuration.insertBidirectionalRelationship(fromConcept,"owner","owned", toConcept);
}
/*
* print out the XML representation of the RDM...
*/
System.out.println(configuration.getRegistryDomainModel().getXmlRepresentation());
System.out.println("Finish configuration.");
PropertyManagement.resetProperties();
}
}
User Management
The user management of the registry allows
dynamically adding and removing users to and from the registry. Further is
supports group management of the users.
import java.util.Properties;
import uk.ac.soton.itinnovation.registry.icomponent.usermanagement.UserManagement;
import uk.ac.soton.itinnovation.registry.icomponent.usermanagement.UserManagementException;
import uk.ac.soton.itinnovation.registry.icomponent.util.PropertyConstants;
import uk.ac.soton.itinnovation.registry.icomponent.util.PropertyManagement;
import uk.ac.soton.itinnovation.registry.management.factory.RegistryManagementFactory;
import uk.ac.soton.itinnovation.registry.management.factory.StartupRegistryManagementFactory;
import uk.ac.soton.itinnovation.registry.management.factory.SupportedTechnology;
/**
* User Management Client...
*/
public class
UserManagementRegistryClient {
public static void main(String[] args) throws UserManagementException{
/*
* Setup registry properties...
*/
Properties systemProps = System.getProperties();
String configDir = systemProps.getProperty(PropertyConstants.registryConfigurationDir);
if(configDir==null){
String msg = "Configuration directory is not specified, " +
"e.g. -Dregistry.conf.dir=... ";
throw new RuntimeException(msg);
}
PropertyManagement.configurationDirectory = configDir;
/*
* Get a configuration object...
*/
RegistryManagementFactory factory = StartupRegistryManagementFactory.createRegistryFactory(SupportedTechnology.XML);
UserManagement userManagement = factory.createUserManagementFacility();
/*
* Add user to the registry...
*/
userManagement.addUser("myUser", "myPass", new String[]{"myGroup", "all"});
PropertyManagement.resetProperties();
}
}
Registry Client
This section describes how to implement a registry client enabling registration and discovery.
Factories
After installation the new registry is ready to use. However, configuration and user management can happen beforehand or on-the-fly later on during usage of the registry. In this section we focus on the registration and discovery possibilities of the registry.
In the following classes we use a factory to instantiate discovery and registration classes.
public class XmlRegistryFactory<E> implements RegistryFactory<E> {
public Discovery<E> createRegistryDiscoveryFacility() {
return new XmlDiscoveryFacility<E>();
}
public Registration createRegistrationFacility() throws AccessException {
return new XmlRegistrationFacility();
}
public Credential createCredentialFacility() {
return new XmlCredentialFacility();
}
}
The class XmlRegistryFactory that implements the RegistryFactory interface is instantiated like this:
new XmlRegistryFactory<XMLResource>();
However, it is not required to use this class, instead the user can also create the required interfaces by directly calling the appropriate classes, e.g.
Discovery<XMLResource> = new XmlDiscoveryFacility<XMLResource>();
Finally, the interface Credential is used for login and logout of a user who wants to access the registry. This interface can be used in the following way
Registration registration = new XmlRegistrationFacility();
Credential credential = new XmlCredentialFacility();
/*
* the registration interface should use the following credential...
*/
registration.setCredential(credential);
/*
* user login to the registry...
*/
credential.login("myUser", "myPass", "myGroup");
...
/*
* logout current user...
*/
credential.logout();
Registration of XML documents and establishing of relationships between XML documents
In the following example code we explain how to register XML documents with the registry and how to establish relationships between independent documents, whereby the relationships and concepts are defined by the RDM of the previous examples.
When registering, the user can provide a unique identifier to the registry for the document or the registry creates a unique identifier on its own. The result of a successful registration is however the identifier used for the document. These identifiers are required to create relationships between concrete XML documents.
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Properties;
import uk.ac.soton.itinnovation.registry.icomponent.access.AccessException;
import uk.ac.soton.itinnovation.registry.icomponent.access.Credential;
import uk.ac.soton.itinnovation.registry.icomponent.registration.Registration;
import uk.ac.soton.itinnovation.registry.icomponent.registration.RegistrationException;
import uk.ac.soton.itinnovation.registry.icomponent.util.PropertyConstants;
import uk.ac.soton.itinnovation.registry.icomponent.util.PropertyManagement;
import uk.ac.soton.itinnovation.registry.test.factory.RegistryFactory;
import uk.ac.soton.itinnovation.registry.test.factory.StartupRegistryFactory;
import uk.ac.soton.itinnovation.registry.test.util.SupportedTechnology;
public class RegistrationRegistryClient {
/**
* Registration client...
*/
@SuppressWarnings("unchecked")
public static void main(String[] args) throws RegistrationException, AccessException, URISyntaxException {
/*
* setup registry properties...
*/
Properties systemProps = System.getProperties();
String configDir = systemProps.getProperty(PropertyConstants.registryConfigurationDir);
if(configDir==null){
String msg = "Configuration directory is not specified, "+
"e.g. -Dregistry.conf.dir=... ";
throw new RuntimeException(msg);
}
PropertyManagement.configurationDirectory = configDir;
// working with the registry...
RegistryFactory factory = StartupRegistryFactory.createRegistryFactory(SupportedTechnology.XML);
Registration registration = factory.createRegistrationFacility();
Credential credential = factory.createCredentialFacility();
registration.setCredential(credential);
/*
* user login to the registry...
*/
System.out.println("Login...");
credential.login("myUser","myPass", "myGroup");
String path = "./";
ClassLoader classLoader = RegistrationRegistryClient.class.getClassLoader();
/*
* get the document URIs...
*/
URI[] uris = new URI[] {
classLoader.getResource(path+"sla.xml").toURI(),
classLoader.getResource(path+"slaConversationEPR.xml").toURI(),
classLoader.getResource(path+"slaservice.wsdl").toURI(),
classLoader.getResource(path+"slaServiceEPR.xml").toURI(),
classLoader.getResource(path+"slaTemplate.xml").toURI()
};
/*
* register resources...
*/
System.out.println("Register resources...");
String sla = registration.registerEntity("Sla", uris[0], null);
String slaConvEPR = registration.registerEntity("SLAConversation", uris[1], null);
String slaService = registration.registerEntity("Service", uris[2], "slaservice.wsdl");
String slaServiceEPR = registration.registerEntity("RemoteSLAService", uris[3], null);
String slaTemplate = registration.registerEntity("SlaTemplate", uris[4], null);
/*
* create relationships between entities...
*/
System.out.println("Create relationships...");
registration.insertRelationship(sla, "derivedFrom", slaTemplate);
registration.insertRelationship(sla, "has", slaConvEPR);
registration.insertRelationship(slaService, "has", slaServiceEPR);
registration.insertRelationship(slaService, "parent", sla);
/*
* logout current user...
*/
System.out.println("Logout.");
credential.logout();
}
}
Discovery of registered XML documents
Discovery is the process of finding XML documents previously registered. The RC supports different kinds of discovery, like lookup, query or executing predefined queries by name. The Java program below illustrates some of these features by example. The current realisation of the RC supports XQuery, XPath and ooXmlQL as query languages. However, we illustrate only ooXmlQL, because this language supports join queries and sub queries based on the defined RDM. Using XQuery is much more complicated, because the user has to know the internal structure for building correct queries.
import java.io.StringReader;
import java.util.Properties;
import org.xmldb.api.base.XMLDBException;
import org.xmldb.api.modules.XMLResource;
import uk.ac.soton.itinnovation.registry.icomponent.access.AccessException;
import uk.ac.soton.itinnovation.registry.icomponent.access.Credential;
import uk.ac.soton.itinnovation.registry.icomponent.discovery.Discovery;
import uk.ac.soton.itinnovation.registry.icomponent.discovery.DiscoveryException;
import uk.ac.soton.itinnovation.registry.icomponent.discovery.ResultIterator;
import uk.ac.soton.itinnovation.registry.icomponent.search.object.ParameterValue;
import uk.ac.soton.itinnovation.registry.icomponent.search.parser.ParsingException;
import uk.ac.soton.itinnovation.registry.icomponent.search.parser.XmlQueryParser;
import uk.ac.soton.itinnovation.registry.icomponent.search.query.XmlQuery;
import uk.ac.soton.itinnovation.registry.icomponent.util.PropertyConstants;
import uk.ac.soton.itinnovation.registry.icomponent.util.PropertyManagement;
import uk.ac.soton.itinnovation.registry.test.factory.RegistryFactory;
import uk.ac.soton.itinnovation.registry.test.factory.StartupRegistryFactory;
import uk.ac.soton.itinnovation.registry.test.util.SupportedTechnology;
/**
* Discovery client.
*/
public class DiscoveryRegistryClient {
@SuppressWarnings("unchecked")
public static void main(String[] args) throws DiscoveryException,AccessException, XMLDBException, ParsingException {
/*
* Setup registry properties...
*/
Properties systemProps = System.getProperties();
String configDir = systemProps.getProperty(PropertyConstants.registryConfigurationDir);
if (configDir == null) {
String msg = "Configuration directory is not specified, "
+ "e.g. -Dregistry.conf.dir=... ";
throw new RuntimeException(msg);
}
PropertyManagement.configurationDirectory = configDir;
/*
* Discovery interface
*/
RegistryFactory<XMLResource> factory = (RegistryFactory<XMLResource>)
StartupRegistryFactory.createRegistryFactory(SupportedTechnology.XML);
Discovery<XMLResource> discovery = factory.createRegistryDiscoveryFacility();
Credential credential = factory.createCredentialFacility();
discovery.setCredential(credential);
/*
* login
*/
credential.login("myUser","myPass", "myGroup");
/*
* execute predefined queries...
*/
System.out.println("execute predefined query...");
ResultIterator<XMLResource> i = discovery.executePredefinedQuery(
"LookupByDocId",
new ParameterValue[] {
new ParameterValue("docId", "slaservice.wsdl")
}
);
System.out.println("output of predefined query...");
for (XMLResource r : i) {
System.out.println(r.getContent());
}
System.out.println();
/*
* lookup by identifier...
*/
System.out.println("lookup by identifier...");
XMLResource r = discovery.lookup(null, "slaservice.wsdl");
System.out.println(r.getContent());
System.out.println();
/*
* discovery by ooXmlQL query...
*/
System.out.println("query using ooXmlQL...");
String ooXmlQueryStr = ""
+ "<query>\n"
+ " <select>$ref</select>\n "
+ " <declare name=\"ns1\">"
+ " http://it-innovation.soton.ac.uk/2005/grid</declare>\n"
+ " <declare name=\"addressing\">"
+ " http://www.w3.org/2005/08/addressing</declare>\n"
+ " <from as=\"$ref\">"
+ " <class name=\"Reference\"/>"
+ " </from>\n "
+ "</query>";
System.out.println("Number of results: "+ query("ooXmlQL", discovery, ooXmlQueryStr));
/*
* discovery by ooXmlQL query with join...
*/
System.out.println("query using ooXmlQL with join...");
ooXmlQueryStr = ""
+ "<query>\n"
+ " <select>$refAble $epr</select>\n "
+ " <declare name=\"ns1\">"
+ " http://it-innovation.soton.ac.uk/2005/grid</declare>\n"
+ " <declare name=\"addressing\">"
+ " http://www.w3.org/2005/08/addressing</declare>\n"
+ " <from as=\"$refAble\">"
+ " <union>"
+ " <class name=\"Service\"/>"
+ " <class name=\"ManagerResource\"/> "
+ " </union> "
+ " <join on=\"has\" as=\"$epr\" class=\"Reference\"/> "
+ " </from>\n "
// + " <where> "
// + " $epr//addressing:Metadata/ns1:type = \"SlaService\" "
// + " </where>"
+ "</query>";
System.out.println("Number of results: "+ query("ooXmlQL with join", discovery, ooXmlQueryStr));
/*
* another discovery by ooXmlQL query with join...
*/
System.out.println("query using ooXmlQL with join...");
ooXmlQueryStr = ""
+ "<query>\n"
+ " <select>$template</select>\n "
+ " <declare name=\"ns1\">"
+ " http://it-innovation.soton.ac.uk/2005/grid</declare>\n"
+ " <declare name=\"addressing\">"
+ " http://www.w3.org/2005/08/addressing</declare>\n"
+ " <from as=\"$epr\">"
+ " <class name=\"Reference\"/>"
+" <join on=\"holdBy\" as=\"$refAble\" class=\"Sla\"> "
+ " <join on=\"derivedFrom\" as=\"$template\" class=\"SlaTemplate\"/> "
+ " </join> "
+ " </from>\n "
+ " <where> "
+ " $template//currency = \"EUR\" "
+ " </where>"
+ "</query>";
System.out.println("Number of results: " + query("ooXmlQL with join", discovery, ooXmlQueryStr));
/*
* logout
*/
credential.logout();
}
@SuppressWarnings("unchecked")
private static int query(String label, Discovery<XMLResource> discovery, String ooXmlQueryStr)
throws DiscoveryException, AccessException, XMLDBException, ParsingException {
StringReader reader = new StringReader(ooXmlQueryStr);
XmlQuery ooXmlQuery = XmlQueryParser.readQuery(reader,discovery.getRegistryDomainModel());
ResultIterator<XMLResource> i = discovery.query(ooXmlQuery);
int number = output(label, discovery, i);
return number;
}
private static int output(String label, Discovery<XMLResource> discovery, ResultIterator<XMLResource> i)
throws XMLDBException, DiscoveryException, AccessException {
System.out.println("output of " + label);
int j = 0;
for (XMLResource r : i) {
/*
* get identifier of document...
*/
String identifier = discovery.getIdentifier(r, "").toString();
/*
* get content...
*/
System.out.println(j+".");
System.out.println("ID: "+identifier);
System.out.println(r.getContent());
j++;
}
return j;
}
}
Removing (unregister) of registered XML documents
The registration interface allows also removing registered XML documents from the registry.
import java.util.HashSet;
import java.util.Properties;
import org.xmldb.api.modules.XMLResource;
import uk.ac.soton.itinnovation.registry.icomponent.access.AccessException;
import uk.ac.soton.itinnovation.registry.icomponent.access.Credential;
import uk.ac.soton.itinnovation.registry.icomponent.discovery.Discovery;
import uk.ac.soton.itinnovation.registry.icomponent.discovery.DiscoveryException;
import uk.ac.soton.itinnovation.registry.icomponent.discovery.ResultIterator;
import uk.ac.soton.itinnovation.registry.icomponent.registration.Registration;
import uk.ac.soton.itinnovation.registry.icomponent.registration.RegistrationException;
import uk.ac.soton.itinnovation.registry.icomponent.util.PropertyConstants;
import uk.ac.soton.itinnovation.registry.icomponent.util.PropertyManagement;
import uk.ac.soton.itinnovation.registry.test.factory.RegistryFactory;
import uk.ac.soton.itinnovation.registry.test.factory.StartupRegistryFactory;
import uk.ac.soton.itinnovation.registry.test.util.SupportedTechnology;
/**
* Remove entities client...
*/
public class RemoveRegistryClient { @SuppressWarnings("unchecked")
public static void main(String[] args) throws RegistrationException, AccessException, DiscoveryException {
/*
* setup registry properties...
*/
Properties systemProps = System.getProperties();
String configDir = systemProps.getProperty(PropertyConstants.registryConfigurationDir);
if (configDir == null) {
String msg = "Configuration directory is not specified, "
+ "e.g. -Dregistry.conf.dir=... ";
throw new RuntimeException(msg);
}
PropertyManagement.configurationDirectory = configDir;
/*
* registration...
*/
RegistryFactory<XMLResource> factory = (RegistryFactory<XMLResource>)
StartupRegistryFactory.createRegistryFactory(SupportedTechnology.XML);
Registration registration = factory.createRegistrationFacility();
Credential credential = factory.createCredentialFacility();
registration.setCredential(credential);
/*
* discovery...
*/
Discovery<XMLResource> discovery = factory.createRegistryDiscoveryFacility();
discovery.setCredential(credential);
/*
* login...
*/
credential.login("myUser", "myPass", "myGroup");
/*
* remove entity (requires identifier) ...
*/
System.out.println("Remove slaservice.wsdl");
registration.deleteEntity("Service", "slaservice.wsdl");
/*
* look out for documents in Sla
*/
String concept = "Sla";
ResultIterator<XMLResource> i = discovery.lookupByConcept(concept);
for (XMLResource r : i) {
/*
* get identifier of document...
*/
HashSet<String> identifiers = discovery.getIdentifier(r, concept);
for(String identifier : identifiers){
System.out.println("Remove "+identifier);
registration.deleteEntity(concept, identifier);
}
}
/*
* remove all entities of the current user...
*/
System.out.println("Remove all...");
registration.deleteAllEntities();
/*
* logout
*/
credential.logout();
}
}
Appendix
Schemata of properties files, RDM files and the ooXmlQL query language.
Registry Properties
The registry properties file will have entries like this
#########################################################################
#
# Registry properties specification
#
#########################################################################
# database administrator for installing and configuration of the
registry database
db.admin.user=<admin login name>
db.admin.password=<admin password>
db.admin.group=<group name all registry users belong to, e.g.‘all’>
# namespace of registry domain model
# e.g. 'http://www.gria.org/registrydomainmodel.owl'
registry.domain.model.ns=<namespace>
# XML database URI
# e.g. 'xmldb:exist://localhost:8080/exist/xmlrpc'
xml.db.uri=<location of eXist>
# Registration default policy. Used during registration.
# Usage: r|w|u, e.g. for an owner who should have read,
# write and update access: xml.db.perm.owner=rwu
# In general these rules should be applied like this…
# entities
# owner
xml.db.perm.entity.owner=rwu
# group
xml.db.perm.entity.group=r
# other
xml.db.perm.entity.other=
# concepts
# owner
xml.db.perm.concept.owner=rwu
# group
xml.db.perm.concept.group=rw
# other
xml.db.perm.concept.other=
Registry Domain Model (RDM)
The RDM can be specified using OWL. The following OWL concepts are currently supported by the registry component:
- owl:Class (rdfs:label specifies the name of the concept used within the registry, it is therefore always REQUIRED and has to be UNIQUE)
- rdfs:subClassOf (only simple inheritance is supported)
- owl:ObjectProperty (rdfs:label specifies the name of the relationship used within the registry, it is therefore always REQUIRED and has to be UNIQUE)
- owl:inverseOf definition of inverse relationships
The following shows an example RDM
<rdf:RDF
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#">
<owl:Ontology rdf:about="">
<rdfs:comment>Registry Domain Model for GRIA Client Management. (C) 2007, University of Southampton IT Innovation Center</rdfs:comment>
<owl:versionInfo>$Id:RegistryDomainModel.owl,v 1.0 2006/10/31 Uwe Radetzki$</owl:versionInfo>
</owl:Ontology>
<!-- -->
<!-- Concepts -->
<!-- -->
<owl:Class rdf:ID="ReferenceAble">
<rdfs:comment>
Reference-able elements have a unique reference (EPR)
</rdfs:comment>
<rdfs:label>ReferenceAble</rdfs:label>
</owl:Class>
<owl:Class rdf:ID="Reference">
<rdfs:comment>Reference could be an EPR</rdfs:comment>
<rdfs:label>Reference</rdfs:label>
</owl:Class>
<!-- -->
<!-- Relationships between concepts -->
<!-- -->
<owl:ObjectProperty rdf:ID="Reference-holdBy-ReferenceAble">
<rdfs:range rdf:resource="#ReferenceAble"/>
<rdfs:label>holdBy</rdfs:label>
<rdfs:domain rdf:resource="#Reference"/>
<owl:inverseOf rdf:resource="#ReferenceAble-has-Reference"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="ReferenceAble-has-Reference">
<rdfs:domain rdf:resource="#ReferenceAble"/>
<rdfs:label>has</rdfs:label>
<rdfs:range rdf:resource="#Reference"/>
<owl:inverseOf rdf:resource="#Reference-holdBy-ReferenceAble"/>
</owl:ObjectProperty>
</rdf:RDF>
Predefined queries
The following example defines a lookup query that retrieves a document by its identifier. Users can execute this query by specifying the query name (“LookupByDocId”) and the required variables (“docId”).
<queries>
<query name="LookupByDocId">
<definition>
xquery version "1.0";
for $col in fn:collection("/db/registry/")
for $doc in util:document-name($col)
where $doc = $docId
return $col
</definition>
<parameter name="docId"/>
</query>
</queries>
ooXmlQL Specification and Example
The following EBNF grammar specifies sound ooXmlQL queries. Remark: A strange behavior can be observed when using variables where one variable is a prefix of another variable, e.g. $ref and $refAlias. It seems there is a bug in the XQuery processor. Therefore this variable setting should be avoided.
ooXmlQuery = query.
query = ‘<query>’ ( queryelements ) ( declareNS)* ‘</query>’.
queryelements = ( select )?
from
( declareVar )*
( restriction )?
( where )?.
select = ‘<select>’ ( ‘*’ | xpath expression+ ) ‘</select>’.
declareNS = ‘<declare name=“’name’”>’ namespace ‘</declare>’.
from = ‘<from as=“’var‘”>’ ( class | setOperation ) ( join )? ‘</from>’.
setOperation = ‘<union>’ ( class | setOperation )+ ‘</union>’ |
‘<intersect>’ ( class | setOperation )+ ‘</intersect>’ |
‘<except>’ ( class | setOperation )+ ‘</except>’.
class = ‘<class name=“’classname’”/>.
join = ‘<join on=“’relation’” as=“’var’” class=“’class’”>’
( restriction )? ( join )?
‘</join>’.
declareVar = ‘<declare var=“’var’”>’ xpath expression ‘</declare>’.
where = ‘<where>’ xpath or xquery expression ‘</where>’.
restriction = subquery | and | or | not.
subquery = ‘<query return=“’relationship’”>’
queryelements
‘</query>’.
and = ‘<and>’ restriction+ ‘</and>’
or = ‘<or>’ restriction+ ‘</or>’.
not = ‘<not>’ restriction ‘</not>’.
Variables can be used in the following elements of the query:
- where clause <where>
- select clause <select>
- declare variable clause <declareVar>
Example ooXmlQL query:
<query>
<select>*</select>
<declare name="ns1">http://it-innovation.soton.ac.uk/2005/grid</declare>
<declare name="ns2">http://www.w3.org/2005/08/addressing</declare>
<from as="$sla">
<class name="Sla"/>
<join on="provides" as="$res" class="Resource"/>
</from>
<declare var="$min">fn:min($sla//cpu)</declare>
<declare var="$max">fn:max($sla//cpu)</declare>
<query return="providedBy">
<from class="Resource" as="$res"/>
<declare var="$avg">fn:avg($res//cpu)</declare>
<where>
$res//ns2:Metadata/ns1:type = "uk.ac.soton.ecs.iam.grid.comms.client.RemoteDataService"
</where>
</query>
<where>$sla//cpu = $min or $sla//cpu = $max</where>
</query>
See the
GRIA Client section about
discovery for more information about ooXmlQL.
How to get the sources of the tutorial?
This section describes, how to obtain the sources used within this tutorial.
The sources used within this tutorial can be downloaded from the Download page.
The sources can be build using Maven 2 (mvn install).
To run the examples one can go to the created target directory and use the following command:
java -Dregistry.conf.dir=../src/resources -jar gria-registry-tutorial-5.1.jar <attribute>
The provided attributes are
- install: executing the install client
- configuration: executing the configuration client
- dynamic_configuration: executing the dynamic configuration client
- user_management: executing the user management client
- registration: executing the registration client
- discovery: executing the discovery client
- remove: executing the client for removing registered entries
- all: execute all programs in the order of this list