Download
FAQ
History
PrevHomeNext API
Search
Feedback
Divider

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. It covers the following topics:

This tutorial does not describe how to implement a JAXR provider. A JAXR provider provides an implementation of the JAXR specification that allows access to an existing registry provider, such as a UDDI or ebXML registry. The implementation of JAXR in the Java WSDP itself is an example of a JAXR provider.

This tutorial includes several client examples, which are described in Running the Client Examples. The examples are in the directory <INSTALL>/jwstutorial13/examples/jaxr/. (<INSTALL> is the directory where you installed the tutorial bundle.) Each example directory has a build.xml file that refers to a targets.xml file and a build.properties file in the directory <INSTALL>/jwstutorial13/examples/jaxr/common/.

Establishing a Connection

The first task a JAXR client must complete is to establish a connection to a registry. Establishing a connection involves the following tasks:

Preliminaries: Getting Access to a Registry

Any user of a JAXR client may perform queries on a 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. To register with one of the public UDDI version 2 registries, go to one of the following Web sites and follow the instructions:

These UDDI version 2 registries are intended for testing purposes. When you register, you will obtain a user name and password. You will specify this user name and password for some of the JAXR client example programs.

You do not have to register with the Java WSDP Registry Server in order to add or update data. You can use the default user name and password, testuser and testuser.


Note: The JAXR API has been tested with the Microsoft and IBM registries and with the Java WSDP Registry Server, but not with the SAP registry.


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.

At this release of the Java WSDP, JAXR does not 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 or URLs of the registry or registries being accessed. For example, the following code provides the URLs of the query service and publishing service for the IBM test registry. (There should be no line break in the strings.)

Properties props = new Properties();
props.setProperty("javax.xml.registry.queryManagerURL",
  "http://uddi.ibm.com/testregistry/inquiryapi");
props.setProperty("javax.xml.registry.lifeCycleManagerURL",
  "https://uddi.ibm.com/testregistry/publishapi"); 

With the Java WSDP implementation of JAXR, if the client is accessing a registry that is outside a firewall, it must also specify proxy host and port information for the network on which it is running. For queries it may need to specify only the HTTP proxy host and port; for updates it must specify the HTTPS proxy host and port.

props.setProperty("com.sun.xml.registry.http.proxyHost", 
  "myhost.mydomain");
props.setProperty("com.sun.xml.registry.http.proxyPort", 
  "8080");
props.setProperty("com.sun.xml.registry.https.proxyHost", 
  "myhost.mydomain");
props.setProperty("com.sun.xml.registry.https.proxyPort", 
  "8080"); 

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 the sample programs shows the steps used to create a JAXR connection.

Setting Connection Properties

The implementation of JAXR in the Java WSDP allows you to set a number of properties on a JAXR connection. Some of these are standard properties defined in the JAXR specification. Other properties are specific to the implementation of JAXR in the Java WSDP. Table 14-1 and Table 14-2 list and describe these properties.

Table 14-1 Standard JAXR Connection Properties
Property Name and Description
Data Type
Default Value
javax.xml.registry.queryManagerURL
 
Specifies the URL of the query manager service within the target registry provider
String
None
javax.xml.registry.lifeCycleManagerURL
 
Specifies the URL of the life cycle manager service within the target registry provider (for registry updates)
String
Same as the specified queryManagerURL value
javax.xml.registry.semanticEquivalences
 
Specifies semantic equivalences of concepts as one or more tuples of the ID values of two equivalent concepts separated by a comma; the tuples are separated by vertical bars:
id1,id2|id3,id4
String
None
javax.xml.registry.security.authenticationMethod
 
Provides a hint to the JAXR provider on the authentication method to be used for authenticating with the registry provider
String
None; UDDI_GET_AUTHTOKEN is the only supported value
javax.xml.registry.uddi.maxRows
 
The maximum number of rows to be returned by find operations. Specific to UDDI providers
Integer
None
javax.xml.registry.postalAddressScheme
 
The ID of a ClassificationScheme to be used as the default postal address scheme. See Specifying Postal Addresses  for an example
String
None

