HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML
 

"Intelligent Phones & Java Apps"
Vol. 6, Issue 7, p. 88

	


Listing 1:

A Rule class combines IAction and ICondition interfaces.

public class Rule {
    private IAction    m_action;
    private ICondition m_condition;
                
    public Rule(IAction action, ICondition condition) {
        setRule(action, condition);
    }
    
    public void setRule(IAction action, ICondition condition) {
        m_action = action;
        m_condition = condition;        
    }

    public boolean evaluate(Object data)  {
        boolean bDidApply = false;
            
        // Apply rule if condition is satisfied
        if (m_condition.isSatisfied(data)) {
            m_action.apply(data);
            bDidApply = true;
        }                
        return bDidApply;
    }
}

Listing 2:

A ConditionSet class.

public class ConditionSet implements ICondition {
    private Vector m_vConditions ;

    public ConditionSet() {
        m_vConditions = new Vector() ;
    }

    public synchronized void addCondition(ICondition condition) {
        m_vConditions.addElement(condition) ;
    }

    public synchronized void removeCondition(ICondition condition) {
        m_vConditions.removeElement(condition) ;
    }
    
    public synchronized boolean isSatisfied(Object data) {
        boolean bIsSatisifed = false ;
    
        // Loop through all of our conditions and look for the first one to fail
        for (int i=0; i<m_vConditions.size(); i++) {
            ICondition condition = (ICondition) m_vConditions.elementAt(i) ;
            bIsSatisifed = condition.isSatisfied(data) ;
            if (!bIsSatisifed)
                break ;                    
        }            
        return bIsSatisifed ;
    }
}

Listing 3:

A RuleSet class.

public class RuleSet extends Rule {    
    private Vector m_vRules ;
   
    public RuleSet() {
        m_vRules = new Vector() ;
    }

    public synchronized void addRule(Rule rule) {
        m_vRules.addElement(rule) ;
    }

    public synchronized void removeRule(Rule rule) {
        m_vRules.removeElement(rule) ;
    }

    public boolean evaluate(Object data) {
        boolean bDidApply = false ;
            
        // Loop through all of our rules and try to apply each one
        for (int i=0; i<m_vRules.size(); i++) {
            Rule rule = (Rule) m_vRules.elementAt(i) ;
            bDidApply = rule.evaluate(data) ;
            if (bDidApply)
                break ;
        }                
        return bDidApply ;
    }
}


/**
 * CONDITIONS
 */

Listing 4:

The UserMatchesCondition.

public class UserMatchesCondition implements ICondition {

    public UserMatchesCondition(String strName) {
        m_strName = strName ;
    }
               
    public boolean isSatisfied(Object data) {
        boolean bIsSatisifed = false ;
        
        if ((data != null) && (data instanceof CallFilterHookData)) {
            CallFilterHookData hookData = (CallFilterHookData) data ;
            
            PAddress address = hookData.getAddress() ;
            
            // Check to see if this is a SIP address. If this is a SIP address 
            // then pull the address apart and compare the appropriate pieces.           
            if (address instanceof PSIPAddress) {
                PSIPAddress sipAddress = (PSIPAddress) address ;                    
                if (m_strName.equalsIgnoreCase(sipAddress.getUser())) {
                    bIsSatisifed = true ;
                }
            } 
        }
        return bIsSatisifed ;
    }                
}

Listing 5:

The DomainMatchesCondition.

public class DomainMatchesCondition implements ICondition {
    private String m_strDomain ;  // The domain name that we will test against
        
    public DomainMatchesCondition(String strDomain) {
        m_strDomain = strDomain ;
    }
               
    public boolean isSatisfied(Object data) {
        boolean bIsSatisifed = false ;
        
        if ((data != null) && (data instanceof CallFilterHookData)) {
            CallFilterHookData hookData = (CallFilterHookData) data ;
                                   
            // Check to see if this is a SIP address. If this is a SIP address 
            // then pull the address apart and compare the appropriate pieces.           
            PAddress address = hookData.getAddress() ;
            if (address instanceof PSIPAddress) {
                PSIPAddress sipAddress = (PSIPAddress) address ;
                    
                if (m_strDomain.equalsIgnoreCase(sipAddress.getAddr())) {
                    bIsSatisifed = true ;
                }
            } 
        }            
        return bIsSatisifed ;
    }                
}

Listing 6:

The AfterSpecifiedTimeCondition.

public class AfterSpecifiedTimeCondition implements ICondition
{
    private int m_iPivotHour ;
    private int m_iPivotMinute ;
    
    public AfterSpecifiedTimeCondition(Date time) {            
        // Pull the hour and minute of the time parameter
        Calendar calendar = Calendar.getInstance() ;
        calendar.setTime(time) ;            
        m_iPivotHour = calendar.get(Calendar.HOUR_OF_DAY) ;
        m_iPivotMinute = calendar.get(Calendar.MINUTE) ;        
    }
               
