Publishing Objects to the Registry

If a client has authorization to do so, it can submit objects to the Service Registry, modify them, and remove them. A client uses the BusinessLifeCycleManager interface to perform these tasks.

Registries usually allow a client to modify or remove objects only if the objects are being modified or removed by the same user who first submitted them. Access policies can control who is authorized to publish objects and perform actions on them.

Publishing registry objects involves the following tasks:

It is important to remember that submitting objects is a multi-step task: you create the objects and populate them by setting their attributes, then you save them. The objects appear in the registry only after you save them.

You may remember that when you search for objects by classification, external identifier, and the like, you create the classification or other object that you are using in the search. (For an example, see Finding Objects by Classification.) However, you do not save this object. You create the object only for the purposes of the search, after which it disappears. You do not need authorization from the Registry to create an object, but you must have authorization to save it.


Note: At this release, you do not need authorization from the Registry to save objects.


Creating Objects

A client creates an object and populates it with data before publishing it. You can create and publish any of the following types of RegistryObject:

The following types of RegistryObject cannot be published separately, but you can create and save them as part of another object:

Some objects fall into special categories:

The subsections that follow describe first the tasks common to creating and saving all registry objects. They then describe some tasks specific to particular object types.

Using Create Methods for Objects

The LifeCycleManager interface supports create methods for all types of RegistryObject (except AuditableEvent and Notification, which can be created only by the Registry itself).

In addition, you can use the LifeCycleManager.createObject factory method to create an object of a particular type. This method takes a String argument consisting of one of the static fields supported by the LifeCycleManager interface. In the following code fragment, blcm is the BusinessLifeCycleManager object:

Organization org = (Organization)
  blcm.createObject(blcm.ORGANIZATION); 

The object-specific create methods usually take one or more parameters that set some of the attributes of the object. For example, the createOrganization method sets the name of the organization:

Organization org = blcm.createOrganization("MyOrgName"); 

On the other hand, the createExtrinsicObject method takes a DataHandler argument that sets the repository item for the extrinsic object.

Adding Names and Descriptions to Objects

For all objects, you can set the name and description attributes by calling setter methods. These attributes are of type InternationalString. An InternationalString includes a set of LocalizedString objects that allow users to display the name and description in one or more locales. By default, the InternationalString value uses the default locale.

For example, the following fragment creates a description for an organization that uses two localized strings, one in the language of the default locale and one in French (Canada).

InternationalString is =
  blcm.createInternationalString("What We Do"));
Locale loc = new Locale("fr", "CA");
LocalizedString ls = blcm.createLocalizedString(loc, 
  "ce que nous faisons");
is.addLocalizedString(ls);
org.setDescription(is); 

Identifying Objects

As stated in Finding Objects by Unique Identifier, every object in the Registry has two identifiers, a unique identifier and a logical identifier. If you do not set these identifiers when you create the object, the Registry generates a unique value and assigns that value to both the unique and the logical identifiers.

Whenever a new version of an object is created (see Retrieving the Version of an Object, and Changing the State of Objects in the Registry), the logical identifier remains the same as the original one, but the Registry generates a new unique identifier by adding a colon and the version number to the unique identifier.


Note: At this release, versioning is disabled by default. The logical and unique identifiers remain the same after the object is modified.


If you plan to use your own identification scheme, you can use API methods to set object identifiers. In the JAXR API, the unique identifier is called a Key object. You can use the LifeCycleManager.createKey method to create a unique identifier from a String object, and you can use the RegistryObject.setKey method to set it. The logical identifier is called a lid, and the JAXR provider for the Registry has an implementation-specific method, RegistryObjectImpl.setLid, which also takes a String argument, for setting this identifier. The method has the following signature:

public void setLid(java.lang.String lid)
  throws JAXRException 

Any identifier you specify must be a valid, globally unique URN (Uniform Resource Name). When the JAXR API generates a key for an object, the key is in the form of a DCE 128 UUID (Universal Unique IDentifier).

Creating and Using Classification Schemes and Concepts

You can create your own classification schemes and concept hierarchies for classifying registry objects. To do so, follow these steps:

  1. Use the LifeCycleManager.createClassificationScheme method to create the classification scheme.
  2. Use the LifeCycleManager.createConcept method to create concepts.
  3. Use the ClassificationScheme.addChildConcept method to add the concepts to the classification scheme.
  4. For a deeper hierarchy, use the Concept.addChildConcept method to add child concepts to the concepts.
  5. Save the classification scheme.

