引言
IBM® WebSphere® Service Registry and Repository(以下稱為 Service Registry)包括一個支持使用 SOAP/HTTP 或 RMI/IIOP 來訪問 Service Registry 的 Java™ 客戶端,同時帶有一個基於服務數據對象 (SDO) 2.0 的編程模型。也可以直接使用該客戶端使用的 SOAP API,本文將說明如何使用 JAX-RPC 客戶端來調用此 API。
本文首先說明如何查找描述 Service Registry 的接口的 Web 服務描述語言 (WSDL) 和 XML 模式文件(可以根據這些文件用特定編程語言生成客戶端接口)。文中還包括用於說明如何生成 JAX-RPC 客戶端的示例。
接下來將說明使用 Service Registry SOAP API 時涉及到的一些常規主題,並且還將介紹一些實用函數的來源,這些實用函數在使用 Service Registry 的 JAX-RPC 客戶端時非常有用。
在介紹了實用函數之後,我們將提供一些示例來說明如何調用根據 WSDL 生成的每個 Service Registry 操作。
在開始學習本文之前,您應該對以下內容有很好的了解:
使用 WebSphere 進行 Java 和 JAX-RPC 編程
Service Registry Information Center 中關於已提供的客戶端和 SOAP API 的信息
檢索 Service Registry SOAP API 的 WSDL 描述
第一步是獲取 Service Registry SOAP API 的 WSDL 描述,以便您可以根據它生成 Java 客戶端。要這樣做,最簡單的方法是使用運行 Service Registry 的 WebSphere Application Server(Service Registry 支持 WebSphere Application Server 6.0.2.x)實例的管理控制台。
請執行以下步驟:
啟動承載 Service Registry 的 WebSphere Application Server 概要的管理控制台。
如果安全性處於啟用狀態,則輸入用戶 ID 和密碼,並單擊 Log in。
單擊 Applications。
單擊 Enterprise Applications。
單擊 ServiceRegistry。
單擊位於“Additonal Properties”下方的 Publish WSDL Files。
單擊 ServiceRegistry_WSDLFiles.zip。
保存文件。
展開該文件,您將看到一個名為 ServiceRegistry.ear 的目錄/文件夾
該目錄/文件夾內有另一個名為 WSRRCoreSDO.jar 的目錄/文件夾。
該目錄/文件夾內有另一個名為 META-INF 的目錄/文件夾。
該目錄/文件夾內有另一個名為 wsdl 的目錄/文件夾。
該目錄/文件夾內有一組用於定義 Service Registry SOAP API 的 WSDL 和 XML 模式文件。您必須對如何使用 WebSphere 進行 Java 和 JAX-RPC 編程有很好的了解,並且您還應該閱讀 Service Registry Information Center 中關於已提供的客戶端和 SOAP API 的信息。
提示:請注意,在 wsrrSdoWS.wsdl 文件中,端點是 WebSphere Application Server 實例中的 Service Registry 的端點。
生成客戶端
本文中的示例代碼假設由 WSDL2Java 工具生成的缺省客戶端是 WebSphere Application Server 的一部分。
要生成客戶端,請執行以下操作:
轉到 WebSphere Application Server 安裝的 bin 目錄。
運行 setupcmdline 並將 PATH 環境變量設置為 WAS_PATH 的值。
在包含 WSDL 和 XSD 文件的目錄中,運行以下命令: WSDL2Java –a –r client wsrrSdoW.wsdl.
您將看到一些關於命名空間 commonj.sdo 的警告,但您可以忽略它們。
從命名空間到 Java 包的映射既可以由 WSDL2Java 命令的參數進行控制,也可以由映射文件進行控制。
生成的接口
根據 WSDL 生成的 Java 接口如下所示:
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;
實用工具
本部分說明一些用於簡化 Service Registry SOAP API 的使用的實用函數。
創建 DataGraphType 的實例
portType 的某些操作會將 DataGraphType 的實例作為輸入參數。在所有這些情況下,DataGraphType 實例的根對象是一個 WSRR 類型的實例。對於該實例,WSRR 類型具有以下兩部分內容:
一個構件屬性,包含要作為請求的一部分傳遞到 Service Registry 的對象。
一個根屬性,包含構件數組中的對象的 bsrURI 值,該構件數組即請求將應用到的對象。
在創建多個文檔的示例(下文將進行說明)中,如果您在一個創建請求中使用 DataGraphType 來創建與 Policy 文檔關聯的 WSDL 文檔,則會將這兩個文檔添加到構件數組中,並且將 WSDL 文檔的 bsrURI 值指定為 WSRR 實例(此實例是 DataGraphType 實例的根對象)的根屬性。
在 Service Registry 中創建內容時,DataGraphType 實例中的對象必須是 GenericObjects 或 Document 的子類型的實例,並且無須為包含關系而擔憂。
在調用 executeQuery 時,查詢是唯一要傳遞的對象,因此,您同樣不必為包含關系而擔憂。
然而,在調用更新時,有可能要更新邏輯對象,在此情況下,有必要了解包含關系對構件數組的影響。只需將構件數組內的對象不包含的對象添加到該數組中即可。例如,如果更新調用是添加兩個 WSDL portType 之間的關系,則只需將這兩個 portType 添加到構件數組中,而無需將表示每個 portType 的操作的對象添加到數組中,因為這些對象包含在其中一個 portType 中。
下面是可用來創建 DataGraphType 實例的代碼示例(給定將作為請求的一部分進行發送的對象(即構件)數組和請求將應用到的對象的 bsrURI 值)。
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;
}
處理返回的 DataGraphType 實例
在處理從查詢或檢索操作返回的 DataGraphType 實例時,為數據圖中的所有對象建立索引將非常有用。如上所述,由於只將數據圖中的另一個對象不包含的對象添加到構件數組中,因此,僅了解構件數組中的對象是不夠的。
以下代碼處理 DataGraphType 實例,並通過跟蹤構件數組內的每個對象中所有可能的包含關系來生成找到的所有對象的 HashMap。
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());
}
}
在建立此 HashMap 後,只要在處理數據圖時遇到 bsrURI 值,就可以通過查找 HashMap 中的 bsrURI 值很容易地找到相應的對象。
聲明文檔內容已更改
在更新文檔內容時,有必要添加 SDO 更改摘要以表明內容已更改的事實並說明原始內容是什麼。以下實用函數將必要的更改摘要添加到數據圖中。在更改文檔內容前應調用此函數。
提示:請注意,可以更改的是根文檔的內容,並不是數據圖中任何其他對象的內容。
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");
}
}
處理查詢結果
所有與查詢相關的操作都返回 QueryResult 類型的實例。QueryResult 實例包含一列 DataGraphType 實例,一個 DataGraphType 實例對應一個與查詢條件匹配的對象。如果是屬性查詢,則每個 DataGraphType 實例都包含一組 UserDefinedProperty 實例,一個 UserDefinedProperty 實例對應查詢中請求的一個屬性。如果是 datagraph 查詢,則每個 DataGraphType 實例都包含與查詢匹配的對象的數據圖。
以下代碼說明如何訪問 datagraph 查詢的結果。
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;
}
返回數據圖的根對象
以下代碼返回數據圖的根對象。
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;
}
示例
本部分包括調用每個根據 WSDL 生成的 Service Registry 操作的示例。
創建單個文檔
以下代碼說明如何創建和填充 XMLDocument 實例。
提示:請注意,對於有關檢索將成為文檔內容的 byte[] 的部分,我們留給讀者自己練習。應將位置屬性的值設置為文檔內容的位置。
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;
}
以上代碼創建 XMLDocument 實例,然後在該實例上設置一些標准屬性(名稱、命名空間、描述和位置)。
以上代碼還將用戶定義屬性添加到實例,並且說明了如何處理 Service Registry 中的每個對象幾乎都可以具有的用戶定義屬性的數組。在此示例中,我們添加一個具有“ValueOne”值的名為“UserDefinedPropertyOne”的屬性。
現在我們有一個文檔實例,以下代碼將說明如何將其保存到 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);
}
用於獲取存根實例以調用 Service Registry 的代碼取決於您的環境以及您是否需要為不同的端點提供 URL,因此上述代碼省略了此代碼。對 Utilities.createDataGraph 的調用將調用上一部分(標題為“創建 DataGraphType 的實例”)中顯示的代碼。這裡,構件數組中只有單個對象,並且根值是一個臨時的 bsrURI 值(因為根值會引用將在 Service Registry 中創建的內容)。
創建多個相關的文檔
有多種方法可以通過對 Service Registry 的單次調用來創建多個文檔。其中一種方法是將 GenericObject 用作一組文檔的根,在此情況下,通過對創建操作的單次調用,將創建 GenericObject 和所有新文檔(GenericObject 作為根對象)。只能用這種方法來影響依賴關系(如 WSDL 文檔之間的依賴關系)的解析。
另一種方法是構造對象(這些對象之間具有用戶定義關系)的數據圖。下面是第二種方法的示例。
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);
}
在此示例中,創建兩個文檔的方式與前一個示例中創建單個文檔的方式相同。一旦創建了文檔,就可以調用 addRelationship 方法,以便將關系從第一個文檔添加到第二個文檔。對第一個文檔調用創建操作時,正是此關系會引發創建第二個文檔。
執行命名查詢
執行命名查詢是最容易的調用操作。以下代碼說明如何調用 getAllXMLDocuments 命名查詢。
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);
}
對 Utilities.printQueryResult() 的調用將調用在上面有關處理查詢結果的部分中顯示的示例代碼。
執行帶參數的命名查詢
可以對一些命名查詢進行參數化。以下代碼說明如何調用 getXSDDocument 查詢,同時傳入以下兩個參數(要進行匹配的屬性的名稱和該屬性的值),因此該示例查詢具有名為“TrueOrFalseBO.xsd”的 XSDDocument。
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);
}
執行查詢
如果沒有合適的命名查詢,則有可能會調用一個特定的查詢,其中查詢表達式是使用 XPath 進行描述的。
以下代碼說明如何查詢所有的 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);
}
以上代碼將創建 GraphQuery 實例並將 XPath 查詢表達式設置為“/WSRR/XMLDocument”,對 Service Registry 中的任何 XMLDocument 實例進行匹配。臨時的 bsrURI 值“_1”會分配到 GraphQuery 實例,即使並不會持久保留該值。這是因為我們仍需要將一個值設置為 DataGraphType 實例中包含的 WSRR 實例的根屬性。
一旦創建並填充了 WSRR 實例,就會將它設置為 DataGraphType 實例的根對象並且會在此時調用 executeQuery 操作,由於這是 GraphQuery 實例,因此該調用會返回包含一組標准的 DataGraphType 實例的 QueryResult。
檢索內容
為了從 Service Registry 檢索對象,有必要知道其 bsrURI,因此,以下示例將說明如何發出 PropertyQuery 以便僅返回 bsrURI,然後,該 bsrURI 會在檢索調用中使用。
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);
}
queryDocID 發出假設只與一個文檔匹配的 PropertyQuery,返回該文檔的 bsrURI,而要檢索的正是該文檔。queryDocID 方法的代碼如下所示。
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;
該代碼調用一個實用方法 (queryMatchingURIs),以便調用屬性查詢,同時傳入要使用的 XPath 表達式,在此示例中,該表達式為:WSRR/XMLDocument[@name='CreateSingleObjectTestDocument']"。 queryMatchingURIs 為已提供的 XPath 表達式建立 PropertyQuery,並指定要為每個與 XPath 表達式匹配的對象返回的 bsrURI 屬性的值。queryMatchingURIs 方法的代碼如下所示。
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;
更新內容
本部分將提供用於更新元數據和文檔內容的代碼示例。
更新元數據
以下代碼是用於更新有關文檔的元數據(將在此示例中更新描述)的示例。此代碼假設已經知道要更新的文檔的 bsrURI 值。檢索文檔,對描述進行更改,然後在 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);
}
該代碼使用實用方法來返回數據圖的根對象,從而獲取要更新的對象。
提示:由檢索調用返回的 DataGraphType 實例可用於後續更新調用。
更新文檔內容
以下代碼是更新文檔內容的示例。
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);
}
刪除內容
在刪除內容時,必須知道 bsrURI 值,這一點與檢索內容時類似。以下代碼是刪除對象的示例。
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);
}
queryDocID 方法與上面檢索示例中的類似。
結束語
本文說明了如何根據 Service Registry API 的 WSDL 描述來生成 JAX-RPC 客戶端。文中介紹了若干有用的實用方法,並且給出了一些用於調用每個方法的示例。