    public boolean isSatisfied(Object object) {
        boolean bIsSatisfied = false ;
        
        // Validate parameter
        if ((object != null) && (object instanceof CallFilterHookData)) {
            PAddress address = ((CallFilterHookData) object).getAddress() ;
                                
            // Get the current time
            Calendar calendar = Calendar.getInstance() ;            
            int iCurrentHour = calendar.get(Calendar.HOUR_OF_DAY) ;
            int iCurrentMinute = calendar.get(Calendar.MINUTE) ;
                
            // Compare the current time against out stored pivot time
            if (iCurrentHour > m_iPivotHour)
                bIsSatisfied = true ;                
            else if ((iCurrentHour == m_iPivotHour) &&
                    (iCurrentMinute > m_iPivotMinute))
                bIsSatisfied = true ;
        }                        
        return bIsSatisfied ;            
    }
}

Listing 7:

The BeforeSpecifiedTimeCondition.

public class BeforeSpecifiedTimeCondition implements ICondition{
    private int m_iPivotHour ;
    private int m_iPivotMinute ;

    public BeforeSpecifiedTimeCondition(Date time) {            
        // Pull the hour and minute of the time parameter
        Calendar calendar = Calendar.getInstance() ;
        calendar.setTime(time) ;            
        m_iPivotHour = calendar.get(Calendar.HOUR_OF_DAY) ;
        m_iPivotMinute = calendar.get(Calendar.MINUTE) ;
    }
       
    public boolean isSatisfied(Object object) {
        boolean bIsSatisfied = false ;
        
        // Validate parameter
        if ((object != null) && (object instanceof CallFilterHookData)) {
            PAddress address = ((CallFilterHookData) object).getAddress() ;
                                
            // Get the current time
            Calendar calendar = Calendar.getInstance() ;            
            int iCurrentHour = calendar.get(Calendar.HOUR_OF_DAY) ;
            int iCurrentMinute = calendar.get(Calendar.MINUTE) ;
                
            // Compare the current time against out stored pivot time
            if (iCurrentHour < m_iPivotHour)
                bIsSatisfied = true ;                
            else if ((iCurrentHour == m_iPivotHour) &&
                    (iCurrentMinute < m_iPivotMinute))
                bIsSatisfied = true ;
        }                        
        return bIsSatisfied ;            
    }
}

/**
 * ACTIONS
 */ 

Listing 8:

The three possible call filtering actions: accept the call, reject the call, or redirect the call.

public class AcceptCallAction implements IAction{
    public void apply(Object data) {
        if ((data != null) && (data instanceof CallFilterHookData)) {
            CallFilterHookData hookData = (CallFilterHookData) data ;
            hookData.accept() ;
        }
    }                        
}    

public class RejectCallAction implements IAction {
    public void apply(Object data) {
        if ((data != null) && (data instanceof CallFilterHookData)) {
            CallFilterHookData hookData = (CallFilterHookData) data ;
            hookData.decline() ;
        }
    }                        
}    

public class RedirectCallAction implements IAction {
    private PAddress m_address ;    // address to redirecting to
    
    public RedirectCallAction(PAddress address) { 
        m_address = address ;
    }
        
    
    public void apply(Object data) {
        if ((data != null) && (data instanceof CallFilterHookData)) {
            CallFilterHookData hookData = (CallFilterHookData) data ;
            hookData.redirect(m_address) ;
        }
    }
}


/*
 * RULES CODE
 */

Listing 9:

The CallFilterHook implementation class.

public class CallFilterHook implements Hook {    
    RuleSet m_ruleSet = new RuleSet() ;
    
        
    public CallFilterHook() {
        PAddress cellphone = null ;
        PAddress vpSales = null ;
        
        try {
            vpSales = new PSIPAddress("[email protected]") ;
            cellPhone = new PSIPAddress("[email protected]") ;            
        } catch (MalformedURLException exception) { }               
                                
        // Before 3pm Rules
        m_ruleSet.addRule(new AcceptUserAtDomainBeforeTimeRule("pete", 
"star.com", new Date("3:00pm"))) ;
        m_ruleSet.addRule(new AcceptUserBeforeTimeRule("dan.smith", 
new Date("3:00pm"))) ;
        m_ruleSet.addRule(new AcceptDomainBeforeTimeRule("global.com", 
new Date("3:00pm"))) ;
            
        // After 3pm Rules        
        m_ruleSet.addRule(new RedirectUserAtDomainAfterTimeRule(vpSales, 
"pete", "star.com", new Date("3:00pm"))) ;
        m_ruleSet.addRule(new RedirectUserAfterTimeRule(cellphone, 
"dan.smith", new Date("3:00pm"))) ;        
        m_ruleSet.addRule(new RedirectDomainAfterTimeRule(cellphone, 
"global.com", new Date("3:00pm"))) ;
        
        // Default Rule
        m_ruleSet.addRule(new Rule(new RejectCallAction(), 
new AlwaysSatisfiedCondition())) ;                                                   
    }
        