Table 14-2 Implementation-Specific JAXR Connection Properties
Property Name and Description
Data Type
Default Value
com.sun.xml.registry.http.proxyHost
 
Specifies the HTTP proxy host to be used for accessing external registries
String
None
com.sun.xml.registry.http.proxyPort
 
Specifies the HTTP proxy port to be used for accessing external registries; usually 8080
String
None
com.sun.xml.registry.https.proxyHost
 
Specifies the HTTPS proxy host to be used for accessing external registries
String
Same as HTTP proxy host value
com.sun.xml.registry.https.proxyPort
 
Specifies the HTTPS proxy port to be used for accessing external registries; usually 8080
String
Same as HTTP proxy port value
com.sun.xml.registry.http.proxyUserName
 
Specifies the user name for the proxy host for HTTP proxy authentication, if one is required
String
None
com.sun.xml.registry.http.proxyPassword
 
Specifies the password for the proxy host for HTTP proxy authentication, if one is required
String
None
com.sun.xml.registry.useCache
 
Tells the JAXR implementation to look for registry objects in the cache first and then to look in the registry if not found
Boolean, passed in as String
True

You can set these properties as follows:

An additional system property specific to the implementation of JAXR in the Java WSDP is com.sun.xml.registry.userTaxonomyFilenames. For details on using this property, see Defining a Taxonomy.

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 simple 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. The most useful of these methods are:

The JAXRQuery program illustrates how to query a registry by organization name and display the data returned. The JAXRQueryByNAICSClassification and JAXRQueryByWSDLClassification programs illustrate how to query a registry using classifications. All JAXR providers support at least the following taxonomies for classifications:

The following sections describe how to perform some common queries:

Finding Organizations by Name

To search for organizations by name, you normally use a combination of find qualifiers (which affect sorting and pattern matching) and name patterns (which specify the strings to be searched). The findOrganizations method takes a collection of findQualifier objects as its first argument and a collection of namePattern objects as its second argument. The following fragment 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 use percent signs (%) to specify that the query string can occur anywhere within the organization name. For example, the following code fragment performs a case-sensitive search for organizations whose names contain qString:

Collection findQualifiers = new ArrayList();
findQualifiers.add(FindQualifier.CASE_SENSITIVE_MATCH);
Collection namePatterns = new ArrayList();
namePatterns.add("%" + qString + "%");

