## A bill calculator service in Scala

I was recently asked to build an bill calculator service in scala .

Scenario
Cafe X menu consists of the following items:

•  Cola – Cold – 50p
•  Coffee – Hot – £1.00
•  Cheese Sandwich – Cold – £2.00  Steak Sandwich – Hot – £4.50

Customers don’t know how much to tip and staff need tips to survive!

Step 1 : Standard Bill
Pass in a list of purchased items that produces a total bill.
e.g. [“Cola”, “Coffee”, “Cheese Sandwich”] returns 3.5

Step 2: Service Charge

Add support for a service charge :

•  When all purchased items are drinks no service charge is applied
•  When purchased items include any food apply a service charge of 10% to the total bill (rounded to 2 decimal places)
•  When purchased items include any hot food apply a service charge of 20% to the total bill with a maximum £20 service charge

Solution:

Lets start with constructing the model objects using TDD. I used an Item trait and made two case classes Food and Drink to implement them. I have used an ITEM type enum  as a distinguisher.

```trait Item {
val name: String
val price: Double
var itemType: ItemType.Value = ItemType.COLD;
}```
```case class Food(name: String, price: Double) extends Item {

def this(name: String, price: Double, itemType: ItemType.Value) = {
this(name, price)
this.itemType = itemType
}

override def toString: String = {
return " Name = " + name +
", price = " + price +
", itemType = " + itemType.toString()
}
}

```
```case class Drink(name: String, price: Double) extends Item {

def this(name: String, price: Double, itemType: ItemType.Value) = {
this(name, price)
this.itemType = itemType
}```

}

```object ItemType extends Enumeration {
val HOT , COLD= Value
}```

I then proceeded to write the unit tests that resulted in a Order class that holds menu items . This had three boolean variables that denoted the state of the order as below:

```import scala.collection.mutable.ListBuffer
class Order {

var drinksOnly : Boolean = true
var includesFood: Boolean = false
var containsHotFood : Boolean = false

val itemList:ListBuffer[Item] = ListBuffer[Item]()

if( item.isInstanceOf[Food] ){

drinksOnly = false;

if( item.itemType == ItemType.HOT){
containsHotFood = true
}
includesFood = true;
}

itemList+=item

}

def calculateServiceCharge( stdBill:Double) :Double = {

var serviceCharge = 0.0

if( includesFood ){
serviceCharge = stdBill * .1;
}

if( containsHotFood ) {
serviceCharge = stdBill * .2;
}

if ( serviceCharge > 20 ) {
return 20
}else {
return serviceCharge
}

}

def calculateStandardBill : Double = {

var total:Double = 0

for( itm <- itemList )
{
total += itm.price
}

}

def getTotalBill : Double = {

val stdBill : Double = calculateStandardBill
return stdBill + calculateServiceCharge(stdBill)

}
}```

The code was developed using TDD and can be found here .

## Removing objects from a list in Java 8

Scenario: I have a list of objects . I need to remove an object from the list if it meets a condition.
Please use the new way as below to avoid getting concurrent modification exceptions

```
List cars = Arrays.asList("BMW","AUDI","MERCEDES","HYUNDAI");

cars.removeIf( car -> { return car.equalsIgnoresCase("HYUNDAI") ;});

sysout(cars);

Output: "BMW","AUDI","MERCEDES"
```

## Grouping objects in a list

Use this simple line of code if you need to group a list of objects from a collection.

```public class Field {

private Long id;

private String name;

private Long groupId;

// constructors ,getters and setters goes here
}

```
```Field f1 = new Field(1l,"goutham",1l);
Field f2 = new Field(2l,"goutham",1l);
Field f3 = new Field(3l,"goutham2",2l);
Field f4 = new Field(4l,"goutham2",2l);
Field f5 = new Field(5l,"goutham3",3l);
Field f6 = new Field(6l,"goutham4",4l);<
`/code>`

List fields = Arrays.asList(f1,f2,f3,f4,f5,f6);
```
```Map fieldsGroupedById = fields.stream()
.collect(Collectors.groupingBy(Field::getGroupId,
Collectors.toList()));
```
```fieldsGroupedById.forEach(
(key,value) -> {
StringBuffer b = new StringBuffer();
value.forEach( (field ) -> b.append(field.getName()).append(" "));
System.out.println("key = "+key +" values = "+b.toString());
});
```

