Chapter 17 – OSGi and Scala

package com.extensiblejava.calculator.scala

import com.extensiblejava.loan._
//import MonthlyPaymentCalculator._

class MinimumPaymentScheduleCalculator(paymentFactory:PaymentFactory) extends LoanCalculator {
	def calculateLoan(value:java.math.BigDecimal, rate:java.math.BigDecimal, term:Int): Loan = {

		Console.println("---** IN SCALA CALCULATOR **---")
		val mc = new java.math.MathContext(2, java.math.RoundingMode.HALF_UP)
		val presentValue = BigDecimal(value)
		val presentRate = BigDecimal(rate).apply(mc)

		var cumulativePrincipal = BigDecimal("0.00")
		var cumulativeInterest = BigDecimal("0.00")

		val paymentSchedule = paymentFactory.createPaymentSchedule()
		val adjustedRate = (presentRate / (BigDecimal("1200")).setScale(2, BigDecimal.RoundingMode.HALF_UP))
		val calculator = new MonthlyPaymentCalculator()
		val monthlyPayment = calculator.calculatePayment(presentValue, presentRate, term)

		var loanBalance = BigDecimal(presentValue.bigDecimal)

		while (loanBalance.toDouble > monthlyPayment.toDouble) {
			val interest = (loanBalance.*(adjustedRate)).setScale(2, BigDecimal.RoundingMode.HALF_UP)
			val principal = (monthlyPayment.-(interest)).setScale(2, BigDecimal.RoundingMode.HALF_UP);
			val payment = paymentFactory.createPayment(principal.bigDecimal, interest.bigDecimal);
			paymentSchedule.addPayment(payment);

			cumulativeInterest = cumulativeInterest.+(interest).setScale(2, BigDecimal.RoundingMode.HALF_UP);
			cumulativePrincipal = cumulativePrincipal.+(principal).setScale(2, BigDecimal.RoundingMode.HALF_UP);
			loanBalance = loanBalance.-(principal);
		}
		val interest = (loanBalance.*(adjustedRate)).setScale(2, BigDecimal.RoundingMode.HALF_UP)
		val principal = loanBalance.setScale(2, BigDecimal.RoundingMode.HALF_UP)
		cumulativeInterest = cumulativeInterest.+(interest).setScale(2, BigDecimal.RoundingMode.HALF_UP)
		cumulativePrincipal = cumulativePrincipal.+(principal).setScale(2, BigDecimal.RoundingMode.HALF_UP)
		val payment = paymentFactory.createPayment(principal.bigDecimal, interest.bigDecimal)
		paymentSchedule.addPayment(payment)

		val loan = paymentFactory.createLoan(paymentSchedule, cumulativeInterest.bigDecimal, cumulativePrincipal.bigDecimal)
		loan

	}
}
package com.extensiblejava.calculator.scala

import scala.math._

class MonthlyPaymentCalculator {
	def calculatePayment(presentValue:BigDecimal, rate:BigDecimal, term:Int): BigDecimal = {		
		val dPresentValue = presentValue.toDouble
		val dRate = rate.toDouble / 1200
		
		val revisedRate = dRate + 1;
		val dTerm = term.toDouble
		
		val powRate = pow(revisedRate, dTerm)
		
		val left = powRate * dPresentValue
		val middle = dRate / (powRate - 1)
		val right = 1/(1);
		
		val payment = BigDecimal(left * middle * right).setScale(2, BigDecimal.RoundingMode.HALF_UP)
		payment
	}
}
<bean name="loanCalculator" class="com.extensiblejava.calculator.scala.MinimumPaymentScheduleCalculator">
		<constructor-arg ref="paymentFactory"/>
	</bean>
<osgi:reference id="paymentFactory" interface="com.extensiblejava.loan.PaymentFactory"/>
	<osgi:service id="LoanCalculator" ref="loanCalculator" interface="com.extensiblejava.loan.LoanCalculator"/>
<path id="scala.class.path">
		<pathelement path="${scala.library.jar}"/>
		<pathelement path="${scala.compiler.jar}"/>
	</path>
	
	<taskdef resource="scala/tools/ant/antlib.xml" classpathref="scala.class.path"/>
	
	<target name="clean" description="clean up">
		<delete dir="${scala.bin}"/>
		<delete dir="${scala.build}"/>
		<delete dir="${buildstats}"/>
		<!-- <delete file="junitresults.txt"/> -->
	</target>
	
	<target name="init" depends="clean">
		<tstamp/>
		<mkdir dir="${scala.build}"/>
		<mkdir dir="${buildstats}"/>
	</target>
	
	<target name="compile" depends="init">
		<scalac srcdir="${scala.src}" destdir="${scala.build}">
			<classpath refid="project.class.path"/>
		</scalac>
	</target>