Accessing the IBM WebSphere Service Registry and Repository using JAX-RPC

This article tells you how to access IBM WebSphere Service Registry and Repository Version 6.0 using JAX-RPC. It is intended for developers of applications for which the supplied WebSphere Service Registry and Repository client is not appropriate.

John Colgrave (colgrave@uk.ibm.com), Architect, WebSphere Service Registry and Repository, IBM

John Colgrave is a Senior Software Engineer at the IBM Hursley Laboratory in the United Kingdom. He is an architect for the IBM WebSphere Service Registry and Repository product. You can reach John at colgrave@uk.ibm.com.



13 December 2006

Introduction

The IBM® WebSphere® Service Registry and Repository (hereafter referred to as Service Registry) includes a Java™ client which supports accessing the Service Registry using either SOAP/HTTP or RMI/IIOP, with a programming model based on Service Data Objects (SDO) 2.0. The SOAP API that this client uses can also be used directly, and this article describes how to invoke this API using a JAX-RPC client.

The article begins with a description of how to find the Web Services Description Language (WSDL) and XML Schema files that describe the interface to the Service Registry and which can be used to generate a client interface in a particular programming language. Also included is an example that shows you how to generate a JAX-RPC client.

The next section describes some general topics when working with the Service Registry SOAP API and includes the source of some utility functions that are useful in working with a JAX-RPC client for the Service Registry.

Following these utility functions are examples of calling each of the Service Registry operations generated from the WSDL.

Before you get started with this article, you should have a good understanding of the following:

  • Java and JAX-RPC programming with WebSphere
  • The information in the Service Registry Information Center on the supplied client and the SOAP API

Retrieving the WSDL description of the Service Registry SOAP API

The first step is to obtain the WSDL description of the Service Registry SOAP API, so that you can generate a Java client from it. The easiest way to do this is to use the Administrative console of an instance of the WebSphere Application Server (Service Registry supports WebSphere Application Server 6.0.2.x) that is running the Service Registry.

Use the following steps:

  1. Start the Administrative console of the WebSphere Application Server profile that is hosting the Service Registry.
  2. Enter a User ID, and a password if security is on, and click on Log in.
  3. Click on Applications.
  4. Click on Enterprise Applications.
  5. Click on ServiceRegistry.
  6. Click on Publish WSDL Files which is located under Additonal Properties.
  7. Click on ServiceRegistry_WSDLFiles.zip.
  8. Save the file.
  9. Expand the file and you will see a directory/folder named ServiceRegistry.ear
  10. Inside this directory/folder is another named WSRRCoreSDO.jar
  11. Inside this directory/folder is another named META-INF
  12. Inside this directory/folder is another named wsdl

Inside this directory/folder is the set of WSDL and XML schema files that define the Service Registry SOAP API. It is important that you have a good understanding of Java and JAX-RPC programming with WebSphere, and you should have also read the information in the Service Registry Information Center on the supplied client and the SOAP API.

Tip: Notice that in the wsrrSdoWS.wsdl file, the endpoint is the endpoint for the Service Registry in that instance of the WebSphere Application Server.


Generating the client

The sample code in this article assumes the default client generated by the WSDL2Java tool that is part of the WebSphere Application Server.

To generate the client:

  1. Go to the bin directory of your installation of the WebSphere Application Server.
  2. Run setupcmdline and set your PATH environment variable to the value of WAS_PATH.
  3. In the directory containing the WSDL and XSD files, run the following command: WSDL2Java –a –r client wsrrSdoW.wsdl.

You will see some warnings about the namespace commonj.sdo, but they can be ignored.

The mapping from the namespace to the Java package can be controlled either by parameters to the WSDL2Java command or by a mapping file.

Generated interface

The Java interface generated from the WSDL is shown below:

import com.ibm.serviceregistry.jaxrpc.commonj.sdo.DataGraphType;
import com.ibm.serviceregistry.jaxrpc.ws.QueryResult;
import com.ibm.serviceregistry.jaxrpc.ws.ServiceRegistryWebServiceException;