// Find orgs with name containing qString
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 NAICS taxonomy. (You can find the NAICS codes at http://www.census.gov/epcd/naics/naicscod.txt.)

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

You can also use classifications to find organizations that offer services based on technical specifications that take the form of WSDL (Web Services Description Language) documents. In JAXR, a concept is used as a proxy to hold the information about a specification. The steps are a little more complicated than in the previous example, because the client must find the specification concepts first, then the organizations that use those concepts.

The following code fragment finds all the WSDL specification instances used within a given registry. You can see that the code is similar to the NAICS query code except that it ends with a call to findConcepts instead of findOrganizations.

String schemeName = "uddi-org:types";
ClassificationScheme uddiOrgTypes =
  bqm.findClassificationSchemeByName(null, schemeName);

/*
 * Create a classification, specifying the scheme
 *  and the taxonomy name and value defined for WSDL
 *  documents by the UDDI specification.
 */
Classification wsdlSpecClassification = 
blcm.createClassification(uddiOrgTypes, 
  "wsdlSpec", "wsdlSpec");

Collection classifications = new ArrayList();
classifications.add(wsdlSpecClassification);

// Find concepts
BulkResponse br = bqm.findConcepts(null, null, 
  classifications, null, null); 

To narrow the search, you could use other arguments of the findConcepts method (search qualifiers, names, external identifiers, or external links).

The next step is to go through the concepts, find the WSDL documents they correspond to, and display the organizations that use each document:

// Display information about the concepts found
Collection specConcepts = br.getCollection();
Iterator iter = specConcepts.iterator();
if (!iter.hasNext()) {
  System.out.println("No WSDL specification concepts found");
} else {
  while (iter.hasNext()) {
  Concept concept = (Concept) iter.next();

  String name = getName(concept);

  Collection links = concept.getExternalLinks();
  System.out.println("\nSpecification Concept:\n\tName: " + 
    name + "\n\tKey: " + 
    concept.getKey().getId() + 
    "\n\tDescription: " + 
    getDescription(concept));
  if (links.size() > 0) {
    ExternalLink link = 
      (ExternalLink) links.iterator().next();
    System.out.println("\tURL of WSDL document: '" +
      link.getExternalURI() + "'");
  }

  // Find organizations that use this concept
  Collection specConcepts1 = new ArrayList();
  specConcepts1.add(concept);
  br = bqm.findOrganizations(null, null, null, 
    specConcepts1, null, null);

  // Display information about organizations
  ...
} 

If you find an organization that offers a service you wish to use, you can invoke the service using the JAX-RPC API.

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 or remove data only if the data is being modified or removed by the same user who first submitted the data.

Managing registry data involves the following tasks:

Getting Authorization from the Registry

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

String username = "myUserName";
String password = "myPassword";

// 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 publishing 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 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 " +
    "the finest coffees. Established 1914");
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 based on one or more classification schemes (taxonomies). To establish a classification for an organization using a taxonomy, the client first locates the taxonomy it wants to use. It uses the BusinessQueryManager to find the taxonomy. The findClassificationSchemeByName method takes a set of FindQualifier objects as its first argument, but this argument can be null.

// Set classification scheme to NAICS
ClassificationScheme cScheme = 
  bqm.findClassificationSchemeByName(null, "ntis-gov:naics"); 

The client then creates a classification using the classification scheme and a concept (a taxonomy element) within the classification scheme. For example, the following code sets up a classification for the organization within the NAICS taxonomy. The second and third arguments of the createClassification method are the name and value of the concept.

// Create and add 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. Because the access URI is not real and because JAXR by default checks for the validity of any published URI, the binding sets its validateURI property to false.

// 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);
// allow us to publish a bogus URL without an error
binding.setValidateURI(false);
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); 

Publishing 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 and replaces 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);
  }
} 

Publishing a Specification Concept

A service binding may have a technical specification that describes how to access the service. An example of such a specification is a WSDL document. To publish the location of a service's specification (if the specification is a WSDL document), you create a Concept object and then add the URL of the WSDL document to the Concept object as an ExternalLink object. The following code fragment shows how to create a concept for the WSDL document associated with the simple web service example in Creating a Web Service with JAX-RPC. First, you call the createConcept method to create a concept named HelloConcept. After setting the description of the concept, you create an external link to the URL of the Hello service's WSDL document, then add the external link to the concept.

Concept specConcept = 
  blcm.createConcept(null, "HelloConcept", "");
InternationalString s =
  blcm.createInternationalString(
    "Concept for Hello Service");
specConcept.setDescription(s);
ExternalLink wsdlLink = 
  blcm.createExternalLink(
    "http://localhost:8080/hello-jaxrpc/hello?WSDL", 
    "Hello WSDL document");
specConcept.addExternalLink(wsdlLink); 

Next, you classify the Concept object as a WSDL document. To do this for a UDDI registry, you search the registry for the well-known classification scheme uddi-org:types. (The UDDI term for a classification scheme is tModel.) Then you create a classification using the name and value wsdlSpec. Finally, you add the classification to the concept.

String schemeName = "uddi-org:types";
ClassificationScheme uddiOrgTypes =
  bqm.findClassificationSchemeByName(null, schemeName);

Classification wsdlSpecClassification = 
    blcm.createClassification(uddiOrgTypes, 
    "wsdlSpec", "wsdlSpec");
specConcept.addClassification(wsdlSpecClassification); 

Finally, you save the concept using the saveConcepts method, similarly to the way you save an organization:

Collection concepts = new ArrayList();
concepts.add(specConcept);
BulkResponse concResponse = blcm.saveConcepts(concepts); 