You should get the below output :

```key = 1 values = goutham goutham
key = 2 values = goutham2 goutham2
key = 3 values = goutham3
key = 4 values = goutham4```

## Sorting collections in Java 8 using Lambda

With introduction of java 8 lambdas it is very easy to sort collections .

Ex: Consider a class Person as below
``` public class Person{```

``` private String name; private String age: ```

```// constructors //getters and setters } ```

Now sorting an list of persons based on their age is very easy . There is no need for a comparator class to be written.

``` List persons = new ArrayList(); persons.add( new Person("john",38)); persons.add( new Person("peter",23)); persons.add( new Person("sam",32));```

``` ```

```persons.sort( (p1,p2) -> p1.getAge().compareTo(p2.getAge())); ```

## JaxB and List wrapper (@XmlSeeAlso annotation usage)

JaxB cannot deserialise collections which is general handicap of JaxB . When your rest endpoint needs to send in a list of objects in xml you will need to wrap your collection in a wrapper object and this is is where ` GenericEntity<T>` class of JaxB comes into place.

Your code would then look something like this below:

``````      public Response getAddresLists(Long personId) {
return Response.ok(entity).build();
}
``````

In case if you do not know the type of the object your collection holds ( your list is non generic ) then we will need to hack around to get this working.

I reimplemented the GenericEntity class to add a few more jaxb annotations to get it working .

`````` @XmlRootElement(name="Address")
@XmlAccessorType (XmlAccessType.FIELD)
public class NonGenricEntity <T> {
@XmlAnyElement(lax=true)
private List<T> data;
public NonGenricEntity() {
super();
// TODO Auto-generated constructor stub
}
public NonGenricEntity(List<T> myData) {
super();
this.data = myData;
}
public List<T> getObject() {
return data;
}
public void setMyData(List<T> myData) {
this.data = myData;
}
}
``````

So when JaxB marshalls the object in the collection to XML @XmlSeeAlso annotation helps it to match the fields of the object to the type of class and you get the appropriate response.

## Configuring Jackson Json provider in Talend ESB /Apache Karaf ( Apache CXF ).

Talend ESB uses apache CXF internally to as the rest service provider. Jackson provides good support for hibernate through its hibernate4module.

I did notice that inspite of configuring the provider in the blueprint.xml file correctly it was not being picked up and the internal json provider

that gets shipped along with apache cxf was being used. I could see that it was being registered , but not used.

One digging deeper into the implementation code apache cxf I noticed that it while marshalling the object it was looping through the providers and picking the first , remember list.get(0) method.

Luckily the onlyway to get around that is to not load the default provider . This ensures that only JacksonJsonProvider is registered and gets used.

``````      <cxf:bus id="bus">
<cxf:features>
<cxf:logging />
</cxf:features>
<cxf:properties>
<entry key="skip.default.json.provider.registration" value="true"/>
</cxf:properties>
</cxf:bus>
<jaxrs:providers>
<bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" />
</jaxrs:providers>
</jaxrs:server>
``````

## Learning Scala: Some Notes

Introduction to Scala notes:

Class: A class describes how you would want to represent a concept such as a customer. To have an instance of the concept to represent a specific person you have to instantiate the class with the new
keyword.

Ex:

scala> class Hello
defined class Hello

scala> new Hello()
Hello
res5: Hello = Hello@6d5cfb9

Contructor: body of the class defines the constructor
Ex:

scala> class Hello {
| println(“Hello”)
| }
defined class Hello

scala> new Hello()
Hello

===============================================================================================================================================================
Parameters: You can pass values into an instance of a class using a parameter. You must specify the type
of parameter , it is visibile internally to the class instance during its lifetime and not accessible outside the instance.

scala> class Hello(message: String){
| println(message)
| }
defined class Hello

scala> new Hello(“Hello workd”)
Hello workd
res6: Hello = Hello@3275e8bc

scala> res6.message
<console>:14: error: value message is not a member of Hello
res6.message

===============================================================================================================================================================
Immutable and Mutable Fields :
Field: hold state and is accessible from outside world

Difference between parameters and fields:
parameters are passed to a class and are only visible within a class
fields: exists inside the body of the class and are accessible from outside.

