📄 credithistoryreviewer.java
字号:
/**
* Copyright (c) 1996-2004 Borland Software Corporation. All Rights Reserved.
*
* This SOURCE CODE FILE, which has been provided by Borland Software as part
* of a Borland Software product for use ONLY by licensed users of the product,
* includes CONFIDENTIAL and PROPRIETARY information of Borland Software.
*
* USE OF THIS SOFTWARE IS GOVERNED BY THE TERMS AND CONDITIONS
* OF THE LICENSE STATEMENT AND LIMITED WARRANTY FURNISHED WITH
* THE PRODUCT.
*
* IN PARTICULAR, YOU WILL INDEMNIFY AND HOLD BORLAND SOFTWARE, ITS
* RELATED COMPANIES AND ITS SUPPLIERS, HARMLESS FROM AND AGAINST ANY
* CLAIMS OR LIABILITIES ARISING OUT OF THE USE, REPRODUCTION, OR
* DISTRIBUTION OF YOUR PROGRAMS, INCLUDING ANY CLAIMS OR LIABILITIES
* ARISING OUT OF OR RESULTING FROM THE USE, MODIFICATION, OR
* DISTRIBUTION OF PROGRAMS OR FILES CREATED FROM, BASED ON, AND/OR
* DERIVED FROM THIS SOURCE CODE FILE.
*/
//------------------------------------------------------------------------------
// Copyright (c) 1996-2004 Borland Software Corporation. All Rights Reserved.
//------------------------------------------------------------------------------
package com.borland.samples.creditapproval.server;
import java.io.*;
import java.util.*;
import java.net.*;
import com.borland.dx.dataset.*;
import com.borland.dx.sql.dataset.*;
import com.borland.samples.creditapproval.CORBAInterface.*;
/**
* CreditHistoryReviewer reviews the credit history of a specified applicant.
*
* History is reviewed to determine if an applicant should be granted a cliffhanger
* credit card, and if so, the amount of credit that should be extended.
*
* The following business rules are used:
*
* Credit Approval:
* 1) Deny credit if 10% of all payments were late.
* 2) Deny credit if any accounts are in 'COLLECTIONS'.
* 3) Deny credit if the percentage of total monthly payments(TMP)
* to total monthly income(TMI) is greater than 40%.
*
* Credit Limit calculation:
* 1) Calculate maximum monthly payment (MMP):
* MMP = (0.4 * TMI) - TMP
* 2) Since monthly payment is 5% of total balance, the credit
* limit can be calculated by dividing the MMP by 5%.
* LIMIT = MMP / 0.05
* 3) Make sure credit limit is in the range of $100 - $5000
* (This range is resourced to enable conversion into foreign currency)
*
*/
public class CreditHistoryReviewer implements DataModule{
private boolean generateRandomData;
private static CreditHistoryReviewer myDM;
private static final String ACCOUNT_STATUS_COLLECTIONS = "COLLECTION";
private static final String ACCOUNT_STATUS_OPEN = "OPEN";
Database acmeDb = new Database();
QueryDataSet queryCreditHistory = new QueryDataSet();
QueryDataSet queryHistoryIdLookupByName = new QueryDataSet();
QueryDataSet queryHistoryIdLookupByPid = new QueryDataSet();
ResourceBundle res = Res.getBundle("com.borland.samples.creditapproval.server.Res");
public CreditHistoryReviewer( boolean randomData ) throws Exception {
generateRandomData = randomData;
try {
jbInit();
}
catch (Exception e) {
e.printStackTrace();
throw(e);
}
}
private void jbInit() throws Exception{
// Initialize database connection
acmeDb.setConnection(new com.borland.dx.sql.dataset.ConnectionDescriptor(CreditHistoryReviewer.getInterBaseURL("OnlineStore", "acmecb.gdb"), "SYSDBA", "masterkey", false, "interbase.interclient.Driver"));
acmeDb.setTransactionIsolation(java.sql.Connection.TRANSACTION_NONE);
acmeDb.setSQLDialect(com.borland.dx.sql.dataset.SQLDialect.INTERBASE);
ParameterRow historyParameters = new ParameterRow();
historyParameters.addColumn( "HISTORYID", com.borland.dx.dataset.Variant.INT );
queryCreditHistory.setReadOnly(true);
queryCreditHistory.setTableName("");
queryCreditHistory.setQuery(new com.borland.dx.sql.dataset.QueryDescriptor(acmeDb, "SELECT ACCOUNTTYPE, STATUS, MONTHLYPAYMENT, PASTDUE120, PASTDUE90, PASTDUE60, PASTDUE30, TOTALPAYMENTS FROM ACCOUNT WHERE HISTORYID =:HISTORYID", historyParameters, false, Load.ALL));
ParameterRow byNameParameters = new ParameterRow();
byNameParameters.addColumn( "APPLICANTDOB", com.borland.dx.dataset.Variant.DATE );
byNameParameters.addColumn( "APPLICANTFIRSTNAME", com.borland.dx.dataset.Variant.STRING );
byNameParameters.addColumn( "APPLICANTLASTNAME", com.borland.dx.dataset.Variant.STRING );
queryHistoryIdLookupByName.setReadOnly(true);
queryHistoryIdLookupByName.setQuery(new com.borland.dx.sql.dataset.QueryDescriptor(acmeDb, "SELECT HISTORYID, FIRSTNAME, MI FROM CREDITHISTORY WHERE DOB = :APPLICANTDOB AND Upper( FIRSTNAME ) = :APPLICANTFIRSTNAME AND Upper( LASTNAME ) = :APPLICANTLASTNAME", byNameParameters, false, Load.ALL));
ParameterRow byPidParameters = new ParameterRow();
byPidParameters.addColumn( "APPLICANTID", com.borland.dx.dataset.Variant.STRING );
queryHistoryIdLookupByPid.setDisplayErrors(true);
queryHistoryIdLookupByPid.setReadOnly(true);
queryHistoryIdLookupByPid.setQuery(new com.borland.dx.sql.dataset.QueryDescriptor(acmeDb, "SELECT HISTORYID FROM CREDITHISTORY WHERE IDENTIFICATION = :APPLICANTID", byPidParameters, false, Load.ALL));
}
/**
* Connect/Disconnect to/from the database based on 'connect' parameter.
* @param open boolean
* @throws DataSetException datasetexception
*/
void connect(boolean open) throws DataSetException {
if (open) {
// Try to connect every 5 seconds for a total of 30 seconds
if (!acmeDb.isOpen()) new TimedConnect(acmeDb, 2, 8 );
}
else {
if (acmeDb.isOpen()) {
try {
acmeDb.closeConnection();
} catch (Exception e) {
System.err.println( e );
}
}
}
}
/**
* Return singleton instance of the DataModule
* @throws Exception excpetion
* @return CreditHistoryReviewer
*/
static public CreditHistoryReviewer getDataModule() throws Exception {
if (myDM == null)
myDM = new CreditHistoryReviewer( false );
return myDM;
}
public com.borland.dx.sql.dataset.QueryDataSet getQueryCreditHistory() {
return queryCreditHistory;
}
/**
* Queries the ACME Database to find a Credit History ID for the
* applicant. If one does not exist, the credit history for the applicant
* is not tracked by ACME and the applicant cannot be approved.
* @param appInfo applicantInfoStruct
* @throws Exception exception
* @return int
*/
private int getCreditHistoryId( applicantInfoStruct appInfo )
throws Exception {
int historyId = -1;
//return new CreditHistoryRandomData().generateRandomData( appInfo, acmeDb );
// If an IDENTIFICATION number was not specified for the applicant,
// attempt to find them using their DOB and Name.
if (appInfo.PID.trim().length() == 0 ||
appInfo.PID.trim().compareTo("0") == 0) {
//ParameterRow parameters = queryHistoryIdLookupByName.getParameterRow();
ReadWriteRow parameters = queryHistoryIdLookupByName.getParameterRow();
parameters.setDate( "APPLICANTDOB", java.sql.Date.valueOf( appInfo.DOB ) );
parameters.setString( "APPLICANTFIRSTNAME", appInfo.firstName.trim().toUpperCase() );
parameters.setString( "APPLICANTLASTNAME", appInfo.lastName.trim().toUpperCase() );
queryHistoryIdLookupByName.open();
queryHistoryIdLookupByName.executeQuery();
// If the applicant is not in the ACME Database, throw an exception
if (queryHistoryIdLookupByName.getRowCount() == 0) {
if (generateRandomData) {
return new CreditHistoryRandomData().generateRandomData( appInfo, acmeDb );
}
else throw new CreditDeniedException(
res.getString("Applicant_not_in_ACME"));
}
queryHistoryIdLookupByName.first();
historyId = queryHistoryIdLookupByName.getInt( "HISTORYID" );
}
// Attempt to find the applicant using their IDENTIFICATION number
else {
//ParameterRow parameters = queryHistoryIdLookupByPid.getParameterRow();
ReadWriteRow parameters = queryHistoryIdLookupByPid.getParameterRow();
parameters.setString( "APPLICANTID", appInfo.PID );
queryHistoryIdLookupByPid.open();
queryHistoryIdLookupByPid.executeQuery();
// If the applicant is not in the ACME Database, throw an exception
if (queryHistoryIdLookupByPid.getRowCount() == 0) {
if (generateRandomData) {
return new CreditHistoryRandomData().generateRandomData( appInfo, acmeDb );
}
else throw new CreditDeniedException(
res.getString("Applicant_not_in_ACME"));
}
queryHistoryIdLookupByPid.first();
historyId = queryHistoryIdLookupByPid.getInt( "HISTORYID" );
}
return historyId;
}
/**
* Implements the Credit Approval and Limit Calculation business rules.
* @param appInfo applicantInfoStruct
* @throws Exception exception
* @return creditApprovalStruct
*/
public creditApprovalStruct approveCredit(applicantInfoStruct appInfo)
throws Exception {
creditApprovalStruct approval = new creditApprovalStruct();
int historyId = getCreditHistoryId( appInfo );
// Retrieve account information for applicant.
//ParameterRow parameters = queryCreditHistory.getParameterRow();
ReadWriteRow parameters = queryCreditHistory.getParameterRow();
parameters.setInt( "HISTORYID", historyId );
queryCreditHistory.open();
queryCreditHistory.executeQuery();
int rowCount = queryCreditHistory.getRowCount();
double totalMonthlyPayments = appInfo.rentMortgagePayment;
double maximumMonthlyPayment = 0f;
int latePaymentCount = 0;
int totalPaymentsMade = 0;
// Loop through all accounts and calculate then following aggregates:
// 1) totalMonthlyPatments
// 2) Late Payment Count
// 3) Total Payments Made
for (int rowLoop = 0; rowLoop < rowCount; rowLoop++) {
queryCreditHistory.goToRow( rowLoop );
String status = queryCreditHistory.getString( "STATUS" );
// If any of the accounts are in COLLECTIONS, deny credit.
if ( status.compareTo(ACCOUNT_STATUS_COLLECTIONS) == 0 ) {
approval.approved = false;
throw new CreditDeniedException(res.getString("Account_in_Collections"));
}
// Add the monthly payment to the total ONLY if the account
// is currently open.
if ( status.compareTo(ACCOUNT_STATUS_OPEN) == 0 ) {
totalMonthlyPayments += queryCreditHistory.getDouble( "MONTHLYPAYMENT" );
}
// Add to Payment and Late Payment counts
latePaymentCount += queryCreditHistory.getShort( "PASTDUE30" ) +
queryCreditHistory.getShort( "PASTDUE60" ) +
queryCreditHistory.getShort( "PASTDUE90" ) +
queryCreditHistory.getShort( "PASTDUE120" );
totalPaymentsMade += queryCreditHistory.getShort( "TOTALPAYMENTS" );
}
// If more than 10% of all payments were late, deny credit
if (totalPaymentsMade > 0) {
if ((float) latePaymentCount / (float) totalPaymentsMade > 0.10f) {
approval.approved = false;
throw new CreditDeniedException(res.getString("Too_many_late"));
}
}
// Determine maximum amount the applicant can afford per month.
// Total Payments plus Credit Card payment cannot be more than 40% of total income.
maximumMonthlyPayment = 0.40f * appInfo.monthlyIncome - totalMonthlyPayments;
approval.limit = maximumMonthlyPayment / 0.05f;
double minCredit = ((Double) res.getObject("Minimum_Limit")).doubleValue();
// If the limit is less than the resourced Minimum Limit, deny credit
if (approval.limit < minCredit) {
approval.approved = false;
throw new CreditDeniedException(res.getString("You_do_not_qualify"));
}
// Make sure credit limit is less than the Resourced Maximum Limit
double maxCredit = ((Double) res.getObject("Maximum_Limit")).doubleValue();
approval.limit = (approval.limit > maxCredit) ? maxCredit : (int) approval.limit;
approval.approved = true;
return approval;
}
public com.borland.dx.sql.dataset.QueryDataSet getQueryHistoryIdLookupByName() {
return queryHistoryIdLookupByName;
}
public com.borland.dx.sql.dataset.QueryDataSet getQueryHistoryIdLookupByPid() {
return queryHistoryIdLookupByPid;
}
/**
* The following method (not described in the tutorial) is used to dynamically
* locate the database used by this sample, since the absolute location of the
* database varies depending upon where the sample is installed. A database
* for a non-sample application would normally be in a static location, and
* this would not be necessary.
*
* @param sampleDirRoot String
* @param fileName String
* @return String
*/
public static String getInterBaseURL(String sampleDirRoot, String fileName) {
String url = null;
try {
File file = new File(CreditHistoryReviewer.class.getResource("CreditHistoryReviewer.class").
getFile());
File parentDir = file.getParentFile();
do {
parentDir = parentDir.getParentFile();
} while (!parentDir.getName().equals(sampleDirRoot));
String path = parentDir.getParent();
url = "jdbc:interbase://localhost/" + URLDecoder.decode(path, "UTF-8") +
"/OnlineStore/database/" + fileName;
System.out.println(
"CreditHistoryReviewer.getInterBaseURL() using this URL to connect to " + fileName +
": " + url);
} catch (UnsupportedEncodingException uex) {
uex.printStackTrace();
}
return url;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -