Author: niklas
Date: Thu Feb  8 01:48:21 2007
New Revision: 504840

URL: http://svn.apache.org/viewvc?view=rev&rev=504840
Log:
STATE annotations can now be spread out over several classes.

Modified:
    
mina/sandbox/niklas/mina-sm/src/main/java/org/apache/mina/sm/StateMachineFactory.java
    
mina/sandbox/niklas/mina-sm/src/test/java/org/apache/mina/sm/StateMachineFactoryTest.java

Modified: 
mina/sandbox/niklas/mina-sm/src/main/java/org/apache/mina/sm/StateMachineFactory.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/niklas/mina-sm/src/main/java/org/apache/mina/sm/StateMachineFactory.java?view=diff&rev=504840&r1=504839&r2=504840
==============================================================================
--- 
mina/sandbox/niklas/mina-sm/src/main/java/org/apache/mina/sm/StateMachineFactory.java
 (original)
+++ 
mina/sandbox/niklas/mina-sm/src/main/java/org/apache/mina/sm/StateMachineFactory.java
 Thu Feb  8 01:48:21 2007
@@ -46,33 +46,31 @@
 
     public static StateMachine create( Object handler )
     {
-        return create( handler.getClass(), handler );
+        return create( handler, new Object[0] );
     }
     
     public static StateMachine create( String start, Object handler )
     {
-        return create( start, handler.getClass(), handler );
+        return create( start, handler, new Object[0] );
     }
     
     public static StateMachine create( Object handler, Object... handlers )
     {
-        return create( "start", handler.getClass(), handler, handlers );
+        return create( "start", handler, handlers );
     }
     
     public static StateMachine create( String start, Object handler, Object... 
handlers )
     {
-        return create( start, handler.getClass(), handler, handlers );
-    }
-    
-    public static StateMachine create( Class clazz, Object handler, Object... 
handlers )
-    {
-        return create( "start", clazz, handler, handlers );
-    }
-    
-    public static StateMachine create( String start, Class clazz, Object 
handler, Object... handlers )
-    {
         HashMap<String, State> states = new HashMap<String, State>();
-        for( State state: createStates( clazz ) )
+        ArrayList<Object> handlersList = new ArrayList<Object>(1 + 
handlers.length);
+        handlersList.add( handler );
+        handlersList.addAll( Arrays.asList( handlers ) );
+        
+        LinkedList<Field> fields = new LinkedList<Field>();
+        for (Object h: handlersList) {
+            fields.addAll( getFields( h instanceof Class ? (Class) h : 
h.getClass() ) );
+        }
+        for( State state: createStates( fields ) )
         {
             states.put( state.getId(), state );
         }
@@ -82,9 +80,6 @@
             throw new StateMachineCreationException( "Start state '" + start + 
"' not found." );
         }
         
-        ArrayList<Object> handlersList = new ArrayList<Object>();
-        handlersList.add( handler );
-        handlersList.addAll( Arrays.asList( handlers ) );
         setupTransitions( states, handlersList );
         
         return new StateMachine( states.values(), start );
@@ -175,7 +170,7 @@
         }
     }
 
-    static State[] createStates( Class clazz )
+    static List<Field> getFields( Class clazz )
     {
         LinkedList<Field> fields = new LinkedList<Field>();
         
@@ -204,49 +199,54 @@
             fields.add( f );
         }
         