    public void hookAction(HookData data) {        
        if (data instanceof CallFilterHookData) {
            CallFilterHookData filterData = (CallFilterHookData) data ;            
            m_ruleSet.evaluate(filterData) ;                                                
        }
    }
}

Listing 10:

The six call filtering rules.

public class AcceptUserAtDomainBeforeTimeRule extends Rule {
    public AcceptUserAtDomainBeforeTimeRule(String strUser, 
	String strDomain, Date time) {
        ConditionSet conditions = new ConditionSet() ;
        
        conditions.addCondition(new UserMatchesCondition(strUser)) ;
        conditions.addCondition(new DomainMatchesCondition(strDomain)) ;
        conditions.addCondition(new BeforeSpecifiedTimeCondition(time)) ;
        
        setRule(new AcceptCallAction(), conditions) ;
    }
}


public class AcceptUserBeforeTimeRule extends Rule {
    public AcceptUserBeforeTimeRule(String strUser, Date time) {
        ConditionSet conditions = new ConditionSet() ;
        
        conditions.addCondition(new UserMatchesCondition(strUser));
        conditions.addCondition(new BeforeSpecifiedTimeCondition(time)) ;
        
        setRule(new AcceptCallAction(), conditions) ;
    }
}


public class AcceptDomainBeforeTimeRule extends Rule{
    public AcceptDomainBeforeTimeRule(String strDomain, Date time) {
        ConditionSet conditions = new ConditionSet() ;
        
        conditions.addCondition(new DomainMatchesCondition(strDomain));
        conditions.addCondition(new BeforeSpecifiedTimeCondition(time)) ;
        
        setRule(new AcceptCallAction(), conditions) ;
    }
}


public class RedirectDomainAfterTimeRule extends Rule {    
    public RedirectDomainAfterTimeRule(PAddress address, 
	String strDomain, Date time) {
        ConditionSet conditions = new ConditionSet() ;
        
        conditions.addCondition(new DomainMatchesCondition(strDomain));
        conditions.addCondition(new AfterSpecifiedTimeCondition(time)) ;
        
        setRule(new RedirectCallAction(address), conditions) ;
    }
}


public class RedirectUserAfterTimeRule extends Rule implements Serializable {
    public RedirectUserAfterTimeRule(PAddress address, String strUser, 
	Date time) {
        ConditionSet conditions = new ConditionSet() ;
        
        conditions.addCondition(new UserMatchesCondition(strUser));
        conditions.addCondition(new AfterSpecifiedTimeCondition(time)) ;
        
        setRule(new RedirectCallAction(address), conditions) ;
    }
}


public class RedirectUserAtDomainAfterTimeRule extends Rule {
    public RedirectUserAtDomainAfterTimeRule(PAddress address, 
	String strUser, String strDomain, Date time) {
        ConditionSet conditions = new ConditionSet() ;
        
        conditions.addCondition(new UserMatchesCondition(strUser));
        conditions.addCondition(new UserMatchesCondition(strDomain));
        conditions.addCondition(new AfterSpecifiedTimeCondition(time)) ;
        
        setRule(new RedirectCallAction(address), conditions) ;
    }
}

Listing 11:

The CallFilterApp

public class CallFilterApp extends Application { 
    private static CallFilterHook s_hookCallFilter = null ;
    
    public static void onLoad() {
        // Get a reference to the hook manager
        HookManager hookManager = Shell.getHookManager() ;
        
// Install the CallFilterHook
       s_hookCallFilter = new CallFilterHook() ;
       hookManager.installHook(HookManager.HOOK_CALL_FILTER, s_hookCallFilter) ;
    }

    public static void onUnload() {
        // Get a reference to the hook manager
HookManager hookManager = Shell.getHookManager() ;

// Uninstall our CallFilterHook
       hookManager.deinstallHook(HookManager.HOOK_CALL_FILTER, s_hookCallFilter) ;
    }        
    
    public void main(String argv[])
    {
	// Insert GUI code here
    }    
}

Listing 12:

The properties file.

Title=Call Filter
Version=1.0
Hint=This applications allows you to filter your incoming calls
LongDescription = The application allows you to filter your incoming calls
Author=Robert Andreasen and William Saunders
LauncherIcon=callfilter.gif
MainClassName=com.pingtel.xpressa.apps.callfilter.CallFilterApp
InstallationMethod=URL
Load=SystemStart
Run=OnDemand
Type=Normal





  
 
 

All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: [email protected]

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.