Chapter 18 – OSGi and Groovy

package com.extensiblejava.calculator.groovy

import com.extensiblejava.loan.*

class MinimumPaymentScheduleCalculator implements LoanCalculator {
	def paymentFactory

	MinimumPaymentScheduleCalculator(pFactory) {
		paymentFactory = pFactory
	}
	
	def Loan calculateLoan(BigDecimal presentValue, BigDecimal rate, int term) {
	
		println("---** IN GROOVY CALCULATOR **---")

		def cumulativePrincipal = new BigDecimal("0.00")
		def cumulativeInterest = new BigDecimal("0.00")
		
		def paymentSchedule = paymentFactory.createPaymentSchedule()
		def adjustedRate = (rate / (new BigDecimal("1200")).setScale(2, BigDecimal.ROUND_HALF_UP))
		def calculator = new MonthlyPaymentCalculator()
		def monthlyPayment = calculator.calculatePayment(presentValue, rate, term)
		
		def loanBalance = new BigDecimal(presentValue)
		
		while (loanBalance.doubleValue() > monthlyPayment.doubleValue()) {
			def interest = loanBalance.multiply(adjustedRate).setScale(2, BigDecimal.ROUND_HALF_UP)
			def principal = monthlyPayment.subtract(interest).setScale(2, BigDecimal.ROUND_HALF_UP)
			def payment = paymentFactory.createPayment(principal, interest)
			paymentSchedule.addPayment(payment)

			cumulativeInterest = cumulativeInterest.add(interest).setScale(2, BigDecimal.ROUND_HALF_UP)
			cumulativePrincipal = cumulativePrincipal.add(principal).setScale(2, BigDecimal.ROUND_HALF_UP)
			loanBalance = loanBalance.subtract(principal)
		}
		def interest = loanBalance.multiply(adjustedRate).setScale(2, BigDecimal.ROUND_HALF_UP)
		def principal = loanBalance.setScale(2, BigDecimal.ROUND_HALF_UP)
		cumulativeInterest = cumulativeInterest.add(interest).setScale(2, BigDecimal.ROUND_HALF_UP)
		cumulativePrincipal = cumulativePrincipal.add(principal).setScale(2, BigDecimal.ROUND_HALF_UP)
		def payment = paymentFactory.createPayment(principal, interest)
		paymentSchedule.addPayment(payment)
		
		def loan = paymentFactory.createLoan(paymentSchedule, cumulativeInterest, cumulativePrincipal)
		loan
		
	}
}
package com.extensiblejava.calculator.groovy

class MonthlyPaymentCalculator {

	def calculatePayment(presentValue, rate, term) {

		def dPresentValue = presentValue.doubleValue()
		def dRate = rate.doubleValue() / 1200
	
		def revisedRate = dRate + 1;
		def dTerm = term.doubleValue()
	
		def powRate = Math.pow(revisedRate, dTerm)
	
		def left = powRate * dPresentValue
		def middle = dRate / (powRate - 1)
		def right = 1/(1);
	
		def payment = new BigDecimal(left * middle * right).setScale(2, BigDecimal.ROUND_HALF_UP)
	}
}
<bean name="loanCalculator" class="com.extensiblejava.calculator.groovy.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="groovy.class.path">
		<pathelement path="${groovy.library.jar}"/>
		<pathelement path="${groovy.dir}/lib/commons-cli-1.2.jar"/>
		<pathelement path="${groovy.dir}/lib/asm-3.2.jar"/>
		<pathelement path="${groovy.dir}/lib/antlr-2.7.7.jar"/>
	</path>
	
	<taskdef name="groovyc" classname="org.codehaus.groovy.ant.Groovyc" classpathref="groovy.class.path"/>
	
	<target name="clean" description="clean up">
		<delete dir="${groovy.bin}"/>
		<delete dir="${groovy.build}"/>
		<delete dir="${buildstats}"/>
		<!-- <delete file="junitresults.txt"/> -->
	</target>
	
	<target name="init" depends="clean">
		<tstamp/>
		<mkdir dir="${groovy.build}"/>
		<mkdir dir="${buildstats}"/>
	</target>
	
	<target name="compile" depends="init">
		<groovyc srcdir="${groovy.src}" destdir="${groovy.build}">
			<classpath refid="project.class.path"/>
		</groovyc>
	</target>