## Chapter 19 - Exercise 9

(5) Modify class PostOffice so that it uses an EnumMap. Project:2 Specialized languages like Prolog use backward chaining in order to solve problems like this. Using PostOffice.java for inspiration, research such languages and develop a program that allows new "rules" to be easily added to the system.

#### Mail.java

``````

package com.ciaoshen.thinkinjava.chapter19;
import java.util.*;

public class Mail {
// The NO’s lower the probability of random selection:
enum GeneralDelivery {YES,NO1,NO2,NO3,NO4,NO5}
enum Scannability {UNSCANNABLE,YES1,YES2,YES3,YES4}
enum Forward {YES,NO}

GeneralDelivery generalDelivery;
Scannability scannability;
Forward forward;

static long counter = 0;
long id = counter++;
public String toString() { return "Mail " + id; }
public String details() {
", General Delivery: " + generalDelivery +
", Address Scanability: " + scannability +
", Forward: " + forward +
}
// Generate test Mail:
public static Mail randomMail() {
Mail m = new Mail();
m.generalDelivery= Enums.random(GeneralDelivery.class);
m.scannability = Enums.random(Scannability.class);
m.forward = Enums.random(Forward.class);
return m;
}
public static Iterable<Mail> generator(final int count) {
return new Iterable<Mail>() {
int n = count;
public Iterator<Mail> iterator() {
return new Iterator<Mail>() {
public boolean hasNext() { return n-- > 0; }
public Mail next() { return randomMail(); }
public void remove() { // Not implemented
throw new UnsupportedOperationException();
}
};
}
};
}
}

``````

#### PostOffice9.java

``````

package com.ciaoshen.thinkinjava.chapter19;
import java.util.*;

public class PostOffice9 {
enum MailHandler { GENERAL_DELIVERY, MACHINE_SCAN, VISUAL_INSPECTION, FORWARD_STEP, RETURN_TO_SENDER }

public static interface Handler{public boolean handle(Mail m);}

private static EnumMap<MailHandler, PostOffice9.Handler> em=new EnumMap<MailHandler,PostOffice9.Handler>(MailHandler.class);

static{
em.put(MailHandler.GENERAL_DELIVERY,new PostOffice9.Handler(){
public boolean handle(Mail m) {
switch(m.generalDelivery) {
case YES:
System.out.println("Using general delivery for " + m);
return true;
default: return false;
}
}
});
em.put(MailHandler.MACHINE_SCAN, new PostOffice9.Handler(){
public boolean handle(Mail m) {
switch(m.scannability) {
case UNSCANNABLE: return false;
default:
case INCORRECT: return false;
default:
System.out.println("Delivering "+ m + " automatically");
return true;
}
}
}
});
em.put(MailHandler.VISUAL_INSPECTION, new PostOffice9.Handler(){
public boolean handle(Mail m) {
case ILLEGIBLE: return false;
default:
case INCORRECT: return false;
default:
System.out.println("Delivering " + m + " normally");
return true;
}
}
}
});
em.put(MailHandler.FORWARD_STEP, new PostOffice9.Handler(){
public boolean handle(Mail m) {
switch(m.forward){
case NO:
return false;
default:
case INCORRECT: return false;
default:
System.out.println("Forward "+ m +" normally");
return true;
}
}
}
});
em.put(MailHandler.RETURN_TO_SENDER, new PostOffice9.Handler(){
public boolean handle(Mail m) {
case MISSING: return false;
default:
System.out.println("Returning " + m + " to sender");
return true;
}
}
});
}

public static void handle(Mail m) {
for(Map.Entry<MailHandler,PostOffice9.Handler> entry: PostOffice9.em.entrySet()){
if(entry.getValue()!=null){
if(entry.getValue().handle(m)){
return;
}
}
}
System.out.println(m + " is a dead letter");
}

public static void showHandleMap(){
System.out.println(em);
}

public static void main(String[] args){

}
}

``````

#### Exercise9.java

``````

package com.ciaoshen.thinkinjava.chapter19;
import java.util.*;

public class Exercise9 {
public static void main(String[] args) {
for(Mail mail : Mail.generator(10)) {
System.out.println(mail.details());
PostOffice9.handle(mail);
System.out.println("*****");
}
}
}

``````

## Need Java Developers? Hire Me »

I know Java. Talk is cheap, watch my code.