immutable field: use val keyword

scala> class Hello{
| val message: String =”HEllo”
| }
defined class Hello

scala> new Hello
res9: Hello = Hello@42a03285

scala> res9.message
res10: String = HEllo
non-immutable field : use var keyword
scala> class Hello{
| var message: String = “Hello”
| }
defined class Hello

scala> new Hello()
res11: Hello = Hello@4673b889

scala> res11.message
res12: String = Hello

scala> res11.message = “Hello world”
res11.message: String = Hello world

scala> res11.message
res13: String = Hello world

===============================================================================================================================================================

Methods:
define a method it is of the format:
def methodName( variableName: scalaType): returnScalaType = method

ex:

scala> def echo( message: String): String = “Hello” + message
echo: (message: String)String

scala> echo(“Goutham”)
res16: String = HelloGoutham

Methods are evaluated everytime they are called , while fields are evaluated only during creation
===============================================================================================================================================================
Default and Named Arguments:

You can have default values when no value is passed to the method and specifically say which parameter we are passing into the method like last=”Rao”. It can be used in class constructors too

scala> def name( first: String=”Goutham” ,last: String=””): String = first + ” ” + last
name: (first: String, last: String)String

scala> name(last=”Rao”)
res17: String = Goutham Rao

===============================================================================================================================================================
Singleton object: Scala objects are used for creating Class Factories, Utility Methods, Constant Definitions

scala> object Hello{
| def message():String=”hello message”
| }

scala> Hello.message
res18: String = hello message

===============================================================================================================================================================
Case Classes:

In short are our domain/DTO classes. Compiler generates jvm specific convinience methods.
Every parameter in the case class is made into a field inside the class and is immutable. NO need to use the new keyword.
Ex:

scala> case class Time(hours: Int=0, minutes: Int=0)
defined class Time

scala> val time = Time(9,0)
time: Time = Time(9,0)

scala> time.hours
res22: Int = 9

Performs value based equivalence by default

scala> val time = Time(9,0)
time: Time = Time(9,0)

scala> time == Time(9,0)
res19: Boolean = true

scala> time == Time(9,30)
res20: Boolean = false

scala> time == Time(9)
res21: Boolean = true

Case Object:
Singleton object of a domain model. Ony single instance of the case class is made available.
===============================================================================================================================================================

Apply and Unapply:
A type is a description of a concept in an application – A class is a type.
A term is a concrete representation of a type
– Any class instance ( or even an Object ) is a term
– A method is also a term , as it is also concrete and callable
When you call a term without specifying the method on it , it calls the apply method in background

scala> case class Time( hours : Int =9, mins:Int =0 )
defined class Time

scala> Time(9)
res23: Time = Time(9,0)

scala>

scala> Time.apply(9)
res24: Time = Time(9,0)

scala> res23 == res24
res25: Boolean = true

===============================================================================================================================================================
JVM has a well defined memory model with specific gurantees. Ex : a website selling books. Means there is a variable holding the stock inside the app. Two concerns with regards to threads:
– Synchronize-with: which thread is able to make the change and in what order
– Happens-Before: how does the other threads see this change

When you are writing scala there are two things we need to watch out for. The left hand side of the equals and the right hand side of the equals. ( the pointer and its value )

val me = new Person(“Jamie”, “Allen”)
^ ^
| |
name value

If pointer can be changed , then it is a var
if can’t be changed , then it is a val.

1.var pointing to a mutable state inside the class we are creating ( then there is mutability in both the pointer and inside of the reference . Not good )
2.val pointing to a mutable data

In both the conditions we need to defining locking mechanisms

3. A var pointing to an immutable state . In this case we have snapshots , if the state on the right hand side changes , then we will be pointing to a new instance of the state.We use the copy method to change state. We now have a var that is updated and this needs to be made visible to all threads. We do this using @volatile annotation
4. a val pointing to an immutable state

scala> case class Customer(first: String=””, last: String=””)
defined class Customer

scala> @volatile var customer = Customer(“Martin”, “Odersky”)
customer: Customer = Customer(Martin,Odersky)

scala> customer = customer.copy(last=”Charles”)
customer: Customer = Customer(Martin,Charles)

==============================================================================================================================================================