-        int maxIterations = fields.size();
+        return fields;
+    }
+        
+    static State[] createStates( List<Field> fields )
+    {
         LinkedHashMap<String, State> states = new LinkedHashMap<String, 
State>();
-        for( int i = 0; i < maxIterations && !fields.isEmpty(); i++ )
-        {
-            Field f = fields.removeFirst();
-            
-            String value = null;
-            try
-            {
-                value = ( String ) f.get( null );
+        
+        while (!fields.isEmpty()) {
+            int size = fields.size();
+            int numStates = states.size();
+            for (int i = 0; i < size; i++) {
+                Field f = fields.remove(0);
+
+                String value = null;
+                try {
+                    value = (String) f.get(null);
+                } catch (IllegalAccessException iae) {
+                    throw new StateMachineCreationException(
+                            "Error encountered when " + "processing field " + f
+                                    + ".", iae);
+                }
+
+                org.apache.mina.sm.annotation.State stateAnnotation = f
+                        
.getAnnotation(org.apache.mina.sm.annotation.State.class);
+                if (stateAnnotation.value().equals(
+                        org.apache.mina.sm.annotation.State.ROOT)) {
+                    states.put(value, new State(value));
+                } else if (states.containsKey(stateAnnotation.value())) {
+                    states.put(value, new State(value, states
+                            .get(stateAnnotation.value())));
+                } else {
+                    // Move to the back of the list of fields for later
+                    // processing
+                    fields.add(f);
+                }
             }
-            catch( IllegalAccessException iae )
-            {
+        
+            /*
+             * If no new states were added to states during this iteration it 
+             * means that all fields in fields specify non-existent parents.
+             */
+            if (states.size() == numStates) {
                 throw new StateMachineCreationException(
-                        "Error encountered when " + "processing field "
-                                + f + ".", iae );
-            }
-            
-            org.apache.mina.sm.annotation.State stateAnnotation = 
f.getAnnotation( org.apache.mina.sm.annotation.State.class );
-            if( stateAnnotation.value().equals( 
org.apache.mina.sm.annotation.State.ROOT ) )
-            {
-                states.put( value, new State( value ) );
-            }
-            else if( states.containsKey( stateAnnotation.value() ) )
-            {
-                states.put( value, new State( value, states.get( 
stateAnnotation.value() ) ) );
-            }
-            else
-            {
-                // Move to the back of the list of fields for later processing
-                fields.addLast( f );
+                        "Error encountered while creating "
+                                + "FSM. The following fields specify 
non-existing "
+                                + "parent states: " + fields);
             }
         }
-        
-        // The list of fields should be empty by now. If not it means that at
-        // least one field specifies a non-existent parent.
-        if( !fields.isEmpty() )
-        {
-            throw new StateMachineCreationException( "Error encountered while 
creating "
-                    + "FSM. The following fields specify non-existing "
-                    + "parent states: " + fields );
-        }
-        
 
         return states.values().toArray( new State[ 0 ] );
     }

Modified: 
mina/sandbox/niklas/mina-sm/src/test/java/org/apache/mina/sm/StateMachineFactoryTest.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/niklas/mina-sm/src/test/java/org/apache/mina/sm/StateMachineFactoryTest.java?view=diff&rev=504840&r1=504839&r2=504840
==============================================================================
--- 
mina/sandbox/niklas/mina-sm/src/test/java/org/apache/mina/sm/StateMachineFactoryTest.java
 (original)
+++ 
mina/sandbox/niklas/mina-sm/src/test/java/org/apache/mina/sm/StateMachineFactoryTest.java
 Thu Feb  8 01:48:21 2007
@@ -100,7 +100,7 @@
     
     public void testCreateStates() throws Exception
     {
-        State[] states = StateMachineFactory.createStates( States.class );
+        State[] states = StateMachineFactory.createStates( 
StateMachineFactory.getFields( States.class ) );
         assertEquals( States.A, states[ 0 ].getId() );
         assertNull( states[ 0 ].getParent() );
         assertEquals( States.B, states[ 1 ].getId() );
@@ -115,7 +115,7 @@
     {
         try
         {
-            StateMachineFactory.createStates( StatesWithMissingParents.class );
+            StateMachineFactory.createStates( StateMachineFactory.getFields( 
StatesWithMissingParents.class ) );
             fail( "Missing parents. FsmCreationException expected." );
         }
         catch( StateMachineCreationException fce )


Reply via email to