FELIX-2647 : Implement Coordinator Service - further fixes for the CT tests cases, 59 of 61 passing (implemented nested failure handling, wrong thread)

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1551422 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationImpl.java b/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationImpl.java
index bd9ad7f..26b6afc 100644
--- a/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationImpl.java
+++ b/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationImpl.java
@@ -160,10 +160,20 @@
      */
     public void end()
     {
+        if ( !this.isTerminated() && this.associatedThread != null && Thread.currentThread() != this.associatedThread )
+        {
+            throw new CoordinationException("Coordination is associated with different thread", this, CoordinationException.WRONG_THREAD);
+        }
+
         if (startTermination())
         {
-            // TODO check for WRONG_THREAD
-            boolean partialFailure = this.owner.endNestedCoordinations(this);
+
+            final CoordinationException nestedFailed = this.owner.endNestedCoordinations(this);
+            if ( nestedFailed != null )
+            {
+                this.failReason = nestedFailed;
+            }
+            boolean partialFailure = false;
             this.owner.unregister(this, true);
 
             final List<Participant> releaseList = new ArrayList<Participant>();
@@ -178,7 +188,14 @@
                 final Participant part = releaseList.get(i);
                 try
                 {
-                    part.ended(this);
+                    if ( this.failReason != null )
+                    {
+                        part.failed(this);
+                    }
+                    else
+                    {
+                        part.ended(this);
+                    }
                 }
                 catch (final Exception e)
                 {
@@ -197,6 +214,11 @@
                 this.waitLock.notifyAll();
             }
 
+            if ( this.failReason != null )
+            {
+                throw new CoordinationException("Nested coordination failed", this,
+                        CoordinationException.FAILED, this.failReason);
+            }
             if (partialFailure)
             {
                 throw new CoordinationException("One or more participants threw while ending the coordination", this,
diff --git a/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationMgr.java b/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationMgr.java
index e3225e9..a6e09ac 100644
--- a/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationMgr.java
+++ b/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinationMgr.java
@@ -408,9 +408,9 @@
 		return null;
 	}
 
-	public boolean endNestedCoordinations(final CoordinationImpl c)
+	public CoordinationException endNestedCoordinations(final CoordinationImpl c)
 	{
-	    boolean partiallyFailed = false;
+	    CoordinationException partiallyFailed = null;
         final Stack<CoordinationImpl> stack = this.getThreadStack(false);
         if ( stack != null )
         {
@@ -423,11 +423,15 @@
         			final CoordinationImpl nested = stack.pop();
         			try
         			{
+        			    if ( partiallyFailed != null)
+        			    {
+        			        nested.fail(partiallyFailed);
+        			    }
     			        nested.end();
         			}
         			catch ( final CoordinationException ce)
         			{
-        			    partiallyFailed = true;
+        			    partiallyFailed = ce;
         			}
         		}
         	}
diff --git a/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinatorImpl.java b/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinatorImpl.java
index 0de2654..1eb9c6e 100644
--- a/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinatorImpl.java
+++ b/coordinator/src/main/java/org/apache/felix/coordinator/impl/CoordinatorImpl.java
@@ -23,6 +23,7 @@
 
 import org.osgi.framework.Bundle;
 import org.osgi.service.coordinator.Coordination;
+import org.osgi.service.coordinator.CoordinationException;
 import org.osgi.service.coordinator.Coordinator;
 import org.osgi.service.coordinator.Participant;
 
@@ -255,7 +256,7 @@
 		return mgr.getEnclosingCoordination(c);
 	}
 
-	boolean endNestedCoordinations(final CoordinationImpl c)
+	CoordinationException endNestedCoordinations(final CoordinationImpl c)
 	{
 		return this.mgr.endNestedCoordinations(c);
 	}