Once you have published the concept, you normally add the concept for the WSDL document to a service binding. To do this, you could retrieve the key for the concept from the response returned by the saveConcepts method, using a code sequence very similar to that of finding the key for a saved organization.

String conceptKeyId = null;
Collection concExceptions = concResponse.getExceptions();
javax.xml.registry.infomodel.Key concKey = null;
if (concExceptions == null) {
  System.out.println("WSDL Specification Concept saved");

  Collection keys = concResponse.getCollection();
  Iterator keyIter = keys.iterator();
  if (keyIter.hasNext()) {
    concKey = 
      (javax.xml.registry.infomodel.Key) keyIter.next();
    conceptKeyId = concKey.getId();
    System.out.println("Concept key is " + id);
  }
} 

Then you could call the getRegistryObject method to retrieve the concept from the registry:

Concept specConcept = 
  (Concept) bqm.getRegistryObject(conceptKeyId, 
    LifeCycleManager.CONCEPT); 

Next, you create a SpecificationLink object for the service binding and set the concept as the value of its SpecificationObject:

SpecificationLink specLink = 
  blcm.createSpecificationLink();
specLink.setSpecificationObject(specConcept);
binding.addSpecificationLink(specLink); 

Now when you publish the organization with its service and service bindings, you have also published a link to the WSDL document, so that the organization can be found in queries like those described in Finding Organizations by Classification.

If the concept was published by someone else and you don't have access to the key, you can find it using its name and classification. The code would look very similar to the code used to search for a WSDL document in Finding Organizations by Classification, except that you would also create a collection of name patterns and include that in your search. For example:

// Define name pattern
Collection namePatterns = new ArrayList();
namePatterns.add("HelloConcept");

BulkResponse br = bqm.findConcepts(null, namePatterns, 
  classifications, null, null); 

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, deleteConcepts, and others.

The JAXRDelete sample program deletes the organization created by the JAXRPublish program. It deletes the organization that corresponds to a specified key string 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 concepts, services, and service bindings.

Using Taxonomies in JAXR Clients

In the JAXR API, a taxonomy is represented by a ClassificationScheme object.

This section describes how to use the implementation of JAXR in the Java WSDP:

Defining a Taxonomy

The JAXR specification requires a JAXR provider to be able to add user-defined taxonomies for use by JAXR clients. The mechanisms clients use to add and administer these taxonomies are implementation-specific.

The implementation of JAXR in the Java WSDP uses a simple file-based approach to provide taxonomies to the JAXR client. These files are read at run time, when the JAXR provider starts up.

The taxonomy structure for the Java WSDP is defined by the JAXR Predefined Concepts DTD, which is declared both in the file jaxrconcepts.dtd and, in XML schema form, in the file jaxrconcepts.xsd. The file jaxrconcepts.xml contains the taxonomies for the implementation of JAXR in the Java WSDP. All these files are contained in the <JWSDP_HOME>/jaxr/lib/jaxr-impl.jar file, but you can find copies of them in the directory <JWSDP_HOME>/jaxr/docs/taxonomies/. This directory also includes files that define the well-known taxonomies that the implementation of JAXR in the Java WSDP uses: naics.xml, iso3166.xml, and unspsc.xml.

The entries in the jaxrconcepts.xml file look like this:

<PredefinedConcepts>
<JAXRClassificationScheme id="schId" name="schName">
<JAXRConcept id="schId/conCode" name="conName" 
parent="parentId" code="conCode"></JAXRConcept>
...
</JAXRClassificationScheme>
</PredefinedConcepts> 

The taxonomy structure is a containment-based structure. The element PredefinedConcepts is the root of the structure and must be present. The JAXRClassificationScheme element is the parent of the structure, and the JAXRConcept elements are children and grandchildren. A JAXRConcept element may have children, but it is not required to do so.

In all element definitions, attribute order and case are significant.