import java.rmi.RemoteException;

package com.ibm.serviceregistry.jaxrpc.ws;

public interface WSRRCoreSDOPortType extends java.rmi.Remote {
    public String create(DataGraphType datagraph) throws
        RemoteException, ServiceRegistryWebServiceException;

    public void delete(String bsrURI) throws
        RemoteException, ServiceRegistryWebServiceException;

    public QueryResult executeQuery(DataGraphType datagraph) throws
        RemoteException, ServiceRegistryWebServiceException;

    public QueryResult executeNamedQuery(String query) throws
        RemoteException, ServiceRegistryWebServiceException;

    public QueryResult executeNamedQueryWithParameters(String query,
                                            String[] parameters) throws
        RemoteException, ServiceRegistryWebServiceException;

    public DataGraphType retrieve(String bsrURI) throws
        RemoteException, ServiceRegistryWebServiceException;

    public DataGraphType retrieveWithDepth(String bsrURI,
                                           int    depth) throws
        RemoteException, ServiceRegistryWebServiceException;

    public void update(DataGraphType datagraph) throws
        RemoteException, ServiceRegistryWebServiceException;

Utilities

This section describes some utility functions that simplify working with the Service Registry SOAP API.

Creating an instance of DataGraphType

Several of the operations of the portType take an instance of DataGraphType as an input parameter. In all these cases, the root object of the DataGraphType instance is an instance of the WSRR type. The WSRR type has two parts to it:

