/*
 * The Spring Framework is published under the terms
 * of the Apache Software License.
 */
 
package org.springframework.transaction.interceptor;

import java.lang.reflect.Method;

import junit.framework.TestCase;

import org.aopalliance.intercept.MethodInvocation;
import org.easymock.EasyMock;
import org.easymock.MockControl;
import org.springframework.transaction.TransactionDefinition;

/**
 * Format is 
 * FQN.Method=tx attribute representation
 * @author Rod Johnson
 * @since 26-Apr-2003
 * @version $Revision: 1.1.1.1 $
 */
public class TransactionAttributeSourceEditorTests extends TestCase {

	public TransactionAttributeSourceEditorTests(String arg0) {
		super(arg0);
	}

	public void testNull() throws Exception {
		TransactionAttributeSourceEditor pe = new TransactionAttributeSourceEditor();
		pe.setAsText(null);
		TransactionAttributeSource tas = (TransactionAttributeSource) pe.getValue();

		MockControl miControl = EasyMock.controlFor(MethodInvocation.class);
		MethodInvocation mi = (MethodInvocation) miControl.getMock();
		Method m = Object.class.getMethod("hashCode", null);
		mi.getMethod();
		miControl.setReturnValue(m);
		miControl.activate();
		
		assertTrue(tas.getTransactionAttribute(mi) == null);
	}

	public void testInvalid() throws Exception {
		TransactionAttributeSourceEditor pe = new TransactionAttributeSourceEditor();
		try {
			pe.setAsText("foo=bar");
			fail();
		}
		catch (IllegalArgumentException ex) {
			// Ok
		}
	}
	
	public void testMatchesSpecific() throws Exception {
		TransactionAttributeSourceEditor pe = new TransactionAttributeSourceEditor();
		// TODO need FQN?
		pe.setAsText("java.lang.Object.hashCode=PROPAGATION_REQUIRED\n" +
			"java.lang.Object.equals=PROPAGATION_MANDATORY\n" +
		  "java.lang.Object.wait=PROPAGATION_SUPPORTS\n" +
			"java.lang.Object.not*=PROPAGATION_REQUIRED");
		TransactionAttributeSource tas = (TransactionAttributeSource) pe.getValue();

		checkTransactionProperties(tas, Object.class.getMethod("hashCode", null),
		                     TransactionDefinition.PROPAGATION_REQUIRED);
		checkTransactionProperties(tas, Object.class.getMethod("equals", new Class[] { Object.class }),
		                     TransactionDefinition.PROPAGATION_MANDATORY);
		checkTransactionProperties(tas, Object.class.getMethod("wait", null),
		                     TransactionDefinition.PROPAGATION_SUPPORTS);
		checkTransactionProperties(tas, Object.class.getMethod("wait", new Class[] { long.class }),
		                     TransactionDefinition.PROPAGATION_SUPPORTS);
		checkTransactionProperties(tas, Object.class.getMethod("wait", new Class[] { long.class, int.class }),
		                     TransactionDefinition.PROPAGATION_SUPPORTS);
		checkTransactionProperties(tas, Object.class.getMethod("notify", null),
		                     TransactionDefinition.PROPAGATION_REQUIRED);
		checkTransactionProperties(tas, Object.class.getMethod("notifyAll", null),
		                     TransactionDefinition.PROPAGATION_REQUIRED);
		checkTransactionProperties(tas, Object.class.getMethod("toString", null),
		                     -1);
	}

	public void testMatchesAll() throws Exception {
		TransactionAttributeSourceEditor pe = new TransactionAttributeSourceEditor();
		pe.setAsText("java.lang.Object.*=PROPAGATION_REQUIRED");
		TransactionAttributeSource tas = (TransactionAttributeSource) pe.getValue();

		checkTransactionProperties(tas, Object.class.getMethod("hashCode", null),
		                     TransactionDefinition.PROPAGATION_REQUIRED);
		checkTransactionProperties(tas, Object.class.getMethod("equals", new Class[] { Object.class }),
		                     TransactionDefinition.PROPAGATION_REQUIRED);
		checkTransactionProperties(tas, Object.class.getMethod("wait", null),
		                     TransactionDefinition.PROPAGATION_REQUIRED);
		checkTransactionProperties(tas, Object.class.getMethod("wait", new Class[] { long.class }),
		                     TransactionDefinition.PROPAGATION_REQUIRED);
		checkTransactionProperties(tas, Object.class.getMethod("wait", new Class[] { long.class, int.class }),
		                     TransactionDefinition.PROPAGATION_REQUIRED);
		checkTransactionProperties(tas, Object.class.getMethod("notify", null),
		                     TransactionDefinition.PROPAGATION_REQUIRED);
		checkTransactionProperties(tas, Object.class.getMethod("notifyAll", null),
		                     TransactionDefinition.PROPAGATION_REQUIRED);
		checkTransactionProperties(tas, Object.class.getMethod("toString", null),
		                     TransactionDefinition.PROPAGATION_REQUIRED);
	}

	private void checkTransactionProperties(TransactionAttributeSource tas, Method method, int propagationBehavior) {
		MockControl miControl = EasyMock.controlFor(MethodInvocation.class);
		MethodInvocation mi = (MethodInvocation) miControl.getMock();
		mi.getMethod();
		miControl.setReturnValue(method);
		miControl.activate();
		TransactionAttribute ta = tas.getTransactionAttribute(mi);
		if (propagationBehavior >= 0) {
			assertTrue(ta != null);
			assertTrue(ta.getIsolationLevel() == TransactionDefinition.ISOLATION_DEFAULT);
			assertTrue(ta.getPropagationBehavior() == propagationBehavior);
		}
		else {
			assertTrue(ta == null);
		}
	}

}

@@ -519,21 +519,17 @@
 sion: 1.
-1.1.1
+2
  $%0A */%0Ap
@@ -1679,33 +1679,45 @@
 REQUIRED%5Cn%22 +%0A%09%09
-%09
+             
 %22java.lang.Objec
@@ -1756,16 +1756,27 @@
 %22 +%0A%09%09  
+           
 %22java.la
@@ -1818,17 +1818,95 @@
 %5Cn%22 +%0A%09%09
-%09
+             %22java.lang.Object.notify=PROPAGATION_SUPPORTS%5Cn%22 +%0A%09%09             
 %22java.la
@@ -2937,32 +2937,32 @@
 PROPAGATION_
-REQUIRED
+SUPPORTS
 );%0A%09%09checkTr

support for overlapping method name patterns