To add a user-defined taxonomy, follow these steps.

  1. Publish the JAXRClassificationScheme element for the taxonomy as a ClassificationScheme object in the registry that you will be accessing. For example, you can publish the ClassificationScheme object to the Java WSDP Registry Server. In order to publish a ClassificationScheme object, you must set its name. You also give the scheme a classification within a known classification scheme such as uddi-org:types. In the following code fragment, the name is the first argument of the LifeCycleManager.createClassificationScheme method call.
  2. ClassificationScheme cScheme =
      blcm.createClassificationScheme("MyScheme",
        "A Classification Scheme");
    ClassificationScheme uddiOrgTypes =
      bqm.findClassificationSchemeByName(null,
        "uddi-org:types");
    if (uddiOrgTypes != null) {
      Classification classification =
        blcm.createClassification(uddiOrgTypes,
          "postalAddress", "categorization" );
      postalScheme.addClassification(classification);
      ExternalLink externalLink =
      blcm.createExternalLink(
        "http://www.mycom.com/myscheme.html",
        "My Scheme");
      postalScheme.addExternalLink(externalLink);
      Collection schemes = new ArrayList();
      schemes.add(cScheme);
      BulkResponse br =
        blcm.saveClassificationSchemes(schemes);
    }

    The BulkResponse object returned by the saveClassificationSchemes method contains the key for the classification scheme, which you need to retrieve:

    if (br.getStatus() == JAXRResponse.STATUS_SUCCESS) {
      System.out.println("Saved ClassificationScheme");
      Collection schemeKeys = br.getCollection();
      Iterator keysIter = schemeKeys.iterator();
      while (keysIter.hasNext()) {
        javax.xml.registry.infomodel.Key key =
          (javax.xml.registry.infomodel.Key)
            keysIter.next();
        System.out.println("The postalScheme key is " +
          key.getId());
        System.out.println("Use this key as the scheme" +
          " uuid in the taxonomy file");
      }
    }

  3. In an XML file, define a taxonomy structure that is compliant with the JAXR Predefined Concepts DTD. Enter the ClassificationScheme element in your taxonomy XML file by specifying the returned key ID value as the id attribute and the name as the name attribute. For the code fragment above, for example, the opening tag for the JAXRClassificationScheme element looks something like this (all on one line):
  4. <JAXRClassificationScheme
    id="uuid:nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn"
    name="MyScheme">

    The ClassificationScheme id must be a UUID.

  5. Enter each JAXRConcept element in your taxonomy XML file by specifying the following four attributes, in this order:
    1. id is the JAXRClassificationScheme id value, followed by a / separator, followed by the code of the JAXRConcept element
    2. name is the name of the JAXRConcept element
    3. parent is the immediate parent id (either the ClassificationScheme id or that of the parent JAXRConcept)
    4. code is the JAXRConcept element code value
    5. The first JAXRConcept element in the naics.xml file looks like this (all on one line):

      <JAXRConcept
      id="uuid:C0B9FE13-179F-413D-8A5B-5004DB8E5BB2/11"
      name="Agriculture, Forestry, Fishing and Hunting"
      parent="uuid:C0B9FE13-179F-413D-8A5B-5004DB8E5BB2"
      code="11"></JAXRConcept>

  6. To add the user-defined taxonomy structure to the JAXR provider, specify the system property com.sun.xml.registry.userTaxonomyFilenames when you run your client program. The command line (all on one line) would look like this. A vertical bar (|) is the file separator.
  7. java myProgram
    -Dcom.sun.xml.registry.userTaxonomyFilenames=c:\mydir\xxx.xml|c:\mydir\xxx2.xml

    You can use a <sysproperty> tag to set this property in a build.xml file for a client program. Or, in your program, you can set the property as follows:

    System.setProperty
    ("com.sun.xml.registry.userTaxonomyFilenames",
      "c:\mydir\xxx.xml|c:\mydir\xxx2.xml");

Specifying Postal Addresses

