diff --git a/org.springframework.aspects/.classpath b/org.springframework.aspects/.classpath
index 8b4c6992f5..b650717c2e 100644
--- a/org.springframework.aspects/.classpath
+++ b/org.springframework.aspects/.classpath
@@ -1,15 +1,19 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/org.springframework.aspects/build.xml b/org.springframework.aspects/build.xml
index 98488bc099..bab62bd033 100644
--- a/org.springframework.aspects/build.xml
+++ b/org.springframework.aspects/build.xml
@@ -3,4 +3,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/org.springframework.aspects/ivy.xml b/org.springframework.aspects/ivy.xml
index 5bd5219b48..ae5786d640 100644
--- a/org.springframework.aspects/ivy.xml
+++ b/org.springframework.aspects/ivy.xml
@@ -22,9 +22,14 @@
-
-
+
+
+
+
+
+
+
diff --git a/org.springframework.aspects/src/test/java/org/springframework/aop/aspectj/autoproxy/AutoProxyWithCodeStyleAspectsTests.java b/org.springframework.aspects/src/test/java/org/springframework/aop/aspectj/autoproxy/AutoProxyWithCodeStyleAspectsTests.java
new file mode 100644
index 0000000000..d593e1d118
--- /dev/null
+++ b/org.springframework.aspects/src/test/java/org/springframework/aop/aspectj/autoproxy/AutoProxyWithCodeStyleAspectsTests.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2002-2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.aop.aspectj.autoproxy;
+
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+import junit.framework.TestCase;
+
+/**
+ * @author Adrian Colyer
+ */
+public class AutoProxyWithCodeStyleAspectsTests extends TestCase {
+
+ public void testNoAutoproxyingOfAjcCompiledAspects() {
+ new ClassPathXmlApplicationContext("org/springframework/aop/aspectj/autoproxy/ajcAutoproxyTests.xml");
+ }
+
+}
diff --git a/org.springframework.aspects/src/test/java/org/springframework/aop/aspectj/autoproxy/CodeStyleAspect.aj b/org.springframework.aspects/src/test/java/org/springframework/aop/aspectj/autoproxy/CodeStyleAspect.aj
new file mode 100644
index 0000000000..bf16e144a9
--- /dev/null
+++ b/org.springframework.aspects/src/test/java/org/springframework/aop/aspectj/autoproxy/CodeStyleAspect.aj
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2002-2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.aop.aspectj.autoproxy;
+
+import org.aspectj.lang.annotation.Aspect;
+
+/**
+ * @author Adrian Colyer
+ */
+@Aspect
+public aspect CodeStyleAspect {
+
+ private String foo;
+
+ pointcut somePC() : call(* someMethod());
+
+ before() : somePC() {
+ System.out.println("match");
+ }
+
+ public void setFoo(String foo) {
+ this.foo = foo;
+ }
+
+}
diff --git a/org.springframework.aspects/src/test/java/org/springframework/aop/aspectj/autoproxy/ajcAutoproxyTests.xml b/org.springframework.aspects/src/test/java/org/springframework/aop/aspectj/autoproxy/ajcAutoproxyTests.xml
new file mode 100644
index 0000000000..4af6ec7968
--- /dev/null
+++ b/org.springframework.aspects/src/test/java/org/springframework/aop/aspectj/autoproxy/ajcAutoproxyTests.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/org.springframework.aspects/src/test/java/org/springframework/beans/Colour.java b/org.springframework.aspects/src/test/java/org/springframework/beans/Colour.java
new file mode 100644
index 0000000000..60dc333e0b
--- /dev/null
+++ b/org.springframework.aspects/src/test/java/org/springframework/beans/Colour.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2002-2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.beans;
+
+import org.springframework.core.enums.ShortCodedLabeledEnum;
+
+/**
+ * @author Rob Harrop
+ */
+public class Colour extends ShortCodedLabeledEnum {
+
+ public static final Colour RED = new Colour(0, "RED");
+ public static final Colour BLUE = new Colour(1, "BLUE");
+ public static final Colour GREEN = new Colour(2, "GREEN");
+ public static final Colour PURPLE = new Colour(3, "PURPLE");
+
+ private Colour(int code, String label) {
+ super(code, label);
+ }
+
+}
\ No newline at end of file
diff --git a/org.springframework.aspects/src/test/java/org/springframework/beans/DerivedTestBean.java b/org.springframework.aspects/src/test/java/org/springframework/beans/DerivedTestBean.java
new file mode 100644
index 0000000000..2bb41a9d5b
--- /dev/null
+++ b/org.springframework.aspects/src/test/java/org/springframework/beans/DerivedTestBean.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2002-2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.beans;
+
+import java.io.Serializable;
+
+import org.springframework.beans.factory.BeanNameAware;
+import org.springframework.beans.factory.DisposableBean;
+
+/**
+ * @author Juergen Hoeller
+ * @since 21.08.2003
+ */
+public class DerivedTestBean extends TestBean implements Serializable, BeanNameAware, DisposableBean {
+
+ private String beanName;
+
+ private boolean initialized;
+
+ private boolean destroyed;
+
+
+ public DerivedTestBean() {
+ }
+
+ public DerivedTestBean(String[] names) {
+ if (names == null || names.length < 2) {
+ throw new IllegalArgumentException("Invalid names array");
+ }
+ setName(names[0]);
+ setBeanName(names[1]);
+ }
+
+ public static DerivedTestBean create(String[] names) {
+ return new DerivedTestBean(names);
+ }
+
+
+ public void setBeanName(String beanName) {
+ if (this.beanName == null || beanName == null) {
+ this.beanName = beanName;
+ }
+ }
+
+ public String getBeanName() {
+ return beanName;
+ }
+
+ public void setSpouseRef(String name) {
+ setSpouse(new TestBean(name));
+ }
+
+
+ public void initialize() {
+ this.initialized = true;
+ }
+
+ public boolean wasInitialized() {
+ return initialized;
+ }
+
+
+ public void destroy() {
+ this.destroyed = true;
+ }
+
+ public boolean wasDestroyed() {
+ return destroyed;
+ }
+
+}
\ No newline at end of file
diff --git a/org.springframework.aspects/src/test/java/org/springframework/beans/INestedTestBean.java b/org.springframework.aspects/src/test/java/org/springframework/beans/INestedTestBean.java
new file mode 100644
index 0000000000..7d87547b5f
--- /dev/null
+++ b/org.springframework.aspects/src/test/java/org/springframework/beans/INestedTestBean.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2002-2005 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.beans;
+
+public interface INestedTestBean {
+
+ public String getCompany();
+
+}
\ No newline at end of file
diff --git a/org.springframework.aspects/src/test/java/org/springframework/beans/IOther.java b/org.springframework.aspects/src/test/java/org/springframework/beans/IOther.java
new file mode 100644
index 0000000000..797486ec44
--- /dev/null
+++ b/org.springframework.aspects/src/test/java/org/springframework/beans/IOther.java
@@ -0,0 +1,24 @@
+
+/*
+ * Copyright 2002-2005 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.beans;
+
+public interface IOther {
+
+ void absquatulate();
+
+}
\ No newline at end of file
diff --git a/org.springframework.aspects/src/test/java/org/springframework/beans/ITestBean.java b/org.springframework.aspects/src/test/java/org/springframework/beans/ITestBean.java
new file mode 100644
index 0000000000..cdf5ef510d
--- /dev/null
+++ b/org.springframework.aspects/src/test/java/org/springframework/beans/ITestBean.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2002-2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.beans;
+
+import java.io.IOException;
+
+/**
+ * Interface used for {@link org.springframework.beans.TestBean}.
+ *
+ *
Two methods are the same as on Person, but if this
+ * extends person it breaks quite a few tests..
+ *
+ * @author Rod Johnson
+ * @author Juergen Hoeller
+ */
+public interface ITestBean {
+
+ int getAge();
+
+ void setAge(int age);
+
+ String getName();
+
+ void setName(String name);
+
+ ITestBean getSpouse();
+
+ void setSpouse(ITestBean spouse);
+
+ ITestBean[] getSpouses();
+
+ String[] getStringArray();
+
+ void setStringArray(String[] stringArray);
+
+ /**
+ * Throws a given (non-null) exception.
+ */
+ void exceptional(Throwable t) throws Throwable;
+
+ Object returnsThis();
+
+ INestedTestBean getDoctor();
+
+ INestedTestBean getLawyer();
+
+ IndexedTestBean getNestedIndexedBean();
+
+ /**
+ * Increment the age by one.
+ * @return the previous age
+ */
+ int haveBirthday();
+
+ void unreliableFileOperation() throws IOException;
+
+}
\ No newline at end of file
diff --git a/org.springframework.aspects/src/test/java/org/springframework/beans/IndexedTestBean.java b/org.springframework.aspects/src/test/java/org/springframework/beans/IndexedTestBean.java
new file mode 100644
index 0000000000..ddb091770e
--- /dev/null
+++ b/org.springframework.aspects/src/test/java/org/springframework/beans/IndexedTestBean.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2002-2006 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.beans;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * @author Juergen Hoeller
+ * @since 11.11.2003
+ */
+public class IndexedTestBean {
+
+ private TestBean[] array;
+
+ private Collection collection;
+
+ private List list;
+
+ private Set set;
+
+ private SortedSet sortedSet;
+
+ private Map map;
+
+ private SortedMap sortedMap;
+
+
+ public IndexedTestBean() {
+ this(true);
+ }
+
+ public IndexedTestBean(boolean populate) {
+ if (populate) {
+ populate();
+ }
+ }
+
+ public void populate() {
+ TestBean tb0 = new TestBean("name0", 0);
+ TestBean tb1 = new TestBean("name1", 0);
+ TestBean tb2 = new TestBean("name2", 0);
+ TestBean tb3 = new TestBean("name3", 0);
+ TestBean tb4 = new TestBean("name4", 0);
+ TestBean tb5 = new TestBean("name5", 0);
+ TestBean tb6 = new TestBean("name6", 0);
+ TestBean tb7 = new TestBean("name7", 0);
+ TestBean tbX = new TestBean("nameX", 0);
+ TestBean tbY = new TestBean("nameY", 0);
+ this.array = new TestBean[] {tb0, tb1};
+ this.list = new ArrayList();
+ this.list.add(tb2);
+ this.list.add(tb3);
+ this.set = new TreeSet();
+ this.set.add(tb6);
+ this.set.add(tb7);
+ this.map = new HashMap();
+ this.map.put("key1", tb4);
+ this.map.put("key2", tb5);
+ this.map.put("key.3", tb5);
+ List list = new ArrayList();
+ list.add(tbX);
+ list.add(tbY);
+ this.map.put("key4", list);
+ }
+
+
+ public TestBean[] getArray() {
+ return array;
+ }
+
+ public void setArray(TestBean[] array) {
+ this.array = array;
+ }
+
+ public Collection getCollection() {
+ return collection;
+ }
+
+ public void setCollection(Collection collection) {
+ this.collection = collection;
+ }
+
+ public List getList() {
+ return list;
+ }
+
+ public void setList(List list) {
+ this.list = list;
+ }
+
+ public Set getSet() {
+ return set;
+ }
+
+ public void setSet(Set set) {
+ this.set = set;
+ }
+
+ public SortedSet getSortedSet() {
+ return sortedSet;
+ }
+
+ public void setSortedSet(SortedSet sortedSet) {
+ this.sortedSet = sortedSet;
+ }
+
+ public Map getMap() {
+ return map;
+ }
+
+ public void setMap(Map map) {
+ this.map = map;
+ }
+
+ public SortedMap getSortedMap() {
+ return sortedMap;
+ }
+
+ public void setSortedMap(SortedMap sortedMap) {
+ this.sortedMap = sortedMap;
+ }
+
+}
\ No newline at end of file
diff --git a/org.springframework.aspects/src/test/java/org/springframework/beans/NestedTestBean.java b/org.springframework.aspects/src/test/java/org/springframework/beans/NestedTestBean.java
new file mode 100644
index 0000000000..a06e15d150
--- /dev/null
+++ b/org.springframework.aspects/src/test/java/org/springframework/beans/NestedTestBean.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2002-2005 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.beans;
+
+/**
+ * Simple nested test bean used for testing bean factories, AOP framework etc.
+ *
+ * @author Trevor D. Cook
+ * @since 30.09.2003
+ */
+public class NestedTestBean implements INestedTestBean {
+
+ private String company = "";
+
+ public NestedTestBean() {
+ }
+
+ public NestedTestBean(String company) {
+ setCompany(company);
+ }
+
+ public void setCompany(String company) {
+ this.company = (company != null ? company : "");
+ }
+
+ public String getCompany() {
+ return company;
+ }
+
+ public boolean equals(Object obj) {
+ if (!(obj instanceof NestedTestBean)) {
+ return false;
+ }
+ NestedTestBean ntb = (NestedTestBean) obj;
+ return this.company.equals(ntb.company);
+ }
+
+ public int hashCode() {
+ return this.company.hashCode();
+ }
+
+ public String toString() {
+ return "NestedTestBean: " + this.company;
+ }
+
+}
\ No newline at end of file
diff --git a/org.springframework.aspects/src/test/java/org/springframework/beans/TestBean.java b/org.springframework.aspects/src/test/java/org/springframework/beans/TestBean.java
new file mode 100644
index 0000000000..7842bbfeac
--- /dev/null
+++ b/org.springframework.aspects/src/test/java/org/springframework/beans/TestBean.java
@@ -0,0 +1,437 @@
+/*
+ * Copyright 2002-2008 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.beans;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.BeanFactoryAware;
+import org.springframework.beans.factory.BeanNameAware;
+import org.springframework.util.ObjectUtils;
+
+/**
+ * Simple test bean used for testing bean factories, the AOP framework etc.
+ *
+ * @author Rod Johnson
+ * @author Juergen Hoeller
+ * @since 15 April 2001
+ */
+public class TestBean implements BeanNameAware, BeanFactoryAware, ITestBean, IOther, Comparable {
+
+ private String beanName;
+
+ private String country;
+
+ private BeanFactory beanFactory;
+
+ private boolean postProcessed;
+
+ private String name;
+
+ private String sex;
+
+ private int age;
+
+ private boolean jedi;
+
+ private ITestBean[] spouses;
+
+ private String touchy;
+
+ private String[] stringArray;
+
+ private Integer[] someIntegerArray;
+
+ private Date date = new Date();
+
+ private Float myFloat = new Float(0.0);
+
+ private Collection friends = new LinkedList();
+
+ private Set someSet = new HashSet();
+
+ private Map someMap = new HashMap();
+
+ private List someList = new ArrayList();
+
+ private Properties someProperties = new Properties();
+
+ private INestedTestBean doctor = new NestedTestBean();
+
+ private INestedTestBean lawyer = new NestedTestBean();
+
+ private IndexedTestBean nestedIndexedBean;
+
+ private boolean destroyed;
+
+ private Number someNumber;
+
+ private Colour favouriteColour;
+
+ private Boolean someBoolean;
+
+ private List otherColours;
+
+ private List pets;
+
+
+ public TestBean() {
+ }
+
+ public TestBean(String name) {
+ this.name = name;
+ }
+
+ public TestBean(ITestBean spouse) {
+ this.spouses = new ITestBean[] {spouse};
+ }
+
+ public TestBean(String name, int age) {
+ this.name = name;
+ this.age = age;
+ }
+
+ public TestBean(ITestBean spouse, Properties someProperties) {
+ this.spouses = new ITestBean[] {spouse};
+ this.someProperties = someProperties;
+ }
+
+ public TestBean(List someList) {
+ this.someList = someList;
+ }
+
+ public TestBean(Set someSet) {
+ this.someSet = someSet;
+ }
+
+ public TestBean(Map someMap) {
+ this.someMap = someMap;
+ }
+
+ public TestBean(Properties someProperties) {
+ this.someProperties = someProperties;
+ }
+
+
+ public void setBeanName(String beanName) {
+ this.beanName = beanName;
+ }
+
+ public String getBeanName() {
+ return beanName;
+ }
+
+ public void setBeanFactory(BeanFactory beanFactory) {
+ this.beanFactory = beanFactory;
+ }
+
+ public BeanFactory getBeanFactory() {
+ return beanFactory;
+ }
+
+ public void setPostProcessed(boolean postProcessed) {
+ this.postProcessed = postProcessed;
+ }
+
+ public boolean isPostProcessed() {
+ return postProcessed;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getSex() {
+ return sex;
+ }
+
+ public void setSex(String sex) {
+ this.sex = sex;
+ if (this.name == null) {
+ this.name = sex;
+ }
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public boolean isJedi() {
+ return jedi;
+ }
+
+ public void setJedi(boolean jedi) {
+ this.jedi = jedi;
+ }
+
+ public ITestBean getSpouse() {
+ return (spouses != null ? spouses[0] : null);
+ }
+
+ public void setSpouse(ITestBean spouse) {
+ this.spouses = new ITestBean[] {spouse};
+ }
+
+ public ITestBean[] getSpouses() {
+ return spouses;
+ }
+
+ public String getTouchy() {
+ return touchy;
+ }
+
+ public void setTouchy(String touchy) throws Exception {
+ if (touchy.indexOf('.') != -1) {
+ throw new Exception("Can't contain a .");
+ }
+ if (touchy.indexOf(',') != -1) {
+ throw new NumberFormatException("Number format exception: contains a ,");
+ }
+ this.touchy = touchy;
+ }
+
+ public String getCountry() {
+ return country;
+ }
+
+ public void setCountry(String country) {
+ this.country = country;
+ }
+
+ public String[] getStringArray() {
+ return stringArray;
+ }
+
+ public void setStringArray(String[] stringArray) {
+ this.stringArray = stringArray;
+ }
+
+ public Integer[] getSomeIntegerArray() {
+ return someIntegerArray;
+ }
+
+ public void setSomeIntegerArray(Integer[] someIntegerArray) {
+ this.someIntegerArray = someIntegerArray;
+ }
+
+ public Date getDate() {
+ return date;
+ }
+
+ public void setDate(Date date) {
+ this.date = date;
+ }
+
+ public Float getMyFloat() {
+ return myFloat;
+ }
+
+ public void setMyFloat(Float myFloat) {
+ this.myFloat = myFloat;
+ }
+
+ public Collection getFriends() {
+ return friends;
+ }
+
+ public void setFriends(Collection friends) {
+ this.friends = friends;
+ }
+
+ public Set getSomeSet() {
+ return someSet;
+ }
+
+ public void setSomeSet(Set someSet) {
+ this.someSet = someSet;
+ }
+
+ public Map getSomeMap() {
+ return someMap;
+ }
+
+ public void setSomeMap(Map someMap) {
+ this.someMap = someMap;
+ }
+
+ public List getSomeList() {
+ return someList;
+ }
+
+ public void setSomeList(List someList) {
+ this.someList = someList;
+ }
+
+ public Properties getSomeProperties() {
+ return someProperties;
+ }
+
+ public void setSomeProperties(Properties someProperties) {
+ this.someProperties = someProperties;
+ }
+
+ public INestedTestBean getDoctor() {
+ return doctor;
+ }
+
+ public void setDoctor(INestedTestBean doctor) {
+ this.doctor = doctor;
+ }
+
+ public INestedTestBean getLawyer() {
+ return lawyer;
+ }
+
+ public void setLawyer(INestedTestBean lawyer) {
+ this.lawyer = lawyer;
+ }
+
+ public Number getSomeNumber() {
+ return someNumber;
+ }
+
+ public void setSomeNumber(Number someNumber) {
+ this.someNumber = someNumber;
+ }
+
+ public Colour getFavouriteColour() {
+ return favouriteColour;
+ }
+
+ public void setFavouriteColour(Colour favouriteColour) {
+ this.favouriteColour = favouriteColour;
+ }
+
+ public Boolean getSomeBoolean() {
+ return someBoolean;
+ }
+
+ public void setSomeBoolean(Boolean someBoolean) {
+ this.someBoolean = someBoolean;
+ }
+
+ public IndexedTestBean getNestedIndexedBean() {
+ return nestedIndexedBean;
+ }
+
+ public void setNestedIndexedBean(IndexedTestBean nestedIndexedBean) {
+ this.nestedIndexedBean = nestedIndexedBean;
+ }
+
+ public List getOtherColours() {
+ return otherColours;
+ }
+
+ public void setOtherColours(List otherColours) {
+ this.otherColours = otherColours;
+ }
+
+ public List getPets() {
+ return pets;
+ }
+
+ public void setPets(List pets) {
+ this.pets = pets;
+ }
+
+
+ /**
+ * @see org.springframework.beans.ITestBean#exceptional(Throwable)
+ */
+ public void exceptional(Throwable t) throws Throwable {
+ if (t != null) {
+ throw t;
+ }
+ }
+
+ public void unreliableFileOperation() throws IOException {
+ throw new IOException();
+ }
+ /**
+ * @see org.springframework.beans.ITestBean#returnsThis()
+ */
+ public Object returnsThis() {
+ return this;
+ }
+
+ /**
+ * @see org.springframework.beans.IOther#absquatulate()
+ */
+ public void absquatulate() {
+ }
+
+ public int haveBirthday() {
+ return age++;
+ }
+
+
+ public void destroy() {
+ this.destroyed = true;
+ }
+
+ public boolean wasDestroyed() {
+ return destroyed;
+ }
+
+
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (other == null || !(other instanceof TestBean)) {
+ return false;
+ }
+ TestBean tb2 = (TestBean) other;
+ return (ObjectUtils.nullSafeEquals(this.name, tb2.name) && this.age == tb2.age);
+ }
+
+ public int hashCode() {
+ return this.age;
+ }
+
+ public int compareTo(Object other) {
+ if (this.name != null && other instanceof TestBean) {
+ return this.name.compareTo(((TestBean) other).getName());
+ }
+ else {
+ return 1;
+ }
+ }
+
+ public String toString() {
+ return this.name;
+ }
+
+}
\ No newline at end of file
diff --git a/org.springframework.aspects/src/test/java/org/springframework/beans/factory/aspectj/BeanConfigurerTests.java b/org.springframework.aspects/src/test/java/org/springframework/beans/factory/aspectj/BeanConfigurerTests.java
new file mode 100644
index 0000000000..59c2bc88f6
--- /dev/null
+++ b/org.springframework.aspects/src/test/java/org/springframework/beans/factory/aspectj/BeanConfigurerTests.java
@@ -0,0 +1,622 @@
+/*
+ * Copyright 2002-2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.beans.factory.aspectj;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+
+import junit.framework.TestCase;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+
+import org.springframework.beans.TestBean;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.beans.factory.UnsatisfiedDependencyException;
+import org.springframework.beans.factory.annotation.Autowire;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Configurable;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.mail.MailSender;
+import org.springframework.mail.javamail.JavaMailSenderImpl;
+
+/**
+ * @author Adrian Colyer
+ * @author Rod Johnson
+ * @author Ramnivas Laddad
+ * @author Juergen Hoeller
+ */
+public class BeanConfigurerTests extends TestCase {
+
+ private ClassPathXmlApplicationContext context;
+
+ @Override
+ protected void setUp() throws Exception {
+ this.context =
+ new ClassPathXmlApplicationContext("org/springframework/beans/factory/aspectj/beanConfigurerTests.xml");
+ }
+
+ public void testConfigurableWithExplicitBeanName() {
+ ShouldBeConfiguredBySpring myObject = new ShouldBeConfiguredBySpring();
+ assertEquals("Rod", myObject.getName());
+ }
+
+ public void testInjectionAfterRefresh() {
+ context.refresh();
+ ShouldBeConfiguredBySpring myObject = new ShouldBeConfiguredBySpring();
+ assertEquals("Rod", myObject.getName());
+ }
+
+ public void testWithoutAnnotation() {
+ ShouldNotBeConfiguredBySpring myObject = new ShouldNotBeConfiguredBySpring();
+ assertNull("Name should not have been set", myObject.getName());
+ }
+
+ public void testConfigurableWithImplicitBeanName() {
+ ShouldBeConfiguredBySpringUsingTypeNameAsBeanName myObject =
+ new ShouldBeConfiguredBySpringUsingTypeNameAsBeanName();
+ assertEquals("Rob", myObject.getName());
+ }
+
+ public void testConfigurableUsingAutowireByType() {
+ ShouldBeConfiguredBySpringUsingAutowireByType myObject =
+ new ShouldBeConfiguredBySpringUsingAutowireByType();
+ assertNotNull(myObject.getFriend());
+ assertEquals("Ramnivas", myObject.getFriend().getName());
+ }
+
+ public void testConfigurableUsingAutowireByName() {
+ ValidAutowireByName myObject = new ValidAutowireByName();
+ assertNotNull(myObject.getRamnivas());
+ assertEquals("Ramnivas", myObject.getRamnivas().getName());
+ }
+
+ public void testInvalidAutowireByName() {
+ try {
+ new InvalidAutowireByName();
+ fail("Autowire by name cannot work");
+ }
+ catch (UnsatisfiedDependencyException ex) {
+ // Ok
+ }
+ }
+
+ public void testNewAspectAppliesToArbitraryNonAnnotatedPojo() {
+ ArbitraryExistingPojo aep = new ArbitraryExistingPojo();
+ assertNotNull(aep.friend);
+ assertEquals("Ramnivas", aep.friend.getName());
+ }
+
+ public void testNewAspectThatWasNotAddedToSpringContainer() {
+ try{
+ new ClassThatWillNotActuallyBeWired();
+ }
+ catch (IllegalStateException ex) {
+ assertTrue(ex.getMessage().indexOf("BeanFactory") != -1);
+ }
+ }
+
+ public void testInjectionOnDeserialization() throws Exception {
+ ShouldBeConfiguredBySpring domainObject = new ShouldBeConfiguredBySpring();
+ domainObject.setName("Anonymous");
+ ShouldBeConfiguredBySpring deserializedDomainObject =
+ serializeAndDeserialize(domainObject);
+ assertEquals("Dependency injected on deserialization","Rod",deserializedDomainObject.getName());
+ }
+
+ public void testInjectionOnDeserializationForClassesThatContainsPublicReadResolve() throws Exception {
+ ShouldBeConfiguredBySpringContainsPublicReadResolve domainObject = new ShouldBeConfiguredBySpringContainsPublicReadResolve();
+ domainObject.setName("Anonymous");
+ ShouldBeConfiguredBySpringContainsPublicReadResolve deserializedDomainObject =
+ serializeAndDeserialize(domainObject);
+ assertEquals("Dependency injected on deserialization","Rod",deserializedDomainObject.getName());
+ assertEquals("User readResolve should take precedence", 1, deserializedDomainObject.readResolveInvocationCount);
+ }
+
+ // See ShouldBeConfiguredBySpringContainsPrivateReadResolve
+// public void testInjectionOnDeserializationForClassesThatContainsPrivateReadResolve() throws Exception {
+// ShouldBeConfiguredBySpringContainsPrivateReadResolve domainObject = new ShouldBeConfiguredBySpringContainsPrivateReadResolve();
+// domainObject.setName("Anonymous");
+// ShouldBeConfiguredBySpringContainsPrivateReadResolve deserializedDomainObject =
+// serializeAndDeserialize(domainObject);
+// assertEquals("Dependency injected on deserialization","Rod",deserializedDomainObject.getName());
+// }
+
+ public void testNonInjectionOnDeserializationForSerializedButNotConfigured() throws Exception {
+ SerializableThatShouldNotBeConfiguredBySpring domainObject = new SerializableThatShouldNotBeConfiguredBySpring();
+ domainObject.setName("Anonymous");
+ SerializableThatShouldNotBeConfiguredBySpring deserializedDomainObject =
+ serializeAndDeserialize(domainObject);
+ assertEquals("Dependency injected on deserialization","Anonymous",deserializedDomainObject.getName());
+ }
+
+ public void testSubBeanConfiguredOnlyOnce() throws Exception {
+ SubBean subBean = new SubBean();
+ assertEquals("Property injected more than once", 1, subBean.setterCount);
+ }
+
+ public void testSubBeanConfiguredOnlyOnceForPreConstruction() throws Exception {
+ SubBeanPreConstruction subBean = new SubBeanPreConstruction();
+ assertEquals("Property injected more than once", 1, subBean.setterCount);
+ }
+
+ public void testSubSerializableBeanConfiguredOnlyOnce() throws Exception {
+ SubSerializableBean subBean = new SubSerializableBean();
+ assertEquals("Property injected more than once", 1, subBean.setterCount);
+ subBean.setterCount = 0;
+
+ SubSerializableBean deserializedSubBean = serializeAndDeserialize(subBean);
+ assertEquals("Property injected more than once", 1, deserializedSubBean.setterCount);
+ }
+
+ public void testPreConstructionConfiguredBean() {
+ PreConstructionConfiguredBean bean = new PreConstructionConfiguredBean();
+ assertTrue("Injection didn't occur before construction", bean.preConstructionConfigured);
+ }
+
+ public void testPreConstructionConfiguredBeanDeserializationReinjection() throws Exception {
+ PreConstructionConfiguredBean bean = new PreConstructionConfiguredBean();
+ PreConstructionConfiguredBean deserialized = serializeAndDeserialize(bean);
+ assertEquals("Injection didn't occur upon deserialization", "ramnivas", deserialized.getName());
+ }
+
+ public void testPostConstructionConfiguredBean() {
+ PostConstructionConfiguredBean bean = new PostConstructionConfiguredBean();
+ assertFalse("Injection occurred before construction", bean.preConstructionConfigured);
+ }
+
+ public void testPostConstructionConfiguredBeanDeserializationReinjection() throws Exception {
+ PostConstructionConfiguredBean bean = new PostConstructionConfiguredBean();
+ PostConstructionConfiguredBean deserialized = serializeAndDeserialize(bean);
+ assertEquals("Injection didn't occur upon deserialization", "ramnivas", deserialized.getName());
+ }
+
+ public void testInterfaceDrivenDependencyInjection() {
+ MailClientDependencyInjectionAspect.aspectOf().setMailSender(new JavaMailSenderImpl());
+ Order testOrder = new Order();
+ assertNotNull("Interface driven injection didn't occur for direct construction", testOrder.mailSender);
+ }
+
+ public void testInterfaceDrivenDependencyInjectionMultipleInterfaces() {
+ MailClientDependencyInjectionAspect.aspectOf().setMailSender(new JavaMailSenderImpl());
+ PaymentProcessorDependencyInjectionAspect.aspectOf().setPaymentProcessor(new PaymentProcessor());
+
+ ShoppingCart testCart = new ShoppingCart();
+
+ assertNotNull("Interface driven injection didn't occur for direct construction", testCart.mailSender);
+ assertNotNull("Interface driven injection didn't occur for direct construction", testCart.paymentProcessor);
+ }
+
+ public void testInterfaceDrivenDependencyInjectionUponDeserialization() throws Exception {
+ MailClientDependencyInjectionAspect.aspectOf().setMailSender(new JavaMailSenderImpl());
+ Order testOrder = new Order();
+ Order deserializedOrder = serializeAndDeserialize(testOrder);
+ assertNotNull("Interface driven injection didn't occur for deserialization", testOrder.mailSender);
+ }
+
+ public void testFieldAutoWiredAnnotationInjection() {
+ FieldAutoWiredServiceBean bean = new FieldAutoWiredServiceBean();
+ assertNotNull(bean.testService);
+ }
+
+ public void testMethodAutoWiredAnnotationInjection() {
+ MethodAutoWiredServiceBean bean = new MethodAutoWiredServiceBean();
+ assertNotNull(bean.testService);
+ }
+
+ public void testMultiArgumentMethodAutoWiredAnnotationInjection() {
+ MultiArgumentMethodAutoWiredServiceBean bean = new MultiArgumentMethodAutoWiredServiceBean();
+ assertNotNull(bean.testService);
+ assertNotNull(bean.paymentService);
+ }
+
+ public void testGenericParameterConfigurableBean() {
+ GenericParameterConfigurableBean bean = new GenericParameterConfigurableBean();
+ assertNotNull(bean.testService);
+ }
+
+ @SuppressWarnings("unchecked")
+ private T serializeAndDeserialize(T serializable) throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ oos.writeObject(serializable);
+ oos.close();
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ ObjectInputStream ois = new ObjectInputStream(bais);
+ return (T)ois.readObject();
+ }
+
+
+ @Configurable("beanOne")
+ private static class ShouldBeConfiguredBySpring implements Serializable {
+
+ private String name;
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+ }
+
+
+ @Configurable("beanOne")
+ private static class ShouldBeConfiguredBySpringContainsPublicReadResolve implements Serializable {
+
+ private String name;
+
+ private int readResolveInvocationCount = 0;
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public Object readResolve() throws ObjectStreamException {
+ readResolveInvocationCount++;
+ return this;
+ }
+ }
+
+
+// Won't work until we use hasmethod() experimental pointcut in AspectJ.
+// @Configurable("beanOne")
+// private static class ShouldBeConfiguredBySpringContainsPrivateReadResolve implements Serializable {
+//
+// private String name;
+//
+// public void setName(String name) {
+// this.name = name;
+// }
+//
+// public String getName() {
+// return this.name;
+// }
+//
+// private Object readResolve() throws ObjectStreamException {
+// return this;
+// }
+// }
+
+
+ private static class ShouldNotBeConfiguredBySpring {
+
+ private String name;
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+ }
+
+
+ private static class SerializableThatShouldNotBeConfiguredBySpring implements Serializable {
+
+ private String name;
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+ }
+
+
+ @Configurable
+ private static class ShouldBeConfiguredBySpringUsingTypeNameAsBeanName {
+
+ private String name;
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+ }
+
+
+ @Configurable(autowire=Autowire.BY_TYPE)
+ private static class ShouldBeConfiguredBySpringUsingAutowireByType {
+
+ private TestBean friend = null;
+
+ public TestBean getFriend() {
+ return friend;
+ }
+
+ public void setFriend(TestBean friend) {
+ this.friend = friend;
+ }
+ }
+
+
+ @Configurable(autowire=Autowire.BY_NAME)
+ private static class ValidAutowireByName {
+
+ private TestBean friend = null;
+
+ public TestBean getRamnivas() {
+ return friend;
+ }
+
+ public void setRamnivas(TestBean friend) {
+ this.friend = friend;
+ }
+ }
+
+
+ @Configurable(autowire=Autowire.BY_NAME, dependencyCheck=true)
+ private static class InvalidAutowireByName {
+
+ private TestBean friend;
+
+ public TestBean getFriend() {
+ return friend;
+ }
+
+ public void setFriend(TestBean friend) {
+ this.friend = friend;
+ }
+ }
+
+
+ private static class ArbitraryExistingPojo {
+
+ private TestBean friend;
+
+ public void setFriend(TestBean f) {
+ this.friend = f;
+ }
+ }
+
+
+ public static class CircularFactoryBean implements FactoryBean{
+
+ public CircularFactoryBean() {
+// ValidAutowireByName autowired = new ValidAutowireByName();
+// assertNull(autowired.getRamnivas());
+ }
+
+ public Object getObject() throws Exception {
+ return new TestBean();
+ }
+
+ public Class getObjectType() {
+ return TestBean.class;
+ }
+
+ public boolean isSingleton() {
+ return false;
+ }
+ }
+
+
+ @Configurable
+ private static class BaseBean {
+
+ public int setterCount;
+
+ private String name;
+
+ public void setName(String name) {
+ this.name = name;
+ setterCount++;
+ }
+ }
+
+
+ private static class SubBean extends BaseBean {
+ }
+
+ @Configurable(preConstruction=true)
+ private static class SubBeanPreConstruction extends BaseBean {
+ }
+
+ @Configurable
+ private static class BaseSerializableBean implements Serializable {
+
+ public int setterCount;
+
+ private String name;
+
+ public void setName(String name) {
+ this.name = name;
+ setterCount++;
+ }
+ }
+
+
+ private static class SubSerializableBean extends BaseSerializableBean {
+ }
+
+
+ @Aspect
+ private static class WireArbitraryExistingPojo extends AbstractBeanConfigurerAspect {
+
+ @Pointcut("initialization(ArbitraryExistingPojo.new(..)) && this(beanInstance)")
+ protected void beanCreation(Object beanInstance){
+
+ }
+ }
+
+
+ @Aspect
+ private static class AspectThatWillNotBeUsed extends AbstractBeanConfigurerAspect {
+
+ @Pointcut("initialization(ClassThatWillNotActuallyBeWired.new(..)) && this(beanInstance)")
+ protected void beanCreation(Object beanInstance){
+ }
+ }
+
+ private static aspect MailClientDependencyInjectionAspect extends AbstractInterfaceDrivenDependencyInjectionAspect {
+ private MailSender mailSender;
+
+ public pointcut inConfigurableBean() : within(MailSenderClient+);
+
+ public void configureBean(Object bean) {
+ ((MailSenderClient)bean).setMailSender(this.mailSender);
+ }
+
+ declare parents: MailSenderClient implements ConfigurableObject;
+
+ public void setMailSender(MailSender mailSender) {
+ this.mailSender = mailSender;
+ }
+ }
+
+ private static aspect PaymentProcessorDependencyInjectionAspect extends AbstractInterfaceDrivenDependencyInjectionAspect {
+ private PaymentProcessor paymentProcessor;
+
+ public pointcut inConfigurableBean() : within(PaymentProcessorClient+);
+
+ public void configureBean(Object bean) {
+ ((PaymentProcessorClient)bean).setPaymentProcessor(this.paymentProcessor);
+ }
+
+ declare parents: PaymentProcessorClient implements ConfigurableObject;
+
+ public void setPaymentProcessor(PaymentProcessor paymentProcessor) {
+ this.paymentProcessor = paymentProcessor;
+ }
+ }
+
+ public static interface MailSenderClient {
+ public void setMailSender(MailSender mailSender);
+ }
+
+ public static interface PaymentProcessorClient {
+ public void setPaymentProcessor(PaymentProcessor paymentProcessor);
+ }
+
+ public static class PaymentProcessor {
+
+ }
+
+ public static class Order implements MailSenderClient, Serializable {
+ private transient MailSender mailSender;
+
+ public void setMailSender(MailSender mailSender) {
+ this.mailSender = mailSender;
+ }
+ }
+
+ public static class ShoppingCart implements MailSenderClient, PaymentProcessorClient {
+ private transient MailSender mailSender;
+ private transient PaymentProcessor paymentProcessor;
+
+ public void setMailSender(MailSender mailSender) {
+ this.mailSender = mailSender;
+ }
+
+ public void setPaymentProcessor(PaymentProcessor paymentProcessor) {
+ this.paymentProcessor = paymentProcessor;
+ }
+ }
+
+ private static class ClassThatWillNotActuallyBeWired {
+
+ }
+
+ @Configurable
+ private static class PreOrPostConstructionConfiguredBean implements Serializable {
+ private transient String name;
+ protected transient boolean preConstructionConfigured;
+ transient int count;
+
+ public PreOrPostConstructionConfiguredBean() {
+ preConstructionConfigured = (this.name != null);
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+ }
+
+
+ @Configurable(preConstruction=true)
+ public static class PreConstructionConfiguredBean extends PreOrPostConstructionConfiguredBean {
+ }
+
+
+ @Configurable(preConstruction=false)
+ private static class PostConstructionConfiguredBean extends PreOrPostConstructionConfiguredBean {
+ }
+
+ @Configurable
+ public static class FieldAutoWiredServiceBean {
+ @Autowired transient private TestService testService;
+ }
+
+ @Configurable
+ public static class MethodAutoWiredServiceBean {
+ transient private TestService testService;
+
+ @Autowired
+ public void setTestService(TestService testService) {
+ this.testService = testService;
+ }
+ }
+
+ @Configurable
+ public static class MultiArgumentMethodAutoWiredServiceBean {
+ transient private TestService testService;
+ transient private PaymentService paymentService;
+
+ @Autowired
+ public void setDependencies(TestService testService, PaymentService paymentService) {
+ this.testService = testService;
+ this.paymentService = paymentService;
+ }
+ }
+
+ @Configurable
+ public static class GenericParameterConfigurableBean {
+ private TestService testService;
+
+ public void setTestService(TestService testService) {
+ this.testService = testService;
+ }
+ }
+
+ public static class TestService {
+
+ }
+
+ public static class PaymentService {
+
+ }
+
+}
diff --git a/org.springframework.aspects/src/test/java/org/springframework/beans/factory/aspectj/SpringConfiguredWithAutoProxyingTests.java b/org.springframework.aspects/src/test/java/org/springframework/beans/factory/aspectj/SpringConfiguredWithAutoProxyingTests.java
new file mode 100644
index 0000000000..aa8aef07a1
--- /dev/null
+++ b/org.springframework.aspects/src/test/java/org/springframework/beans/factory/aspectj/SpringConfiguredWithAutoProxyingTests.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2002-2006 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.beans.factory.aspectj;
+
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+import junit.framework.TestCase;
+
+public class SpringConfiguredWithAutoProxyingTests extends TestCase {
+
+ @Override
+ protected void setUp() throws Exception {
+ new ClassPathXmlApplicationContext("org/springframework/beans/factory/aspectj/springConfigured.xml");
+ }
+
+ public void testSpringConfiguredAndAutoProxyUsedTogether() {
+ ; // set up is sufficient to trigger failure if this is going to fail...
+ }
+}
\ No newline at end of file
diff --git a/org.springframework.aspects/src/test/java/org/springframework/beans/factory/aspectj/beanConfigurerTests.xml b/org.springframework.aspects/src/test/java/org/springframework/beans/factory/aspectj/beanConfigurerTests.xml
new file mode 100644
index 0000000000..8dc971af52
--- /dev/null
+++ b/org.springframework.aspects/src/test/java/org/springframework/beans/factory/aspectj/beanConfigurerTests.xml
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/org.springframework.aspects/src/test/java/org/springframework/beans/factory/aspectj/springConfigured.xml b/org.springframework.aspects/src/test/java/org/springframework/beans/factory/aspectj/springConfigured.xml
new file mode 100644
index 0000000000..1ee36a11da
--- /dev/null
+++ b/org.springframework.aspects/src/test/java/org/springframework/beans/factory/aspectj/springConfigured.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
diff --git a/org.springframework.aspects/src/test/java/org/springframework/transaction/CallCountingTransactionManager.java b/org.springframework.aspects/src/test/java/org/springframework/transaction/CallCountingTransactionManager.java
new file mode 100644
index 0000000000..d5c2531fbd
--- /dev/null
+++ b/org.springframework.aspects/src/test/java/org/springframework/transaction/CallCountingTransactionManager.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2002-2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.transaction;
+
+import org.springframework.transaction.support.AbstractPlatformTransactionManager;
+import org.springframework.transaction.support.DefaultTransactionStatus;
+
+/**
+ * @author Rod Johnson
+ * @author Juergen Hoeller
+ */
+public class CallCountingTransactionManager extends AbstractPlatformTransactionManager {
+
+ public TransactionDefinition lastDefinition;
+ public int begun;
+ public int commits;
+ public int rollbacks;
+ public int inflight;
+
+ protected Object doGetTransaction() {
+ return new Object();
+ }
+
+ protected void doBegin(Object transaction, TransactionDefinition definition) {
+ this.lastDefinition = definition;
+ ++begun;
+ ++inflight;
+ }
+
+ protected void doCommit(DefaultTransactionStatus status) {
+ ++commits;
+ --inflight;
+ }
+
+ protected void doRollback(DefaultTransactionStatus status) {
+ ++rollbacks;
+ --inflight;
+ }
+
+ public void clear() {
+ begun = commits = rollbacks = inflight = 0;
+ }
+
+}
diff --git a/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/ClassWithPrivateAnnotatedMember.java b/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/ClassWithPrivateAnnotatedMember.java
new file mode 100644
index 0000000000..899e0feb67
--- /dev/null
+++ b/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/ClassWithPrivateAnnotatedMember.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2002-2006 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Created on 11 Sep 2006 by Adrian Colyer
+ */
+package org.springframework.transaction.aspectj;
+
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * @author Adrian Colyer
+ * @since 2.0
+ */
+public class ClassWithPrivateAnnotatedMember {
+
+ public void doSomething() {
+ doInTransaction();
+ }
+
+ @Transactional
+ private void doInTransaction() {}
+}
diff --git a/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/ClassWithProtectedAnnotatedMember.java b/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/ClassWithProtectedAnnotatedMember.java
new file mode 100644
index 0000000000..a4cb30c50f
--- /dev/null
+++ b/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/ClassWithProtectedAnnotatedMember.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2002-2006 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Created on 11 Sep 2006 by Adrian Colyer
+ */
+package org.springframework.transaction.aspectj;
+
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * @author Adrian Colyer
+ * @since 2.0
+ */
+public class ClassWithProtectedAnnotatedMember {
+
+ public void doSomething() {
+ doInTransaction();
+ }
+
+ @Transactional
+ protected void doInTransaction() {}
+}
diff --git a/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/ITransactional.java b/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/ITransactional.java
new file mode 100644
index 0000000000..48670fbf6a
--- /dev/null
+++ b/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/ITransactional.java
@@ -0,0 +1,10 @@
+package org.springframework.transaction.aspectj;
+
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public interface ITransactional {
+
+ Object echo(Throwable t) throws Throwable;
+
+}
diff --git a/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/MethodAnnotationOnClassWithNoInterface.java b/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/MethodAnnotationOnClassWithNoInterface.java
new file mode 100644
index 0000000000..29b9b311b7
--- /dev/null
+++ b/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/MethodAnnotationOnClassWithNoInterface.java
@@ -0,0 +1,19 @@
+package org.springframework.transaction.aspectj;
+
+import org.springframework.transaction.annotation.Transactional;
+
+public class MethodAnnotationOnClassWithNoInterface {
+
+ @Transactional(rollbackFor=InterruptedException.class)
+ public Object echo(Throwable t) throws Throwable {
+ if (t != null) {
+ throw t;
+ }
+ return t;
+ }
+
+ public void noTransactionAttribute() {
+
+ }
+
+}
diff --git a/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/TransactionAspectTests-context.xml b/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/TransactionAspectTests-context.xml
new file mode 100644
index 0000000000..02ea3f7799
--- /dev/null
+++ b/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/TransactionAspectTests-context.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/TransactionAspectTests.java b/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/TransactionAspectTests.java
new file mode 100644
index 0000000000..39fedc70b3
--- /dev/null
+++ b/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/TransactionAspectTests.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright 2002-2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.transaction.aspectj;
+
+import java.lang.reflect.Method;
+
+import junit.framework.AssertionFailedError;
+
+import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
+import org.springframework.transaction.CallCountingTransactionManager;
+import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
+import org.springframework.transaction.interceptor.TransactionAttribute;
+
+/**
+ * @author Rod Johnson
+ * @author Ramnivas Laddad
+ */
+public class TransactionAspectTests extends AbstractDependencyInjectionSpringContextTests {
+
+ private TransactionAspectSupport transactionAspect;
+
+ private CallCountingTransactionManager txManager;
+
+ private TransactionalAnnotationOnlyOnClassWithNoInterface annotationOnlyOnClassWithNoInterface;
+
+ private ClassWithProtectedAnnotatedMember beanWithAnnotatedProtectedMethod;
+
+ private ClassWithPrivateAnnotatedMember beanWithAnnotatedPrivateMethod;
+
+ private MethodAnnotationOnClassWithNoInterface methodAnnotationOnly = new MethodAnnotationOnClassWithNoInterface();
+
+
+ public void setAnnotationOnlyOnClassWithNoInterface(
+ TransactionalAnnotationOnlyOnClassWithNoInterface annotationOnlyOnClassWithNoInterface) {
+ this.annotationOnlyOnClassWithNoInterface = annotationOnlyOnClassWithNoInterface;
+ }
+
+ public void setClassWithAnnotatedProtectedMethod(ClassWithProtectedAnnotatedMember aBean) {
+ this.beanWithAnnotatedProtectedMethod = aBean;
+ }
+
+ public void setClassWithAnnotatedPrivateMethod(ClassWithPrivateAnnotatedMember aBean) {
+ this.beanWithAnnotatedPrivateMethod = aBean;
+ }
+
+ public void setTransactionAspect(TransactionAspectSupport transactionAspect) {
+ this.transactionAspect = transactionAspect;
+ this.txManager = (CallCountingTransactionManager) transactionAspect.getTransactionManager();
+ }
+
+ public TransactionAspectSupport getTransactionAspect() {
+ return this.transactionAspect;
+ }
+
+ @Override
+ protected String getConfigPath() {
+ return "TransactionAspectTests-context.xml";
+ }
+
+
+ public void testCommitOnAnnotatedClass() throws Throwable {
+ txManager.clear();
+ assertEquals(0, txManager.begun);
+ annotationOnlyOnClassWithNoInterface.echo(null);
+ assertEquals(1, txManager.commits);
+ }
+
+ public void testCommitOnAnnotatedProtectedMethod() throws Throwable {
+ txManager.clear();
+ assertEquals(0, txManager.begun);
+ beanWithAnnotatedProtectedMethod.doInTransaction();
+ assertEquals(1, txManager.commits);
+ }
+
+ public void testCommitOnAnnotatedPrivateMethod() throws Throwable {
+ txManager.clear();
+ assertEquals(0, txManager.begun);
+ beanWithAnnotatedPrivateMethod.doSomething();
+ assertEquals(1, txManager.commits);
+ }
+
+ public void testNoCommitOnNonAnnotatedNonPublicMethodInTransactionalType() throws Throwable {
+ txManager.clear();
+ assertEquals(0,txManager.begun);
+ annotationOnlyOnClassWithNoInterface.nonTransactionalMethod();
+ assertEquals(0,txManager.begun);
+ }
+
+ public void testCommitOnAnnotatedMethod() throws Throwable {
+ txManager.clear();
+ assertEquals(0, txManager.begun);
+ methodAnnotationOnly.echo(null);
+ assertEquals(1, txManager.commits);
+ }
+
+
+ public static class NotTransactional {
+ public void noop() {
+ }
+ }
+
+ public void testNotTransactional() throws Throwable {
+ txManager.clear();
+ assertEquals(0, txManager.begun);
+ new NotTransactional().noop();
+ assertEquals(0, txManager.begun);
+ }
+
+
+ public void testDefaultCommitOnAnnotatedClass() throws Throwable {
+ testRollback(new TransactionOperationCallback() {
+ public Object performTransactionalOperation() throws Throwable {
+ return annotationOnlyOnClassWithNoInterface.echo(new Exception());
+ }
+ }, false);
+ }
+
+ public void testDefaultRollbackOnAnnotatedClass() throws Throwable {
+ testRollback(new TransactionOperationCallback() {
+ public Object performTransactionalOperation() throws Throwable {
+ return annotationOnlyOnClassWithNoInterface.echo(new RuntimeException());
+ }
+ }, true);
+ }
+
+
+ public static class SubclassOfClassWithTransactionalAnnotation extends TransactionalAnnotationOnlyOnClassWithNoInterface {
+ }
+
+ public void testDefaultCommitOnSubclassOfAnnotatedClass() throws Throwable {
+ testRollback(new TransactionOperationCallback() {
+ public Object performTransactionalOperation() throws Throwable {
+ return new SubclassOfClassWithTransactionalAnnotation().echo(new Exception());
+ }
+ }, false);
+ }
+
+ public static class SubclassOfClassWithTransactionalMethodAnnotation extends MethodAnnotationOnClassWithNoInterface {
+ }
+
+ public void testDefaultCommitOnSubclassOfClassWithTransactionalMethodAnnotated() throws Throwable {
+ testRollback(new TransactionOperationCallback() {
+ public Object performTransactionalOperation() throws Throwable {
+ return new SubclassOfClassWithTransactionalMethodAnnotation().echo(new Exception());
+ }
+ }, false);
+ }
+
+ public static class ImplementsAnnotatedInterface implements ITransactional {
+ public Object echo(Throwable t) throws Throwable {
+ if (t != null) {
+ throw t;
+ }
+ return t;
+ }
+ }
+
+ public void testDefaultCommitOnImplementationOfAnnotatedInterface() throws Throwable {
+// testRollback(new TransactionOperationCallback() {
+// public Object performTransactionalOperation() throws Throwable {
+// return new ImplementsAnnotatedInterface().echo(new Exception());
+// }
+// }, false);
+
+ final Exception ex = new Exception();
+ testNotTransactional(new TransactionOperationCallback() {
+ public Object performTransactionalOperation() throws Throwable {
+ return new ImplementsAnnotatedInterface().echo(ex);
+ }
+ }, ex);
+ }
+
+ /**
+ * Note: resolution does not occur. Thus we can't make a class transactional if
+ * it implements a transactionally annotated interface. This behaviour could only
+ * be changed in AbstractFallbackTransactionAttributeSource in Spring proper.
+ * @throws SecurityException
+ * @throws NoSuchMethodException
+ */
+ public void testDoesNotResolveTxAnnotationOnMethodFromClassImplementingAnnotatedInterface() throws SecurityException, NoSuchMethodException {
+ AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource();
+ Method m = ImplementsAnnotatedInterface.class.getMethod("echo", Throwable.class);
+ TransactionAttribute ta = atas.getTransactionAttribute(m, ImplementsAnnotatedInterface.class);
+ assertNull(ta);
+ }
+
+
+ public void testDefaultRollbackOnImplementationOfAnnotatedInterface() throws Throwable {
+// testRollback(new TransactionOperationCallback() {
+// public Object performTransactionalOperation() throws Throwable {
+// return new ImplementsAnnotatedInterface().echo(new RuntimeException());
+// }
+// }, true);
+
+ final Exception rollbackProvokingException = new RuntimeException();
+ testNotTransactional(new TransactionOperationCallback() {
+ public Object performTransactionalOperation() throws Throwable {
+ return new ImplementsAnnotatedInterface().echo(rollbackProvokingException);
+ }
+ }, rollbackProvokingException);
+ }
+
+
+ protected void testRollback(TransactionOperationCallback toc, boolean rollback) throws Throwable {
+ txManager.clear();
+ assertEquals(0, txManager.begun);
+ try {
+ toc.performTransactionalOperation();
+ assertEquals(1, txManager.commits);
+ }
+ catch (Throwable caught) {
+ if (caught instanceof AssertionFailedError) {
+ return;
+ }
+ }
+
+ if (rollback) {
+ assertEquals(1, txManager.rollbacks);
+ }
+ assertEquals(1, txManager.begun);
+ }
+
+ protected void testNotTransactional(TransactionOperationCallback toc, Throwable expected) throws Throwable {
+ txManager.clear();
+ assertEquals(0, txManager.begun);
+ try {
+ toc.performTransactionalOperation();
+ }
+ catch (Throwable t) {
+ if (expected == null) {
+ fail("Expected " + expected);
+ }
+ assertSame(expected, t);
+ }
+ finally {
+ assertEquals(0, txManager.begun);
+ }
+ }
+
+
+ private interface TransactionOperationCallback {
+
+ Object performTransactionalOperation() throws Throwable;
+ }
+
+}
diff --git a/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/TransactionalAnnotationOnlyOnClassWithNoInterface.java b/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/TransactionalAnnotationOnlyOnClassWithNoInterface.java
new file mode 100644
index 0000000000..a111f57241
--- /dev/null
+++ b/org.springframework.aspects/src/test/java/org/springframework/transaction/aspectj/TransactionalAnnotationOnlyOnClassWithNoInterface.java
@@ -0,0 +1,20 @@
+package org.springframework.transaction.aspectj;
+
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class TransactionalAnnotationOnlyOnClassWithNoInterface {
+
+ public Object echo(Throwable t) throws Throwable {
+ if (t != null) {
+ throw t;
+ }
+ return t;
+ }
+
+ void nonTransactionalMethod() {
+ // no-op
+ }
+
+}
+