The LifeCycleManager.createClassificationScheme method has several forms. You can specify two arguments, a name and description, as either String or InternationalString values. For example, to create a classification scheme to describe how books are shelved in a library, you could use the following code fragment:

ClassificationScheme cs = 
  blcm.createClassificationScheme("LibraryFloors", 
    "Scheme for Shelving Books"); 

An alternate form of the createClassificationScheme method takes one argument, a Concept, and converts it to a ClassificationScheme.

The createConcept method takes three arguments: a parent, a name, and a value. The parent can be either a ClassificationScheme or another Concept. It is acceptable to specify a value but no name.

The following code fragment uses a static String array containing the names of the floors of the library to create a concept for each floor of the library, and then adds the concept to the classification scheme.

for (int i = 0; i < floors.length; i++) {
  Concept con = blcm.createConcept(cs, floors[i], floors[i]);
  cs.addChildConcept(con);
  ... 

For each concept, you can create more new concepts and call Concept.addChildConcept to create another level of the hierarchy. When you save the classification scheme, the entire concept hierarchy is also saved.

Creating Classification Schemes: Example

For an example of creating a classification scheme, see <INSTALL>/registry/samples/classification-schemes/src/JAXRPublishScheme.java. This example creates a classification scheme named LibraryFloors and a concept hierarchy that includes each floor of the library and the subject areas that can be found there. To run the example, follow these steps:

  1. Go to the directory <INSTALL>/registry/samples/classification-schemes.
  2. Type the following command:
  3. ant pub-scheme

To display the concept hierarchy, use the program <INSTALL>/registry/samples/classification-schemes/src/JAXRQueryScheme.java. This example displays the concept hierarchy for any classification scheme you specify. To run the example, follow these steps:

  1. Go to the directory <INSTALL>/registry/samples/classification-schemes.
  2. Type the following command:
  3. ant query-scheme -Dname=LibraryFloors

To delete this classification scheme, use the program <INSTALL>/registry/samples/classification-schemes/src/JAXRQueryScheme.java. To run the example, follow these steps:

  1. Go to the directory <INSTALL>/registry/samples/classification-schemes.
  2. Type the following command:
  3. ant del-scheme -Dname=LibraryFloors

Adding Classifications to Objects

Objects can have one or more classifications based on one or more classification schemes (taxonomies). To establish a classification for an object, the client first locates the taxonomy it wants to use. The client then creates a classification using the classification scheme and a concept (a taxonomy element) within the classification scheme.

For information on creating a new classification scheme with a hierarchy of concepts, see Creating Relationships Between Objects: Associations. A classification scheme with a concept hierarchy is called an internal classification scheme.

To add a classification that uses an existing classification scheme, you usually call the BusinessQueryManager.findClassificationSchemeByName method. This method takes two arguments, a Collection of FindQualifier objects and a String that specifies a name pattern. It is an error for this method to return more than one result, so you must define the search very precisely. For example, the following code fragment searches for the classification scheme named AssociationType:

String schemeName = "AssociationType";
ClassificationScheme cScheme = 
  bqm.findClassificationSchemeByName(null, schemeName); 

After you locate the classification scheme, you call the LifeCycleManager.createClassification method, specifying three arguments: the classification scheme and the name and value of the concept.

Classification classification = 
  blcm.createClassification(cScheme, "Extends", "Extends"); 

An alternative method is to call BusinessQueryManager.findConcepts (or BusinessQueryManagerImpl.findObjects with a "Concept" argument), locate the concept you wish to use, and call another form of createClassification, with the concept as the only argument:

Classification classification = 
  blcm.createClassification(concept); 

After creating the classification, you call RegistryObject.addClassification to add the classification to the object.

object.addClassification(classification); 

To add multiple classifications, you can create a Collection, add the classification to the Collection, and call RegistryObject.addClassifications to add the Collection to the object.

Adding Classifications: Example

For an example of adding classifications to an object, see <INSTALL>/registry/samples/publish-object/src/JAXRPublishObject.java. This example creates an organization and adds a number of objects to it. To run the example, follow these steps:

  1. Go to the directory <INSTALL>/registry/samples/publish-object.
  2. Type the following command:
  3. ant run

Adding External Identifiers to Objects

To add an external identifier to an object, follow these steps:

  1. Find or create the classification scheme to be used.
  2. Create an external identifier using the classification scheme.

To create external identifiers, you use an external classification scheme, which is a classification scheme without a concept hierarchy. You specify a name and value for the external identifier.

The database supplied with the Registry does not include any external classification schemes, so before you can use one you must create it, using code like the following:

ClassificationScheme extScheme = 
  blcm.createClassificationScheme("NASDAQ", 
    "OTC Stock Exchange"); 

To find an existing classification scheme, you typically call the BusinessQueryManager.findClassificationSchemeByName method, as described in Adding Classifications to Objects.

For example, the following code fragment finds the external classification scheme you just created:

ClassificationScheme extScheme = 
  bqm.findClassificationSchemeByName(null, 
    "NASDAQ"); 

To add the external identifier, you call the LifeCycleManager.createExternalIdentifier method, which takes three arguments: the classification scheme and the name and value of the external identifier. Then you add the external identifier to the object.

ExternalIdentifier extId = 
  blcm.createExternalIdentifier(extScheme, "Sun", 
    "SUNW);
object.addExternalIdentifier(extId); 

The example <INSTALL>/registry/samples/publish-object/src/JAXRPublishObject.java, described in Adding Classifications: Example, also adds an external identifier to an object.

Adding External Links to Objects

To add an external link to an object, you call the LifeCycleManager.createExternalLink method, which takes two arguments: the URI of the link, and a description of the link. Then you add the external link to the object.

String eiURI = "http://java.sun.com/";
String eiDescription = "Java Technology";
ExternalLink extLink = 
  blcm.createExternalLink(eiURI, eiDescription);
object.addExternalLink(extLink); 

The URI must be a valid URI, and the JAXR provider checks its validity. If the link you specify is outside your firewall, you need to specify the system properties http.proxyHost and http.proxyPort when you run the program so that JAXR can determine the validity of the URI.

To disable URI validation (for example, if you want to specify a link that is not currently active), call the ExternalLink.setValidateURI method before you create the link.

extLink.setValidateURI(false); 

The example <INSTALL>/registry/samples/publish-object/src/JAXRPublishObject.java, described in Adding Classifications: Example, also adds an external link to an object.

Adding Slots to Objects

Slots are arbitrary attributes, so the API provides maximum flexibility for you to create them. You can provide a name, one or more values, and a type. The name and type are String objects. The value or values are stored as a Collection of String objects, but the LifeCycleManager.createSlot method has a form that allows you to specify a single String value. For example, the following code fragment creates a slot using a String value, then adds the slot to the object.

String slotName = "Branch";
String slotValue = "Paris";
String slotType = "City";
Slot slot = blcm.createSlot(slotName, slotValue, slotType);
org.addSlot(slot); 

The example <INSTALL>/registry/samples/publish-object/src/JAXRPublishObject.java, described in Adding Classifications: Example, also adds a slot to an object.

Creating Organizations

An Organization object is probably the most complex registry object. It normally includes the following attributes, in addition to those common to all objects:

An organization can also have one or more child organizations, which can in turn have children, to form a hierarchy of organizations.

The following code fragment creates an organization and specifies its name, description, postal address, and telephone number.

// Create organization name and description
Organization org = 
  blcm.createOrganization("The ebXML Coffee Break");
InternationalString is =
  blcm.createInternationalString("Purveyor of " +
    "the finest coffees. Established 1905");
org.setDescription(is);

// create postal address for 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 = "Type US";
PostalAddress postAddr = 
  blcm.createPostalAddress(streetNumber, street, city, state,
    country, postalCode, type);
org.setPostalAddress(postAddr);

// create telephone number for organization
TelephoneNumber tNum = blcm.createTelephoneNumber();
tNum.setCountryCode("1");
tNum.setAreaCode("100");
tNum.setNumber("100-1000");
tNum.setType("OfficePhone");
Collection tNums = new ArrayList();
tNums.add(tNum);
org.setTelephoneNumbers(tNums); 

The telephone number type is the value of a concept in the PhoneType classification scheme: "OfficePhone", "MobilePhone", "HomePhone", "FAX", or "Beeper".

To create a hierarchy of organizations, use the Organization.addChildOrganization method to add one organization to another, or use the Organization.addChildOrganizations method to add a Collection of organizations to another.

Creating an Organization: Examples

For examples of creating an organization, see JAXRPublishOrg.java and JAXRPublishOrgNoPC.java in the directory <INSTALL>/registry/samples/organizations/src.

The JAXRPublishOrg example creates an organization, its primary contact, and a service and service binding. It displays the unique identifiers for the organization, user, and service so that you can use them later when you delete the objects. This example creates a fictitious User as the primary contact for the organization.

The other example, JAXRPublishOrgNoPC, does not set a primary contact for the organization. In this case, the primary contact by default is the User who is authenticated when you run the program.

To run the examples, follow these steps:

  1. Go to the directory <INSTALL>/registry/samples/organizations.
  2. Type the following commands:
  3. ant pub-org
    ant pub-org-nopc

Creating and Retrieving an Organization Hierarchy: Example

For examples of publishing and retrieving an organization hierarchy, see the examples <INSTALL>/registry/samples/organizations/src/JAXRPublishOrgFamily.java and <INSTALL>/registry/samples/organizations/src/JAXRQueryOrgFamily.java. To run the examples, follow these steps:

  1. Go to the directory <INSTALL>/registry/samples/organizations.
  2. Type the following command to publish the organizations:
  3. ant pub-fam

  4. Type the following command to retrieve the organizations you published:
  5. ant query-fam

Creating Users

If you create an organization without specifying a primary contact, the default primary contact is the User object that created the organization (that is, the user whose credentials you set when you created the connection to the Registry). However, you can specify a different user as the primary contact. A User is also a complex type of registry object. It normally includes the following attributes, in addition to those common to all objects:

The following code fragment creates a User and then sets that User as the primary contact for the organization. This User has a telephone number and email address but no postal address.

// Create primary contact, set name
User primaryContact = blcm.createUser();
String userId = primaryContact.getKey().getId();
System.out.println("User URN is " + userId);
PersonName pName = 
  blcm.createPersonName("Jane", "M.", "Doe");
primaryContact.setPersonName(pName);

// Set primary contact phone number
TelephoneNumber pctNum = blcm.createTelephoneNumber();
pctNum.setCountryCode("1");
pctNum.setAreaCode("100");
pctNum.setNumber("100-1001");
pctNum.setType("MobilePhone");
Collection phoneNums = new ArrayList();
phoneNums.add(pctNum);
primaryContact.setTelephoneNumbers(phoneNums);

// Set primary contact email address
EmailAddress emailAddress =
blcm.createEmailAddress("jane.doe@TheCoffeeBreak.com");
emailAddress.setType("OfficeEmail"));
Collection emailAddresses = new ArrayList();
emailAddresses.add(emailAddress);
primaryContact.setEmailAddresses(emailAddresses);

URL pcUrl = new URL((bundle.getString("person.url"));
primaryContact.setUrl(pcUrl);

// Set primary contact for organization
org.setPrimaryContact(primaryContact); 

The telephone number type for the primary contact is the value of a concept in the PhoneType classification scheme: "OfficePhone", "MobilePhone", "HomePhone", "FAX", or "Beeper". The email address type for the primary contact is the value of a concept in the EmailType classification scheme: either "OfficeEmail" or "HomeEmail".

Creating Services and Service Bindings

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

You can also create services that are not attached to any organization.

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

In addition to the attributes common to all objects, 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 by using the service binding.

The following code fragment shows how to create a collection of services, add service bindings to a service, and 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 attribute 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 " + 
  "Name"));
binding.setName(is);
is = blcm.createInternationalString("My Service Binding " +
  "Description");
binding.setDescription(is);
// allow us to publish a fictitious URI 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); 

A service binding normally has 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 SpecificationLink object that refers to an ExtrinsicObject. For details, see Storing Items in the Repository.

(This mechanism is different from the way you publish a specification's location to a UDDI registry: for a UDDI registry you create a Concept object and then add the URL of the WSDL document to the Concept object as an ExternalLink object.)

Saving Objects in the Registry

Once you have created an object and set its attributes, you publish it to the Registry by calling the LifeCycleManager.saveObjects method or an object-specific save method like BusinessLifeCycleManager.saveOrganizations or BusinessLifeCycleManager.saveServices. You always publish a collection of objects, not a single object. The save methods return a BulkResponse object that contains the keys (that is, the unique identifiers) for the saved objects. The following code fragment saves an organization and retrieves its key:

// 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.getExceptions();
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);
  }
} 

If one of the objects exists but some of the data have changed, the save methods update and replace the data. This normally results in the creation of a new version of the object (see Changing the State of Objects in the Registry).