//[C] 2002 Sun Microsystems, Inc.---
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
public class RunInterpreterPattern {
public static void main(String[] arguments) {
System.out.println("Example for the Interpreter pattern");
System.out.println("In this demonstration, the syntax defined");
System.out.println(" by the Interpreter can be used to search");
System.out.println(" among a collection of Contacts, returning");
System.out.println(" the subset that match the given search criteria.");
ContactList candidates = makeContactList();
Context ctx = new Context();
System.out.println("Contents of the ContactList:");
System.out.println(candidates);
System.out.println();
Contact testContact = new ContactImpl();
VariableExpression varLName = new VariableExpression(testContact,
"getLastName");
ConstantExpression constLName = new ConstantExpression("u");
ContainsExpression eqLName = new ContainsExpression(varLName,
constLName);
System.out.println("Contents of the search on ContactList:");
System.out.println("(search was contains 'u' in Lase Name)");
Object result = candidates.getContactsMatchingExpression(eqLName, ctx,
testContact);
System.out.println(result);
VariableExpression varTitle = new VariableExpression(testContact,
"getTitle");
ConstantExpression constTitle = new ConstantExpression("LT");
EqualsExpression eqTitle = new EqualsExpression(varTitle, constTitle);
System.out.println("Contents of the search on ContactList:");
System.out.println("(search was all LT personnel)");
result = candidates.getContactsMatchingExpression(eqTitle, ctx,
testContact);
System.out.println(result);
System.out.println();
VariableExpression varLastName = new VariableExpression(testContact,
"getLastName");
ConstantExpression constLastName = new ConstantExpression("S");
ContainsExpression cLName = new ContainsExpression(varLastName,
constLastName);
AndExpression andExpr = new AndExpression(eqTitle, cLName);
System.out.println("Contents of the search on ContactList:");
System.out
.println("(search was all LT personnel with 'S' in Last Name)");
result = candidates.getContactsMatchingExpression(andExpr, ctx,
testContact);
System.out.println(result);
}
private static ContactList makeContactList() {
ContactList returnList = new ContactList();
returnList.addContact(new ContactImpl("James", "Kirk", "Captain",
"USS Enterprise"));
returnList.addContact(new ContactImpl("Mr.", "Spock",
"Science Officer", "USS Enterprise"));
returnList.addContact(new ContactImpl("LT", "Uhura", "LT",
"USS Enterprise"));
returnList.addContact(new ContactImpl("LT", "Sulu", "LT",
"USS Enterprise"));
returnList.addContact(new ContactImpl("Ensign", "Checkov", "Ensign",
"USS Enterprise"));
returnList.addContact(new ContactImpl("Dr.", "McCoy", "Ship's Doctor",
"USS Enterprise"));
returnList.addContact(new ContactImpl("Montgomery", "Scott", "LT",
"USS Enterprise"));
return returnList;
}
}
interface Contact extends Serializable {
public static final String SPACE = " ";
public String getFirstName();
public String getLastName();
public String getTitle();
public String getOrganization();
public void setFirstName(String newFirstName);
public void setLastName(String newLastName);
public void setTitle(String newTitle);
public void setOrganization(String newOrganization);
}
class ContactImpl implements Contact {
private String firstName;
private String lastName;
private String title;
private String organization;
public ContactImpl() {
}
public ContactImpl(String newFirstName, String newLastName,
String newTitle, String newOrganization) {
firstName = newFirstName;
lastName = newLastName;
title = newTitle;
organization = newOrganization;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String getTitle() {
return title;
}
public String getOrganization() {
return organization;
}
public void setFirstName(String newFirstName) {
firstName = newFirstName;
}
public void setLastName(String newLastName) {
lastName = newLastName;
}
public void setTitle(String newTitle) {
title = newTitle;
}
public void setOrganization(String newOrganization) {
organization = newOrganization;
}
public String toString() {
return firstName + SPACE + lastName;
}
}
class ContactList implements Serializable {
private ArrayList contacts = new ArrayList();
public ArrayList getContacts() {
return contacts;
}
public Contact[] getContactsAsArray() {
return (Contact[]) (contacts.toArray(new Contact[1]));
}
public ArrayList getContactsMatchingExpression(Expression expr,
Context ctx, Object key) {
ArrayList results = new ArrayList();
Iterator elements = contacts.iterator();
while (elements.hasNext()) {
Object currentElement = elements.next();
ctx.addVariable(key, currentElement);
expr.interpret(ctx);
Object interpretResult = ctx.get(expr);
if ((interpretResult != null)
&& (interpretResult.equals(Boolean.TRUE))) {
results.add(currentElement);
}
}
return results;
}
public void setContacts(ArrayList newContacts) {
contacts = newContacts;
}
public void addContact(Contact element) {
if (!contacts.contains(element)) {
contacts.add(element);
}
}
public void removeContact(Contact element) {
contacts.remove(element);
}
public String toString() {
return contacts.toString();
}
}
class Context {
private HashMap map = new HashMap();
public Object get(Object name) {
return map.get(name);
}
public void addVariable(Object name, Object value) {
map.put(name, value);
}
}
interface Expression {
void interpret(Context c);
}
class OrExpression extends CompoundExpression {
public OrExpression(ComparisonExpression expressionA,
ComparisonExpression expressionB) {
super(expressionA, expressionB);
}
public void interpret(Context c) {
expressionA.interpret(c);
expressionB.interpret(c);
Boolean result = new Boolean(((Boolean) c.get(expressionA))
.booleanValue()
|| ((Boolean) c.get(expressionB)).booleanValue());
c.addVariable(this, result);
}
}
abstract class CompoundExpression implements Expression {
protected ComparisonExpression expressionA;
protected ComparisonExpression expressionB;
public CompoundExpression(ComparisonExpression expressionA,
ComparisonExpression expressionB) {
this.expressionA = expressionA;
this.expressionB = expressionB;
}
}
class ConstantExpression implements Expression {
private Object value;
public ConstantExpression(Object newValue) {
value = newValue;
}
public void interpret(Context c) {
c.addVariable(this, value);
}
}
abstract class ComparisonExpression implements Expression {
protected Expression expressionA;
protected Expression expressionB;
public ComparisonExpression(Expression expressionA, Expression expressionB) {
this.expressionA = expressionA;
this.expressionB = expressionB;
}
}
class AndExpression extends CompoundExpression {
public AndExpression(ComparisonExpression expressionA,
ComparisonExpression expressionB) {
super(expressionA, expressionB);
}
public void interpret(Context c) {
expressionA.interpret(c);
expressionB.interpret(c);
Boolean result = new Boolean(((Boolean) c.get(expressionA))
.booleanValue()
&& ((Boolean) c.get(expressionB)).booleanValue());
c.addVariable(this, result);
}
}
class VariableExpression implements Expression {
private Object lookup;
private String methodName;
public VariableExpression(Object newLookup, String newMethodName) {
lookup = newLookup;
methodName = newMethodName;
}
public void interpret(Context c) {
try {
Object source = c.get(lookup);
if (source != null) {
Method method = source.getClass().getMethod(methodName, null);
Object result = method.invoke(source, null);
c.addVariable(this, result);
}
} catch (NoSuchMethodException exc) {
} catch (IllegalAccessException exc) {
} catch (InvocationTargetException exc) {
}
}
}
class EqualsExpression extends ComparisonExpression {
public EqualsExpression(Expression expressionA, Expression expressionB) {
super(expressionA, expressionB);
}
public void interpret(Context c) {
expressionA.interpret(c);
expressionB.interpret(c);
Boolean result = new Boolean(c.get(expressionA).equals(
c.get(expressionB)));
c.addVariable(this, result);
}
}
class ContainsExpression extends ComparisonExpression {
public ContainsExpression(Expression expressionA, Expression expressionB) {
super(expressionA, expressionB);
}
public void interpret(Context c) {
expressionA.interpret(c);
expressionB.interpret(c);
Object exprAResult = c.get(expressionA);
Object exprBResult = c.get(expressionB);
if ((exprAResult instanceof String) && (exprBResult instanceof String)) {
if (((String) exprAResult).indexOf((String) exprBResult) != -1) {
c.addVariable(this, Boolean.TRUE);
return;
}
}
c.addVariable(this, Boolean.FALSE);
return;
}
}
|