When you create a business object, you can override the default BO handler by specifying the CBOH keyword in the BO verb ASI. At connector run time, the doVerbFor() method retrieves the business object ASI. If it detects the CBOH keyword, doVerbFor() invokes the custom BO handler.
A custom BO handler can access proxy classes directly. Therefore, it bypasses the Loader, the Invoker, and the process of retrieving connections from the connection pool. These processes are described in Step 5 and Step 7.
The connector supports custom BO handlers on parent-level business objects only. For details about creating a custom BO handler, see the Connector Development Guide.
The following example of a custom BO handler assumes that a business object has been defined with a verb ASI of CBOH=comadaptertest.Lotus123BOHandler. The business object has an attribute ASI of CellAddress=A1, where A1 is the address in which the attribute will appear in the worksheet. The custom BO handler puts the attribute on the worksheet, using the cell address specified by the attribute ASI.
package comadaptertest; import com.crossworlds.cwconnectorapi.*; import com.crossworlds.cwconnectorapi.exceptions.*; import java.util.*; import com.ibm.adapters.utils.comproxy.*; import lotus123.*; public class Lotus123BOHandler implements CWCustomBOHandlerInterface { public int doVerbForCustom(CWConnectorBusObj bo) throws VerbProcessingFailedException { Application currentApplication; Document currentDocument; CWConnectorUtil.traceWrite(CWConnectorUtil.LEVEL4, "Entering AdapterBOHandler.doVerbFor()"); try { currentDocument = new Document(); // Get the application object. currentApplication = new Application(currentDocument. get_Parent()); // Make the application visible. currentApplication.set_Visible(new Boolean("true")); currentDocument = new Document(currentApplication. NewDocument()); } catch (ComException e) { CWConnectorUtil.generateAndLogMsg(91000, CWConnectorUtil.XRD_ERROR, CWConnectorUtil. CONNECTOR_MESSAGE_FILE, e.getMessage()); CWConnectorExceptionObject vSub = new CWConnectorExceptionObject(); vSub.setMsg(e.getMessage()); vSub.setStatus(CWConnectorConstant. APPRESPONSETIMEOUT); throw new VerbProcessingFailedException(vSub); } //do verb processing on this business object dispatch(bo, currentDocument); CWConnectorUtil.traceWrite(CWConnectorUtil. LEVEL4, "Leaving AdapterBOHandler.doVerbFor()"); return CWConnectorConstant.SUCCEED; } //doVerbFor private void dispatch(CWConnectorBusObj bo, Document currentDocument) throws VerbProcessingFailedException { CWConnectorUtil.traceWrite(CWConnectorUtil. LEVEL4, "Entering dispatch"); CWConnectorUtil.traceWrite(CWConnectorUtil. LEVEL3, "Processing business object" + bo.getName()); try { //put this object out onto the spreadsheet. //Follow ASI for Cell addresses businessObjectToWorksheet(bo, currentDocument); } catch (ComException e) { CWConnectorUtil.generateAndLogMsg(90001, CWConnectorUtil.XRD_ERROR, CWConnectorUtil. CONNECTOR_MESSAGE_FILE, e.getMessage()); CWConnectorExceptionObject vSub = new CWConnectorExceptionObject(); vSub.setMsg(e.getMessage()); vSub.setStatus(CWConnectorConstant. APPRESPONSETIMEOUT); throw new VerbProcessingFailedException(vSub); } catch (CWException e) { CWConnectorExceptionObject vSub = new CWConnectorExceptionObject(); vSub.setMsg(e.getMessage()); vSub.setStatus(CWConnectorConstant.FAIL); throw new VerbProcessingFailedException(vSub); } } public static void businessObjectToWorksheet(CWConnectorBusObj bo, Document currentDocument) throws CWException { String incomingAttribute = ""; int attrCount = bo.getAttrCount() - 1; //ignore objeventID Ranges ranges; Range currentRange; ranges = new Ranges(currentDocument.get_Ranges()); for (int i = 0; i < attrCount; i++) { try { if ((!bo.isObjectType(i)) && (!bo.isIgnore(i))) { if (bo.isBlank(i)) incomingAttribute = ""; else incomingAttribute = bo.getStringValue(i); String CellAddress = getCellAddress(bo, i); currentRange = new Range(ranges.Item(new String(CellAddress))); currentRange.set_Contents(incomingAttribute); if (CWConnectorUtil.isTraceEnabled (CWConnectorUtil.LEVEL5)) { CWConnectorUtil.traceWrite (CWConnectorUtil.LEVEL5, "Application datum from BO to application " + CellAddress + "=" + incomingAttribute); } } } catch (AttributeNotFoundException e) { CWConnectorUtil.generateAndLogMsg(91012, CWConnectorUtil.XRD_ERROR, CWConnectorUtil.CONNECTOR_MESSAGE_FILE, bo.getAttrName(i), bo.getName()); throw e; } catch (WrongAttributeException e) { CWConnectorUtil.generateAndLogMsg(91013, CWConnectorUtil.XRD_ERROR, CWConnectorUtil.CONNECTOR_MESSAGE_FILE, bo.getAttrName(i), bo.getName()); throw e; } } } public static String getCellAddress(CWConnectorBusObj bo, int i) throws CWException { String columnName = null; try { columnName = getNameFromASI (bo.getAttrASIHashtable(i, ":"), "CellAddress"); } catch (WrongASIFormatException e) { CWConnectorUtil.generateAndLogMsg(91014, CWConnectorUtil.XRD_ERROR, CWConnectorUtil.CONNECTOR_MESSAGE_FILE, bo.getAttrName(i), "ColumnName"); throw e; } return columnName; } private static String getNameFromASI(Hashtable asi, String fieldName) throws CWException, WrongASIFormatException { String resultName = (String) asi.get(fieldName); if (resultName == null || resultName.equals("")) throw new WrongASIFormatException(); resultName = resultName.toUpperCase(); CWConnectorUtil.traceWrite(CWConnectorUtil.LEVEL4, "Found " + fieldName + " = " + resultName); return resultName; } }