felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cziege...@apache.org
Subject svn commit: r1550646 - in /felix/trunk/coordinator/src: main/java/org/apache/felix/coordinator/impl/ test/java/org/apache/felix/coordinator/impl/
Date Fri, 13 Dec 2013 05:26:28 GMT
Author: cziegeler
Date: Fri Dec 13 05:26:27 2013
New Revision: 1550646

URL: http://svn.apache.org/r1550646
Log:
FELIX-2647 : Implement Coordinator Service - start implementing nested coordinations and fix
failing CT test cases

Modified:
    felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationImpl.java
    felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationMgr.java
    felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinatorImpl.java
    felix/trunk/coordinator/src/test/java/org/apache/felix/coordinator/impl/CoordinatorImplTest.java

Modified: felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationImpl.java?rev=1550646&r1=1550645&r2=1550646&view=diff
==============================================================================
--- felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationImpl.java
(original)
+++ felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationImpl.java
Fri Dec 13 05:26:27 2013
@@ -99,11 +99,13 @@ public class CoordinationImpl implements
     {
         if (startTermination())
         {
+            this.owner.unregister(this);
             this.failReason = reason;
 
             // consider failure reason (if not null)
-            for (Participant part : participants)
+            for (int i=participants.size()-1;i>=0;i--)
             {
+                final Participant part = participants.get(i);
                 try
                 {
                     part.failed(this);
@@ -131,11 +133,16 @@ public class CoordinationImpl implements
 
     public void end()
     {
+    	
         if (startTermination())
         {
-            boolean partialFailure = false;
-            for (Participant part : participants)
+        	this.owner.endNestedCoordinations(this);
+            this.owner.unregister(this);
+
+        	boolean partialFailure = false;
+            for (int i=participants.size()-1;i>=0;i--)
             {
+                final Participant part = participants.get(i);
                 try
                 {
                     part.ended(this);
@@ -287,8 +294,10 @@ public class CoordinationImpl implements
 
     public Coordination push()
     {
-        // TODO: Check whether this has already been pushed !
-        // throw new CoordinationException("Coordination already pushed", this, CoordinationException.ALREADY_PUSHED);
+    	if ( isTerminated() )
+    	{
+            throw new CoordinationException("Coordination already ended", this, CoordinationException.ALREADY_ENDED);
+    	}
 
         return owner.push(this);
     }
@@ -329,7 +338,6 @@ public class CoordinationImpl implements
         if (state == ACTIVE)
         {
             state = TERMINATING;
-            owner.unregister(this);
             scheduleTimeout(-1);
             return true;
         }
@@ -368,13 +376,37 @@ public class CoordinationImpl implements
         }
     }
 
-    public Bundle getBundle() {
-        // TODO Auto-generated method stub
-        return null;
+    public Bundle getBundle()
+    {
+        return this.owner.getBundle();
     }
 
-    public Coordination getEnclosingCoordination() {
-        // TODO Auto-generated method stub
-        return null;
+    public Coordination getEnclosingCoordination()
+    {
+        return this.owner.getEnclosingCoordination(this);
     }
+
+	@Override
+	public int hashCode() 
+	{
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + (int) (id ^ (id >>> 32));
+		return result;
+	}
+
+	@Override
+	public boolean equals(final Object obj) 
+	{
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		final CoordinationImpl other = (CoordinationImpl) obj;
+		if (id != other.id)
+			return false;
+		return true;
+	}
 }

Modified: felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationMgr.java
URL: http://svn.apache.org/viewvc/felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationMgr.java?rev=1550646&r1=1550645&r2=1550646&view=diff
==============================================================================
--- felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationMgr.java
(original)
+++ felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationMgr.java
Fri Dec 13 05:26:27 2013
@@ -206,6 +206,13 @@ public class CoordinationMgr implements 
             stack = new Stack<Coordination>();
             threadStacks.set(stack);
         }
+        else
+        {
+            if ( stack.contains(c) ) 
+            {
+                throw new CoordinationException("Coordination already pushed", c, CoordinationException.ALREADY_PUSHED);
+            }
+        }
         return stack.push(c);
     }
 
@@ -318,4 +325,36 @@ public class CoordinationMgr implements 
             { c.getId(), c.getName(), c.getDeadLine() });
     }
     */
+
+	public Coordination getEnclosingCoordination(final CoordinationImpl c) 
+	{
+        Stack<Coordination> stack = threadStacks.get();
+        if ( stack != null )
+        {
+        	final int index = stack.indexOf(c);
+        	if ( index > 0 )
+        	{
+        		return stack.elementAt(index - 1);
+        	}
+        }
+		return null;
+	}
+
+	public void endNestedCoordinations(final CoordinationImpl c) 
+	{
+        Stack<Coordination> stack = threadStacks.get();
+        if ( stack != null )
+        {
+        	final int index = stack.indexOf(c) + 1;
+        	if ( index > 0 && stack.size() > index )
+        	{
+        		final int count = stack.size()-index;
+        		for(int i=0;i<count;i++) 
+        		{
+        			final Coordination nested = (Coordination)stack.pop();
+        			nested.end();
+        		}
+        	}
+        }
+	}
 }

Modified: felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinatorImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinatorImpl.java?rev=1550646&r1=1550645&r2=1550646&view=diff
==============================================================================
--- felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinatorImpl.java
(original)
+++ felix/trunk/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinatorImpl.java
Fri Dec 13 05:26:27 2013
@@ -20,6 +20,7 @@ package org.apache.felix.coordinator.imp
 
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.Set;
 import java.util.TimerTask;
 
 import org.osgi.framework.Bundle;
@@ -27,7 +28,6 @@ import org.osgi.service.coordinator.Coor
 import org.osgi.service.coordinator.CoordinationException;
 import org.osgi.service.coordinator.Participant;
 
-@SuppressWarnings("deprecation")
 public class CoordinatorImpl implements org.osgi.service.coordinator.Coordinator
 {
 
@@ -35,7 +35,7 @@ public class CoordinatorImpl implements 
 
     private final CoordinationMgr mgr;
 
-    private final HashSet<Coordination> coordinations;
+    private final Set<Coordination> coordinations;
 
     CoordinatorImpl(final Bundle owner, final CoordinationMgr mgr)
     {
@@ -72,17 +72,89 @@ public class CoordinatorImpl implements 
         if (active != null)
         {
             Throwable reason = new Exception("Coordinator service released");
-            for (int i = 0; i < active.length; i++)
+            for (int i = active.length -1; i >=0; i--)
             {
                 active[i].fail(reason);
             }
         }
     }
 
+    /**
+     * Ensures the <code>name</code> complies with the <em>symbolic-name</em>
+     * production of the OSGi core specification (1.3.2):
+     *
+     * <pre>
+     * symbolic-name :: = token('.'token)*
+     * digit    ::= [0..9]
+     * alpha    ::= [a..zA..Z]
+     * alphanum ::= alpha | digit
+     * token    ::= ( alphanum | ’_’ | ’-’ )+
+     * </pre>
+     *
+     * If the key does not comply an <code>IllegalArgumentException</code> is
+     * thrown.
+     *
+     * @param key
+     *            The configuration property key to check.
+     * @throws IllegalArgumentException
+     *             if the key does not comply with the symbolic-name production.
+     */
+    private void checkName( final String name )
+    {
+        // check for empty string
+        if ( name.length() == 0 )
+        {
+            throw new IllegalArgumentException( "Name must not be an empty string" );
+        }
+        final String[] parts = name.split("\\.");
+        for(final String p : parts)
+        {
+        	boolean valid = true;
+        	if ( p.length() == 0 ) 
+        	{
+        		valid = false;
+        	}
+        	else
+        	{
+	            for(int i=0; i<p.length(); i++)
+	            {
+	            	final char c = p.charAt(i);
+	            	if ( c >= '0' && c <= '9') {
+	            		continue;
+	            	}
+	            	if ( c >= 'a' && c <= 'z') {
+	            		continue;
+	            	}
+	            	if ( c >= 'A' && c <= 'Z') {
+	            		continue;
+	            	}
+	            	if ( c == '_' || c == '-') {
+	            		continue;
+	            	}
+	            	valid = false;
+	            	break;
+	            }
+        	}
+        	if ( !valid ) 
+        	{
+                throw new IllegalArgumentException( "Name [" + name + "] does not comply
with the symbolic-name definition." );        		        		
+        	}
+        }
+    }
+    
     public Coordination create(final String name, final long timeout)
     {
         // TODO: check permission
-        Coordination c = mgr.create(this, name, timeout);
+
+    	// check arguments
+    	checkName(name);
+    	if ( timeout < 0 ) 
+    	{
+    		throw new IllegalArgumentException("Timeout must not be negative");
+    	}
+    	
+    	// create coordination
+        final Coordination c = mgr.create(this, name, timeout);
         synchronized (coordinations)
         {
             coordinations.add(c);
@@ -174,4 +246,19 @@ public class CoordinatorImpl implements 
     {
         mgr.releaseParticipant(p);
     }
+
+    Bundle getBundle()
+    {
+        return this.owner;
+    }
+
+	public Coordination getEnclosingCoordination(final CoordinationImpl c) 
+	{
+		return mgr.getEnclosingCoordination(c);
+	}
+
+	public void endNestedCoordinations(final CoordinationImpl c) 
+	{
+		this.mgr.endNestedCoordinations(c);		
+	}
 }

Modified: felix/trunk/coordinator/src/test/java/org/apache/felix/coordinator/impl/CoordinatorImplTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/coordinator/src/test/java/org/apache/felix/coordinator/impl/CoordinatorImplTest.java?rev=1550646&r1=1550645&r2=1550646&view=diff
==============================================================================
--- felix/trunk/coordinator/src/test/java/org/apache/felix/coordinator/impl/CoordinatorImplTest.java
(original)
+++ felix/trunk/coordinator/src/test/java/org/apache/felix/coordinator/impl/CoordinatorImplTest.java
Fri Dec 13 05:26:27 2013
@@ -156,9 +156,17 @@ public class CoordinatorImplTest extends
         assertEquals(c2, coordinator.peek());
 
         c1.end();
-        assertEquals(c2, coordinator.peek());
+        assertNull(coordinator.peek());
 
-        c2.end();
+        try
+        {
+            c2.end();
+            fail("c2 is already terminated");
+        }
+        catch (CoordinationException ce)
+        {
+            assertEquals(CoordinationException.ALREADY_ENDED, ce.getType());
+        }
         assertNull(coordinator.peek());
     }
 
@@ -192,7 +200,7 @@ public class CoordinatorImplTest extends
         assertEquals(c2, p21.c);
         assertTrue(p22.ended);
         assertEquals(c2, p22.c);
-        assertTrue("p21 must be called before p22", p21.time < p22.time);
+        assertTrue("p22 must be called before p21", p22.time < p21.time);
 
         // assert order of call with two registrations
         final Coordination c3 = coordinator.create(name, 0);
@@ -210,7 +218,7 @@ public class CoordinatorImplTest extends
         assertEquals(c3, p31.c);
         assertTrue(p32.ended);
         assertEquals(c3, p32.c);
-        assertTrue("p21 must be called before p22", p31.time < p32.time);
+        assertTrue("p32 must be called before p31", p32.time < p31.time);
     }
 
     public void test_addParticipant_with_failed()
@@ -243,7 +251,7 @@ public class CoordinatorImplTest extends
         assertEquals(c2, p21.c);
         assertTrue(p22.failed);
         assertEquals(c2, p22.c);
-        assertTrue("p21 must be called before p22", p21.time < p22.time);
+        assertTrue("p22 must be called before p21", p22.time < p21.time);
 
         // assert order of call with two registrations
         final Coordination c3 = coordinator.create(name, 0);
@@ -261,7 +269,7 @@ public class CoordinatorImplTest extends
         assertEquals(c3, p31.c);
         assertTrue(p32.failed);
         assertEquals(c3, p32.c);
-        assertTrue("p21 must be called before p22", p31.time < p32.time);
+        assertTrue("p31 must be called before p32", p32.time < p31.time);
     }
 
     public void test_Coordination_timeout() throws InterruptedException



Mime
View raw message