  1. an artefacts property that contains the objects to be passed to the Service Registry as part of the request
  2. a root property that contains the bsrURI value of the object in the artefacts array that is the object to which the request applies

In the example of creating multiple documents (described below), if you use the DataGraphType in a create request to create a WSDL document with a relationship to a Policy document, you would add the two documents to the artefacts array and the bsrURI value of the WSDL document would be specified as the value of the root attribute of the WSRR instance that was the root object of the DataGraphType instance.

When you create content in the Service Registry, the objects that are in the DataGraphType instance must be either GenericObjects or instances of subtypes of Document, and there are no containment relationships to worry about.

When you call the executeQuery, the only object being passed is the query, so again, you don't have to worry about containment relationships.

However, when you call update, it is possible that it is a logical object that is being updated, and in this case, it is necessary to understand the impact of containment relationships on the artefacts array. Only objects that are not contained by an object in the artefacts array need to be added to the array. For example, if the update call is to add a relationship between two WSDL portTypes, then only the portTypes need to be added to the artefacts array, the objects representing the operations of each of the portTypes do not need to be added to the array because they are contained in one or other of the portTypes.

Here is an example of code you can use to create an instance of DataGraphType given the array of objects that are the artefacts to be sent as part of the request, and the bsrURI value of the object that is the object to which the request applies.

static DataGraphType createDataGraph(BaseObject[] objects,
                                     String rootID) {
    WSRR wsrr = new WSRR();
    wsrr.setArtefacts(objects);
    wsrr.setRoot(rootID);
    DataGraphType dg = new DataGraphType();
    dg.setWSRR(wsrr);
    return dg;
}

Processing a returned instance of DataGraphType

When working with a returned DataGraphType instance, either from a query or a retrieve operation, it is useful to have an index of all of the objects contained in the data graph. As described above, only objects that are not contained by another object in the data graph are added to the artefacts array, so it is not sufficient just to look at the objects that are in the artefacts array.

The following code processes an instance of DataGraphType and produces a HashMap of all the objects found by following all the possible containment relationships from each object in the artefacts array.

static HashMap buildHashMap(DataGraphType dg) {
    HashMap hm = new HashMap();
    BaseObject[] topLevelObjects = dg.getWSRR().getArtefacts();
    mapArrayOfBaseObjects(hm, topLevelObjects);
    return hm;
}

private static void mapArrayOfBaseObjects(HashMap hm,
                                          BaseObject[] baseObjects) {
    int arrayLength = baseObjects.length;
    for (int i = 0; i < arrayLength; i++) {
        BaseObject baseObject = baseObjects[i];
        mapBaseObject(hm, baseObject);
    }
}

private static void mapBaseObject(HashMap hm, BaseObject baseObject) {
    String bsrURI = baseObject.getBsrURI();
    if (hm.get(bsrURI) == null) {
        hm.put(bsrURI, baseObject);
    }
    /*
     * Now follow containment relationships, recursing to add either a
     * single object or an array of objects as appropriate.
     */
    if (baseObject instanceof ComplexTypeDefinition) {
        ComplexTypeDefinition ctd = (ComplexTypeDefinition) baseObject;
        mapArrayOfBaseObjects(hm, ctd.getLocalAttributes());
    } else if (baseObject instanceof Export) {
        Export exp = (Export) baseObject;
        mapBaseObject(hm, exp.getExportBinding());
        mapArrayOfBaseObjects(hm, exp.getInterfaces());
    } else if (baseObject instanceof _import) {
        _import imp = (_import) baseObject;
        mapBaseObject(hm, imp.getImportBinding());
        mapArrayOfBaseObjects(hm, imp.getInterfaces());
    } else if (baseObject instanceof Module) {
        Module module = (Module) baseObject;
        mapArrayOfBaseObjects(hm, module.getImports());
        mapArrayOfBaseObjects(hm, module.getExports());
    } else if (baseObject instanceof WSDLBinding) {
        mapBaseObject(hm, ((WSDLBinding) baseObject).getSOAPBinding());
    } else if (baseObject instanceof WSDLMessage) {
        mapArrayOfBaseObjects(hm,
                         ((WSDLMessage) baseObject).getMessageParts());
    } else if (baseObject instanceof WSDLPort) {
        mapBaseObject(hm, ((WSDLPort) baseObject).getSOAPAddress());
    } else if (baseObject instanceof WSDLPortType) {
        mapArrayOfBaseObjects(hm,
                          ((WSDLPortType) baseObject).getOperations());
    } else if (baseObject instanceof WSDLService) {
      mapArrayOfBaseObjects(hm, ((WSDLService) baseObject).getPorts());
    }
}

Having built up this HashMap, whenever a bsrURI value is encountered in the processing of the data graph, the corresponding object is easily found by looking up the bsrURI value in the HashMap.

Declaring that document content has been changed

When updating document content, it is necessary to add an SDO change summary to indicate the fact that the content has been changed, and what the original content was. The following utility function adds the necessary change summary to a data graph. This function should be called before the content of the document has been changed.

Tip: Note that it is the content of the root document that can be changed, not the content of any other object in the data graph.

static void declareRootDocumentContentChanged(DataGraphType dg) {
    if (dg != null) {
        Document doc = (Document) getRootObject(dg);
        if (doc != null) {
            ChangeSummaryType changeSummary = new ChangeSummaryType();
            changeSummary.setLogging(true);
            ObjectChangesType objectChanges = new ObjectChangesType();
            objectChanges.setKey("#" + doc.getBsrURI());
            ChangeSummarySetting changeSummarySetting =
                                            new ChangeSummarySetting();
            changeSummarySetting.setDataValue(doc.getContent());
            changeSummarySetting.setFeatureName("content");
            ObjectChangeValueType[] objectChangeValueTypes =
                                          new ObjectChangeValueType[1];
            objectChangeValueTypes[0] = changeSummarySetting;
            objectChanges.setValue(objectChangeValueTypes);
            ObjectChangesType[] objectChangesArray =
                                              new ObjectChangesType[1];
            objectChangesArray[0] = objectChanges;
            changeSummary.setObjectChanges(objectChangesArray);
            dg.setChangeSummary(changeSummary);
        } else {
            System.err.println("null doc");
        }
    } else {
        System.err.println("null dg");
    }
}

Processing query results

All of the query-related operations return an instance of the QueryResult type. The QueryResult instance contains a list of DataGraphType instances, one for each object that matched the query criteria. If the query was a property query then each DataGraphType instance contains an array of UserDefinedProperty instances, one for each property that was requested in the query. If the query was a datagraph query, then each DataGraphType instance contains the data graph for the object that matched the query.

The following code shows how to access the results of a datagraph query.

static void printQueryResult(QueryResult queryResult) {
    DataGraphType[] resultArray = queryResult.getDatagraph();
    if (resultArray != null) {
        System.out.println("Number of results: " + resultArray.length);
        for (int i = 0; i < resultArray.length; i++) {
            DataGraphType dg = (DataGraphType) resultArray[i];
            if (dg != null) {
                printRootObject(dg);
            } else {
                System.err.println("Null dg");
            }
        }
    } else {
        System.err.println("Null resultArray");
    }
}

static void printRootObject(DataGraphType dg) {
    BaseObject baseObject = getRootObject(dg);
    if (baseObject != null) {
        System.out.print("{");
        System.out.print(baseObject.getName());
        System.out.print(", ");
        System.out.print(baseObject.getNamespace());
        System.out.print(", ");
        System.out.print(baseObject.getVersion());
        System.out.println("}");
        if (baseObject instanceof Document) {
            System.out.println("content:");
            Document doc = (Document) baseObject;
            String documentContent = new String(doc.getContent());
            System.out.println(documentContent);
        }
    } else {
        System.err.println("Root object not found");
    }
}

static BaseObject getRootObject(DataGraphType dg) {
    BaseObject baseObject = null;
    WSRR wsrr = dg.getWSRR();
    if (wsrr != null) {
        String rootObjectID = wsrr.getRoot();
        if (rootObjectID != null) {
            if (!rootObjectID.equals("")) {
                HashMap hm = buildHashMap(dg);
                if (hm != null) {
                    baseObject = (BaseObject)(hm.get(rootObjectID));
                } else {
                    System.err.println("Root object not in HashMap");
                }
            } else {
                System.err.println("empty rootObjectID");
            }
        } else {
            System.err.println("null rootObjectID");
        }
    } else {
        System.err.println("null wsrr");
    }
    return baseObject;
}

Returning the root object of a data graph

The following code returns the root object of a data graph.

static BaseObject getRootObject(DataGraphType dg) {
    BaseObject baseObject = null;
    WSRR wsrr = dg.getWSRR();
    if (wsrr != null) {
        String rootObjectID = wsrr.getRoot();
        if (rootObjectID != null) {
            if (!rootObjectID.equals("")) {
                HashMap hm = buildHashMap(dg);
                if (hm != null) {
                    baseObject = (BaseObject)(hm.get(rootObjectID));
                } else {
                    System.err.println("Root object not in HashMap");
                }
            } else {
                System.err.println("empty rootObjectID");
            }
        } else {
            System.err.println("null rootObjectID");
        }
    } else {
        System.err.println("null wsrr");
    }
    return baseObject;
}

Examples

This section includes examples of calling each of the Service Registry operations generated from the WSDL.

Creating a single document

The following code shows how to create and populate an instance of XMLDocument.

Tip: Note that retrieving the byte[] that is to be the content of the document is left as an exercise for the reader. The value of the location property should be set to the location of the content of the document.

private static XMLDocument createSingleXMLDocument() {
    XMLDocument doc = new XMLDocument();
    doc.setName("CreateSingleObjectTestDocument");
    doc.setNamespace("http://www.ibm.com/colgrave/WSRR/test");
    doc.setDescription("Single document created via JAX-RPC");
    doc.setLocation("…");
    UserDefinedProperty[] udps = new UserDefinedProperty[1];
    UserDefinedProperty udp = new UserDefinedProperty();
    udp.setName("UserDefinedPropertyOne");
    udp.setValue("ValueOne");
    udps[0] = udp;
    doc.setUserDefinedProperties(udps);
    try {
        byte[] content = …;
        if (content != null) {
            doc.setContent(content);
        } else {
            System.err.println("Got null content");
        }
    } catch (Throwable t) {
        t.printStackTrace(System.err);
    }
    return doc;
}

An instance of XMLDocument is created and then several of the standard properties are set on that instance (name, namespace, description and location).

A user-defined property is also added to the instance, showing how to work with the array of user-defined properties that almost every object in the Service Registry can have. In this case, we add a property named "UserDefinedPropertyOne" with a value of "ValueOne".

Now that we have an instance of the document, the following code shows how to save it to the Service Registry.

try {
    WSRRCoreSDOPortType wsrrCoreSDOPortType = ...;
    XMLDocument doc = // The code above;
    /*
     * Assign a temporary bsrURI value, which must begin with '_', to
     * the object so that we can refer to it, including referring to it
     * as the root object contained by the WSRR instance.
     */
    doc.setBsrURI("_1");
    BaseObject[] artefactArray = new BaseObject[1];
    artefactArray[0] = doc;
    DataGraphType dg = Utilities.createDataGraph(artefactArray, "_1");
    String bsrURI = wsrrCoreSDOPortType.create(dg);
    System.out.println("Returned bsrURI is " + bsrURI);
} catch (ServiceRegistryWebServiceException srwse) {
    System.err.println("Caught ServiceRegistryWebServiceException");
    System.err.println("message: " + srwse.getMessage());
} catch (Throwable t) {
    t.printStackTrace(System.err);
}

The code to obtain an instance of the stub to call the Service Registry depends on your environment and whether you need to supply a URL for a different endpoint, so is omitted from the code above. The call to Utilities.createDataGraph invokes the code shown in the section above entitled Creating an instance of DataGraphType. Here there is only a single object in the artefacts array and the root value is a temporary bsrURI value as it refers to something that is to be created in the Service Registry.

Creating multiple related documents

There are several ways to create multiple documents with a single call to the Service Registry. One is to use a GenericObject as the root of a collection of documents, in which case the GenericObject and all of the new documents are created with a single call to the create operation with the GenericObject as the root object. This is the only way in which the resolution of dependencies, such as between WSDL documents, can be influenced.

The other way is to construct a data graph of objects that have user-defined relationships between them. The following example is an example of this second approach.

try {
    WSRRCoreSDOPortType wsrrCoreSDOPortType = ...;
    // Create document that will be the source of the relationship
    XMLDocument doc1 = createSourceDocument();
    // Create second document that will be the target of the relationship
    XMLDocument doc2 = createTargetDocument();
    // Now create the relationship between the two
    addRelationship(doc1, doc2);
    // Create the DataGraph with the source document as the root object
    BaseObject[] artefactArray = new BaseObject[2];
    artefactArray[0] = doc1;
    artefactArray[1] = doc2;
    DataGraphType dg = Utilities.createDataGraph(artefactArray,
                                                 doc1.getBsrURI());
    String bsrURI = wsrrCoreSDOPortType.create(dg);
    System.out.println("Returned bsrURI is " + bsrURI);
} catch (ServiceRegistryWebServiceException srwse) {
    System.err.println("Caught ServiceRegistryWebServiceException");
    System.err.println("message: " + srwse.getMessage());
} catch (Throwable t) {
    t.printStackTrace(System.err);
}

private static void addRelationship(XMLDocument sourceDocument,
                                    XMLDocument targetDocument) {
    UserDefinedRelationship udr = new UserDefinedRelationship();
    udr.setName("CreateMultipleObjectsTestRelationship");
    // Only one target
    String[] targets = new String[1];
    // Use the temporary bsrURI value to refer to the target object
    targets[0] = targetDocument.getBsrURI();
    udr.setTargets(targets);
    // Add the relationship to the source document
    UserDefinedRelationship[] udrs = new UserDefinedRelationship[1];
    udrs[0] = udr;
    sourceDocument.setUserDefinedRelationships(udrs);
}

In this example, two documents are created in the same way that the single document was in the previous example. Once the documents have been created, the addRelationship method is called to add a relationship from the first document to the second document. It is this relationship that will cause the second document to be created when the create operation is called on the first document.

Executing a named query

Executing a named query is the easiest operation to invoke. The following code shows how to invoke the getAllXMLDocuments named query.

try {
    WSRRCoreSDOPortType wsrrCoreSDOPortType = ...;
    QueryResult queryResult =
        wsrrCoreSDOPortType.executeNamedQuery("getAllXMLDocuments"); 
    Utilities.printQueryResult(queryResult);
} catch (ServiceRegistryWebServiceException srwse) {
    System.err.println("Caught ServiceRegistryWebServiceException");
    System.err.println("message: " + srwse.getMessage());
} catch (Throwable t) {
    t.printStackTrace(System.err);
}

The call to Utilities.printQueryResult() invokes the example code shown above in the section on processing query results.

Executing a named query with parameters

Some named queries can be parameterized. The following code shows how to invoke the getXSDDocument query, passing in two parameters: the name of a property to be matched and the value of that property, so this example queries for an XSDDocument with a name of "TrueOrFalseBO.xsd".

try {
    WSRRCoreSDOPortType wsrrCoreSDOPortType = ...;
    // Query for an XSD Document with a specific name
    String[] parameters = new String[2];
    parameters[0] = "name";
    parameters[1] = "TrueOrFalseBO.xsd";
    QueryResult queryResult =
  wsrrCoreSDOPortType.executeNamedQueryWithParameters("getXSDDocument",
                                                      parameters);
    Utilities.printQueryResult(queryResult);
} catch (ServiceRegistryWebServiceException srwse) {
    System.err.println("Caught ServiceRegistryWebServiceException");
    System.err.println("message: " + srwse.getMessage());
} catch (Throwable t) {
    t.printStackTrace(System.err);
}

Executing a query

If there is no appropriate named query, then it is possible to invoke an ad-hoc query where the query expression is described using XPath.

The following code shows how to query for all XMLDocuments.

try {
    WSRRCoreSDOPortType wsrrCoreSDOPortType = …;
    String query = "/WSRR/XMLDocument";
    GraphQuery gq = new GraphQuery();
    gq.setBsrURI("_1");
    gq.setQueryExpression(query);
    BaseObject[] artefactsArray = new BaseObject[1];
    artefactsArray[0] = gq;
    WSRR wsrr = new WSRR();
    wsrr.setArtefacts(artefactsArray);
    // Set the GraphQuery object as the root object.
    wsrr.setRoot("_1");
    DataGraphType dg = new DataGraphType();
    dg.setWSRR(wsrr);
    QueryResult response = wsrrCoreSDOPortType.executeQuery(dg);
    Utilities.printQueryResult(response);
} catch (Throwable t) {
    t.printStackTrace(System.err);
}

The code creates an instance of GraphQuery and sets the XPath query expression to "/WSRR/XMLDocument", which will match against any XMLDocument instance in the Service Registry. The temporary bsrURI value of "_1" is assigned to the GraphQuery instance, even though it will not be persisted. This is because we still need a value to set as the root attribute of the WSRR instance contained in the DataGraphType instance.

Once the WSRR instance has been created and populated, it is set as the root object of the DataGraphType instance and the executeQuery operation is then invoked, which because this is an instance of GraphQuery, will return a QueryResult that contains an array of normal DataGraphType instances.

Retrieving content

In order to retrieve an object from the Service Registry, it is necessary to know its bsrURI, so the following example shows how to issue a PropertyQuery to return just the bsrURI, which is then used in the retrieve call.

try {
    WSRRCoreSDOPortType wsrrCoreSDOPortType = …;
    String bsrURI = queryDocID(wsrrCoreSDOPortType);
    if (bsrURI != null) {
      System.out.println("Attempting to retrieve document with bsrURI "
+ bsrURI);
        DataGraphType retrieveResult =
                                  wsrrCoreSDOPortType.retrieve(bsrURI);
        if (retrieveResult != null) {
            Utilities.printRootObject(retrieveResult);
        } else {
            System.err.println("null retrieveResult");
        }
    } else {
        System.err.println("null bsrURI");
    }
} catch (ServiceRegistryWebServiceException srwse) {
    System.err.println("Caught ServiceRegistryWebServiceException");
    System.err.println("message: " + srwse.getMessage());
} catch (Throwable t) {
    t.printStackTrace(System.err);
}

The queryDocID issues a PropertyQuery that is assumed to match only one document, and the bsrURI of that document is returned, and it is that document that is retrieved. The code of the queryDocID method is as follows.

String bsrURI = null;
/*
 * Do a property query to retrieve the bsrURI of the document created
 * in CreateSingleObjectTest
 */
String[] uris = Utilities.queryMatchingURIs(wsrrCoreSDOPortType,
          "/WSRR/XMLDocument[@name='CreateSingleObjectTestDocument']");
if (uris != null) {
    if (uris.length == 1) {
        bsrURI = uris[0];
    } else {
        System.err.println("was expecting one bsrURI");
    }
} else {
    System.err.println("null uris");
}
return bsrURI;

This code invokes a utility method, queryMatchingURIs, to invoke the property query, passing in the XPath expression to be used, in this case WSRR/XMLDocument[@name='CreateSingleObjectTestDocument']". The queryMatchingURIs builds up a PropertyQuery for the supplied XPath expression and specifies that the value of the bsrURI property is to be returned for each object that matches the XPath expression. The code of the queryMatchingURIs method is shown below.

String[] results = null;
PropertyQuery pq = new PropertyQuery();
// Set temporary bsrURI value
pq.setBsrURI("_1");
pq.setQueryExpression(queryExpression);
/*
 * Add the user-defined property to the PropertyQuery object to declare
 * that we want the value of the bsrURI property of the matching
 * document(s) to be returned.
 */
UserDefinedProperty[] udps = new UserDefinedProperty[1];
UserDefinedProperty udp = new UserDefinedProperty();
udps[0] = udp;
udp.setName("TheNameIsUnimportant");
udp.setValue("bsrURI");
pq.setUserDefinedProperties(udps);
// Construct the DataGraph to represent the query and issue it.
BaseObject[] artefactArray = new BaseObject[1];
artefactArray[0] = pq;
DataGraphType dg = Utilities.createDataGraph(artefactArray,
                                             pq.getBsrURI());
try {
    QueryResult response = wsrrCoreSDOPortType.executeQuery(dg);
    // Now retrieve the bsrURI value of the document
    if (response != null) {
        DataGraphType[] resultDGs = response.getDatagraph();
        if (resultDGs != null) {
            if (resultDGs.length > 0) {
                results = new String[resultDGs.length];
                for (int i = 0; i < resultDGs.length; i++) {
                    DataGraphType resultDG = resultDGs[i];
                    if (resultDG != null) {
                        UserDefinedProperty[] resultUDPs =
                                     resultDG.getPropertyQueryResult();
                        if (resultUDPs != null) {
                         UserDefinedProperty resultUDP = resultUDPs[0];
                            results[i] = resultUDP.getValue();
                        } else {
                  System.err.println("Got null UserDefinedProperties");
                        }
                    } else {
                        System.err.println("null resultDG");
                    }
                }
            } else {
                System.err.println("Was expecting at least one DG");
            }
        } else {
            System.err.println("null resultDGs");
        }
    } else {
        System.err.println("executeQuery returned null");
    }
} catch (ServiceRegistryWebServiceException srwse) {
    System.err.println("Caught ServiceRegistryWebServiceException");
    System.err.println(srwse.getMessage());
}
return results;

Updating content

This section provides code examples for updating metadata and document content.

Updating metadata

The following code is an example of updating the metadata about a document, in this case updating the description. The code assumes that the bsrURI value of the document to be updated is known. The document is retrieved, the description is changed, and then the document is updated in the Service Registry.

try {
    WSRRCoreSDOPortType wsrrCoreSDOPortType = …;
    String bsrURI = …; // The bsrURI of the doc. to be updated.
    if (bsrURI != null) {
        DataGraphType retrieveResult =
                                  wsrrCoreSDOPortType.retrieve(bsrURI);
        if (retrieveResult != null) {
            BaseObject baseObject =
                               Utilities.getRootObject(retrieveResult);
            if (baseObject != null) {
       baseObject.setDescription("Description modified by UpdateTest");
                wsrrCoreSDOPortType.update(retrieveResult);
                System.out.println("Description updated successfully");
            }
        } else {
            System.err.println("null retrieveResult");
        }
    } else {
        System.err.println("null bsrURI");
    }
} catch (ServiceRegistryWebServiceException srwse) {
    System.err.println("Caught ServiceRegistryWebServiceException");
    System.err.println("message: " + srwse.getMessage());
} catch (Throwable t) {
    t.printStackTrace(System.err);
}

This code uses the utility method to return the root object of a data graph to get the object to be updated.

Tip: The DataGraphType instance returned by the retrieve call can be used in the subsequent update call.

Updating document content

The following code is an example of updating the content of a document.

try {
    WSRRCoreSDOPortType wsrrCoreSDOPortType = ...;
    String bsrURI = ...;
    if (bsrURI != null) {
        DataGraphType retrieveResult =
                                  wsrrCoreSDOPortType.retrieve(bsrURI);
        if (retrieveResult != null) {
            BaseObject baseObject =
                               Utilities.getRootObject(retrieveResult);
            Document doc = (Document) baseObject;
            if (doc != null) {
           Utilities.declareRootDocumentContentChanged(retrieveResult);
                Byte[] newContent = …;
                doc.setContent(newContent);
                wsrrCoreSDOPortType.update(retrieveResult);
            }
        } else {
            System.err.println("null retrieveResult");
        }
    } else {
        System.err.println("null bsrURI");
    }
} catch (ServiceRegistryWebServiceException srwse) {
    System.err.println("Caught ServiceRegistryWebServiceException");
    System.err.println("message: " + srwse.getMessage());
} catch (Throwable t) {
    t.printStackTrace(System.err);
}

Deleting content

Deleting content is similar to retrieving content in that the bsrURI value must be known. The following code is an example of deleting an object.

String bsrURI = null;
try {
    WSRRCoreSDOPortType wsrrCoreSDOPortType = …;
    bsrURI = queryDocID(wsrrCoreSDOPortType);
    if (bsrURI != null) {
        System.out.println("Attempting to delete document with bsrURI "
+ bsrURI);
        wsrrCoreSDOPortType.delete(bsrURI);
        System.out.println("Attempt was successful");
    } else {
        System.err.println("null bsrURI");
    }
} catch (ServiceRegistryWebServiceException srwse) {
    System.err.println("Caught ServiceRegistryWebServiceException");
    System.err.println("message: " + srwse.getMessage());
} catch (Throwable t) {
    t.printStackTrace(System.err);
}

The queryDocID method is the same as in the retrieve example above.


Conclusion

This article has shown you how to generate a JAX-RPC client from the WSDL description of the Service Registry API. Several useful utility methods have been included and examples of calling each of the methods are shown.

Resources

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into WebSphere on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere, SOA and web services, Business process management
ArticleID=182370
ArticleTitle=Accessing the IBM WebSphere Service Registry and Repository using JAX-RPC
publish-date=12132006