Commits

Igor Baidiuk  committed 590f373

Implemented closures for events and wrote some smal tests. Need more excessive testing

  • Participants
  • Parent commits c58de93

Comments (0)

Files changed (2)

 		<echo message="Executing, descending order" />
 		<fire-event name="foo" order="descending" />
 		
+		<!-- Test context closure -->
+		<sequential>
+			<local name="loc.value1" />
+			<property name="loc.value1" value="Local value 1" />
+			<event name="bar" >
+				<echo message="$${global.text} = ${global.text}" />
+				<echo message="$${loc.value1} = ${loc.value1}" />
+			</event>
+		</sequential>
 		
+		<local name="loc.value1" />
+		<property name="loc.value1" value="Not so local value" />
+		<fire-event name="bar" />
 	</target>
-</project>
+	
+	<property name="global.text" value="Global text" />
+</project>

File src/org/antcontrib/events/Event.java

 package org.antcontrib.events;
 
 import java.util.Iterator;
+import java.util.ListIterator;
 import java.util.Map;
 import java.util.Set;
 import java.util.List;
+import java.util.LinkedList;
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Collections;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 
 import org.apache.tools.ant.BuildException;
 
+import org.apache.tools.ant.Project;
 import org.apache.tools.ant.Task;
 import org.apache.tools.ant.TaskContainer;
 import org.apache.tools.ant.PropertyHelper;
 	{
 		if (name == null || name.isEmpty())
 			throw new BuildException("Event name must be a nonempty string");
-		// TODO: implement context capture
-		/*
+		
 		try
 		{
 			// get property stack
 			LocalProperties lp = LocalProperties.get(getProject());
-			Method getStack = lp.class.getDeclaredMethod("current", new Class[0]);
+			Method getStack = LocalProperties.class.getDeclaredMethod("current", new Class[0]);
 			getStack.setAccessible(true);
 			LocalPropertyStack lps = (LocalPropertyStack)getStack.invoke(lp, new Object[0]);
 			// get actual stacks list
 			if (lps != null)
 			{
-				Field list = lps.class.getDeclaredField("stack");
-				LinkedList stack = (LinkedList) list.get(lps);
+				Field list = LocalPropertyStack.class.getDeclaredField("stack");
+				list.setAccessible(true);
+				List stack = (List) list.get(lps);
 				// Now, traverse stack and write its contents to flat hashmap
 				if (stack != null)
 				{
+					// New closure
+					closure = new HashMap();
+					// Clone context stack and reverse it for proper properties override
+					stack = new ArrayList(stack);
+					Collections.reverse(stack);
+					// Now, put all values from each map on stack into closure
+					for (Iterator i = stack.iterator(); i.hasNext(); )
+						closure.putAll((Map)i.next());
 				}
 			}
 		}
 		catch (Throwable t)
 		{
-			log("Failed to capture context");
+			log("Failed to capture context: ".concat(t.toString()), Project.MSG_ERR);
 		}
-		*/
 		// Add this task to respective event list
 		EventList.get(getProject(), name).addEvent(this);
 	}