The JavaTM Web Services Tutorial
Home
TOC
PREV TOP NEXT

Implementing a JAXR Client

This section describes the basic steps to follow in order to implement a JAXR client that can perform queries and updates to a UDDI registry. A JAXR client is a client program that can access registries using the JAXR API.

This tutorial does not describe how to implement a JAXR provider. A JAXR provider provides an implementation of the JAXR specification, usually as a faŤade around an existing registry provider, such as a UDDI or ebXML registry. The JAXR RI itself is an example of a JAXR provider.

This tutorial includes several client examples:

The JAXR release also includes several sample JAXR clients, the most complete of which is a Registry Browser that includes a graphical user interface (GUI). The Registry Browser allows access to any registry, but includes some of the most commonly used registries as preset URLs:

The Registry Browser source code is in the directory <JWSDP_HOME>/samples/jaxr/jaxr-browser (on UNIX systems) or <JWSDP_HOME>\samples\jaxr\jaxr-browser (on Microsoft Windows systems). Much of the source code implements the GUI. The JAXR code is in the file JAXRClient.java.

Establishing a Connection

The first task a JAXR client must complete is to establish a connection to a registry.

Preliminaries: Getting Access to a Registry

Any user of a JAXR client may perform queries on a public registry. In order to add data to the registry or to update registry data, however, a user must obtain permission from the registry to access it through a user name and password. To register with one of the test registries, go to one of the following Web sites and follow the instructions:

You do not need access permission to use the Java WSDP Registry Server.

Creating or Looking Up a Connection Factory

A client creates a connection from a connection factory. A JAXR provider may supply one or more preconfigured connection factories that clients can obtain by looking them up using the Java Naming and Directory Interface (JNDI) API.

The JAXR RI does not currently supply preconfigured connection factories. Instead, a client creates an instance of the abstract class ConnectionFactory:

import javax.xml.registry.*;	
...	
ConnectionFactory connFactory = 	
    ConnectionFactory.newInstance();
 

Creating a Connection

To create a connection, a client first creates a set of properties that specify the URL of the registry or registries being accessed and the type of registry (UDDI or ebXML). For example, the following code provides the URL of the IBM test query registry and specifies the JAXR RI implementation of the connection factory for the UDDI registry. (There should be no line break in the string.)

Properties props = new Properties();	
props.setProperty("javax.xml.registry.queryManagerURL",	
    "http://www-
3.ibm.com/services/uddi/testregistry/inquiryapi");	
props.setProperty("javax.xml.registry.factoryClass", 	
    "com.sun.xml.registry.uddi.ConnectionFactoryImpl");
 

The client then sets the properties for the connection factory and creates the connection:

connFactory.setProperties(props);	
Connection connection = connFactory.createConnection();
 

The makeConnection method in JAXRPublish.java and JAXRDelete.java shows the steps used to create a JAXR connection.

Obtaining and Using a RegistryService Object

After creating the connection, the client uses the connection to obtain a RegistryService object and then the interface or interfaces it will use:

RegistryService rs = connection.getRegistryService();	
BusinessQueryManager bqm = rs.getBusinessQueryManager();	
BusinessLifeCycleManager blcm = 	
    rs.getBusinessLifeCycleManager();
 

Typically, a client obtains both a BusinessQueryManager object and a BusinessLifeCycleManager object from the RegistryService object. If it is using the registry for queries only, it may need to obtain only a BusinessQueryManager object.

Querying a Registry

The simplest way for a client to use a registry is to query it for information about the organizations that have submitted data to it. The BusinessQueryManager interface supports a number of find methods that allow clients to search for data using the JAXR information model. Many of these methods return a BulkResponse (a collection of objects) that meets a set of criteria specified in the method arguments. At this release the most useful of these methods are likely to be

The JAXRQuery program illustrates how to query a registry and display the data returned.

The following sections describe how to perform some common queries.

Finding Organizations by Name

The following fragment of the executeQuery method in JAXRQuery.java shows how to find all the organizations in the registry whose names begin with a specified string, qString, and to sort them in alphabetical order.

// Define find qualifiers and name patterns	
Collection findQualifiers = new ArrayList();	
findQualifiers.add(FindQualifier.SORT_BY_NAME_DESC);	
Collection namePatterns = new ArrayList();	
namePatterns.add(qString);	
	
// Find using the name	
BulkResponse response = 	
    bqm.findOrganizations(findQualifiers, 	
        namePatterns, null, null, null, null);	
Collection orgs = response.getCollection();
 

A client can specify a case-sensitive search by using the first argument of the findOrganizations method to specify a collection of findQualifiers. For example, the following code fragment finds organizations whose names contain the string "Coffee":

Collection findQualifiers = new ArrayList();	
findQualifiers.add(FindQualifier.CASE_SENSITIVE_MATCH);	
Collection namePatterns = new ArrayList();	
namePatterns.add("%Coffee%");	
 	
// Find orgs with name containing 'Coffee'	
BulkResponse response = 	
    bqm.findOrganizations(findQualifiers, namePatterns, null,	
        null, null, null);	
Collection orgs = response.getCollection();
 

Finding Organizations by Classification

To find organizations by classification, you need to establish the classification within a particular classification scheme and then specify the classification as an argument to the findOrganizations method. The following code fragment finds all organizations that correspond to a particular classification within the North American Industry Classification System (NAICS) taxonomy. (You can find the NAICS codes at http://www.census.gov/epcd/naics/naicscod.txt.)

BusinessLifeCycleManager lcm = 	
    rs.getBusinessLifeCycleManager();	
ClassificationScheme cScheme = 	
    lcm.findClassificationSchemeByName("ntis-gov:naics");	
Classification classification = (Classification)	
    lcm.createClassification(cScheme, "Snack and Nonalcoholic	
         Beverage Bars", "722213");	
Collection classifications = new ArrayList();	
classifications.add(classification);	
       	
// make JAXR request	
BulkResponse response = bqManager.findOrganizations(null,	
    null, classifications, null, null, null);	
Collection orgs = response.getCollection();
 

Finding Services and ServiceBindings

After a client has located an organization, it can find that organization's services and the service bindings associated with those services.

Iterator orgIter = orgs.iterator();	
while (orgIter.hasNext()) {	
    Organization org = (Organization) orgIter.next();	
    Collection services = org.getServices();	
    Iterator svcIter = services.iterator();	
    while (svcIter.hasNext()) {	
        Service svc = (Service) svcIter.next();	
        Collection serviceBindings = 	
            svc.getServiceBindings();	
        Iterator sbIter = serviceBindings.iterator();	
        while (sbIter.hasNext()) {	
            ServiceBinding sb = 	
                (ServiceBinding) sbIter.next();	
        }	
    }	
}
 

Managing Registry Data

If a client has authorization to do so, it can submit data to a registry, modify it, and remove it. It uses the BusinessLifeCycleManager interface to perform these tasks.

Registries usually allow a client to modify data only if the data is being modified by the same user who first submitted the data.

Getting Authorization from the Registry

Before it can submit data, the client must send its username and password to the registry in a set of credentials. The following code fragment shows how to do this.

// Edit to provide your own username and password	
String username = "";	
String password = "";	
	
// Get authorization from the registry	
PasswordAuthentication passwdAuth =	
    new PasswordAuthentication(username, 	
        password.toCharArray());	
	
Set creds = new HashSet();	
creds.add(passwdAuth);	
connection.setCredentials(creds);
 

Creating an Organization

The client creates the organization and populates it with data before saving it.

An Organization object is one of the more complex data items in the JAXR API. It normally includes the following:

For example, the following code fragment creates an organization and specifies its name, description, and primary contact. When a client creates an organization, it does not include a key; the registry normally returns the new key when it accepts the newly created organization. The blcm object in this code fragment is the BusinessLifeCycleManager object returned in Obtaining and Using a RegistryService Object. An InternationalString object is used for string values that may need to be localized.

// Create organization name and description	
Organization org = blcm.createOrganization("The Coffee Break");	
InternationalString s =	
    blcm.createInternationalString("Purveyor of only the " +	
        "finest coffees. Established 1895");	
org.setDescription(s);	
	
// Create primary contact, set name	
User primaryContact = blcm.createUser();	
PersonName pName = blcm.createPersonName("Jane Doe");	
primaryContact.setPersonName(pName);	
	
// Set primary contact phone number	
TelephoneNumber tNum = blcm.createTelephoneNumber();	
tNum.setNumber("(800) 555-1212");	
Collection phoneNums = new ArrayList();	
phoneNums.add(tNum);	
primaryContact.setTelephoneNumbers(phoneNums);	
	
// Set primary contact email address	
EmailAddress emailAddress = 	
    blcm.createEmailAddress("jane.doe@TheCoffeeBreak.com");	
Collection emailAddresses = new ArrayList();	
emailAddresses.add(emailAddress);	
primaryContact.setEmailAddresses(emailAddresses);	
	
// Set primary contact for organization	
org.setPrimaryContact(primaryContact);
 

Adding Classifications

Organizations commonly belong to one or more classifications within one or more classification schemes (taxonomies). To establish a classification for an organization within a taxonomy, the client locates the taxonomy it wants to use, then creates a classification. It uses the BusinessQueryManager to find the taxonomy. For example, the following code sets up a classification for the organization within the NAICS taxonomy.

// Set classification scheme to NAICS	
ClassificationScheme cScheme = 	
    bqm.findClassificationSchemeByName("ntis-gov:naics");	
	
// Create and add classification	
Classification classification = (Classification)	
    blcm.createClassification(cScheme, 	
        "Snack and Nonalcoholic Beverage Bars", "722213");   	
Collection classifications = new ArrayList();	
classifications.add(classification);	
org.addClassifications(classifications);
 

Services also use classifications, so you can use similar code to add a classification to a Service object.

Adding Services and Service Bindings to an Organization

Most organizations add themselves to a registry in order to offer services, so the JAXR API has facilities to add services and service bindings to an organization.

Like an Organization object, a Service object has a name and a description. Also like an Organization object, it has a unique key that is generated by the registry when the service is registered. It may also have classifications associated with it.

A service also commonly has service bindings, which provide information about how to access the service. A ServiceBinding object normally has a description, an access URI, and a specification link, which provides the linkage between a service binding and a technical specification that describes how to use the service using the service binding.

The following code fragment shows how to create a collection of services, add service bindings to a service, then add the services to the organization. It specifies an access URI but not a specification link.

// Create services and service	
Collection services = new ArrayList();	
Service service = blcm.createService("My Service Name");	
InternationalString is = 	
  blcm.createInternationalString("My Service Description");	
service.setDescription(is);	
	
// Create service bindings	
Collection serviceBindings = new ArrayList();	
ServiceBinding binding = blcm.createServiceBinding();	
is = blcm.createInternationalString("My Service Binding " +	
    "Description");	
binding.setDescription(is);	
binding.setAccessURI("http://TheCoffeeBreak.com:8080/sb/");	
serviceBindings.add(binding);	
	
// Add service bindings to service	
service.addServiceBindings(serviceBindings);	
	
// Add service to services, then add services to organization	
services.add(service);	
org.addServices(services);
 

Saving an Organization

The primary method a client uses to add or modify organization data is the saveOrganizations method, which creates one or more new organizations in a registry if they did not exist previously. If one of the organizations exists but some of the data have changed, the saveOrganizations method updates the data.

After a client populates an organization with the information it wants to make public, it saves the organization. The registry returns the key in its response, and the client retrieves it.

// Add organization and submit to registry	
// Retrieve key if successful	
Collection orgs = new ArrayList();	
orgs.add(org);	
BulkResponse response = blcm.saveOrganizations(orgs);	
Collection exceptions = response.getException();	
if (exceptions == null) {	
    System.out.println("Organization saved");	
	
    Collection keys = response.getCollection();	
    Iterator keyIter = keys.iterator();	
    if (keyIter.hasNext()) {	
         javax.xml.registry.infomodel.Key orgKey = 	
            (javax.xml.registry.infomodel.Key) keyIter.next();	
        String id = orgKey.getId();	
        System.out.println("Organization key is " + id);	
        org.setKey(orgKey);	
    }	
}
 

Removing Data from the Registry

A registry allows you to remove from the registry any data that you have submitted to it. You use the key returned by the registry as an argument to one of the BusinessLifeCycleManager delete methods: deleteOrganizations, deleteServices, deleteServiceBindings, and others.

The JAXRDelete sample program deletes the organization created by the JAXRPublish program. It searches the registry by name for the organization and uses the key string displayed by the JAXRPublish program to verify that it is removing the correct organization. Once it has the key, it deletes the organization and then displays the key again so that the user can confirm that it has deleted the correct one.

String id = key.getId();	
System.out.println("Deleting organization with id " + id);	
Collection keys = new ArrayList();	
keys.add(key);	
BulkResponse response = blcm.deleteOrganizations(keys);	
Collection exceptions = response.getException();	
if (exceptions == null) {	
    System.out.println("Organization deleted");	
    Collection retKeys = response.getCollection();	
    Iterator keyIter = retKeys.iterator();	
    javax.xml.registry.infomodel.Key orgKey = null;	
    if (keyIter.hasNext()) {	
        orgKey = 	
            (javax.xml.registry.infomodel.Key) keyIter.next();	
        id = orgKey.getId();	
        System.out.println("Organization key was " + id);	
    }	
} 
 

A client can use a similar mechanism to delete services and service bindings.

Running the Client Examples

The simple client programs provided with this tutorial can be run from the command line. You can modify them to suit your needs. Currently they specify the IBM test registry for queries and updates; you can specify another registry.

Before you compile the JAXRPublish and JAXRDelete examples, edit the lines containing the empty strings for the username and password to specify your username and password. Feel free to change any of the organization data in the JAXRPublish program.

Set the JAVA_HOME, JAXR_HOME, and CATALINA_HOME environment variables as specified in the JAXR home page (<JWSDP_HOME>/docs/jaxr/index.html on UNIX systems; <JWSDP_HOME>\docs\jaxr\index.html on Microsoft Windows systems).

To compile the programs, go to the docs/tutorial/examples/jaxr directory (on UNIX systems) or the docs\tutorial\examples\jaxr directory (on Microsoft Windows systems). A build.xml file allows you to use the command

ant build
 

to compile all the examples. The ant tool creates a subdirectory called build and places the class files there.

Before you run the examples, start Tomcat. See the JAXR home page (<JWSDP_HOME>/docs/jaxr/index.html on UNIX systems; <JWSDP_HOME>\docs\jaxr\index.html on Microsoft Windows systems) for details.

To run the JAXRQuery example, use the ant target run-query. Specify a query-string argument on the command line to search the registry for organizations whose names contain that string. For example, the following command line searches for organizations whose names contain the string "sun":

ant -Dquery-string=sun run-query
 

To run the JAXRPublish program, use the run-publish target with no command line arguments:

ant run-publish
 

The program output displays the string value of the key of the new organization.

If you forgot to fill in the username and password strings, you will get a "No Credentials present" error message.

After you run the JAXRPublish program but before you run JAXRDelete, you can run JAXRQuery to look up the organization you published. You can also use the Registry Browser to search for it.

To run the JAXRDelete program, specify the string returned by the JAXRPublish program as input to the run-delete target:

ant -Dkey-string=string-value run-delete
 

To remove the build directory and class files, use the command

ant clean
 

To obtain a syntax reminder for the run-query, run-publish, and run-delete targets, use the command

ant help
 
Home
TOC
PREV TOP NEXT