diff --git a/build.gradle b/build.gradle index 70362231..fe529ff7 100644 --- a/build.gradle +++ b/build.gradle @@ -4,9 +4,9 @@ buildscript { maven { url "http://repo.springsource.org/plugins-snapshot" } } dependencies { - classpath("org.springframework.build.gradle:propdeps-plugin:0.0.3") - classpath("org.springframework.build.gradle:docbook-reference-plugin:0.2.4") - classpath("me.champeau.gradle:gradle-javadoc-hotfix-plugin:0.1-SNAPSHOT") + classpath("org.springframework.build.gradle:propdeps-plugin:0.0.5") + classpath("org.springframework.build.gradle:docbook-reference-plugin:0.2.8") + classpath("me.champeau.gradle:gradle-javadoc-hotfix-plugin:0.1") } } @@ -18,12 +18,13 @@ configure(allprojects) { } configure(subprojects) { subproject -> + apply plugin: "java" apply plugin: "propdeps" apply from: "${rootProject.projectDir}/publish-maven.gradle" - sourceCompatibility=1.5 - targetCompatibility=1.5 + sourceCompatibility=1.6 + targetCompatibility=1.6 [compileJava, compileTestJava]*.options*.compilerArgs = ["-Xlint:none"] @@ -31,6 +32,7 @@ configure(subprojects) { subproject -> repositories { maven { url "http://repo.springsource.org/libs-release" } + maven { url "http://repo.springsource.org/libs-snapshot" } } jar { @@ -54,7 +56,7 @@ configure(subprojects.findAll {it.name != "spring-js-resources"}) { subproject - } subproject.ext { - springVersion = "3.2.1.RELEASE" + springVersion = "4.0.0.RELEASE" springSecurityVersion = "3.1.3.RELEASE" slf4jVersion = "1.6.1" log4jVersion = "1.2.15" @@ -124,7 +126,7 @@ project("spring-js") { dependencies { compile(project(":spring-js-resources")) compile("commons-logging:commons-logging:1.1.1") - provided("javax.servlet:servlet-api:2.5") + provided("javax.servlet:javax.servlet-api:3.0.1") optional("org.apache.tiles:tiles-api:2.1.2") optional("org.apache.tiles:tiles-core:2.1.2") optional("org.apache.tiles:tiles-jsp:2.1.2") @@ -153,13 +155,12 @@ project("spring-webflow") { compile(project(":spring-js")) compile("commons-logging:commons-logging:1.1.1") provided("javax.el:el-api:2.2") - provided("javax.persistence:persistence-api:1.0.2") - provided("javax.servlet:servlet-api:2.5") + provided("org.eclipse.persistence:javax.persistence:2.0.0") + provided("javax.servlet:javax.servlet-api:3.0.1") provided("javax.portlet:portlet-api:2.0") - provided("javax.transaction:transaction-api:1.1-rev-1") provided("junit:junit:3.8.2") compile("opensymphony:ognl:2.6.11") - optional("org.hibernate:hibernate:3.2.7.ga") { + optional("org.hibernate:hibernate-core:3.6.9.Final") { exclude group: "org.slf4j", module: "slf4j-api" } optional("org.slf4j:slf4j-api:$slf4jVersion") @@ -174,10 +175,9 @@ project("spring-webflow") { optional("org.springframework:spring-webmvc-portlet:$springVersion") optional("org.springframework.security:spring-security-core:$springSecurityVersion") testCompile("javax.validation:validation-api:1.0.0.GA") - testCompile("org.apache.openjpa:openjpa:1.1.0") - testCompile("org.apache.openjpa:openjpa-lib:1.1.0") - testCompile("org.apache.openjpa:openjpa-persistence:1.1.0") - testCompile("org.apache.openjpa:openjpa-persistence-jdbc:1.1.0") + testCompile("org.hibernate:hibernate-core:3.6.9.Final") + testCompile("org.hibernate:hibernate-entitymanager:3.6.9.Final") + testCompile("org.hibernate:hibernate-validator:4.3.0.Final") testCompile("org.apache.tomcat:tomcat-jasper-el:7.0.27") testCompile("org.hsqldb:hsqldb:2.2.8") testCompile("org.springframework:spring-aop:$springVersion") @@ -193,7 +193,7 @@ project("spring-faces") { compile(project(":spring-binding")) compile(project(":spring-webflow")) compile("commons-logging:commons-logging:1.1.1") - provided("javax.servlet:servlet-api:2.5") + provided("javax.servlet:javax.servlet-api:3.0.1") provided("javax.portlet:portlet-api:2.0") provided("javax.el:el-api:2.2") compile("org.springframework:spring-beans:$springVersion") @@ -365,7 +365,7 @@ configure(rootProject) { task wrapper(type: Wrapper) { description = "Generates gradlew[.bat] scripts" - gradleVersion = "1.3" + gradleVersion = "1.9" doLast() { def gradleOpts = "-XX:MaxPermSize=1024m -Xmx1024m" diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7b359d71..b6b646b0 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 6a51a7aa..6268a026 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Nov 28 08:28:15 PST 2012 +#Wed Dec 18 15:25:00 EST 2013 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=http\://services.gradle.org/distributions/gradle-1.3-bin.zip +distributionUrl=http\://services.gradle.org/distributions/gradle-1.9-bin.zip diff --git a/gradlew b/gradlew index 9e5a6688..a1787c62 100755 --- a/gradlew +++ b/gradlew @@ -62,9 +62,9 @@ while [ -h "$PRG" ] ; do fi done SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" +cd "`dirname \"$PRG\"`/" >&- APP_HOME="`pwd -P`" -cd "$SAVED" +cd "$SAVED" >&- CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar diff --git a/spring-binding/src/main/java/org/springframework/binding/collection/AbstractCachingMapDecorator.java b/spring-binding/src/main/java/org/springframework/binding/collection/AbstractCachingMapDecorator.java new file mode 100644 index 00000000..c03f2b22 --- /dev/null +++ b/spring-binding/src/main/java/org/springframework/binding/collection/AbstractCachingMapDecorator.java @@ -0,0 +1,295 @@ +package org.springframework.binding.collection; + +import java.io.Serializable; +import java.lang.ref.Reference; +import java.lang.ref.WeakReference; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.Map; +import java.util.Set; +import java.util.WeakHashMap; + +import org.springframework.util.Assert; + +/** + * A simple decorator for a Map, encapsulating the workflow for caching + * expensive values in a target Map. Supports caching weak or strong keys. + *

+ * This class is an abstract template. Caching Map implementations should + * subclass and override the create(key) method which encapsulates + * expensive creation of a new object. + * + * @author Keith Donald + * @author Juergen Hoeller + * @since 2.4 + */ +@SuppressWarnings("serial") +public abstract class AbstractCachingMapDecorator implements Map, Serializable { + + private static Object NULL_VALUE = new Object(); + + + private final Map targetMap; + + private final boolean synchronize; + + private final boolean weak; + + + /** + * Create a CachingMapDecorator with strong keys, + * using an underlying synchronized Map. + */ + public AbstractCachingMapDecorator() { + this(false); + } + + /** + * Create a CachingMapDecorator, + * using an underlying synchronized Map. + * @param weak whether to use weak references for keys and values + */ + public AbstractCachingMapDecorator(boolean weak) { + Map internalMap = (weak ? new WeakHashMap() : new HashMap()); + this.targetMap = Collections.synchronizedMap(internalMap); + this.synchronize = true; + this.weak = weak; + } + + /** + * Create a CachingMapDecorator with initial size, + * using an underlying synchronized Map. + * @param weak whether to use weak references for keys and values + * @param size the initial cache size + */ + public AbstractCachingMapDecorator(boolean weak, int size) { + Map internalMap = weak ? new WeakHashMap (size) : new HashMap(size); + this.targetMap = Collections.synchronizedMap(internalMap); + this.synchronize = true; + this.weak = weak; + } + + /** + * Create a CachingMapDecorator for the given Map. + *

The passed-in Map won't get synchronized explicitly, + * so make sure to pass in a properly synchronized Map, if desired. + * @param targetMap the Map to decorate + */ + public AbstractCachingMapDecorator(Map targetMap) { + this(targetMap, false, false); + } + + /** + * Create a CachingMapDecorator for the given Map. + *

The passed-in Map won't get synchronized explicitly unless + * you specify "synchronize" as "true". + * @param targetMap the Map to decorate + * @param synchronize whether to synchronize on the given Map + * @param weak whether to use weak references for values + */ + @SuppressWarnings("unchecked") + public AbstractCachingMapDecorator(Map targetMap, boolean synchronize, boolean weak) { + Assert.notNull(targetMap, "'targetMap' must not be null"); + this.targetMap = (Map) (synchronize ? Collections.synchronizedMap(targetMap) : targetMap); + this.synchronize = synchronize; + this.weak = weak; + } + + + public int size() { + return this.targetMap.size(); + } + + public boolean isEmpty() { + return this.targetMap.isEmpty(); + } + + public boolean containsKey(Object key) { + return this.targetMap.containsKey(key); + } + + public boolean containsValue(Object value) { + Object valueToCheck = (value != null ? value : NULL_VALUE); + if (this.synchronize) { + synchronized (this.targetMap) { + return containsValueOrReference(valueToCheck); + } + } + else { + return containsValueOrReference(valueToCheck); + } + } + + private boolean containsValueOrReference(Object value) { + if (this.targetMap.containsValue(value)) { + return true; + } + for (Object mapVal : this.targetMap.values()) { + if (mapVal instanceof Reference && value.equals(((Reference) mapVal).get())) { + return true; + } + } + return false; + } + + public V remove(Object key) { + return unwrapReturnValue(this.targetMap.remove(key)); + } + + @SuppressWarnings("unchecked") + private V unwrapReturnValue(Object value) { + Object returnValue = value; + if (returnValue instanceof Reference) { + returnValue = ((Reference) returnValue).get(); + } + return (returnValue == NULL_VALUE ? null : (V) returnValue); + } + + public void putAll(Map map) { + this.targetMap.putAll(map); + } + + public void clear() { + this.targetMap.clear(); + } + + public Set keySet() { + if (this.synchronize) { + synchronized (this.targetMap) { + return new LinkedHashSet(this.targetMap.keySet()); + } + } + else { + return new LinkedHashSet(this.targetMap.keySet()); + } + } + + public Collection values() { + if (this.synchronize) { + synchronized (this.targetMap) { + return valuesCopy(); + } + } + else { + return valuesCopy(); + } + } + + @SuppressWarnings("unchecked") + private Collection valuesCopy() { + LinkedList values = new LinkedList(); + for (Iterator it = this.targetMap.values().iterator(); it.hasNext();) { + Object value = it.next(); + if (value instanceof Reference) { + value = ((Reference) value).get(); + if (value == null) { + it.remove(); + continue; + } + } + values.add(value == NULL_VALUE ? null : (V) value); + } + return values; + } + + public Set> entrySet() { + if (this.synchronize) { + synchronized (this.targetMap) { + return entryCopy(); + } + } + else { + return entryCopy(); + } + } + + @SuppressWarnings("unchecked") + private Set> entryCopy() { + Map entries = new LinkedHashMap(); + for (Iterator> it = this.targetMap.entrySet().iterator(); it.hasNext();) { + Entry entry = it.next(); + Object value = entry.getValue(); + if (value instanceof Reference) { + value = ((Reference) value).get(); + if (value == null) { + it.remove(); + continue; + } + } + entries.put(entry.getKey(), value == NULL_VALUE ? null : (V) value); + } + return entries.entrySet(); + } + + + /** + * Put an object into the cache, possibly wrapping it with a weak + * reference. + * @see #useWeakValue(Object, Object) + */ + public V put(K key, V value) { + Object newValue = value; + if (value == null) { + newValue = NULL_VALUE; + } + else if (useWeakValue(key, value)) { + newValue = new WeakReference(newValue); + } + return unwrapReturnValue(this.targetMap.put(key, newValue)); + } + + /** + * Decide whether to use a weak reference for the value of + * the given key-value pair. + * @param key the candidate key + * @param value the candidate value + * @return true in order to use a weak reference; + * false otherwise. + */ + protected boolean useWeakValue(K key, V value) { + return this.weak; + } + + /** + * Get value for key. + * Creates and caches value if it doesn't already exist in the cache. + *

This implementation is not synchronized: This is highly + * concurrent but does not guarantee unique instances in the cache, + * as multiple values for the same key could get created in parallel. + * Consider overriding this method to synchronize it, if desired. + * @see #create(Object) + */ + @SuppressWarnings("unchecked") + public V get(Object key) { + Object value = this.targetMap.get(key); + if (value instanceof Reference) { + value = ((Reference) value).get(); + } + if (value == null) { + V newValue = create((K) key); + put((K) key, newValue); + return newValue; + } + return (value == NULL_VALUE ? null : (V) value); + } + + /** + * Create a value to cache for the given key. + * Called by get if there is no value cached already. + * @param key the cache key + * @see #get(Object) + */ + protected abstract V create(K key); + + + @Override + public String toString() { + return "CachingMapDecorator [" + getClass().getName() + "]:" + this.targetMap; + } + +} \ No newline at end of file diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/converters/StringToLabeledEnum.java b/spring-binding/src/main/java/org/springframework/binding/convert/converters/StringToLabeledEnum.java deleted file mode 100644 index a8fdbe99..00000000 --- a/spring-binding/src/main/java/org/springframework/binding/convert/converters/StringToLabeledEnum.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2004-2012 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.binding.convert.converters; - -import org.springframework.core.enums.LabeledEnum; -import org.springframework.core.enums.LabeledEnumResolver; -import org.springframework.core.enums.StaticLabeledEnumResolver; - -/** - * Converts from a textual representation to a {@link LabeledEnum}. The text should be the enum's label. - * - * @author Keith Donald - */ -@Deprecated -public class StringToLabeledEnum extends StringToObject { - - private LabeledEnumResolver labeledEnumResolver = StaticLabeledEnumResolver.instance(); - - public StringToLabeledEnum() { - super(LabeledEnum.class); - } - - protected Object toObject(String string, Class targetClass) throws Exception { - return labeledEnumResolver.getLabeledEnumByLabel(targetClass, string); - } - - protected String toString(Object object) throws Exception { - LabeledEnum labeledEnum = (LabeledEnum) object; - return labeledEnum.getLabel(); - } - -} diff --git a/spring-binding/src/main/java/org/springframework/binding/message/DefaultMessageContext.java b/spring-binding/src/main/java/org/springframework/binding/message/DefaultMessageContext.java index c1961cd3..c2f745b5 100644 --- a/spring-binding/src/main/java/org/springframework/binding/message/DefaultMessageContext.java +++ b/spring-binding/src/main/java/org/springframework/binding/message/DefaultMessageContext.java @@ -25,16 +25,16 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.binding.collection.AbstractCachingMapDecorator; import org.springframework.context.MessageSource; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.context.support.AbstractMessageSource; import org.springframework.core.style.ToStringCreator; -import org.springframework.util.CachingMapDecorator; /** * The default message context implementation. Uses a {@link MessageSource} to resolve messages that are added by * callers. - * + * * @author Keith Donald */ public class DefaultMessageContext implements StateManageableMessageContext { @@ -43,8 +43,10 @@ public class DefaultMessageContext implements StateManageableMessageContext { private MessageSource messageSource; - private Map> sourceMessages = new CachingMapDecorator>( + @SuppressWarnings("serial") + private Map> sourceMessages = new AbstractCachingMapDecorator>( new LinkedHashMap>()) { + protected List create(Object source) { return new ArrayList(); } diff --git a/spring-binding/src/main/java/org/springframework/binding/method/MethodInvoker.java b/spring-binding/src/main/java/org/springframework/binding/method/MethodInvoker.java index b626d28d..bae965ca 100644 --- a/spring-binding/src/main/java/org/springframework/binding/method/MethodInvoker.java +++ b/spring-binding/src/main/java/org/springframework/binding/method/MethodInvoker.java @@ -1,12 +1,12 @@ /* * Copyright 2004-2012 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. @@ -20,15 +20,15 @@ import java.lang.reflect.Method; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.binding.collection.AbstractCachingMapDecorator; import org.springframework.binding.convert.ConversionService; import org.springframework.binding.convert.service.DefaultConversionService; import org.springframework.core.style.StylerUtils; -import org.springframework.util.CachingMapDecorator; /** * A helper for invoking typed methods on arbitrary objects, with support for argument value type conversion from values * retrieved from an argument attribute source, and conversion of the result to a desired type. - * + * * @author Keith Donald * @author Jeremy Grelle */ @@ -44,7 +44,8 @@ public class MethodInvoker { /** * A cache of invoked bean methods, keyed weakly. */ - private CachingMapDecorator methodCache = new CachingMapDecorator(true) { + @SuppressWarnings("serial") + private AbstractCachingMapDecorator methodCache = new AbstractCachingMapDecorator(true) { public Method create(MethodKey key) { return key.getMethod(); } @@ -105,7 +106,7 @@ public class MethodInvoker { /** * Apply type conversion on the supplied value - * + * * @param value the raw value to be converted * @param targetType the target type for the conversion * @return the converted result diff --git a/spring-webflow/src/main/java/org/springframework/webflow/action/DispatchMethodInvoker.java b/spring-webflow/src/main/java/org/springframework/webflow/action/DispatchMethodInvoker.java index a00f48d2..6ae1dd87 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/action/DispatchMethodInvoker.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/action/DispatchMethodInvoker.java @@ -19,15 +19,15 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Map; +import org.springframework.binding.collection.AbstractCachingMapDecorator; import org.springframework.binding.method.InvalidMethodKeyException; import org.springframework.binding.method.MethodKey; import org.springframework.util.Assert; -import org.springframework.util.CachingMapDecorator; /** * Invoker and cache for dispatch methods that all share the same target object. The dispatch methods typically share * the same form, but multiple exist per target object, and they only differ in name. - * + * * @author Keith Donald * @author Ben Hale */ @@ -46,7 +46,8 @@ class DispatchMethodInvoker { /** * The resolved method cache. */ - private Map methodCache = new CachingMapDecorator() { + @SuppressWarnings("serial") + private Map methodCache = new AbstractCachingMapDecorator() { public Method create(String key) { String methodName = key; try { diff --git a/spring-webflow/src/main/java/org/springframework/webflow/action/ResultObjectBasedEventFactory.java b/spring-webflow/src/main/java/org/springframework/webflow/action/ResultObjectBasedEventFactory.java index c7ac2e45..c3b0113c 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/action/ResultObjectBasedEventFactory.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/action/ResultObjectBasedEventFactory.java @@ -15,7 +15,6 @@ */ package org.springframework.webflow.action; -import org.springframework.core.enums.LabeledEnum; import org.springframework.util.StringUtils; import org.springframework.webflow.execution.Event; import org.springframework.webflow.execution.RequestContext; @@ -61,7 +60,7 @@ import org.springframework.webflow.execution.RequestContext; *   * * - * + * * @author Keith Donald * @author Erwin Vervaet */ @@ -74,9 +73,6 @@ public class ResultObjectBasedEventFactory extends EventFactorySupport implement return event(source, getNullEventId()); } else if (isBoolean(resultObject.getClass())) { return event(source, ((Boolean) resultObject)); - } else if (isLabeledEnum(resultObject.getClass())) { - String resultId = ((LabeledEnum) resultObject).getLabel(); - return event(source, resultId, getResultAttributeName(), resultObject); } else if (isEnum(resultObject.getClass())) { String eventId = EnumUtils.getEnumName(resultObject); return event(source, eventId, getResultAttributeName(), resultObject); @@ -100,7 +96,7 @@ public class ResultObjectBasedEventFactory extends EventFactorySupport implement * Check whether or not given type is mapped to a corresponding event using special mapping rules. */ public boolean isMappedValueType(Class type) { - return isBoolean(type) || isLabeledEnum(type) || isEnum(type) || isString(type) || isEvent(type); + return isBoolean(type) || isEnum(type) || isString(type) || isEvent(type); } // internal helpers to determine the 'type' of a class @@ -109,10 +105,6 @@ public class ResultObjectBasedEventFactory extends EventFactorySupport implement return Boolean.class.equals(type) || boolean.class.equals(type); } - private boolean isLabeledEnum(Class type) { - return LabeledEnum.class.isAssignableFrom(type); - } - private boolean isEnum(Class type) { return EnumUtils.isEnum(type); } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/context/servlet/HttpSessionMap.java b/spring-webflow/src/main/java/org/springframework/webflow/context/servlet/HttpSessionMap.java index 3678057c..303b3bd8 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/context/servlet/HttpSessionMap.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/context/servlet/HttpSessionMap.java @@ -29,7 +29,7 @@ import org.springframework.webflow.core.collection.CollectionUtils; /** * A Shared Map backed by the Servlet HTTP session, for accessing session scoped attributes. - * + * * @author Keith Donald */ public class HttpSessionMap extends StringKeyedMapAdapter implements SharedMap { @@ -87,11 +87,10 @@ public class HttpSessionMap extends StringKeyedMapAdapter implements Sha } } - @SuppressWarnings("unchecked") protected Iterator getAttributeNames() { HttpSession session = getSession(); - return session == null ? CollectionUtils.emptyIterator() : CollectionUtils.toIterator(session - .getAttributeNames()); + return (session == null) ? + CollectionUtils.emptyIterator() : CollectionUtils.toIterator(session.getAttributeNames()); } public Object getMutex() { diff --git a/spring-webflow/src/test/java/org/springframework/webflow/persistence/JpaFlowExecutionListenerTests.java b/spring-webflow/src/test/java/org/springframework/webflow/persistence/JpaFlowExecutionListenerTests.java index ffefccf0..1adf8c5c 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/persistence/JpaFlowExecutionListenerTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/persistence/JpaFlowExecutionListenerTests.java @@ -1,5 +1,6 @@ package org.springframework.webflow.persistence; +import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; @@ -10,9 +11,10 @@ import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.jdbc.datasource.init.DataSourceInitializer; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; -import org.springframework.orm.jpa.JpaTemplate; +import org.springframework.orm.jpa.EntityManagerFactoryUtils; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter; import org.springframework.transaction.support.TransactionSynchronizationManager; import org.springframework.webflow.engine.EndState; @@ -29,8 +31,6 @@ public class JpaFlowExecutionListenerTests extends TestCase { private JdbcTemplate jdbcTemplate; - private JpaTemplate jpaTemplate; - public void testTemp() { } @@ -42,7 +42,6 @@ public class JpaFlowExecutionListenerTests extends TestCase { entityManagerFactory = getEntityManagerFactory(dataSource); JpaTransactionManager tm = new JpaTransactionManager(entityManagerFactory); jpaListener = new JpaFlowExecutionListener(entityManagerFactory, tm); - jpaTemplate = new JpaTemplate(entityManagerFactory); } public void testFlowNotAPersistenceContext() { @@ -62,7 +61,8 @@ public class JpaFlowExecutionListenerTests extends TestCase { assertSessionBound(); TestBean bean = new TestBean(1, "Keith Donald"); - jpaTemplate.persist(bean); + EntityManager em = EntityManagerFactoryUtils.getTransactionalEntityManager(entityManagerFactory); + em.persist(bean); assertEquals("Table should still only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN")); EndState endState = new EndState(flowSession.getDefinitionInternal(), "success"); @@ -85,14 +85,16 @@ public class JpaFlowExecutionListenerTests extends TestCase { assertSessionBound(); TestBean bean1 = new TestBean(1, "Keith Donald"); - jpaTemplate.persist(bean1); + EntityManager em = EntityManagerFactoryUtils.getTransactionalEntityManager(entityManagerFactory); + em.persist(bean1); assertEquals("Table should still only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN")); jpaListener.paused(context); assertSessionNotBound(); jpaListener.resuming(context); TestBean bean2 = new TestBean(2, "Keith Donald"); - jpaTemplate.persist(bean2); + em = EntityManagerFactoryUtils.getTransactionalEntityManager(entityManagerFactory); + em.persist(bean2); assertEquals("Table should still only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN")); assertSessionBound(); @@ -117,7 +119,8 @@ public class JpaFlowExecutionListenerTests extends TestCase { assertSessionBound(); TestBean bean = new TestBean(1, "Keith Donald"); - jpaTemplate.persist(bean); + EntityManager em = EntityManagerFactoryUtils.getTransactionalEntityManager(entityManagerFactory); + em.persist(bean); assertEquals("Table should still only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN")); EndState endState = new EndState(flowSession.getDefinitionInternal(), "cancel"); @@ -158,7 +161,8 @@ public class JpaFlowExecutionListenerTests extends TestCase { assertSessionBound(); TestBean bean = new TestBean(1, "Keith Donald"); - jpaTemplate.persist(bean); + EntityManager em = EntityManagerFactoryUtils.getTransactionalEntityManager(entityManagerFactory); + em.persist(bean); assertEquals("Table should still only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN")); jpaListener.exceptionThrown(context, new FlowExecutionException("bla", "bla", "bla")); assertEquals("Table should still only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN")); @@ -198,8 +202,7 @@ public class JpaFlowExecutionListenerTests extends TestCase { LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); factory.setDataSource(dataSource); factory.setPersistenceXmlLocation("classpath:org/springframework/webflow/persistence/persistence.xml"); - OpenJpaVendorAdapter openJpa = new OpenJpaVendorAdapter(); - factory.setJpaVendorAdapter(openJpa); + factory.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); factory.afterPropertiesSet(); return factory.getObject(); } diff --git a/spring-webflow/src/test/java/org/springframework/webflow/persistence/JpaFlowManagedPersistenceIntegrationTests.java b/spring-webflow/src/test/java/org/springframework/webflow/persistence/JpaFlowManagedPersistenceIntegrationTests.java index 33631b53..14e1b6a5 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/persistence/JpaFlowManagedPersistenceIntegrationTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/persistence/JpaFlowManagedPersistenceIntegrationTests.java @@ -6,7 +6,7 @@ import javax.sql.DataSource; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; -import org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.support.TransactionSynchronizationManager; import org.springframework.webflow.execution.Action; import org.springframework.webflow.execution.Event; @@ -31,7 +31,7 @@ public class JpaFlowManagedPersistenceIntegrationTests extends AbstractFlowManag public Event execute(RequestContext context) throws Exception { assertSessionBound(); EntityManager em = (EntityManager) context.getFlowScope().get("persistenceContext"); - TestBean bean = (TestBean) em.getReference(TestBean.class, 0); + TestBean bean = (TestBean) em.getReference(TestBean.class, new Long(0)); bean.incrementCount(); assertNotNull(bean); return new Event(this, "success"); @@ -46,7 +46,7 @@ public class JpaFlowManagedPersistenceIntegrationTests extends AbstractFlowManag public void execute(RequestContext context, int expected) throws Exception { assertSessionBound(); EntityManager em = (EntityManager) context.getFlowScope().get("persistenceContext"); - TestBean bean = (TestBean) em.getReference(TestBean.class, 0); + TestBean bean = (TestBean) em.getReference(TestBean.class, new Long(0)); assertEquals(expected, bean.getCount()); } }; @@ -63,8 +63,7 @@ public class JpaFlowManagedPersistenceIntegrationTests extends AbstractFlowManag LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); factory.setDataSource(dataSource); factory.setPersistenceXmlLocation("classpath:org/springframework/webflow/persistence/persistence.xml"); - OpenJpaVendorAdapter openJpa = new OpenJpaVendorAdapter(); - factory.setJpaVendorAdapter(openJpa); + factory.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); factory.afterPropertiesSet(); return factory.getObject(); } diff --git a/spring-webflow/src/test/java/org/springframework/webflow/persistence/JpaPersistenceContextPropagationTests.java b/spring-webflow/src/test/java/org/springframework/webflow/persistence/JpaPersistenceContextPropagationTests.java index 48359817..80864682 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/persistence/JpaPersistenceContextPropagationTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/persistence/JpaPersistenceContextPropagationTests.java @@ -1,12 +1,13 @@ package org.springframework.webflow.persistence; +import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; -import org.springframework.orm.jpa.JpaTemplate; +import org.springframework.orm.jpa.EntityManagerFactoryUtils; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; -import org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.support.TransactionSynchronizationManager; import org.springframework.webflow.execution.FlowExecutionListener; @@ -17,8 +18,6 @@ public class JpaPersistenceContextPropagationTests extends AbstractPersistenceCo private JpaFlowExecutionListener executionListener; - private JpaTemplate jpaTemplate; - private int rowCount; @Override @@ -26,7 +25,6 @@ public class JpaPersistenceContextPropagationTests extends AbstractPersistenceCo entityManagerFactory = getEntityManagerFactory(dataSource); JpaTransactionManager tm = new JpaTransactionManager(entityManagerFactory); executionListener = new JpaFlowExecutionListener(entityManagerFactory, tm); - jpaTemplate = new JpaTemplate(entityManagerFactory); rowCount = 1; } @@ -48,7 +46,8 @@ public class JpaPersistenceContextPropagationTests extends AbstractPersistenceCo @Override protected void assertCommitState(boolean insertRow, boolean isCommited) { if (insertRow) { - jpaTemplate.persist(new TestBean(rowCount++, "Keith Donald")); + EntityManager em = EntityManagerFactoryUtils.getTransactionalEntityManager(entityManagerFactory); + em.persist(new TestBean(rowCount++, "Keith Donald")); } if (!isCommited) { assertEquals("Nothing should be committed yet", 1, @@ -63,8 +62,7 @@ public class JpaPersistenceContextPropagationTests extends AbstractPersistenceCo LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); factory.setDataSource(dataSource); factory.setPersistenceXmlLocation("classpath:org/springframework/webflow/persistence/persistence.xml"); - OpenJpaVendorAdapter openJpa = new OpenJpaVendorAdapter(); - factory.setJpaVendorAdapter(openJpa); + factory.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); factory.afterPropertiesSet(); return factory.getObject(); } diff --git a/spring-webflow/src/test/java/org/springframework/webflow/persistence/TestBean.java b/spring-webflow/src/test/java/org/springframework/webflow/persistence/TestBean.java index 9bed1a86..d4205259 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/persistence/TestBean.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/persistence/TestBean.java @@ -69,6 +69,10 @@ public class TestBean { return count; } + public void setCount(int count) { + this.count = count; + } + public void incrementCount() { this.count++; }