Personal tools
You are here: Home GRIA Documentation Documentation 5.1 Tutorials Building your own contextualised B2B registry

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


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

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
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
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
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
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)


    [1] XML:DB Initiative: API for XML Databases, http://xmldb-org.sourceforge.net/xapi/

    [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