The JAXR specification defines a postal address as a structured interface with attributes for street, city, country, and so on. The UDDI specification, on the other hand, defines a postal address as a free-form collection of address lines, each of which may also be assigned a meaning. To map the JAXR PostalAddress format to a known UDDI address format, you specify the UDDI format as a ClassificationScheme object and then specify the semantic equivalences between the concepts in the UDDI format classification scheme and the comments in the JAXR PostalAddress classification scheme. The JAXR PostalAddress classification scheme is provided by the implementation of JAXR in the Java WSDP.

In the JAXR API, a PostalAddress object has the fields streetNumber, street, city, state, postalCode and country. In the implementation of JAXR in the Java WSDP, these are predefined concepts in the jaxrconcepts.xml file, within the ClassificationScheme named PostalAddressAttributes.

To specify the mapping between the JAXR postal address format and another format, you need to set two connection properties:

For example, suppose you want to use a scheme named MyPostalAddressScheme, which you published to a registry with the UUID uuid:f7922839-f1f7-9228-c97d-ce0b4594736c.

<JAXRClassificationScheme id="uuid:f7922839-f1f7-9228-c97d-
ce0b4594736c" name="MyPostalAddressScheme"> 

First, you specify the postal address scheme using the id value from the JAXRClassificationScheme element (the UUID). Case does not matter:

props.setProperty("javax.xml.registry.postalAddressScheme",
  "uuid:f7922839-f1f7-9228-c97d-ce0b4594736c"); 

Next, you specify the mapping from the id of each JAXRConcept element in the default JAXR postal address scheme to the id of its counterpart in the IBM scheme:

props.setProperty("javax.xml.registry.semanticEquivalences",
  "urn:uuid:PostalAddressAttributes/StreetNumber," +
  "uuid:f7922839-f1f7-9228-c97d-
ce0b4594736c/StreetAddressNumber|" +
  "urn:uuid:PostalAddressAttributes/Street," +
  "urn:uuid:f7922839-f1f7-9228-c97d-
ce0b4594736c/StreetAddress|" +
  "urn:uuid:PostalAddressAttributes/City," +
  "urn:uuid:f7922839-f1f7-9228-c97d-ce0b4594736c/City|" +
  "urn:uuid:PostalAddressAttributes/State," +
  "urn:uuid:f7922839-f1f7-9228-c97d-ce0b4594736c/State|" +
  "urn:uuid:PostalAddressAttributes/PostalCode," +
  "urn:uuid:f7922839-f1f7-9228-c97d-ce0b4594736c/ZipCode|" +
  "urn:uuid:PostalAddressAttributes/Country," +
  "urn:uuid:f7922839-f1f7-9228-c97d-ce0b4594736c/Country"); 

After you create the connection using these properties, you can create a postal address and assign it to the primary contact of the organization before you publish the organization:

String streetNumber = "99";
String street = "Imaginary Ave. Suite 33";
String city = "Imaginary City";
String state = "NY";
String country = "USA";
String postalCode = "00000";
String type = "";
PostalAddress postAddr = 
  blcm.createPostalAddress(streetNumber, street, city, state,
    country, postalCode, type);
Collection postalAddresses = new ArrayList();
postalAddresses.add(postAddr);
primaryContact.setPostalAddresses(postalAddresses); 

A JAXR query can then retrieve the postal address using PostalAddress methods, if the postal address scheme and semantic equivalences for the query are the same as those specified for the publication. To retrieve postal addresses when you do not know what postal address scheme was used to publish them, you can retrieve them as a collection of Slot objects. The JAXRQueryPostal.java sample program shows how to do this.

In general, you can create a user-defined postal address taxonomy for any postalAddress tModels that use the well-known categorization in the uddi-org:types taxonomy, which has the tModel UUID uuid:c1acf26d-9672-4404-9d70-39b756e62ab4 with a value of postalAddress. You can retrieve the tModel overviewDoc, which points to the technical detail for the specification of the scheme, where the taxonomy structure definition can be found. (The JAXR equivalent of an overviewDoc is an ExternalLink.)

Divider
Download
FAQ
History
PrevHomeNext API
Search
Feedback
Divider

All of the material in The Java(TM) Web Services Tutorial is copyright-protected and may not be published in other works without express written permission from Sun Microsystems.