Usage Scenario
For a CMP bean whose fully-qualified name is com.ibm.test.BeCashAcctBean (whose bean implementation class is named BeCashAcctBean), the BeCashAcctBeanUserDefinedPushDownMethods interface would be in the com.ibm.test.websphere_deploy package, and the BeCashAccttBeanUserDefinedPushDownMethodsImpl for a backEndType of CCI would be in the com.ibm.test.websphere_deploy.cci package.
Example
/** * User-defined push-down method ejbCreate. * * @param bean Reference to the bean implementation class * @param connection The CCI connection to the back-end system. This * connection was previously obtained (by the EJBToRAAdapter implementation) * via connectionFactory.getConnection(connectionSpec). For non-CCI based * beans, this will be null and the user will have to manually connect to * the back-end system. * * @exception javax.ejb.CreateException Thrown if an exception occurs creating bean data * @exception ResourceException Any other exceptions are wrapped in a * ResourceException. */ public void ejbCreate(BeCashAcctBean bean, Object connection) throws javax.ejb.CreateException, ResourceException { if (tc.isEntryEnabled()) Tr.entry( tc, "ejbCreate(BeCashAcctBean, Object)", new Object[] { bean, connection }); try { com.ibm.connector2.cics.ECIInteractionSpec iSpec = new com.ibm.connector2.cics.ECIInteractionSpec(); iSpec.setFunctionName("BECASHAC"); // Specify any additional iSpec settings here iSpec.setCommareaLength(1242); iSpec.setReplyLength(1242); iSpec.setInteractionVerb( com.ibm.connector2.cics.ECIInteractionSpec.SYNC_SEND_RECEIVE); WSStreamableRecord input = helper.createCCIStreamableRecord(); String inputBufferString = createInputBuffer("01", bean); input.setValue(inputBufferString); WSStreamableRecord output = (WSStreamableRecord) helper.executeCCIInteraction( connection, iSpec, input); String errorCode = prossessOutputBuffer("01", bean, output.toString()); if (!errorCode.equals("00000000")) { if (errorCode.equals("00000014")) { if (tc.isDebugEnabled()) { Tr.debug(tc, "Record already exists"); } javax.ejb.DuplicateKeyException d = new javax.ejb.DuplicateKeyException(); throw d; } else { if (tc.isDebugEnabled()) { Tr.debug( tc, "Unknown error with return code " + errorCode); } javax.ejb.CreateException c = new javax.ejb.CreateException( "Unknown error with return " + "code " + errorCode); throw c; } } if (tc.isDebugEnabled()) { Tr.debug(tc, "Record created"); } } catch (Exception e) { ResourceException re = helper.createResourceException(e, this.getClass()); if (tc.isEntryEnabled()) Tr.exit(tc, "ejbCreate(BeCashAcctBean, Object)", re); throw re; } //Note that if the return code from the back-end datastore interaction //indicated that a user-defined exception (declared in the push-down //method's signature) should be thrown, then throw it here. if (tc.isEntryEnabled()) Tr.exit(tc, "ejbCreate(BeCashAcctBean, Object)"); } /** * This method will use the bean information to create an * input buffer string for WSStreamableRecord input that * maps to the COBOL commarea. * * Commarea: * -------- * * This program uses a commarea to pass information to the backend * program. The format and size of the commarea is as follows: * * Request type (2) - the method to invoke. Must have a leading * zero * Return Code1 (8) - CICS DFHRESP value or a string with the * word ERROR or ABEND * Return Code2 (8) - CICS DFHRESP2 value or a string with the * error type or abend code. * Trace flag (1) - If set to something other than space or hex * zero, trace information will be written to a * CICS TransientData queue. * Total Records (4) - Number of records found on a browse. * ResType (2) - The resType for the CashAccount record * AccountId (8) - The accountid for the CashAccount record * Balance (8) - The balance for the CashAccount record * Type (1) - The type for the CashAccount record * Utilities (1200) - The utility info for the CashAccount record * * @param request type of method to invoke * @param bean Reference to the bean implementation class * * @return string that contains the mapped commarea. */ public String createInputBuffer(String requestType, BeCashAcctBean bean) { if (tc.isEntryEnabled()) Tr.entry( tc, "createInputBuffer(requestType, bean)", new Object[] { requestType, bean }); /* * Initialize buffer */ StringBuffer sb = new StringBuffer(1242); sb.append(requestType); // request type (01=create, 02=find, 03=update, 04=delete) sb.append("00000000"); // return code 1 sb.append("00000000"); // return code 2 sb.append(" "); // trace sb.append("0001"); // total records sb.append("99"); // resType sb.append("88888888"); // accountId sb.append("00000000"); // balance sb.append("1"); // type sb.append("A"); // utilities /* * Update values from bean */ String resType = bean.getResType(); int start = 25 - resType.length(); int end = 25; sb.replace(start, end, resType); // resType String accoutId = bean.getAccountId(); start = 33 - accoutId.length(); end = 33; sb.replace(start, end, accoutId); // accountId /* * Update values for ejbStore */ if (requestType.equals("03")) { String balance = String.valueOf(bean.getBalance()); start = 41 - balance.length(); end = 41; sb.replace(start, end, balance); String rType = bean.getUType(); start = 41; end = 42; sb.replace(start, end, rType); String utility = bean.getUtility(); start = 42; end = 42 + utility.length(); sb.replace(start, end, utility); } if (tc.isDebugEnabled()) { Tr.debug( tc, "The created string buffer for execute is " + sb.toString()); } if (tc.isEntryEnabled()) Tr.exit(tc, "createInputBuffer(requestType, bean)"); return sb.toString(); } /** * This method will use the bean information to parse the * output buffer string that maps to information returned * from the helper.executeCCIInteraction plus the * COBOL commarea. * * Commarea: * -------- * * This program uses a commarea to pass information to the backend * program. The format and size of the commarea is as follows: * * Request type (2) - the method to invoke. Must have a leading * zero * Return Code1 (8) - CICS DFHRESP value or a string with the * word ERROR or ABEND * Return Code2 (8) - CICS DFHRESP2 value or a string with the * error type or abend code. * Trace flag (1) - If set to something other than space or hex * zero, trace information will be written to a * CICS TransientData queue. * Total Records (4) - Number of records found on a browse. * ResType (2) - The resType for the CashAccount record * AccountId (8) - The accountid for the CashAccount record * Balance (8) - The balance for the CashAccount record * Type (1) - The type for the CashAccount record * Utilities (1200) - The utility info for the CashAccount record * * @param request type of method to invoke * @param bean Reference to the bean implementation class * @param output buffer that contains the commarea * * @return first error code. */ public String prossessOutputBuffer( String requestType, BeCashAcctBean bean, String outputBuffer) { if (tc.isEntryEnabled()) Tr.entry( tc, "prossessOutputBuffer(requestType, bean, outputBuffer)", new Object[] { requestType, bean, outputBuffer }); String returnCode1 = outputBuffer.substring(25, 33); String returnCode2 = outputBuffer.substring(33, 41); if (requestType.equals("03") && returnCode1.equals("00000000")) { String balance = outputBuffer.substring(56, 64); bean.setBalance(Integer.parseInt(balance)); String utype = outputBuffer.substring(64, 65); bean.setUType(utype); String utility = outputBuffer.substring(65, outputBuffer.length()); bean.setUtility(utility); if (tc.isDebugEnabled()) { Tr.debug(tc, "Balance is " + balance); Tr.debug(tc, "utype is " + utype); Tr.debug(tc, "utility is " + utility); } } if (tc.isEntryEnabled()) Tr.exit( tc, "prossessOutputBuffer(requestType, bean, outputBuffer)"); return returnCode1; }