Implement UPDATE operation
Continuing with the altered browsing in the Browsing support implementation topic, the UPDATE operation now receives individual "Contact" objects and is expected to return the same. The operation implementation must now perform the actual SOAP body document construction.
When you use the XMLSplitter and XMLJoiner utilities that are included in the Connector SDK Util project, this is fairly easy to do. For more information about using these utilities, refer to the SOAP Framework recipes: Manipulating data topic in this cookbook.
-
Implement an
XMLJoinersubclass calledRequestXMLJoinerwhich wraps anUpdateContactRequestelement around a collection ofContactelements. -
Implement an
XMLSplittersubclass calledResponseXMLSplitterwhich removes theUpdateContactResponseelement from around a collection ofContactelements and returns them individually. -
Create a subclass of
BaseUpdateOperation(for implementing the UPDATE operation) and implement theexecuteUpdate()method.
Code sample
Example
@Override
protected void executeUpdate(UpdateRequest request, OperationResponse response)
{
// create executor for actually invoking the webservice
WebServiceExecutor executor = getConnection().createExecutor();
// group the inputs into batches for processing
for(List<ObjectData> inputBatch : RequestUtil.pageIterable(request, getContext().getConfig())) {
ResponseXMLSplitter respSplitter = null;
try {
// create a DOM document combining a batch of individual "Contact" documents into a request document
Document requestDoc = DOMUtil.newDocumentNS();
RequestXMLJoiner reqJoiner = null;
try {
joiner = new RequestXMLJoiner("UpdateContactRequest", new DOMResult(doc));
joiner.writeAll(updateBatch);
joiner.close();
} finally {
IOUtil.closeQuietly(joiner);
}
// execute the update operation
WebServiceResponse wsResp = executor.execute(requestDoc);
if(wsResp.isFault()) {
// ... handle fault here ...
continue;
}
// split the response document into individual "Contact" documents
respSplitter = new ResponseXMLSplitter("UpdateContactResponse", new DOMSource(wsResp.getResponseBodyDocument()));
Iterator<ObjectData> inputIter = inputBatch.iterator();
for(Payload p : splitter) {
// we need to inspect the "Contact" element for the response status
StartElement contactEl = (StartElement)splitter.peekNextObjectStart();
Attribute statusAttr = contactEl.getAttributeByName(new QName("status"));
String status = ((statusAttr != null) ? statusAttr.getValue() : MY_SERVICE_UNKNOWN_ERROR_CODE);
// check for success status code (whatever that may be)
OperationStatus opStatus = ("OK".equals(status) ? OperationStatus.SUCCESS : OperationStatus.APPLICATION_ERROR);
// match up each output document with the input document
ObjectData input = inputIter.next();
response.addResult(input, opStatus, status, null, p);
}
// if there are any inputs without outputs, mark them as errored
while(inputIter.hasNext()) {
ResponseUtil.addEmptyFailure(response, inputIter.next(), MY_SERVICE_UNKNOWN_ERROR_CODE);
}
} catch(Exception e) {
if(getConnection().isFatalException(e)) {
throw new ConnectorException(e);
}
// make best effort to process every input
ResponseUtil.addExceptionFailures(response, inputBatch, e);
} finally {
IOUtil.closeQuietly(respSplitter, reqJoiner);
}
}
}