Author: akarasulu Date: Wed Sep 22 02:39:32 2004 New Revision: 47040 Added: incubator/directory/seda/trunk/src/java/org/apache/seda/event/RoutingAdvice.java Modified: incubator/directory/seda/trunk/src/java/org/apache/seda/event/DefaultEventRouter.java incubator/directory/seda/trunk/src/java/org/apache/seda/event/EventRouter.java Log: Commit changes ... o added RoutingAdvice interface o added method to apply advice to routing o added 1/2 implementation to publish Todos ... o figure out what effective advice when is more than one advice is applicable o add changes for multiple applicaple advice to publish() o write some unit test cases to make sure this thing works and complies with the specified semantics. Modified: incubator/directory/seda/trunk/src/java/org/apache/seda/event/DefaultEventRouter.java ============================================================================== --- incubator/directory/seda/trunk/src/java/org/apache/seda/event/DefaultEventRouter.java (original) +++ incubator/directory/seda/trunk/src/java/org/apache/seda/event/DefaultEventRouter.java Wed Sep 22 02:39:32 2004 @@ -17,9 +17,9 @@ package org.apache.seda.event; -import java.util.Set; -import java.util.HashSet; +import java.util.List; import java.util.Iterator; +import java.util.ArrayList; import java.util.EventObject; @@ -31,8 +31,10 @@ */ public class DefaultEventRouter implements EventRouter { - /** the set of subscriptions made with this router */ - private Set subscriptions = new HashSet(); + /** a list of applied routing advice */ + private List adviceList = new ArrayList( 2 ); + /** the list of subscriptions made with this router */ + private List subscriptions = new ArrayList( 15 ); /** the monitor - initially set to the null monitor */ private EventRouterMonitor monitor = new EventRouterMonitorAdapter(); @@ -152,36 +154,108 @@ */ public void publish( EventObject event ) { - final Subscription [] l_subscriptions; - + final ArrayList applicableAdvice = new ArrayList(); + + // -------------------------------------------------------------------- + // Try and see what advice we can apply + // -------------------------------------------------------------------- + + synchronized( adviceList ) + { + for ( int ii = 0; ii < adviceList.size(); ii++ ) + { + RoutingAdvice advice = ( RoutingAdvice ) adviceList.get( ii ) ; + + if ( advice.isApplicable( event ) ) + { + applicableAdvice.add( advice ); + } + } + } + + + Subscription[] subscrArray; synchronized ( subscriptions ) { - l_subscriptions = ( Subscription [] ) subscriptions + subscrArray = ( Subscription [] ) subscriptions .toArray( new Subscription [ subscriptions.size() ] ); } - for ( int ii = 0; ii < l_subscriptions.length; ii++ ) + if ( applicableAdvice.isEmpty() ) { - boolean isAssignable = l_subscriptions[ii].getType() - .isAssignableFrom( event.getClass() ); - + + publish( event, subscrArray ); + return; + } + + + if ( applicableAdvice.size() == 1 ) + { + RoutingAdvice advice = ( RoutingAdvice ) adviceList.get( 0 ) ; + publish( advice.getEvent( event ), + advice.getSubscriptions( event, subscrArray ) ); + return; + } + + throw new UnsupportedOperationException( "only one advice supported" ); + + /* + * you know I'm still not sure what sematics are best here whether to + * keep resubsituting events and the subscriptions or what. + * + + EventObject newEvent = null; + for ( int ii = 0; ii < applicableAdvice.size(); ii++ ) + { + RoutingAdvice advice = ( RoutingAdvice ) adviceList.get( ii ) ; + + if ( ii >= applicableAdvice.size() - 1 ) + { + newEvent = advice.getEvent( event ); + + } + } + */ + + } + + + + private void publish( EventObject ev, Subscription[] subscriptions ) + { + for ( int ii = 0; ii < subscriptions.length; ii++ ) + { + boolean isAssignable = subscriptions[ii].getType() + .isAssignableFrom( ev.getClass() ); + if ( ! isAssignable ) { continue; } - - if ( l_subscriptions[ii].getFilter() == null ) + + if ( subscriptions[ii].getFilter() == null ) { - l_subscriptions[ii].getSubscriber().inform( event ); + subscriptions[ii].getSubscriber().inform( ev ); } - else if ( l_subscriptions[ii].getFilter().accept( event ) ) + else if ( subscriptions[ii].getFilter().accept( ev ) ) { - l_subscriptions[ii].getSubscriber().inform( event ); + subscriptions[ii].getSubscriber().inform( ev ); } } } - - + + + /** + * Adds advice to the advice list. + * + * @param advice the advice to apply + */ + public void apply( RoutingAdvice advice ) + { + adviceList.add( advice ); + } + + /** * Sets the event router's monitor. * Modified: incubator/directory/seda/trunk/src/java/org/apache/seda/event/EventRouter.java ============================================================================== --- incubator/directory/seda/trunk/src/java/org/apache/seda/event/EventRouter.java (original) +++ incubator/directory/seda/trunk/src/java/org/apache/seda/event/EventRouter.java Wed Sep 22 02:39:32 2004 @@ -41,7 +41,7 @@ /** * Subscribes an event subscriber. * - * @param type an event type enumeration value + * @param type an event type * @param subscriber the Subscriber to subscribe */ void subscribe( Class type, Subscriber subscriber ); @@ -56,6 +56,7 @@ /** * Unsubscribes an event subscriber. * + * @param type an event type * @param subscriber the Subscriber to unsubscribe */ void unsubscribe( Class type, Subscriber subscriber ); @@ -67,4 +68,11 @@ * @param event the event to publish */ void publish( EventObject event ); + + /** + * Applies some routing advice to applicable events. + * + * @param advice the advice to apply + */ + void apply( RoutingAdvice advice ); } Added: incubator/directory/seda/trunk/src/java/org/apache/seda/event/RoutingAdvice.java ============================================================================== --- (empty file) +++ incubator/directory/seda/trunk/src/java/org/apache/seda/event/RoutingAdvice.java Wed Sep 22 02:39:32 2004 @@ -0,0 +1,66 @@ +/* + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.seda.event; + + +import java.util.EventObject; + + +/** + * Used to add another dimension to making fine grained routing decisions. + * RoutingAdvice can add to or prune from the registered set of Subscriptions. + * They can transform the event by cloning before Subscribers are informed. + * Other types of logic using these substitutions can be used to implement a + * gambit of routing rules and behavoirs. These objects are stackable in that + * more than one piece of advice can be used to route the same event: this is + * acheived by feeding the result of one advice operation into the input of + * another in a chain. + * + * @author Apache Directory Project + * @version $Rev$ + */ +public interface RoutingAdvice +{ + /** + * Returns an alternative list of Subscriptions which may or may not be + * the same as those already registered with the router service. + * + * @param ev the original event without any chained substitutions + * @param subscriptions the subscriptions already registered with the router + * @return the advised list of subscriptions to use instead + */ + public Subscription[] getSubscriptions( EventObject ev, Subscription[] subscriptions ); + + + /** + * Gets an alternative event to use as the argument to inform Subscribers + * which may or may not be the same as the event argument. + * + * @param ev the event being published + * @return the advised event to use instead + */ + public EventObject getEvent( EventObject ev ); + + + /** + * Checks to see if this advice is applicable to an event. + * + * @param ev the event to check for advice applicability + * @return true if this advice applies, false otherwise + */ + public boolean isApplicable( EventObject ev ); +}