Compare commits

..
Author SHA1 Message Date
Costin Leau 4cf2504fb4 + backport template fix from trunk (rev 3014)
+ change pom version to 3.0.1.RELEASE-A (instead of RELEASE.A)
2010-02-19 11:36:31 +00:00
Arjen Poutsma 677b0b54fc Updated poms 2010-02-19 09:21:04 +00:00
Arjen Poutsma 697baa477f Creating 3.0.1.RELEASE.A branch 2010-02-19 09:13:33 +00:00
Arjen Poutsma c20c4e1f05 spring-framework 3.0.1.RELEASE 2010-02-18 17:56:59 +00:00
Arjen Poutsma 61382e7779 Tag for 3.0.1 2010-02-18 11:31:36 +00:00
491 changed files with 5128 additions and 15146 deletions
-5
View File
@@ -1,5 +0,0 @@
target
integration-repo
ivy-cache
spring-build
jmx.log
+1 -101
View File
@@ -3,106 +3,6 @@ SPRING FRAMEWORK CHANGELOG
http://www.springsource.org
Changes in version 3.0.3 (2010-06-15)
-------------------------------------
* Spring autodetects JodaTime 1.3 or higher (as required), ignoring older JodaTime versions
* clarified that Spring's Jackson support requires Jackson 1.3 or higher
* JPA 2.0 support tested and supported with Hibernate 3.5.2 and OpenJPA 2.0.0 GA as well
* revised VFS support for Spring's component scanning to work on JBoss AS 6.0.0 M3 as well
* fixed URIEditor's URI construction to consider fragment as well
* added default InputSourceEditor for SAX InputSource construction with a URL String as system id
* CachedIntrospectionResults only caches GenericTypeAwarePropertyDescriptors if fully safe
* revised BeanWrapper's exception wrapping to consistently handle ConversionExceptions
* DefaultListableBeanFactory checks for alias circle on registerAlias (avoiding endless loop)
* ConversionService is able to apply Converters to interface-based array elements
* ConversionService fully supports conversion from String to MediaType now (through 'valueOf')
* revised exception handling in ObjectToObjectConverter, avoiding InvocationTargetExceptions
* a context ConversionService is able to override an ApplicationContext's resource editors
* refined LifecycleProcessor exception handling, properly wrapping a start exception from a bean
* revised DefaultLifecycleProcessor's handling of circular dependencies to avoid stack overflow
* fixed constructor argument caching for prototypes with multiple constructor matches
* specific detection of CGLIB subclasses in order to properly handle CGLIB interfaces
* registerDependentBean resolves to the canonical bean name in order to handle alias references
* fixed registerResolvableDependency mechanism to correctly handle non-serializable factory objects
* added "expose-proxy" attribute to aop namespace (enforcing AopContext proxy exposure with CGLIB)
* revised AbstractInterceptorDrivenBeanDefinitionDecorator for further alignment with auto-proxying
* BeanDefinitionVisitor/PropertyPlaceholderConfigurer finds and resolves values in arrays as well
* property placeholders can deal with nested expressions which happen to use the same suffix
* SpEL's Elvis operator is able to deal with #{${myProp}?:defaultValue} case if myProp is empty
* introduced EmbeddedValueResolverAware callback interface for convenient placeholder resolution
* @Transactional qualifier value matches against @Qualifier annotations on @Bean methods as well
* setTransactionIsolation on JDBC Connection only called when actually necessary (for PostgreSQL)
* added limit for parsed SQL cache to NamedParameterJdbcTemplate (default is 256; configurable)
* CachingConnectionFactory detects destination equality for WebSphere MQ as well (using toString)
* DefaultPersistenceUnitManager's getPersistenceUnitInfo method has 2.5 compatible signature again
* DefaultMessageListenerContainer reacts to maxConcurrentConsumers reduction for long-lived tasks
* added "idleConsumerLimit" bean property to DefaultMessageListenerContainer (default is 1)
* AsyncAnnotationBeanPostProcessor consistently adds @Async processing as first Advisor in the chain
* ScheduledTaskRegistrar (as used for @Scheduled processing) properly shuts down its default executor
* CronTrigger defensively protects itself against accidental re-fires if a task runs too early
* MailSendException includes all messages as failed messages in case of a connect failure
* added support for JAX-WS 2.1 WebServiceFeatures to JaxWsPortClientInterceptor/PortProxyFactoryBean
* added XmlAwareFormHttpMessageConverter, taking over the 3.0.2-introduced XML multipart support
* ServletContextResourcePatternResolver handles "/WEB-INF/lib/*.jar!/**/context.xml" style patterns
* fixed MVC mapping regression for servlet url-pattern "/" case on servers other than WebSphere
* MVC mappings properly apply even to welcome file entries that forward to a DispatcherServlet
* fixed @ExceptionHandler resolution in case of multiple matches at different inheritance levels
* revised Portlet SessionStatus.setComplete() to avoid re-exposure of attributes in render phase
* shortened Portlet MVC's implicit model render parameter name to "implicitModel"
* added convenient "checkRefresh" bean property to TilesConfigurer
* TilesConfigurer's "definitionsFactoryClass" property applies common Tiles DefinitionsFactory setup
* JSP FormTag calculates proper default form action even when using a rewrite filter on WebSphere
* JSP HiddenInputTag allows for using common HTML attributes (equivalent to LabelTag)
* fixed JSP ErrorsTag to avoid invalid "*.errors" id, using form object name as id prefix instead
* fixed JSP SelectTag's support for rendering enum constants
* JSP Radiobutton/CheckboxesTag utilizes PropertyEditor/ConversionService for label rendering
* MockHttpServletResponse supports multiple includes
Changes in version 3.0.2 (2010-04-02)
-------------------------------------
* fixed cross-module version ranges in OSGi manifests
* fixed contents of org.springframework.web.struts jar
* upgraded to Hibernate Validator 4.0.2 and Jackson 1.4.2
* compatibility with Hibernate 3.5 final (native and also as a JPA 2.0 provider)
* compatibility with OpenJPA 2.0 (support for JPA 2.0 persistence.xml versioning)
* compatibility with Hessian 4.0 (in terms of exception propagation)
* compatibility with JasperReports 3.x (in terms of resource management)
* restored full compatibility with Servlet 2.4 containers on all VMs
* PropertyEditor lookup fallback works on Google App Engine as well
* fixed TypeDescriptor/MethodParameter toString for all cases in debug log messages
* widened AbstractFactoryBean's "getObjectType" signature to return any Class as well
* BeanPostProcessors are allowed to return a null bean value in the middle of the chain
* autowire="byType" ignores parameter name when choosing a primary bean, as defined
* ObjectFactoryCreatingFactoryBean creates a serializable ObjectFactory reference
* added ProviderCreatingFactoryBean, exposing a serializable JSR-330 Provider reference
* "conversionService" bean will be ignored if it is not of type ConversionService
* revised AbstractInterceptorDrivenBeanDefinitionDecorator for alignment with auto-proxying
* SimpleJdbcCall's "returningResultSet" accepts any plain RowMapper now
* added public "validateDatabaseSchema" method to Hibernate LocalSessionFactoryBean
* HibernateJpaDialect borrows JDBC Connection on demand (supporting aggressive release)
* JCA listener containers delegate to wrapped Transaction handle (for Geronimo compatibility)
* @Transactional qualifiers work in unit tests as well (TransactionalTestExecutionListener)
* @Value processing works in test instances (using the test context framework) as well now
* @DirtiesContext is now inherited for class-level usage
* NativeWebRequest detects native MultipartRequest when decorated by HiddenHttpMethodFilter
* WebRequestInterceptor exposes HttpServletResponse through NativeWebRequest (after downcast)
* WebContentInterceptor does not restrict HTTP methods by default anymore
* WebApplicationObjectSupport's initServletContext will be called only once in any scenario
* DispatcherPortlet passes handler instance into HandlerExceptionResolver for action exception
* DispatcherPortlet applies preHandleRender callbacks in case of action exception as well
* UrlPathHelper cuts off trailing servlet-path slashes for root mappings (on WebSphere)
* introduced support for HttpEntity and ResponseEntity wrappers, adding context to body values
* fixed DataBinder's conversion error handling for direct field access with ConversionService
* @InitBinder methods support all applicable Spring 3.0 parameter annotations as well
* fixed @RequestParam(required=false) regression for @InitBinder methods
* @ExceptionHandler methods consistently receive original exception
* fixed indexed property binding regression in form tag library
* fixed @Configurable issue with null bean name
Changes in version 3.0.1 (2010-02-18)
-------------------------------------
@@ -112,7 +12,7 @@ Changes in version 3.0.1 (2010-02-18)
* support for Hibernate 3.5 (as native Hibernate API and as JPA 2.0 provider)
* support for Tiles 2.2.1 (preserving compatibility with Tiles 2.1.2 and above)
* consistent treatment of unresolvable placeholders for Resource and Resource array properties
* ConversionFailedException exDLBFposes offending value through public "getValue()" method
* ConversionFailedException exposes offending value through public "getValue()" method
* fixed BeanFactory's "getBeansWithAnnotation" to ignore beans with non-determinable type
* widened FactoryBean's "getObjectType" signature to return any Class (Class<?>)
* do not ever consider Object as a candidate type for autowiring by type (autowire="byType")
+2 -2
View File
@@ -1,5 +1,5 @@
SPRING FRAMEWORK 3.0.3 (June 2010)
----------------------------------
SPRING FRAMEWORK 3.0.1 (February 2010)
------------------------------------
http://www.springframework.org
1. INTRODUCTION
+6 -6
View File
@@ -1,12 +1,12 @@
version=3.0.3
# DON'T forget to update spring-context manifest (Import-Package jpa entry)
version=3.0.1
release.type=release
build.stamp=RELEASE-A
# osgi ranges
spring.osgi.range.nq=${version:[=.=.=, =.=.+1)}
spring.osgi.range="${spring.osgi.range.nq}"
spring.osgi.range="${version:[=.=.=, =.=.+1)}"
aj.osgi.range="[1.5.4, 2.0.0)"
#
release.type=release
build.stamp=RELEASE
natural.name=spring-framework
project.name=Spring Framework
project.key=SPR
+20 -21
View File
@@ -1,22 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="src" path="src/main/resources"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="var" path="IVY_CACHE/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-1.0.0.jar" sourcepath="/IVY_CACHE/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-sources-1.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-1.1.1.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-sources-1.1.1.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.easymock/com.springsource.org.easymock/2.5.1/com.springsource.org.easymock-2.5.1.jar" sourcepath="/IVY_CACHE/org.easymock/com.springsource.org.easymock/2.5.1/com.springsource.org.easymock-sources-2.5.1.jar"/>
<classpathentry kind="var" path="IVY_CACHE/com.jamonapi/com.springsource.com.jamonapi/2.4.0/com.springsource.com.jamonapi-2.4.0.jar" sourcepath="/IVY_CACHE/com.jamonapi/com.springsource.com.jamonapi/2.4.0/com.springsource.com.jamonapi-sources-2.4.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/net.sourceforge.cglib/com.springsource.net.sf.cglib/2.2.0/com.springsource.net.sf.cglib-2.2.0.jar" sourcepath="/IVY_CACHE/net.sourceforge.cglib/com.springsource.net.sf.cglib/2.1.3/com.springsource.net.sf.cglib-sources-2.1.3.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.log4j/com.springsource.org.apache.log4j/1.2.15/com.springsource.org.apache.log4j-1.2.15.jar" sourcepath="/IVY_CACHE/org.apache.log4j/com.springsource.org.apache.log4j/1.2.15/com.springsource.org.apache.log4j-sources-1.2.15.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-4.7.0.jar" sourcepath="/IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-sources-4.7.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.pool/1.3.0/com.springsource.org.apache.commons.pool-1.3.0.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.pool/1.3.0/com.springsource.org.apache.commons.pool-sources-1.3.0.jar"/>
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="src" path="src/main/resources"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="var" path="IVY_CACHE/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-1.0.0.jar" sourcepath="/IVY_CACHE/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-sources-1.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-1.1.1.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-sources-1.1.1.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.easymock/com.springsource.org.easymock/2.5.1/com.springsource.org.easymock-2.5.1.jar" sourcepath="/IVY_CACHE/org.easymock/com.springsource.org.easymock/2.5.1/com.springsource.org.easymock-sources-2.5.1.jar"/>
<classpathentry kind="var" path="IVY_CACHE/com.jamonapi/com.springsource.com.jamonapi/2.4.0/com.springsource.com.jamonapi-2.4.0.jar" sourcepath="/IVY_CACHE/com.jamonapi/com.springsource.com.jamonapi/2.4.0/com.springsource.com.jamonapi-sources-2.4.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/net.sourceforge.cglib/com.springsource.net.sf.cglib/2.2.0/com.springsource.net.sf.cglib-2.2.0.jar" sourcepath="/IVY_CACHE/net.sourceforge.cglib/com.springsource.net.sf.cglib/2.1.3/com.springsource.net.sf.cglib-sources-2.1.3.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.log4j/com.springsource.org.apache.log4j/1.2.15/com.springsource.org.apache.log4j-1.2.15.jar" sourcepath="/IVY_CACHE/org.apache.log4j/com.springsource.org.apache.log4j/1.2.15/com.springsource.org.apache.log4j-sources-1.2.15.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-4.7.0.jar" sourcepath="/IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-sources-4.7.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.pool/1.3.0/com.springsource.org.apache.commons.pool-1.3.0.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.pool/1.3.0/com.springsource.org.apache.commons.pool-sources-1.3.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.aspectj/com.springsource.org.aspectj.weaver/1.6.8.RELEASE/com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar" sourcepath="IVY_CACHE/org.aspectj/com.springsource.org.aspectj.weaver/1.6.8.RELEASE/com.springsource.org.aspectj.weaver-sources-1.6.8.RELEASE.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.beans"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.core"/>
<classpathentry kind="lib" path="/org.springframework.asm/target/artifacts/org.springframework.asm.jar" sourcepath="/org.springframework.asm/target/artifacts/org.springframework.asm-sources.jar"/>
<classpathentry kind="var" path="IVY_CACHE"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.beans"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.core"/>
<classpathentry kind="lib" path="/org.springframework.asm/target/artifacts/org.springframework.asm.jar" sourcepath="/org.springframework.asm/target/artifacts/org.springframework.asm-sources.jar"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
+2 -2
View File
@@ -4,12 +4,12 @@
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<packaging>jar</packaging>
<version>3.0.3.RELEASE</version>
<version>3.0.1.RELEASE-A</version>
<parent>
<groupId>org.springframework</groupId>
<artifactId>spring-parent</artifactId>
<relativePath>../org.springframework.spring-parent</relativePath>
<version>3.0.3.RELEASE</version>
<version>3.0.1.RELEASE-A</version>
</parent>
<dependencies>
@@ -34,6 +34,6 @@ public interface TargetClassAware {
* (typically a proxy configuration or an actual proxy).
* @return the target Class, or <code>null</code> if not known
*/
Class<?> getTargetClass();
Class getTargetClass();
}
@@ -1,5 +1,5 @@
/*<
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -39,7 +39,7 @@ public interface TargetSource extends TargetClassAware {
* target class.
* @return the type of targets returned by this {@link TargetSource}
*/
Class<?> getTargetClass();
Class getTargetClass();
/**
* Will all calls to {@link #getTarget()} return the same object?
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -18,7 +18,6 @@ package org.springframework.aop.aspectj;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
@@ -140,7 +139,9 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
private boolean argumentsIntrospected = false;
private Type discoveredReturningGenericType;
// The actual type is java.lang.reflect.Type,
// but for JDK 1.4 compatibility we use Object as the static type.
private Object discoveredReturningGenericType;
// Note: Unlike return type, no such generic information is needed for the throwing type,
// since Java doesn't allow exception types to be parameterized.
@@ -294,7 +295,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
return this.discoveredReturningType;
}
protected Type getDiscoveredReturningGenericType() {
protected Object getDiscoveredReturningGenericType() {
return this.discoveredReturningGenericType;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -69,11 +69,21 @@ public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice implement
*/
private boolean shouldInvokeOnReturnValueOf(Method method, Object returnValue) {
Class type = getDiscoveredReturningType();
Type genericType = getDiscoveredReturningGenericType();
Object genericType = getDiscoveredReturningGenericType();
// If we aren't dealing with a raw type, check if generic parameters are assignable.
return (ClassUtils.isAssignableValue(type, returnValue) &&
(genericType == null || genericType == type ||
TypeUtils.isAssignable(genericType, method.getGenericReturnType())));
(genericType == null || genericType == type || GenericTypeMatcher.isAssignable(genericType, method)));
}
/**
* Inner class to avoid a static JDK 1.5 dependency for generic type matching.
*/
private static class GenericTypeMatcher {
public static boolean isAssignable(Object genericType, Method method) {
return TypeUtils.isAssignable((Type) genericType, method.getGenericReturnType());
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -73,7 +73,7 @@ class RuntimeTestWalker {
catch (IllegalAccessException illegalAccessEx) {
// Famous last words... but I don't see how this can happen given the
// makeAccessible call above
throw new IllegalStateException("Unable to access ShadowMatchImpl.residualTest field");
throw new IllegalStateException("Unable to access ShadowMatchImpl.runtimeTest field.");
}
}
@@ -83,18 +83,15 @@ class RuntimeTestWalker {
* then it tests subtype sensitive vars.
*/
public boolean testsSubtypeSensitiveVars() {
return (this.runtimeTest != null &&
new SubtypeSensitiveVarTypeTestVisitor().testsSubtypeSensitiveVars(this.runtimeTest));
return new SubtypeSensitiveVarTypeTestVisitor().testsSubtypeSensitiveVars(this.runtimeTest);
}
public boolean testThisInstanceOfResidue(Class thisClass) {
return (this.runtimeTest != null &&
new ThisInstanceOfResidueTestVisitor(thisClass).thisInstanceOfMatches(this.runtimeTest));
return new ThisInstanceOfResidueTestVisitor(thisClass).thisInstanceOfMatches(this.runtimeTest);
}
public boolean testTargetInstanceOfResidue(Class targetClass) {
return (this.runtimeTest != null &&
new TargetInstanceOfResidueTestVisitor(targetClass).targetInstanceOfMatches(this.runtimeTest));
return new TargetInstanceOfResidueTestVisitor(targetClass).targetInstanceOfMatches(this.runtimeTest);
}
@@ -142,7 +139,8 @@ class RuntimeTestWalker {
try {
Field varTypeField = ReflectionVar.class.getDeclaredField("varType");
ReflectionUtils.makeAccessible(varTypeField);
return (Integer) varTypeField.get(v);
Integer varTypeValue = (Integer) varTypeField.get(v);
return varTypeValue.intValue();
}
catch (NoSuchFieldException noSuchFieldEx) {
throw new IllegalStateException("the version of aspectjtools.jar / aspectjweaver.jar " +
@@ -152,7 +150,7 @@ class RuntimeTestWalker {
catch (IllegalAccessException illegalAccessEx) {
// Famous last words... but I don't see how this can happen given the
// makeAccessible call above
throw new IllegalStateException("Unable to access ReflectionVar.varType field");
throw new IllegalStateException("Unable to access ReflectionVar.varType field.");
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -215,10 +215,9 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
*/
protected static class AspectJAnnotation<A extends Annotation> {
private static final String[] EXPRESSION_PROPERTIES = new String[] {"value", "pointcut"};
private static Map<Class,AspectJAnnotationType> annotationTypes = new HashMap<Class,AspectJAnnotationType>();
private static Map<Class, AspectJAnnotationType> annotationTypes =
new HashMap<Class, AspectJAnnotationType>();
private static final String[] EXPRESSION_PROPERTIES = new String[]{"value", "pointcut"};
static {
annotationTypes.put(Pointcut.class,AspectJAnnotationType.AtPointcut);
@@ -230,48 +229,46 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
}
private final A annotation;
private AspectJAnnotationType annotationType;
private final String expression;
private final String argNames;
private final AspectJAnnotationType annotationType;
public AspectJAnnotation(A aspectjAnnotation) {
this.annotation = aspectjAnnotation;
for (Class type : annotationTypes.keySet()) {
if (type.isInstance(this.annotation)) {
this.annotationType = annotationTypes.get(type);
break;
}
}
if (this.annotationType == null) {
throw new IllegalStateException("Unknown annotation type: " + this.annotation.toString());
}
private final String pointcutExpression;
private final String argumentNames;
public AspectJAnnotation(A annotation) {
this.annotation = annotation;
this.annotationType = determineAnnotationType(annotation);
// We know these methods exist with the same name on each object,
// but need to invoke them reflectively as there isn't a common interface.
try {
this.pointcutExpression = resolveExpression(annotation);
this.argumentNames = (String) annotation.getClass().getMethod("argNames").invoke(annotation);
this.expression = resolveExpression();
this.argNames = (String)
this.annotation.getClass().getMethod("argNames", (Class[]) null).invoke(this.annotation);
}
catch (Exception ex) {
throw new IllegalArgumentException(annotation + " cannot be an AspectJ annotation", ex);
throw new IllegalArgumentException(aspectjAnnotation + " cannot be an AspectJ annotation", ex);
}
}
private AspectJAnnotationType determineAnnotationType(A annotation) {
for (Class type : annotationTypes.keySet()) {
if (type.isInstance(annotation)) {
return annotationTypes.get(type);
}
}
throw new IllegalStateException("Unknown annotation type: " + annotation.toString());
}
private String resolveExpression(A annotation) throws Exception {
private String resolveExpression() throws Exception {
String expression = null;
for (String methodName : EXPRESSION_PROPERTIES) {
Method method;
try {
method = annotation.getClass().getDeclaredMethod(methodName);
method = this.annotation.getClass().getDeclaredMethod(methodName);
}
catch (NoSuchMethodException ex) {
method = null;
}
if (method != null) {
String candidate = (String) method.invoke(annotation);
String candidate = (String) method.invoke(this.annotation);
if (StringUtils.hasText(candidate)) {
expression = candidate;
}
@@ -289,11 +286,11 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
}
public String getPointcutExpression() {
return this.pointcutExpression;
return this.expression;
}
public String getArgumentNames() {
return this.argumentNames;
public String getArgNames() {
return this.argNames;
}
@Override
@@ -317,7 +314,7 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
if (annotation == null) {
return null;
}
StringTokenizer strTok = new StringTokenizer(annotation.getArgumentNames(), ",");
StringTokenizer strTok = new StringTokenizer(annotation.getArgNames(), ",");
if (strTok.countTokens() > 0) {
String[] names = new String[strTok.countTokens()];
for (int i = 0; i < names.length; i++) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -58,13 +58,18 @@ class InstantiationModelAwarePointcutAdvisorImpl
private String aspectName;
private Boolean isBeforeAdvice;
private Boolean isBeforeAdvice = null;
private Boolean isAfterAdvice;
private Boolean isAfterAdvice = null;
public InstantiationModelAwarePointcutAdvisorImpl(AspectJAdvisorFactory af, AspectJExpressionPointcut ajexp,
MetadataAwareAspectInstanceFactory aif, Method method, int declarationOrderInAspect, String aspectName) {
public InstantiationModelAwarePointcutAdvisorImpl(
AspectJAdvisorFactory af,
AspectJExpressionPointcut ajexp,
MetadataAwareAspectInstanceFactory aif,
Method method,
int declarationOrderInAspect,
String aspectName) {
this.declaredPointcut = ajexp;
this.method = method;
@@ -21,9 +21,9 @@ import java.util.List;
import org.w3c.dom.Node;
import org.springframework.aop.framework.ProxyFactoryBean;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.ManagedList;
@@ -63,38 +63,33 @@ public abstract class AbstractInterceptorDrivenBeanDefinitionDecorator implement
// get the root bean name - will be the name of the generated proxy factory bean
String existingBeanName = definitionHolder.getBeanName();
BeanDefinition targetDefinition = definitionHolder.getBeanDefinition();
BeanDefinitionHolder targetHolder = new BeanDefinitionHolder(targetDefinition, existingBeanName + ".TARGET");
BeanDefinition existingDefinition = definitionHolder.getBeanDefinition();
// delegate to subclass for interceptor definition
BeanDefinition interceptorDefinition = createInterceptorDefinition(node);
// generate name and register the interceptor
String interceptorName = existingBeanName + "." + getInterceptorNameSuffix(interceptorDefinition);
BeanDefinitionReaderUtils.registerBeanDefinition(
new BeanDefinitionHolder(interceptorDefinition, interceptorName), registry);
BeanDefinitionReaderUtils.registerBeanDefinition(new BeanDefinitionHolder(interceptorDefinition, interceptorName), registry);
BeanDefinitionHolder result = definitionHolder;
if (!isProxyFactoryBeanDefinition(targetDefinition)) {
if (!isProxyFactoryBeanDefinition(existingDefinition)) {
// create the proxy definition
RootBeanDefinition proxyDefinition = new RootBeanDefinition();
// create proxy factory bean definition
proxyDefinition.setBeanClass(ProxyFactoryBean.class);
proxyDefinition.setScope(targetDefinition.getScope());
proxyDefinition.setLazyInit(targetDefinition.isLazyInit());
// set up property values
MutablePropertyValues mpvs = new MutablePropertyValues();
proxyDefinition.setPropertyValues(mpvs);
// set the target
proxyDefinition.setDecoratedDefinition(targetHolder);
proxyDefinition.getPropertyValues().add("target", targetHolder);
mpvs.add("target", existingDefinition);
// create the interceptor names list
proxyDefinition.getPropertyValues().add("interceptorNames", new ManagedList<String>());
// copy autowire settings from original bean definition.
proxyDefinition.setAutowireCandidate(targetDefinition.isAutowireCandidate());
proxyDefinition.setPrimary(targetDefinition.isPrimary());
if (targetDefinition instanceof AbstractBeanDefinition) {
proxyDefinition.copyQualifiersFrom((AbstractBeanDefinition) targetDefinition);
}
// wrap it in a BeanDefinitionHolder with bean name
mpvs.add("interceptorNames", new ManagedList<String>());
result = new BeanDefinitionHolder(proxyDefinition, existingBeanName);
}
@@ -104,8 +99,7 @@ public abstract class AbstractInterceptorDrivenBeanDefinitionDecorator implement
@SuppressWarnings("unchecked")
private void addInterceptorNameToList(String interceptorName, BeanDefinition beanDefinition) {
List<String> list = (List<String>)
beanDefinition.getPropertyValues().getPropertyValue("interceptorNames").getValue();
List<String> list = (List<String>) beanDefinition.getPropertyValues().getPropertyValue("interceptorNames").getValue();
list.add(interceptorName);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -97,13 +97,6 @@ public abstract class AopConfigUtils {
}
}
static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);
}
}
private static BeanDefinition registerOrEscalateApcAsRequired(Class cls, BeanDefinitionRegistry registry, Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -46,11 +46,6 @@ public abstract class AopNamespaceUtils {
*/
public static final String PROXY_TARGET_CLASS_ATTRIBUTE = "proxy-target-class";
/**
* The <code>expose-proxy</code> attribute as found on AOP-related XML tags.
*/
private static final String EXPOSE_PROXY_ATTRIBUTE = "expose-proxy";
public static void registerAutoProxyCreatorIfNecessary(
ParserContext parserContext, Element sourceElement) {
@@ -107,10 +102,6 @@ public abstract class AopNamespaceUtils {
if (proxyTargetClass) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
boolean exposeProxy = Boolean.valueOf(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
if (exposeProxy) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
@@ -102,17 +102,20 @@ class ConfigBeanDefinitionParser implements BeanDefinitionParser {
configureAutoProxyCreator(parserContext, element);
List<Element> childElts = DomUtils.getChildElements(element);
for (Element elt: childElts) {
String localName = parserContext.getDelegate().getLocalName(elt);
if (POINTCUT.equals(localName)) {
parsePointcut(elt, parserContext);
}
else if (ADVISOR.equals(localName)) {
parseAdvisor(elt, parserContext);
}
else if (ASPECT.equals(localName)) {
parseAspect(elt, parserContext);
NodeList childNodes = element.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node node = childNodes.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
String localName = parserContext.getDelegate().getLocalName(node);
if (POINTCUT.equals(localName)) {
parsePointcut((Element) node, parserContext);
}
else if (ADVISOR.equals(localName)) {
parseAdvisor((Element) node, parserContext);
}
else if (ASPECT.equals(localName)) {
parseAspect((Element) node, parserContext);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -162,7 +162,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
this.targetSource = EmptyTargetSource.forClass(targetClass);
}
public Class<?> getTargetClass() {
public Class getTargetClass() {
return this.targetSource.getTargetClass();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -19,9 +19,6 @@ package org.springframework.aop.framework;
import java.util.Arrays;
import org.springframework.aop.SpringProxy;
import org.springframework.aop.TargetClassAware;
import org.springframework.aop.TargetSource;
import org.springframework.aop.target.SingletonTargetSource;
import org.springframework.util.Assert;
/**
@@ -37,34 +34,6 @@ import org.springframework.util.Assert;
*/
public abstract class AopProxyUtils {
/**
* Determine the ultimate target class of the given bean instance, traversing
* not only a top-level proxy but any number of nested proxies as well -
* as long as possible without side effects, that is, just for singleton targets.
* @param candidate the instance to check (might be an AOP proxy)
* @return the target class (or the plain class of the given object as fallback;
* never <code>null</code>)
* @see org.springframework.aop.TargetClassAware#getTargetClass()
* @see org.springframework.aop.framework.Advised#getTargetSource()
*/
public static Class<?> ultimateTargetClass(Object candidate) {
Assert.notNull(candidate, "Candidate object must not be null");
Object current = candidate;
Class<?> result = null;
while (current instanceof TargetClassAware) {
result = ((TargetClassAware) current).getTargetClass();
Object nested = null;
if (current instanceof Advised) {
TargetSource targetSource = ((Advised) current).getTargetSource();
if (targetSource instanceof SingletonTargetSource) {
nested = ((SingletonTargetSource) targetSource).getTarget();
}
}
current = nested;
}
return result;
}
/**
* Determine the complete set of interfaces to proxy for the given AOP configuration.
* <p>This will always add the {@link Advised} interface unless the AdvisedSupport's
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -268,7 +268,7 @@ final class Cglib2AopProxy implements AopProxy, Serializable {
// Choose a "straight to target" interceptor. (used for calls that are
// unadvised but can return this). May be required to expose the proxy.
Callback targetInterceptor;
Callback targetInterceptor = null;
if (exposeProxy) {
targetInterceptor = isStatic ?
new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
@@ -316,8 +316,12 @@ final class Cglib2AopProxy implements AopProxy, Serializable {
// Now copy both the callbacks from mainCallbacks
// and fixedCallbacks into the callbacks array.
callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
for (int x = 0; x < mainCallbacks.length; x++) {
callbacks[x] = mainCallbacks[x];
}
for (int x = 0; x < fixedCallbacks.length; x++) {
callbacks[x + mainCallbacks.length] = fixedCallbacks[x];
}
this.fixedInterceptorOffset = mainCallbacks.length;
}
else {
@@ -606,7 +610,7 @@ final class Cglib2AopProxy implements AopProxy, Serializable {
targetClass = target.getClass();
}
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
Object retVal = null;
// Check whether we only have one InvokerInterceptor: that is,
// no real advice, but just reflective invocation of the target.
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -146,7 +146,7 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
* unless a hook method throws an exception.
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;
MethodInvocation invocation = null;
Object oldProxy = null;
boolean setProxyContext = false;
@@ -169,7 +169,7 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
Object retVal = null;
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
@@ -239,7 +239,7 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
return false;
}
JdkDynamicAopProxy otherProxy;
JdkDynamicAopProxy otherProxy = null;
if (other instanceof JdkDynamicAopProxy) {
otherProxy = (JdkDynamicAopProxy) other;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -113,14 +113,12 @@ public class ProxyConfig implements Serializable {
* ThreadLocal for retrieval via the AopContext class. This is useful
* if an advised object needs to call another advised method on itself.
* (If it uses <code>this</code>, the invocation will not be advised).
* <p>Default is "false", in order to avoid unnecessary extra interception.
* This means that no guarantees are provided that AopContext access will
* work consistently within any method of the advised object.
* <p>Default is "false", for optimal performance.
*/
public void setExposeProxy(boolean exposeProxy) {
this.exposeProxy = exposeProxy;
}
/**
* Return whether the AOP proxy will expose the AOP proxy for
* each invocation.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -52,7 +52,7 @@ public abstract class AutoProxyUtils {
* @return whether the given bean should be proxied with its target class
*/
public static boolean shouldProxyTargetClass(ConfigurableListableBeanFactory beanFactory, String beanName) {
if (beanName != null && beanFactory.containsBeanDefinition(beanName)) {
if (beanFactory.containsBeanDefinition(beanName)) {
BeanDefinition bd = beanFactory.getBeanDefinition(beanName);
return Boolean.TRUE.equals(bd.getAttribute(PRESERVE_TARGET_CLASS_ATTRIBUTE));
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -45,7 +45,7 @@ public abstract class ExposeBeanNameAdvisors {
* Binding for the bean name of the bean which is currently being invoked
* in the ReflectiveMethodInvocation userAttributes Map.
*/
private static final String BEAN_NAME_ATTRIBUTE = ExposeBeanNameAdvisors.class.getName() + ".BEAN_NAME";
private static final String BEAN_NAME_ATTRIBUTE = ExposeBeanNameAdvisors.class.getName() + ".beanName";
/**
@@ -114,7 +114,7 @@ public abstract class ExposeBeanNameAdvisors {
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
}
ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
pmi.setUserAttribute(BEAN_NAME_ATTRIBUTE, this.beanName);
pmi.setUserAttribute(BEAN_NAME_ATTRIBUTE, beanName);
return mi.proceed();
}
}
@@ -137,7 +137,7 @@ public abstract class ExposeBeanNameAdvisors {
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
}
ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
pmi.setUserAttribute(BEAN_NAME_ATTRIBUTE, this.beanName);
pmi.setUserAttribute(BEAN_NAME_ATTRIBUTE, beanName);
return super.invoke(mi);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -53,29 +53,28 @@ public abstract class ScopedProxyUtils {
// Create a scoped proxy definition for the original bean name,
// "hiding" the target bean in an internal target definition.
RootBeanDefinition proxyDefinition = new RootBeanDefinition(ScopedProxyFactoryBean.class);
proxyDefinition.setOriginatingBeanDefinition(definition.getBeanDefinition());
proxyDefinition.setSource(definition.getSource());
proxyDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
RootBeanDefinition scopedProxyDefinition = new RootBeanDefinition(ScopedProxyFactoryBean.class);
scopedProxyDefinition.setOriginatingBeanDefinition(definition.getBeanDefinition());
scopedProxyDefinition.setSource(definition.getSource());
scopedProxyDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
String targetBeanName = getTargetBeanName(originalBeanName);
proxyDefinition.getPropertyValues().add("targetBeanName", targetBeanName);
scopedProxyDefinition.getPropertyValues().add("targetBeanName", targetBeanName);
if (proxyTargetClass) {
targetDefinition.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
// ScopedFactoryBean's "proxyTargetClass" default is TRUE, so we don't need to set it explicitly here.
}
else {
proxyDefinition.getPropertyValues().add("proxyTargetClass", Boolean.FALSE);
scopedProxyDefinition.getPropertyValues().add("proxyTargetClass", Boolean.FALSE);
}
// Copy autowire settings from original bean definition.
proxyDefinition.setAutowireCandidate(targetDefinition.isAutowireCandidate());
proxyDefinition.setPrimary(targetDefinition.isPrimary());
if (targetDefinition instanceof AbstractBeanDefinition) {
proxyDefinition.copyQualifiersFrom((AbstractBeanDefinition) targetDefinition);
scopedProxyDefinition.copyQualifiersFrom((AbstractBeanDefinition) targetDefinition);
}
scopedProxyDefinition.setAutowireCandidate(targetDefinition.isAutowireCandidate());
scopedProxyDefinition.setPrimary(targetDefinition.isPrimary());
// The target bean should be ignored in favor of the scoped proxy.
targetDefinition.setAutowireCandidate(false);
targetDefinition.setPrimary(false);
@@ -85,7 +84,7 @@ public abstract class ScopedProxyUtils {
// Return the scoped proxy definition as primary bean definition
// (potentially an inner bean).
return new BeanDefinitionHolder(proxyDefinition, originalBeanName, definition.getAliases());
return new BeanDefinitionHolder(scopedProxyDefinition, originalBeanName, definition.getAliases());
}
/**
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -85,7 +85,7 @@ public abstract class AopUtils {
* Check whether the specified class is a CGLIB-generated class.
* @param clazz the class to check
*/
public static boolean isCglibProxyClass(Class<?> clazz) {
public static boolean isCglibProxyClass(Class clazz) {
return (clazz != null && isCglibProxyClassName(clazz.getName()));
}
@@ -98,24 +98,22 @@ public abstract class AopUtils {
}
/**
* Determine the target class of the given bean instance which might be an AOP proxy.
* Determine the target class of the given bean instance,
* which might be an AOP proxy.
* <p>Returns the target class for an AOP proxy and the plain class else.
* @param candidate the instance to check (might be an AOP proxy)
* @return the target class (or the plain class of the given object as fallback;
* never <code>null</code>)
* @return the target class (or the plain class of the given object as fallback)
* @see org.springframework.aop.TargetClassAware#getTargetClass()
* @see org.springframework.aop.framework.AopProxyUtils#ultimateTargetClass(Object)
*/
public static Class<?> getTargetClass(Object candidate) {
public static Class getTargetClass(Object candidate) {
Assert.notNull(candidate, "Candidate object must not be null");
Class<?> result = null;
if (candidate instanceof TargetClassAware) {
result = ((TargetClassAware) candidate).getTargetClass();
return ((TargetClassAware) candidate).getTargetClass();
}
if (result == null) {
result = (isCglibProxy(candidate) ? candidate.getClass().getSuperclass() : candidate.getClass());
if (isCglibProxy(candidate)) {
return candidate.getClass().getSuperclass();
}
return result;
return candidate.getClass();
}
/**
@@ -167,7 +165,7 @@ public abstract class AopUtils {
* <code>targetClass</code> doesn't implement it or is <code>null</code>
* @see org.springframework.util.ClassUtils#getMostSpecificMethod
*/
public static Method getMostSpecificMethod(Method method, Class<?> targetClass) {
public static Method getMostSpecificMethod(Method method, Class targetClass) {
Method resolvedMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
// If we are dealing with method with generic parameters, find the original method.
return BridgeMethodResolver.findBridgedMethod(resolvedMethod);
@@ -182,7 +180,7 @@ public abstract class AopUtils {
* @param targetClass the class to test
* @return whether the pointcut can apply on any method
*/
public static boolean canApply(Pointcut pc, Class<?> targetClass) {
public static boolean canApply(Pointcut pc, Class targetClass) {
return canApply(pc, targetClass, false);
}
@@ -196,7 +194,7 @@ public abstract class AopUtils {
* for this bean includes any introductions
* @return whether the pointcut can apply on any method
*/
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
public static boolean canApply(Pointcut pc, Class targetClass, boolean hasIntroductions) {
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
@@ -209,7 +207,7 @@ public abstract class AopUtils {
Set<Class> classes = new HashSet<Class>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
classes.add(targetClass);
for (Class<?> clazz : classes) {
for (Class clazz : classes) {
Method[] methods = clazz.getMethods();
for (Method method : methods) {
if ((introductionAwareMethodMatcher != null &&
@@ -231,7 +229,7 @@ public abstract class AopUtils {
* @param targetClass class we're testing
* @return whether the pointcut can apply on any method
*/
public static boolean canApply(Advisor advisor, Class<?> targetClass) {
public static boolean canApply(Advisor advisor, Class targetClass) {
return canApply(advisor, targetClass, false);
}
@@ -245,7 +243,7 @@ public abstract class AopUtils {
* any introductions
* @return whether the pointcut can apply on any method
*/
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
public static boolean canApply(Advisor advisor, Class targetClass, boolean hasIntroductions) {
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
@@ -267,7 +265,7 @@ public abstract class AopUtils {
* @return sublist of Advisors that can apply to an object of the given class
* (may be the incoming List as-is)
*/
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -16,12 +16,15 @@
package org.springframework.aop.target;
import java.io.NotSerializableException;
import java.io.ObjectStreamException;
import java.io.Serializable;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.TargetSource;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.util.ClassUtils;
@@ -62,7 +65,7 @@ public abstract class AbstractBeanFactoryBasedTargetSource
private String targetBeanName;
/** Class of the target */
private Class<?> targetClass;
private Class targetClass;
/**
* BeanFactory that owns this TargetSource. We need to hold onto this
@@ -105,7 +108,7 @@ public abstract class AbstractBeanFactoryBasedTargetSource
* Set the owning BeanFactory. We need to save a reference so that we can
* use the <code>getBean</code> method on every invocation.
*/
public void setBeanFactory(BeanFactory beanFactory) {
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
if (this.targetBeanName == null) {
throw new IllegalStateException("Property'targetBeanName' is required");
}
@@ -120,7 +123,7 @@ public abstract class AbstractBeanFactoryBasedTargetSource
}
public synchronized Class<?> getTargetClass() {
public synchronized Class getTargetClass() {
if (this.targetClass == null && this.beanFactory != null) {
// Determine type of the target bean.
this.targetClass = this.beanFactory.getType(this.targetBeanName);
@@ -128,10 +131,7 @@ public abstract class AbstractBeanFactoryBasedTargetSource
if (logger.isTraceEnabled()) {
logger.trace("Getting bean with name '" + this.targetBeanName + "' in order to determine type");
}
Object beanInstance = this.beanFactory.getBean(this.targetBeanName);
if (beanInstance != null) {
this.targetClass = beanInstance.getClass();
}
this.targetClass = this.beanFactory.getBean(this.targetBeanName).getClass();
}
}
return this.targetClass;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -64,7 +64,7 @@ public abstract class AbstractLazyCreationTargetSource implements TargetSource {
* a meaningful value when the target is still <code>null</code>.
* @see #isInitialized()
*/
public synchronized Class<?> getTargetClass() {
public synchronized Class getTargetClass() {
return (this.lazyTarget != null ? this.lazyTarget.getClass() : null);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -89,7 +89,7 @@ public class EmptyTargetSource implements TargetSource, Serializable {
/**
* Always returns the specified target Class, or <code>null</code> if none.
*/
public Class<?> getTargetClass() {
public Class getTargetClass() {
return this.targetClass;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -59,7 +59,7 @@ public class HotSwappableTargetSource implements TargetSource, Serializable {
* Return the type of the current target object.
* <p>The returned type should usually be constant across all target objects.
*/
public synchronized Class<?> getTargetClass() {
public synchronized Class getTargetClass() {
return this.target.getClass();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -55,7 +55,7 @@ public class SingletonTargetSource implements TargetSource, Serializable {
}
public Class<?> getTargetClass() {
public Class getTargetClass() {
return this.target.getClass();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -63,7 +63,7 @@ public abstract class AbstractRefreshableTargetSource implements TargetSource, R
}
public synchronized Class<?> getTargetClass() {
public synchronized Class getTargetClass() {
if (this.targetObject == null) {
refresh();
}
@@ -56,15 +56,6 @@
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="expose-proxy" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicate that the proxy should be exposed by the AOP framework as a
ThreadLocal for retrieval via the AopContext class. Off by default,
i.e. no guarantees that AopContext access will work.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
@@ -93,15 +84,6 @@
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="expose-proxy" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicate that the proxy should be exposed by the AOP framework as a
ThreadLocal for retrieval via the AopContext class. Off by default,
i.e. no guarantees that AopContext access will work.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -16,14 +16,15 @@
package org.springframework.aop.aspectj.annotation;
import static org.junit.Assert.*;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import static org.junit.Assert.*;
import org.junit.Ignore;
import org.junit.Test;
import test.aop.PerThisAspect;
import test.util.SerializationTestUtils;
/**
* @author Rob Harrop
@@ -75,7 +76,6 @@ public final class AspectProxyFactoryTests {
}
@Test
@Ignore // InstantiationModelAwarePointcutAdvisorImpl not serializable yet
public void testWithInstance() throws Exception {
MultiplyReturnValue aspect = new MultiplyReturnValue();
int multiple = 3;
@@ -88,10 +88,8 @@ public final class AspectProxyFactoryTests {
proxyFactory.addAspect(aspect);
ITestBean proxy = proxyFactory.getProxy();
assertEquals(target.getAge() * multiple, proxy.getAge());
ITestBean serializedProxy = (ITestBean) SerializationTestUtils.serializeAndDeserialize(proxy);
assertEquals(target.getAge() * multiple, serializedProxy.getAge());
assertEquals(target.getAge() * multiple, proxy.getAge());
}
@Test(expected=IllegalArgumentException.class)
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -293,33 +293,20 @@ public final class ProxyFactoryTests {
public void testProxyTargetClassWithInterfaceAsTarget() {
ProxyFactory pf = new ProxyFactory();
pf.setTargetClass(ITestBean.class);
Object proxy = pf.getProxy();
assertTrue("Proxy is a JDK proxy", AopUtils.isJdkDynamicProxy(proxy));
assertTrue(proxy instanceof ITestBean);
assertEquals(ITestBean.class, AopProxyUtils.ultimateTargetClass(proxy));
ProxyFactory pf2 = new ProxyFactory(proxy);
Object proxy2 = pf2.getProxy();
assertTrue("Proxy is a JDK proxy", AopUtils.isJdkDynamicProxy(proxy2));
assertTrue(proxy2 instanceof ITestBean);
assertEquals(ITestBean.class, AopProxyUtils.ultimateTargetClass(proxy2));
}
@Test
public void testProxyTargetClassWithConcreteClassAsTarget() {
ProxyFactory pf = new ProxyFactory();
pf.setTargetClass(TestBean.class);
Object proxy = pf.getProxy();
assertTrue("Proxy is a CGLIB proxy", AopUtils.isCglibProxy(proxy));
assertTrue(proxy instanceof TestBean);
assertEquals(TestBean.class, AopProxyUtils.ultimateTargetClass(proxy));
ProxyFactory pf2 = new ProxyFactory(proxy);
pf2.setProxyTargetClass(true);
Object proxy2 = pf2.getProxy();
assertTrue("Proxy is a CGLIB proxy", AopUtils.isCglibProxy(proxy2));
assertTrue(proxy2 instanceof TestBean);
assertEquals(TestBean.class, AopProxyUtils.ultimateTargetClass(proxy2));
}
@Test
+56 -56
View File
@@ -1,56 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>spring-asm</artifactId>
<packaging>jar</packaging>
<version>3.0.3.RELEASE</version>
<parent>
<groupId>org.springframework</groupId>
<artifactId>spring-parent</artifactId>
<relativePath>../org.springframework.spring-parent</relativePath>
<version>3.0.3.RELEASE</version>
</parent>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>jarjar</id>
<phase>process-classes</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask" classpathref="maven.plugin.classpath" />
<jarjar jarfile="${project.build.directory}${file.separator}${project.build.finalName}-jarjar.jar">
<zipfileset src="${project.build.directory}/jarjar-staging/com.springsource.org.objectweb.asm.jar"/>
<zipfileset src="${project.build.directory}/jarjar-staging/com.springsource.org.objectweb.asm.commons.jar"/>
<rule pattern="org.objectweb.asm.**" result="org.springframework.asm.@1"/>
</jarjar>
<unjar src="${project.build.directory}${file.separator}${project.build.finalName}-jarjar.jar"
dest="${project.build.outputDirectory}">
<patternset>
<include name="**/*.class"/>
<exclude name="*"/>
</patternset>
</unjar>
</tasks>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.google.code</groupId>
<artifactId>jarjar</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>spring-asm</artifactId>
<packaging>jar</packaging>
<version>3.0.1.RELEASE-A</version>
<parent>
<groupId>org.springframework</groupId>
<artifactId>spring-parent</artifactId>
<relativePath>../org.springframework.spring-parent</relativePath>
<version>3.0.1.RELEASE-A</version>
</parent>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>jarjar</id>
<phase>process-classes</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask" classpathref="maven.plugin.classpath" />
<jarjar jarfile="${project.build.directory}${file.separator}${project.build.finalName}-jarjar.jar">
<zipfileset src="${project.build.directory}/jarjar-staging/com.springsource.org.objectweb.asm.jar"/>
<zipfileset src="${project.build.directory}/jarjar-staging/com.springsource.org.objectweb.asm.commons.jar"/>
<rule pattern="org.objectweb.asm.**" result="org.springframework.asm.@1"/>
</jarjar>
<unjar src="${project.build.directory}${file.separator}${project.build.finalName}-jarjar.jar"
dest="${project.build.outputDirectory}">
<patternset>
<include name="**/*.class"/>
<exclude name="*"/>
</patternset>
</unjar>
</tasks>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.google.code</groupId>
<artifactId>jarjar</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
+83 -84
View File
@@ -1,84 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<packaging>jar</packaging>
<version>3.0.3.RELEASE</version>
<parent>
<groupId>org.springframework</groupId>
<artifactId>spring-parent</artifactId>
<relativePath>../org.springframework.spring-parent</relativePath>
<version>3.0.3.RELEASE</version>
</parent>
<dependencies>
<!-- common logging dependency is in spring-core -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${project.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4</version>
<scope>test</scope>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<junitArtifactName>junit:junit</junitArtifactName>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<packaging>jar</packaging>
<version>3.0.1.RELEASE-A</version>
<parent>
<groupId>org.springframework</groupId>
<artifactId>spring-parent</artifactId>
<relativePath>../org.springframework.spring-parent</relativePath>
<version>3.0.1.RELEASE-A</version>
</parent>
<dependencies>
<!-- common logging dependency is in spring-core -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${project.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${project.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<junitArtifactName>junit:junit</junitArtifactName>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
@@ -151,7 +151,7 @@ public abstract aspect AbstractMethodMockingControl percflow(mockStaticsTestMeth
expectations.verify();
}
Object around() : methodToMock() && cflowbelow(mockStaticsTestMethod()) {
Object around() : methodToMock() {
if (recording) {
expectations.expectCall(thisJoinPointStaticPart.toLongString(), thisJoinPoint.getArgs());
// Return value doesn't matter
+2 -2
View File
@@ -4,12 +4,12 @@
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<packaging>jar</packaging>
<version>3.0.3.RELEASE</version>
<version>3.0.1.RELEASE-A</version>
<parent>
<groupId>org.springframework</groupId>
<artifactId>spring-parent</artifactId>
<relativePath>../org.springframework.spring-parent</relativePath>
<version>3.0.3.RELEASE</version>
<version>3.0.1.RELEASE-A</version>
</parent>
<dependencies>
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.core.convert.support;
package org.springframework.beans;
import java.beans.PropertyDescriptor;
import java.lang.annotation.Annotation;
@@ -26,7 +26,6 @@ import java.util.Map;
import org.springframework.core.MethodParameter;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
/**
* {@link TypeDescriptor} extension that exposes additional annotations
@@ -34,9 +33,9 @@ import org.springframework.util.StringUtils;
* (getter/setter) and on the underlying field, if found.
*
* @author Juergen Hoeller
* @since 3.0.2
* @since 3.0
*/
public class PropertyTypeDescriptor extends TypeDescriptor {
class BeanTypeDescriptor extends TypeDescriptor {
private final PropertyDescriptor propertyDescriptor;
@@ -46,10 +45,9 @@ public class PropertyTypeDescriptor extends TypeDescriptor {
/**
* Create a new BeanTypeDescriptor for the given bean property.
* @param propertyDescriptor the corresponding JavaBean PropertyDescriptor
* @param methodParameter the target method parameter
*/
public PropertyTypeDescriptor(PropertyDescriptor propertyDescriptor, MethodParameter methodParameter) {
super(methodParameter);
public BeanTypeDescriptor(PropertyDescriptor propertyDescriptor) {
super(BeanUtils.getWriteMethodParameter(propertyDescriptor));
this.propertyDescriptor = propertyDescriptor;
}
@@ -59,7 +57,7 @@ public class PropertyTypeDescriptor extends TypeDescriptor {
* @param methodParameter the target method parameter
* @param type the specific type to expose (may be an array/collection element)
*/
public PropertyTypeDescriptor(PropertyDescriptor propertyDescriptor, MethodParameter methodParameter, Class<?> type) {
public BeanTypeDescriptor(PropertyDescriptor propertyDescriptor, MethodParameter methodParameter, Class type) {
super(methodParameter, type);
this.propertyDescriptor = propertyDescriptor;
}
@@ -72,43 +70,32 @@ public class PropertyTypeDescriptor extends TypeDescriptor {
return this.propertyDescriptor;
}
@Override
public Annotation[] getAnnotations() {
Annotation[] anns = this.cachedAnnotations;
if (anns == null) {
Map<Class<?>, Annotation> annMap = new LinkedHashMap<Class<?>, Annotation>();
String name = this.propertyDescriptor.getName();
if (StringUtils.hasLength(name)) {
Class<?> clazz = getMethodParameter().getMethod().getDeclaringClass();
Field field = ReflectionUtils.findField(clazz, name);
if (field == null) {
// Same lenient fallback checking as in CachedIntrospectionResults...
field = ReflectionUtils.findField(clazz, name.substring(0, 1).toLowerCase() + name.substring(1));
if (field == null) {
field = ReflectionUtils.findField(clazz, name.substring(0, 1).toUpperCase() + name.substring(1));
}
}
if (field != null) {
for (Annotation ann : field.getAnnotations()) {
annMap.put(ann.annotationType(), ann);
}
Field underlyingField = ReflectionUtils.findField(
getMethodParameter().getMethod().getDeclaringClass(), this.propertyDescriptor.getName());
Map<Class, Annotation> annMap = new LinkedHashMap<Class, Annotation>();
if (underlyingField != null) {
for (Annotation ann : underlyingField.getAnnotations()) {
annMap.put(ann.annotationType(), ann);
}
}
Method targetMethod = getMethodParameter().getMethod();
Method writeMethod = this.propertyDescriptor.getWriteMethod();
Method readMethod = this.propertyDescriptor.getReadMethod();
if (writeMethod != null && writeMethod != getMethodParameter().getMethod()) {
if (writeMethod != null && writeMethod != targetMethod) {
for (Annotation ann : writeMethod.getAnnotations()) {
annMap.put(ann.annotationType(), ann);
}
}
if (readMethod != null && readMethod != getMethodParameter().getMethod()) {
if (readMethod != null && readMethod != targetMethod) {
for (Annotation ann : readMethod.getAnnotations()) {
annMap.put(ann.annotationType(), ann);
}
}
for (Annotation ann : getMethodParameter().getMethodAnnotations()) {
annMap.put(ann.annotationType(), ann);
}
for (Annotation ann : getMethodParameter().getParameterAnnotations()) {
for (Annotation ann : targetMethod.getAnnotations()) {
annMap.put(ann.annotationType(), ann);
}
anns = annMap.values().toArray(new Annotation[annMap.size()]);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -389,17 +389,8 @@ public abstract class BeanUtils {
}
ClassLoader cl = targetType.getClassLoader();
if (cl == null) {
try {
cl = ClassLoader.getSystemClassLoader();
if (cl == null) {
return null;
}
}
catch (Throwable ex) {
// e.g. AccessControlException on Google App Engine
if (logger.isDebugEnabled()) {
logger.debug("Could not access system ClassLoader: " + ex);
}
cl = ClassLoader.getSystemClassLoader();
if (cl == null) {
return null;
}
}
@@ -407,10 +398,8 @@ public abstract class BeanUtils {
try {
Class<?> editorClass = cl.loadClass(editorName);
if (!PropertyEditor.class.isAssignableFrom(editorClass)) {
if (logger.isWarnEnabled()) {
logger.warn("Editor class [" + editorName +
"] does not implement [java.beans.PropertyEditor] interface");
}
logger.warn("Editor class [" + editorName +
"] does not implement [java.beans.PropertyEditor] interface");
unknownEditorTypes.put(targetType, Boolean.TRUE);
return null;
}
@@ -44,7 +44,6 @@ import org.springframework.core.MethodParameter;
import org.springframework.core.convert.ConversionException;
import org.springframework.core.convert.ConverterNotFoundException;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.support.PropertyTypeDescriptor;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
@@ -102,11 +101,6 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
private TypeConverterDelegate typeConverterDelegate;
/**
* The security context used for invoking the property methods
*/
private AccessControlContext acc;
/**
* Cached introspections results for this object, to prevent encountering
* the cost of JavaBeans introspection every time.
@@ -118,6 +112,9 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
*/
private Map<String, BeanWrapperImpl> nestedBeanWrappers;
/** The security context used for invoking the property methods */
private AccessControlContext acc;
private boolean autoGrowNestedPaths = false;
@@ -219,6 +216,16 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
setIntrospectionClass(object.getClass());
}
/**
* Set the security context used during the invocation of the wrapped instance methods.
* Can be null.
*
* @param acc
*/
public void setSecurityContext(AccessControlContext acc) {
this.acc = acc;
}
public final Object getWrappedInstance() {
return this.object;
}
@@ -267,22 +274,6 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
return this.autoGrowNestedPaths;
}
/**
* Set the security context used during the invocation of the wrapped instance methods.
* Can be null.
*/
public void setSecurityContext(AccessControlContext acc) {
this.acc = acc;
}
/**
* Return the security context used during the invocation of the wrapped instance methods.
* Can be null.
*/
public AccessControlContext getSecurityContext() {
return this.acc;
}
/**
* Set the class to introspect.
* Needs to be called when the target object changes.
@@ -369,10 +360,10 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
if (pd != null) {
Class type = getPropertyType(propertyName);
if (pd.getReadMethod() != null) {
return new PropertyTypeDescriptor(pd, new MethodParameter(pd.getReadMethod(), -1), type);
return new BeanTypeDescriptor(pd, new MethodParameter(pd.getReadMethod(), -1), type);
}
else if (pd.getWriteMethod() != null) {
return new PropertyTypeDescriptor(pd, BeanUtils.getWriteMethodParameter(pd), type);
return new BeanTypeDescriptor(pd, BeanUtils.getWriteMethodParameter(pd), type);
}
}
}
@@ -422,8 +413,8 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
return false;
}
public <T> T convertIfNecessary(Object value, Class<T> requiredType, MethodParameter methodParam)
throws TypeMismatchException {
public <T> T convertIfNecessary(
Object value, Class<T> requiredType, MethodParameter methodParam) throws TypeMismatchException {
try {
return this.typeConverterDelegate.convertIfNecessary(value, requiredType, methodParam);
}
@@ -441,39 +432,6 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
}
}
private Object convertIfNecessary(String propertyName, Object oldValue, Object newValue, Class<?> requiredType,
TypeDescriptor td) throws TypeMismatchException {
try {
return this.typeConverterDelegate.convertIfNecessary(propertyName, oldValue, newValue, requiredType, td);
}
catch (ConverterNotFoundException ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, newValue);
throw new ConversionNotSupportedException(pce, td.getType(), ex);
}
catch (ConversionException ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, newValue);
throw new TypeMismatchException(pce, requiredType, ex);
}
catch (IllegalStateException ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, newValue);
throw new ConversionNotSupportedException(pce, requiredType, ex);
}
catch (IllegalArgumentException ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, newValue);
throw new TypeMismatchException(pce, requiredType, ex);
}
}
private Object convertIfNecessary(String propertyName, Object oldValue, Object newValue, Class<?> requiredType)
throws TypeMismatchException {
return convertIfNecessary(propertyName, oldValue, newValue, requiredType, TypeDescriptor.valueOf(requiredType));
}
/**
* Convert the given value for the specified property to the latter's type.
* <p>This method is only intended for optimizations in a BeanFactory.
@@ -490,14 +448,19 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
"No property '" + propertyName + "' found");
}
return convertForProperty(propertyName, null, value, pd);
}
private Object convertForProperty(String propertyName, Object oldValue, Object newValue, PropertyDescriptor pd)
throws TypeMismatchException {
return convertIfNecessary(propertyName, oldValue, newValue, pd.getPropertyType(),
new PropertyTypeDescriptor(pd, BeanUtils.getWriteMethodParameter(pd)));
try {
return this.typeConverterDelegate.convertIfNecessary(null, value, pd);
}
catch (IllegalArgumentException ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, null, value);
throw new TypeMismatchException(pce, pd.getPropertyType(), ex);
}
catch (IllegalStateException ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, null, value);
throw new ConversionNotSupportedException(pce, pd.getPropertyType(), ex);
}
}
@@ -718,6 +681,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
}
Object value;
if (System.getSecurityManager() != null) {
try {
value = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@@ -731,7 +695,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
}
}
else {
value = readMethod.invoke(object, (Object[]) null);
value = readMethod.invoke(object, (Object[]) null);
}
if (tokens.keys != null) {
@@ -788,7 +752,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
Class<?> mapKeyType = GenericCollectionTypeResolver.getMapKeyReturnType(pd.getReadMethod(), i + 1);
// IMPORTANT: Do not pass full property name in here - property editors
// must not kick in for map keys but rather only for map values.
Object convertedMapKey = convertIfNecessary(null, null, key, mapKeyType);
Object convertedMapKey = this.typeConverterDelegate.convertIfNecessary(key, mapKeyType);
// Pass full property name and old value in here, since we want full
// conversion ability for map values.
value = map.get(convertedMapKey);
@@ -803,6 +767,15 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
}
return value;
}
catch (InvocationTargetException ex) {
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
"Getter for property '" + actualName + "' threw exception", ex);
}
catch(IllegalAccessException ex) {
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
"Illegal attempt to get property '" + actualName + "' threw exception", ex);
}
catch (IndexOutOfBoundsException ex) {
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
"Index of out of bounds in property path '" + propertyName + "'", ex);
@@ -811,17 +784,9 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
"Invalid index in property path '" + propertyName + "'", ex);
}
catch (TypeMismatchException ex) {
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
"Invalid index in property path '" + propertyName + "'", ex);
}
catch (InvocationTargetException ex) {
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
"Getter for property '" + actualName + "' threw exception", ex);
}
catch (Exception ex) {
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
"Illegal attempt to get property '" + actualName + "' threw exception", ex);
"Invalid index in property path '" + propertyName + "'", ex);
}
}
@@ -839,16 +804,12 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
}
setPropertyValue(name, newArray);
return newArray;
}
else {
} else {
return array;
}
}
@SuppressWarnings("unchecked")
private void growCollectionIfNecessary(
Collection collection, int index, String name, PropertyDescriptor pd, int nestingLevel) {
private void growCollectionIfNecessary(Collection collection, int index, String name, PropertyDescriptor pd, int nestingLevel) {
if (!this.autoGrowNestedPaths) {
return;
}
@@ -936,8 +897,19 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
if (isExtractOldValueForEditor()) {
oldValue = Array.get(propValue, arrayIndex);
}
Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(), requiredType);
Array.set(propValue, arrayIndex, convertedValue);
Object convertedValue = this.typeConverterDelegate.convertIfNecessary(
propertyName, oldValue, pv.getValue(), requiredType);
Array.set(propValue, Integer.parseInt(key), convertedValue);
}
catch (IllegalArgumentException ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
throw new TypeMismatchException(pce, requiredType, ex);
}
catch (IllegalStateException ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
throw new ConversionNotSupportedException(pce, requiredType, ex);
}
catch (IndexOutOfBoundsException ex) {
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
@@ -954,23 +926,31 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
if (isExtractOldValueForEditor() && index < list.size()) {
oldValue = list.get(index);
}
Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(), requiredType);
if (index < list.size()) {
list.set(index, convertedValue);
}
else if (index >= list.size()) {
for (int i = list.size(); i < index; i++) {
try {
list.add(null);
}
catch (NullPointerException ex) {
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
"Cannot set element with index " + index + " in List of size " +
list.size() + ", accessed using property path '" + propertyName +
"': List does not support filling up gaps with null elements");
}
try {
Object convertedValue = this.typeConverterDelegate.convertIfNecessary(
propertyName, oldValue, pv.getValue(), requiredType);
if (index < list.size()) {
list.set(index, convertedValue);
}
list.add(convertedValue);
else if (index >= list.size()) {
for (int i = list.size(); i < index; i++) {
try {
list.add(null);
}
catch (NullPointerException ex) {
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
"Cannot set element with index " + index + " in List of size " +
list.size() + ", accessed using property path '" + propertyName +
"': List does not support filling up gaps with null elements");
}
}
list.add(convertedValue);
}
}
catch (IllegalArgumentException ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
throw new TypeMismatchException(pce, requiredType, ex);
}
}
else if (propValue instanceof Map) {
@@ -980,18 +960,34 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
Class mapValueType = GenericCollectionTypeResolver.getMapValueReturnType(
pd.getReadMethod(), tokens.keys.length);
Map map = (Map) propValue;
// IMPORTANT: Do not pass full property name in here - property editors
// must not kick in for map keys but rather only for map values.
Object convertedMapKey = convertIfNecessary(null, null, key, mapKeyType);
Object convertedMapKey;
Object convertedMapValue;
try {
// IMPORTANT: Do not pass full property name in here - property editors
// must not kick in for map keys but rather only for map values.
convertedMapKey = this.typeConverterDelegate.convertIfNecessary(key, mapKeyType);
}
catch (IllegalArgumentException ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, null, pv.getValue());
throw new TypeMismatchException(pce, mapKeyType, ex);
}
Object oldValue = null;
if (isExtractOldValueForEditor()) {
oldValue = map.get(convertedMapKey);
}
// Pass full property name and old value in here, since we want full
// conversion ability for map values.
Object convertedMapValue = convertIfNecessary(
propertyName, oldValue, pv.getValue(), mapValueType,
new TypeDescriptor(new MethodParameter(pd.getReadMethod(), -1, tokens.keys.length + 1)));
try {
// Pass full property name and old value in here, since we want full
// conversion ability for map values.
convertedMapValue = this.typeConverterDelegate.convertIfNecessary(
propertyName, oldValue, pv.getValue(), mapValueType,
new MethodParameter(pd.getReadMethod(), -1, tokens.keys.length + 1));
}
catch (IllegalArgumentException ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
throw new TypeMismatchException(pce, mapValueType, ex);
}
map.put(convertedMapKey, convertedMapValue);
}
else {
@@ -1032,8 +1028,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
else {
if (isExtractOldValueForEditor() && pd.getReadMethod() != null) {
final Method readMethod = pd.getReadMethod();
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers()) &&
!readMethod.isAccessible()) {
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers()) && !readMethod.isAccessible()) {
if (System.getSecurityManager()!= null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
@@ -1052,7 +1047,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
public Object run() throws Exception {
return readMethod.invoke(object);
}
}, acc);
},acc);
}
else {
oldValue = readMethod.invoke(object);
@@ -1068,7 +1063,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
}
}
}
valueToApply = convertForProperty(propertyName, oldValue, originalValue, pd);
valueToApply = this.typeConverterDelegate.convertIfNecessary(oldValue, originalValue, pd);
}
pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
}
@@ -1089,6 +1084,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
}
}
final Object value = valueToApply;
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@@ -1097,17 +1093,14 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
return null;
}
}, acc);
}
catch (PrivilegedActionException ex) {
} catch (PrivilegedActionException ex) {
throw ex.getException();
}
}
else {
writeMethod.invoke(this.object, value);
writeMethod.invoke(object, value);
}
}
catch (TypeMismatchException ex) {
throw ex;
}
catch (InvocationTargetException ex) {
PropertyChangeEvent propertyChangeEvent =
@@ -1119,9 +1112,34 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
throw new MethodInvocationException(propertyChangeEvent, ex.getTargetException());
}
}
catch (Exception ex) {
catch (ConverterNotFoundException ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
throw new ConversionNotSupportedException(pce, pd.getPropertyType(), ex);
}
catch (ConversionException ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
throw new TypeMismatchException(pce, pd.getPropertyType(), ex);
}
catch (IllegalStateException ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
throw new ConversionNotSupportedException(pce, pd.getPropertyType(), ex);
}
catch (IllegalArgumentException ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
throw new TypeMismatchException(pce, pd.getPropertyType(), ex);
}
catch (IllegalAccessException ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
throw new MethodInvocationException(pce, ex);
}
catch (Exception ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
throw new MethodInvocationException(pce, ex);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -22,10 +22,11 @@ import java.beans.Introspector;
import java.beans.PropertyDescriptor;
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.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
@@ -140,20 +141,19 @@ public class CachedIntrospectionResults {
results = (CachedIntrospectionResults) value;
}
if (results == null) {
// can throw BeansException
results = new CachedIntrospectionResults(beanClass);
// On JDK 1.5 and higher, it is almost always safe to cache the bean class...
// The sole exception is a custom BeanInfo class being provided in a non-safe ClassLoader.
boolean fullyCacheable =
ClassUtils.isCacheSafe(beanClass, CachedIntrospectionResults.class.getClassLoader()) ||
isClassLoaderAccepted(beanClass.getClassLoader());
if (fullyCacheable || !ClassUtils.isPresent(beanClass.getName() + "BeanInfo", beanClass.getClassLoader())) {
results = new CachedIntrospectionResults(beanClass, fullyCacheable);
if (ClassUtils.isCacheSafe(beanClass, CachedIntrospectionResults.class.getClassLoader()) ||
isClassLoaderAccepted(beanClass.getClassLoader()) ||
!ClassUtils.isPresent(beanClass.getName() + "BeanInfo", beanClass.getClassLoader())) {
classCache.put(beanClass, results);
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Not strongly caching class [" + beanClass.getName() + "] because it is not cache-safe");
}
results = new CachedIntrospectionResults(beanClass, true);
classCache.put(beanClass, new WeakReference<CachedIntrospectionResults>(results));
}
}
@@ -216,7 +216,7 @@ public class CachedIntrospectionResults {
* @param beanClass the bean class to analyze
* @throws BeansException in case of introspection failure
*/
private CachedIntrospectionResults(Class beanClass, boolean cacheFullMetadata) throws BeansException {
private CachedIntrospectionResults(Class beanClass) throws BeansException {
try {
if (logger.isTraceEnabled()) {
logger.trace("Getting BeanInfo for class [" + beanClass.getName() + "]");
@@ -237,29 +237,24 @@ public class CachedIntrospectionResults {
if (logger.isTraceEnabled()) {
logger.trace("Caching PropertyDescriptors for class [" + beanClass.getName() + "]");
}
this.propertyDescriptorCache = new LinkedHashMap<String, PropertyDescriptor>();
this.propertyDescriptorCache = new HashMap<String, PropertyDescriptor>();
// This call is slow so we do it once.
PropertyDescriptor[] pds = this.beanInfo.getPropertyDescriptors();
for (PropertyDescriptor pd : pds) {
if (Class.class.equals(beanClass) && "classLoader".equals(pd.getName())) {
// Ignore Class.getClassLoader() method - nobody needs to bind to that
continue;
}
if (logger.isTraceEnabled()) {
logger.trace("Found bean property '" + pd.getName() + "'" +
(pd.getPropertyType() != null ? " of type [" + pd.getPropertyType().getName() + "]" : "") +
(pd.getPropertyEditorClass() != null ?
"; editor [" + pd.getPropertyEditorClass().getName() + "]" : ""));
}
if (cacheFullMetadata) {
pd = buildGenericTypeAwarePropertyDescriptor(beanClass, pd);
}
pd = new GenericTypeAwarePropertyDescriptor(beanClass, pd.getName(), pd.getReadMethod(),
pd.getWriteMethod(), pd.getPropertyEditorClass());
this.propertyDescriptorCache.put(pd.getName(), pd);
}
}
catch (IntrospectionException ex) {
throw new FatalBeanException("Failed to obtain BeanInfo for class [" + beanClass.getName() + "]", ex);
throw new FatalBeanException("Cannot get BeanInfo for object of class [" + beanClass.getName() + "]", ex);
}
}
@@ -274,35 +269,17 @@ public class CachedIntrospectionResults {
PropertyDescriptor getPropertyDescriptor(String name) {
PropertyDescriptor pd = this.propertyDescriptorCache.get(name);
if (pd == null && StringUtils.hasLength(name)) {
// Same lenient fallback checking as in PropertyTypeDescriptor...
pd = this.propertyDescriptorCache.get(name.substring(0, 1).toLowerCase() + name.substring(1));
if (pd == null) {
pd = this.propertyDescriptorCache.get(name.substring(0, 1).toUpperCase() + name.substring(1));
}
}
return (pd == null || pd instanceof GenericTypeAwarePropertyDescriptor ? pd :
buildGenericTypeAwarePropertyDescriptor(getBeanClass(), pd));
return pd;
}
PropertyDescriptor[] getPropertyDescriptors() {
PropertyDescriptor[] pds = new PropertyDescriptor[this.propertyDescriptorCache.size()];
int i = 0;
for (PropertyDescriptor pd : this.propertyDescriptorCache.values()) {
pds[i] = (pd instanceof GenericTypeAwarePropertyDescriptor ? pd :
buildGenericTypeAwarePropertyDescriptor(getBeanClass(), pd));
i++;
}
return pds;
}
private PropertyDescriptor buildGenericTypeAwarePropertyDescriptor(Class beanClass, PropertyDescriptor pd) {
try {
return new GenericTypeAwarePropertyDescriptor(beanClass, pd.getName(), pd.getReadMethod(),
pd.getWriteMethod(), pd.getPropertyEditorClass());
}
catch (IntrospectionException ex) {
throw new FatalBeanException("Failed to re-introspect class [" + beanClass.getName() + "]", ex);
}
Collection<PropertyDescriptor> descriptorCollection = this.propertyDescriptorCache.values();
return descriptorCollection.toArray(new PropertyDescriptor[descriptorCollection.size()]);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -22,8 +22,6 @@ import java.util.HashMap;
import java.util.Map;
import org.springframework.core.MethodParameter;
import org.springframework.core.convert.ConversionException;
import org.springframework.core.convert.ConverterNotFoundException;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
@@ -124,15 +122,13 @@ public class DirectFieldAccessor extends AbstractPropertyAccessor {
try {
ReflectionUtils.makeAccessible(field);
oldValue = field.get(this.target);
Object convertedValue = this.typeConverterDelegate.convertIfNecessary(
field.getName(), oldValue, newValue, field.getType(), new TypeDescriptor(field));
Object convertedValue = this.typeConverterDelegate.convertIfNecessary(oldValue, newValue, field);
field.set(this.target, convertedValue);
}
catch (ConverterNotFoundException ex) {
PropertyChangeEvent pce = new PropertyChangeEvent(this.target, propertyName, oldValue, newValue);
throw new ConversionNotSupportedException(pce, field.getType(), ex);
catch (IllegalAccessException ex) {
throw new InvalidPropertyException(this.target.getClass(), propertyName, "Field is not accessible", ex);
}
catch (ConversionException ex) {
catch (IllegalArgumentException ex) {
PropertyChangeEvent pce = new PropertyChangeEvent(this.target, propertyName, oldValue, newValue);
throw new TypeMismatchException(pce, field.getType(), ex);
}
@@ -140,13 +136,6 @@ public class DirectFieldAccessor extends AbstractPropertyAccessor {
PropertyChangeEvent pce = new PropertyChangeEvent(this.target, propertyName, oldValue, newValue);
throw new ConversionNotSupportedException(pce, field.getType(), ex);
}
catch (IllegalArgumentException ex) {
PropertyChangeEvent pce = new PropertyChangeEvent(this.target, propertyName, oldValue, newValue);
throw new TypeMismatchException(pce, field.getType(), ex);
}
catch (IllegalAccessException ex) {
throw new InvalidPropertyException(this.target.getClass(), propertyName, "Field is not accessible", ex);
}
}
public <T> T convertIfNecessary(
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -339,10 +339,8 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
@Override
public String toString() {
PropertyValue[] pvs = getPropertyValues();
StringBuilder sb = new StringBuilder("PropertyValues: length=").append(pvs.length);
if (pvs.length > 0) {
sb.append("; ").append(StringUtils.arrayToDelimitedString(pvs, "; "));
}
StringBuilder sb = new StringBuilder("PropertyValues: length=" + pvs.length + "; ");
sb.append(StringUtils.arrayToDelimitedString(pvs, "; "));
return sb.toString();
}
@@ -42,8 +42,6 @@ import java.util.TimeZone;
import java.util.UUID;
import java.util.regex.Pattern;
import org.xml.sax.InputSource;
import org.springframework.beans.propertyeditors.ByteArrayPropertyEditor;
import org.springframework.beans.propertyeditors.CharArrayPropertyEditor;
import org.springframework.beans.propertyeditors.CharacterEditor;
@@ -56,7 +54,6 @@ import org.springframework.beans.propertyeditors.CustomCollectionEditor;
import org.springframework.beans.propertyeditors.CustomMapEditor;
import org.springframework.beans.propertyeditors.CustomNumberEditor;
import org.springframework.beans.propertyeditors.FileEditor;
import org.springframework.beans.propertyeditors.InputSourceEditor;
import org.springframework.beans.propertyeditors.InputStreamEditor;
import org.springframework.beans.propertyeditors.LocaleEditor;
import org.springframework.beans.propertyeditors.PatternEditor;
@@ -93,8 +90,6 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
private Map<Class, PropertyEditor> defaultEditors;
private Map<Class, PropertyEditor> overriddenDefaultEditors;
private Map<Class, PropertyEditor> customEditors;
private Map<String, CustomEditorHolder> customEditorsForPath;
@@ -143,22 +138,6 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
this.configValueEditorsActive = true;
}
/**
* Override the default editor for the specified type with the given property editor.
* <p>Note that this is different from registering a custom editor in that the editor
* semantically still is a default editor. A ConversionService will override such a
* default editor, whereas custom editors usually override the ConversionService.
* @param requiredType the type of the property
* @param propertyEditor the editor to register
* @see #registerCustomEditor(Class, PropertyEditor)
*/
public void overrideDefaultEditor(Class requiredType, PropertyEditor propertyEditor) {
if (this.overriddenDefaultEditors == null) {
this.overriddenDefaultEditors = new HashMap<Class, PropertyEditor>();
}
this.overriddenDefaultEditors.put(requiredType, propertyEditor);
}
/**
* Retrieve the default editor for the given property type, if any.
* <p>Lazily registers the default editors, if they are active.
@@ -170,14 +149,8 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
if (!this.defaultEditorsActive) {
return null;
}
if (this.overriddenDefaultEditors != null) {
PropertyEditor editor = this.overriddenDefaultEditors.get(requiredType);
if (editor != null) {
return editor;
}
}
if (this.defaultEditors == null) {
createDefaultEditors();
doRegisterDefaultEditors();
}
return this.defaultEditors.get(requiredType);
}
@@ -185,7 +158,7 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
/**
* Actually register the default editors for this registry instance.
*/
private void createDefaultEditors() {
private void doRegisterDefaultEditors() {
this.defaultEditors = new HashMap<Class, PropertyEditor>(64);
// Simple editors, without parameterization capabilities.
@@ -196,7 +169,6 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
this.defaultEditors.put(Currency.class, new CurrencyEditor());
this.defaultEditors.put(File.class, new FileEditor());
this.defaultEditors.put(InputStream.class, new InputStreamEditor());
this.defaultEditors.put(InputSource.class, new InputSourceEditor());
this.defaultEditors.put(Locale.class, new LocaleEditor());
this.defaultEditors.put(Pattern.class, new PatternEditor());
this.defaultEditors.put(Properties.class, new PropertiesEditor());
@@ -258,10 +230,9 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
* @param target the target registry to copy to
*/
protected void copyDefaultEditorsTo(PropertyEditorRegistrySupport target) {
target.defaultEditors = this.defaultEditors;
target.defaultEditorsActive = this.defaultEditorsActive;
target.configValueEditorsActive = this.configValueEditorsActive;
target.defaultEditors = this.defaultEditors;
target.overriddenDefaultEditors = this.overriddenDefaultEditors;
}
@@ -33,7 +33,6 @@ import org.springframework.core.GenericCollectionTypeResolver;
import org.springframework.core.MethodParameter;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.support.PropertyTypeDescriptor;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
@@ -77,6 +76,18 @@ class TypeConverterDelegate {
}
/**
* Convert the value to the specified required type.
* @param newValue the proposed new value
* @param requiredType the type we must convert to
* (or <code>null</code> if not known, for example in case of a collection element)
* @return the new value, possibly the result of type conversion
* @throws IllegalArgumentException if type conversion failed
*/
public <T> T convertIfNecessary(Object newValue, Class<T> requiredType) throws IllegalArgumentException {
return convertIfNecessary(null, null, newValue, requiredType, TypeDescriptor.valueOf(requiredType));
}
/**
* Convert the value to the specified required type.
* @param newValue the proposed new value
@@ -111,6 +122,54 @@ class TypeConverterDelegate {
return convertIfNecessary(propertyName, oldValue, newValue, requiredType, TypeDescriptor.valueOf(requiredType));
}
/**
* Convert the value to the required type (if necessary from a String),
* for the specified property.
* @param propertyName name of the property
* @param oldValue the previous value, if available (may be <code>null</code>)
* @param newValue the proposed new value
* @param requiredType the type we must convert to
* (or <code>null</code> if not known, for example in case of a collection element)
* @param methodParam the method parameter that is the target of the conversion
* @return the new value, possibly the result of type conversion
* @throws IllegalArgumentException if type conversion failed
*/
public <T> T convertIfNecessary(String propertyName, Object oldValue, Object newValue,
Class<T> requiredType, MethodParameter methodParam) throws IllegalArgumentException {
return convertIfNecessary(propertyName, oldValue, newValue, requiredType, new TypeDescriptor(methodParam));
}
/**
* Convert the value to the required type for the specified property.
* @param oldValue the previous value, if available (may be <code>null</code>)
* @param newValue the proposed new value
* @param descriptor the JavaBeans descriptor for the property
* @return the new value, possibly the result of type conversion
* @throws IllegalArgumentException if type conversion failed
*/
public Object convertIfNecessary(Object oldValue, Object newValue, PropertyDescriptor descriptor)
throws IllegalArgumentException {
return convertIfNecessary(descriptor.getName(), oldValue, newValue, descriptor.getPropertyType(),
new BeanTypeDescriptor(descriptor));
}
/**
* Convert the value to the required type for the specified property.
* @param oldValue the previous value, if available (may be <code>null</code>)
* @param newValue the proposed new value
* @param field the field that is the target of the conversion
* @return the new value, possibly the result of type conversion
* @throws IllegalArgumentException if type conversion failed
*/
public Object convertIfNecessary(Object oldValue, Object newValue, Field field)
throws IllegalArgumentException {
return convertIfNecessary(field.getName(), oldValue, newValue, field.getType(), new TypeDescriptor(field));
}
/**
* Convert the value to the required type (if necessary from a String),
* for the specified property.
@@ -124,7 +183,7 @@ class TypeConverterDelegate {
* @throws IllegalArgumentException if type conversion failed
*/
@SuppressWarnings("unchecked")
public <T> T convertIfNecessary(String propertyName, Object oldValue, Object newValue,
private <T> T convertIfNecessary(String propertyName, Object oldValue, Object newValue,
Class<T> requiredType, TypeDescriptor typeDescriptor) throws IllegalArgumentException {
Object convertedValue = newValue;
@@ -136,9 +195,8 @@ class TypeConverterDelegate {
ConversionService conversionService = this.propertyEditorRegistry.getConversionService();
if (editor == null && conversionService != null && convertedValue != null) {
TypeDescriptor sourceTypeDesc = TypeDescriptor.forObject(convertedValue);
TypeDescriptor targetTypeDesc = typeDescriptor.forElementType(requiredType);
if (conversionService.canConvert(sourceTypeDesc, targetTypeDesc)) {
return (T) conversionService.convert(convertedValue, sourceTypeDesc, targetTypeDesc);
if (conversionService.canConvert(sourceTypeDesc, typeDescriptor)) {
return (T) conversionService.convert(convertedValue, sourceTypeDesc, typeDescriptor);
}
}
@@ -146,8 +204,8 @@ class TypeConverterDelegate {
if (editor != null || (requiredType != null && !ClassUtils.isAssignableValue(requiredType, convertedValue))) {
if (requiredType != null && Collection.class.isAssignableFrom(requiredType) &&
convertedValue instanceof String && typeDescriptor.getMethodParameter() != null) {
Class elemType = GenericCollectionTypeResolver.getCollectionParameterType(typeDescriptor.getMethodParameter());
if (elemType != null && Enum.class.isAssignableFrom(elemType)) {
Class elementType = GenericCollectionTypeResolver.getCollectionParameterType(typeDescriptor.getMethodParameter());
if (elementType != null && Enum.class.isAssignableFrom(elementType)) {
convertedValue = StringUtils.commaDelimitedListToStringArray((String) convertedValue);
}
}
@@ -290,8 +348,8 @@ class TypeConverterDelegate {
*/
protected PropertyEditor findDefaultEditor(Class requiredType, TypeDescriptor typeDescriptor) {
PropertyEditor editor = null;
if (typeDescriptor instanceof PropertyTypeDescriptor) {
PropertyDescriptor pd = ((PropertyTypeDescriptor) typeDescriptor).getPropertyDescriptor();
if (typeDescriptor instanceof BeanTypeDescriptor) {
PropertyDescriptor pd = ((BeanTypeDescriptor) typeDescriptor).getPropertyDescriptor();
editor = pd.createPropertyEditor(this.targetObject);
}
if (editor == null && requiredType != null) {
@@ -460,10 +518,6 @@ class TypeConverterDelegate {
Collection original, String propertyName, Class requiredType, TypeDescriptor typeDescriptor) {
boolean originalAllowed = requiredType.isInstance(original);
if (!originalAllowed && !Collection.class.isAssignableFrom(requiredType)) {
return original;
}
MethodParameter methodParam = typeDescriptor.getMethodParameter();
Class elementType = null;
if (methodParam != null) {
@@ -517,8 +571,8 @@ class TypeConverterDelegate {
if (methodParam != null) {
methodParam.increaseNestingLevel();
}
Object convertedElement = convertIfNecessary(
indexedPropertyName, null, element, elementType, typeDescriptor);
Object convertedElement =
convertIfNecessary(indexedPropertyName, null, element, elementType, typeDescriptor);
if (methodParam != null) {
methodParam.decreaseNestingLevel();
}
@@ -538,14 +592,8 @@ class TypeConverterDelegate {
}
@SuppressWarnings("unchecked")
protected Map convertToTypedMap(
Map original, String propertyName, Class requiredType, TypeDescriptor typeDescriptor) {
protected Map convertToTypedMap(Map original, String propertyName, Class requiredType, TypeDescriptor typeDescriptor) {
boolean originalAllowed = requiredType.isInstance(original);
if (!originalAllowed && !Map.class.isAssignableFrom(requiredType)) {
return original;
}
Class keyType = null;
Class valueType = null;
MethodParameter methodParam = typeDescriptor.getMethodParameter();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -153,14 +153,8 @@ public interface BeanFactory {
* Return the bean instance that uniquely matches the given object type, if any.
* @param requiredType type the bean must match; can be an interface or superclass.
* {@literal null} is disallowed.
* <p>This method goes into {@link ListableBeanFactory} by-type lookup territory
* but may also be translated into a conventional by-name lookup based on the name
* of the given type. For more extensive retrieval operations across sets of beans,
* use {@link ListableBeanFactory} and/or {@link BeanFactoryUtils}.
* @return an instance of the single bean matching the required type
* @return bean matching required type
* @throws NoSuchBeanDefinitionException if there is not exactly one matching bean found
* @since 3.0
* @see ListableBeanFactory
*/
<T> T getBean(Class<T> requiredType) throws BeansException;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -193,7 +193,7 @@ public abstract class AbstractFactoryBean<T>
* interface, for a consistent offering of abstract template methods.
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
*/
public abstract Class<?> getObjectType();
public abstract Class<? extends T> getObjectType();
/**
* Template method that subclasses must override to construct
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -183,9 +183,6 @@ public class BeanDefinitionVisitor {
return new RuntimeBeanNameReference(newBeanName);
}
}
else if (value instanceof Object[]) {
visitArray((Object[]) value);
}
else if (value instanceof List) {
visitList((List) value);
}
@@ -209,17 +206,6 @@ public class BeanDefinitionVisitor {
return value;
}
@SuppressWarnings("unchecked")
protected void visitArray(Object[] arrayVal) {
for (int i = 0; i < arrayVal.length; i++) {
Object elem = arrayVal[i];
Object newVal = resolveValue(elem);
if (!ObjectUtils.nullSafeEquals(newVal, elem)) {
arrayVal[i] = newVal;
}
}
}
@SuppressWarnings("unchecked")
protected void visitList(List listVal) {
for (int i = 0; i < listVal.size(); i++) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -48,8 +48,7 @@ public interface BeanPostProcessor {
* The returned bean instance may be a wrapper around the original.
* @param bean the new bean instance
* @param beanName the name of the bean
* @return the bean instance to use, either the original or a wrapped one; if
* <code>null</code>, no subsequent BeanPostProcessors will be invoked
* @return the bean instance to use, either the original or a wrapped one
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
*/
@@ -69,8 +68,7 @@ public interface BeanPostProcessor {
* in contrast to all other BeanPostProcessor callbacks.
* @param bean the new bean instance
* @param beanName the name of the bean
* @return the bean instance to use, either the original or a wrapped one; if
* <code>null</code>, no subsequent BeanPostProcessors will be invoked
* @return the bean instance to use, either the original or a wrapped one
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
* @see org.springframework.beans.factory.FactoryBean
@@ -1,94 +0,0 @@
/*
* Copyright 2002-2010 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.config;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.util.StringUtils;
/**
* Bean factory post processor that logs a warning for {@link Deprecated @Deprecated} beans.
*
* @author Arjen Poutsma
* @since 3.0.3
*/
public class DeprecatedBeanWarner implements BeanFactoryPostProcessor {
/**
* Logger available to subclasses.
*/
protected transient Log logger = LogFactory.getLog(getClass());
/**
* Set the name of the logger to use. The name will be passed to the underlying logger implementation through
* Commons Logging, getting interpreted as log category according to the logger's configuration.
* <p>This can be specified to not log into the category of this warner class but rather into a specific named category.
* @see org.apache.commons.logging.LogFactory#getLog(String)
* @see org.apache.log4j.Logger#getLogger(String)
* @see java.util.logging.Logger#getLogger(String)
*/
public void setLoggerName(String loggerName) {
this.logger = LogFactory.getLog(loggerName);
}
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
if (isLogEnabled()) {
String[] beanNames = beanFactory.getBeanDefinitionNames();
for (String beanName : beanNames) {
Class<?> beanType = beanFactory.getType(beanName);
if (beanType != null && beanType.isAnnotationPresent(Deprecated.class)) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
logDeprecatedBean(beanName, beanDefinition);
}
}
}
}
/**
* Logs a warning for a bean annotated with {@link Deprecated @Deprecated}.
*
* @param beanName the name of the deprecated bean
* @param beanDefinition the definition of the deprecated bean
*/
protected void logDeprecatedBean(String beanName, BeanDefinition beanDefinition) {
StringBuilder builder = new StringBuilder();
builder.append(beanDefinition.getBeanClassName());
builder.append(" ['");
builder.append(beanName);
builder.append('\'');
String resourceDescription = beanDefinition.getResourceDescription();
if (StringUtils.hasLength(resourceDescription)) {
builder.append(" in ");
builder.append(resourceDescription);
}
builder.append(" ] has been deprecated");
logger.warn(builder.toString());
}
/**
* Determine whether the {@link #logger} field is enabled.
* <p>Default is {@code true} when the "warn" level is enabled. Subclasses can override this to change the level
* under which logging occurs.
*/
protected boolean isLogEnabled() {
return logger.isWarnEnabled();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -16,10 +16,7 @@
package org.springframework.beans.factory.config;
import java.io.Serializable;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.util.Assert;
@@ -44,7 +41,7 @@ import org.springframework.util.Assert;
* <pre class="code">&lt;beans&gt;
*
* &lt;!-- Prototype bean since we have state --&gt;
* &lt;bean id="myService" class="a.b.c.MyService" scope="prototype"/&gt;
* &lt;bean id="myService" class="a.b.c.MyService" singleton="false"/&gt;
*
* &lt;bean id="myServiceFactory"
* class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean"&gt;
@@ -66,9 +63,9 @@ import org.springframework.util.Assert;
*
* public class MyClientBean {
*
* private ObjectFactory&lt;MyService&gt; myServiceFactory;
* private ObjectFactory myServiceFactory;
*
* public void setMyServiceFactory(ObjectFactory&lt;MyService&gt; myServiceFactory) {
* public void setMyServiceFactory(ObjectFactory myServiceFactory) {
* this.myServiceFactory = myServiceFactory;
* }
*
@@ -94,17 +91,20 @@ import org.springframework.util.Assert;
* @see org.springframework.beans.factory.ObjectFactory
* @see ServiceLocatorFactoryBean
*/
public class ObjectFactoryCreatingFactoryBean extends AbstractFactoryBean<ObjectFactory> {
public class ObjectFactoryCreatingFactoryBean extends AbstractFactoryBean {
private String targetBeanName;
/**
* Set the name of the target bean.
* <p>The target does not <i>have</> to be a non-singleton bean, but realisticially
* always will be (because if the target bean were a singleton, then said singleton
* bean could simply be injected straight into the dependent object, thus obviating
* the need for the extra level of indirection afforded by this factory approach).
* <p>The target does not <i>have</> to be a prototype bean, but realisticially
* always will be (because if the target bean were a singleton, then said
* singleton bean could simply be injected straight into the dependent object,
* thus obviating the need for the extra level of indirection afforded by
* the approach encapsulated by this class). Please note that no exception
* will be thrown if the supplied <code>targetBeanName</code> does not
* reference a prototype bean.
*/
public void setTargetBeanName(String targetBeanName) {
this.targetBeanName = targetBeanName;
@@ -123,28 +123,22 @@ public class ObjectFactoryCreatingFactoryBean extends AbstractFactoryBean<Object
}
@Override
protected ObjectFactory createInstance() {
return new TargetBeanObjectFactory(getBeanFactory(), this.targetBeanName);
protected Object createInstance() {
return new ObjectFactory() {
public Object getObject() throws BeansException {
return getTargetBean(targetBeanName);
}
};
}
/**
* Independent inner class - for serialization purposes.
* Template method for obtaining a target bean instance.
* Called by the exposed ObjectFactory's <code>getObject()</code> method.
* @param targetBeanName the name of the target bean
* @return the target bean instance
*/
private static class TargetBeanObjectFactory implements ObjectFactory, Serializable {
private final BeanFactory beanFactory;
private final String targetBeanName;
public TargetBeanObjectFactory(BeanFactory beanFactory, String targetBeanName) {
this.beanFactory = beanFactory;
this.targetBeanName = targetBeanName;
}
public Object getObject() throws BeansException {
return this.beanFactory.getBean(this.targetBeanName);
}
protected Object getTargetBean(String targetBeanName) {
return getBeanFactory().getBean(targetBeanName);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -193,8 +193,7 @@ public class PropertyPathFactoryBean implements FactoryBean<Object>, BeanNameAwa
public Object getObject() throws BeansException {
BeanWrapper target = this.targetBeanWrapper;
if (target != null) {
if (logger.isWarnEnabled() && this.targetBeanName != null &&
this.beanFactory instanceof ConfigurableBeanFactory &&
if (logger.isWarnEnabled() && this.beanFactory instanceof ConfigurableBeanFactory &&
((ConfigurableBeanFactory) this.beanFactory).isCurrentlyInCreation(this.targetBeanName)) {
logger.warn("Target bean '" + this.targetBeanName + "' is still in creation due to a circular " +
"reference - obtained value for property '" + this.propertyPath + "' may be outdated!");
@@ -1,95 +0,0 @@
/*
* Copyright 2002-2010 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.config;
import java.io.Serializable;
import javax.inject.Provider;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.util.Assert;
/**
* A {@link org.springframework.beans.factory.FactoryBean} implementation that
* returns a value which is a JSR-330 {@link javax.inject.Provider} that in turn
* returns a bean sourced from a {@link org.springframework.beans.factory.BeanFactory}.
*
* <p>This is basically a JSR-330 compliant variant of Spring's good old
* {@link ObjectFactoryCreatingFactoryBean}. It can be used for traditional
* external dependency injection configuration that targets a property or
* constructor argument of type <code>javax.inject.Provider</code>, as an
* alternative to JSR-330's <code>@Inject</code> annotation-driven approach.
*
* @author Juergen Hoeller
* @since 3.0.2
* @see javax.inject.Provider
* @see ObjectFactoryCreatingFactoryBean
*/
public class ProviderCreatingFactoryBean extends AbstractFactoryBean<Provider> {
private String targetBeanName;
/**
* Set the name of the target bean.
* <p>The target does not <i>have</> to be a non-singleton bean, but realisticially
* always will be (because if the target bean were a singleton, then said singleton
* bean could simply be injected straight into the dependent object, thus obviating
* the need for the extra level of indirection afforded by this factory approach).
*/
public void setTargetBeanName(String targetBeanName) {
this.targetBeanName = targetBeanName;
}
@Override
public void afterPropertiesSet() throws Exception {
Assert.hasText(this.targetBeanName, "Property 'targetBeanName' is required");
super.afterPropertiesSet();
}
@Override
public Class getObjectType() {
return Provider.class;
}
@Override
protected Provider createInstance() {
return new TargetBeanProvider(getBeanFactory(), this.targetBeanName);
}
/**
* Independent inner class - for serialization purposes.
*/
private static class TargetBeanProvider implements Provider, Serializable {
private final BeanFactory beanFactory;
private final String targetBeanName;
public TargetBeanProvider(BeanFactory beanFactory, String targetBeanName) {
this.beanFactory = beanFactory;
this.targetBeanName = targetBeanName;
}
public Object get() throws BeansException {
return this.beanFactory.getBean(this.targetBeanName);
}
}
}
@@ -392,9 +392,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessBeforeInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
@@ -405,9 +402,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
@@ -688,14 +682,11 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
*/
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (bean != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
if (exposedObject == null) {
return exposedObject;
}
}
}
}
@@ -1139,7 +1130,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// Do not allow eager init for type matching in case of a prioritized post-processor.
boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
DependencyDescriptor desc = new DependencyDescriptor(methodParam, false, eager);
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
pvs.add(propertyName, autowiredArgument);
@@ -1562,21 +1553,4 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
this.factoryBeanInstanceCache.remove(beanName);
}
/**
* Special DependencyDescriptor variant for autowire="byType".
* Always optional; never considering the parameter name for choosing a primary candidate.
*/
private static class AutowireByTypeDependencyDescriptor extends DependencyDescriptor {
public AutowireByTypeDependencyDescriptor(MethodParameter methodParameter, boolean eager) {
super(methodParameter, false, eager);
}
@Override
public String getDependencyName() {
return null;
}
}
}
@@ -57,7 +57,6 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.SmartFactoryBean;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.BeanExpressionContext;
import org.springframework.beans.factory.config.BeanExpressionResolver;
import org.springframework.beans.factory.config.BeanPostProcessor;
@@ -223,7 +222,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
* @throws BeansException if the bean could not be created
*/
@SuppressWarnings("unchecked")
protected <T> T doGetBean(
private <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
@@ -474,20 +473,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
return parentBeanFactory.isTypeMatch(originalBeanName(name), targetType);
}
// Retrieve corresponding bean definition.
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// Check decorated bean definition, if any: We assume it'll be easier
// to determine the decorated bean's type than the proxy's type.
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
if (dbd != null && !BeanFactoryUtils.isFactoryDereference(name)) {
RootBeanDefinition tbd = getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd);
Class targetClass = predictBeanType(dbd.getBeanName(), tbd, FactoryBean.class, typeToMatch);
if (targetClass != null && !FactoryBean.class.isAssignableFrom(targetClass)) {
return typeToMatch.isAssignableFrom(targetClass);
}
}
Class beanClass = predictBeanType(beanName, mbd, FactoryBean.class, typeToMatch);
if (beanClass == null) {
return false;
@@ -534,24 +520,12 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
}
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// Check decorated bean definition, if any: We assume it'll be easier
// to determine the decorated bean's type than the proxy's type.
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
if (dbd != null && !BeanFactoryUtils.isFactoryDereference(name)) {
RootBeanDefinition tbd = getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd);
Class targetClass = predictBeanType(dbd.getBeanName(), tbd);
if (targetClass != null && !FactoryBean.class.isAssignableFrom(targetClass)) {
return targetClass;
}
}
Class beanClass = predictBeanType(beanName, mbd);
// Check bean class whether we're dealing with a FactoryBean.
if (beanClass != null && FactoryBean.class.isAssignableFrom(beanClass)) {
if (!BeanFactoryUtils.isFactoryDereference(name)) {
// If it's a FactoryBean, we want to look at what it creates, not at the factory class.
// If it's a FactoryBean, we want to look at what it creates, not the factory class.
return getTypeForFactoryBean(beanName, mbd);
}
else {
@@ -927,7 +901,6 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
}
public boolean isCurrentlyInCreation(String beanName) {
Assert.notNull(beanName, "Bean name must not be null");
return isSingletonCurrentlyInCreation(beanName) || isPrototypeCurrentlyInCreation(beanName);
}
@@ -1268,7 +1241,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
if (this.beanExpressionResolver == null) {
return value;
}
Scope scope = (beanDefinition != null ? getRegisteredScope(beanDefinition.getScope()) : null);
Scope scope = getRegisteredScope(beanDefinition.getScope());
return this.beanExpressionResolver.evaluate(value, new BeanExpressionContext(this, scope));
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -136,15 +136,11 @@ abstract class AutowireUtils {
* @return the resolved value
*/
public static Object resolveAutowiringValue(Object autowiringValue, Class requiredType) {
if (autowiringValue instanceof ObjectFactory && !requiredType.isInstance(autowiringValue)) {
ObjectFactory factory = (ObjectFactory) autowiringValue;
if (autowiringValue instanceof Serializable && requiredType.isInterface()) {
autowiringValue = Proxy.newProxyInstance(requiredType.getClassLoader(),
new Class[] {requiredType}, new ObjectFactoryDelegatingInvocationHandler(factory));
}
else {
return factory.getObject();
}
if (autowiringValue instanceof ObjectFactory && !requiredType.isInstance(autowiringValue) &&
autowiringValue instanceof Serializable && requiredType.isInterface()) {
autowiringValue = Proxy.newProxyInstance(
requiredType.getClassLoader(), new Class[] {requiredType},
new ObjectFactoryDelegatingInvocationHandler((ObjectFactory) autowiringValue));
}
return autowiringValue;
}
@@ -42,7 +42,6 @@ import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.UnsatisfiedDependencyException;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder;
import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.beans.factory.config.TypedStringValue;
import org.springframework.core.GenericTypeResolver;
@@ -52,7 +51,6 @@ import org.springframework.util.ClassUtils;
import org.springframework.util.MethodInvoker;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
/**
* Helper class for resolving constructors and factory methods.
@@ -110,7 +108,6 @@ class ConstructorResolver {
this.beanFactory.initBeanWrapper(bw);
Constructor constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
if (explicitArgs != null) {
@@ -178,7 +175,7 @@ class ConstructorResolver {
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
}
ArgumentsHolder argsHolder;
ArgumentsHolder args;
if (resolvedValues != null) {
try {
String[] paramNames = null;
@@ -191,7 +188,7 @@ class ConstructorResolver {
paramNames = pnd.getParameterNames(candidate);
}
}
argsHolder = createArgumentArray(
args = createArgumentArray(
beanName, mbd, resolvedValues, bw, paramTypes, paramNames, candidate, autowiring);
}
catch (UnsatisfiedDependencyException ex) {
@@ -222,16 +219,15 @@ class ConstructorResolver {
if (paramTypes.length != explicitArgs.length) {
continue;
}
argsHolder = new ArgumentsHolder(explicitArgs);
args = new ArgumentsHolder(explicitArgs);
}
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
args.getTypeDifferenceWeight(paramTypes) : args.getAssignabilityWeight(paramTypes));
// Choose this constructor if it represents the closest match.
if (typeDiffWeight < minTypeDiffWeight) {
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
argsToUse = args.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousConstructors = null;
}
@@ -257,7 +253,6 @@ class ConstructorResolver {
if (explicitArgs == null) {
mbd.resolvedConstructorOrFactoryMethod = constructorToUse;
argsHolderToUse.storeCache(mbd);
}
}
@@ -275,8 +270,8 @@ class ConstructorResolver {
}, beanFactory.getAccessControlContext());
}
else {
beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
beanInstance = beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, beanFactory, constructorToUse, argsToUse);
}
bw.setWrappedInstance(beanInstance);
@@ -366,7 +361,6 @@ class ConstructorResolver {
}
Method factoryMethodToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
if (explicitArgs != null) {
@@ -438,7 +432,7 @@ class ConstructorResolver {
Class[] paramTypes = candidate.getParameterTypes();
if (paramTypes.length >= minNrOfArgs) {
ArgumentsHolder argsHolder;
ArgumentsHolder args;
if (resolvedValues != null) {
// Resolved constructor arguments: type conversion and/or autowiring necessary.
@@ -448,7 +442,7 @@ class ConstructorResolver {
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
argsHolder = createArgumentArray(
args = createArgumentArray(
beanName, mbd, resolvedValues, bw, paramTypes, paramNames, candidate, autowiring);
}
catch (UnsatisfiedDependencyException ex) {
@@ -480,16 +474,15 @@ class ConstructorResolver {
if (paramTypes.length != explicitArgs.length) {
continue;
}
argsHolder = new ArgumentsHolder(explicitArgs);
args = new ArgumentsHolder(explicitArgs);
}
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
args.getTypeDifferenceWeight(paramTypes) : args.getAssignabilityWeight(paramTypes));
// Choose this factory method if it represents the closest match.
if (typeDiffWeight < minTypeDiffWeight) {
factoryMethodToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
argsToUse = args.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousFactoryMethods = null;
}
@@ -504,25 +497,12 @@ class ConstructorResolver {
}
if (factoryMethodToUse == null) {
boolean hasArgs = resolvedValues.getArgumentCount() > 0;
String argDesc = "";
if (hasArgs) {
List<String> argTypes = new ArrayList<String>();
for (ValueHolder value : resolvedValues.getIndexedArgumentValues().values()) {
String argType = value.getType() != null ?
ClassUtils.getShortName(value.getType()) : value.getValue().getClass().getSimpleName();
argTypes.add(argType);
}
argDesc = StringUtils.collectionToCommaDelimitedString(argTypes);
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"No matching factory method found: " +
(mbd.getFactoryBeanName() != null ?
"factory bean '" + mbd.getFactoryBeanName() + "'; " : "") +
"factory method '" + mbd.getFactoryMethodName() + "(" + argDesc + ")'. " +
"Check that a method with the specified name " +
(hasArgs ? "and arguments " : "") +
"exists and that it is " +
"factory bean '" + mbd.getFactoryBeanName() + "'; " : "") +
"factory method '" + mbd.getFactoryMethodName() + "'. " +
"Check that a method of the specified name exists and that it is " +
(isStatic ? "static" : "non-static") + ".");
}
else if (void.class.equals(factoryMethodToUse.getReturnType())) {
@@ -539,7 +519,6 @@ class ConstructorResolver {
if (explicitArgs == null) {
mbd.resolvedConstructorOrFactoryMethod = factoryMethodToUse;
argsHolderToUse.storeCache(mbd);
}
}
@@ -646,6 +625,7 @@ class ConstructorResolver {
Set<ConstructorArgumentValues.ValueHolder> usedValueHolders =
new HashSet<ConstructorArgumentValues.ValueHolder>(paramTypes.length);
Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);
boolean resolveNecessary = false;
for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
Class<?> paramType = paramTypes[paramIndex];
@@ -682,7 +662,7 @@ class ConstructorResolver {
args.preparedArguments[paramIndex] = convertedValue;
}
else {
args.resolveNecessary = true;
resolveNecessary = true;
args.preparedArguments[paramIndex] = sourceValue;
}
}
@@ -712,7 +692,7 @@ class ConstructorResolver {
args.rawArguments[paramIndex] = autowiredArgument;
args.arguments[paramIndex] = autowiredArgument;
args.preparedArguments[paramIndex] = new AutowiredArgumentMarker();
args.resolveNecessary = true;
resolveNecessary = true;
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(
@@ -729,6 +709,13 @@ class ConstructorResolver {
}
}
if (resolveNecessary) {
mbd.preparedConstructorArguments = args.preparedArguments;
}
else {
mbd.resolvedConstructorArguments = args.arguments;
}
mbd.constructorArgumentsResolved = true;
return args;
}
@@ -797,8 +784,6 @@ class ConstructorResolver {
public Object preparedArguments[];
public boolean resolveNecessary = false;
public ArgumentsHolder(int size) {
this.rawArguments = new Object[size];
this.arguments = new Object[size];
@@ -834,16 +819,6 @@ class ConstructorResolver {
}
return Integer.MAX_VALUE - 1024;
}
public void storeCache(RootBeanDefinition mbd) {
if (this.resolveNecessary) {
mbd.preparedConstructorArguments = this.preparedArguments;
}
else {
mbd.resolvedConstructorArguments = this.arguments;
}
mbd.constructorArgumentsResolved = true;
}
}
@@ -248,17 +248,6 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
public <T> T getBean(Class<T> requiredType) throws BeansException {
Assert.notNull(requiredType, "Required type must not be null");
String[] beanNames = getBeanNamesForType(requiredType);
if (beanNames.length > 1) {
ArrayList<String> autowireCandidates = new ArrayList<String>();
for (String beanName : beanNames) {
if (getBeanDefinition(beanName).isAutowireCandidate()) {
autowireCandidates.add(beanName);
}
}
if (autowireCandidates.size() > 0) {
beanNames = autowireCandidates.toArray(new String[autowireCandidates.size()]);
}
}
if (beanNames.length == 1) {
return getBean(beanNames[0], requiredType);
}
@@ -273,7 +262,6 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
@Override
public boolean containsBeanDefinition(String beanName) {
Assert.notNull(beanName, "Bean name must not be null");
return this.beanDefinitionMap.containsKey(beanName);
}
@@ -586,7 +574,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.hasText(beanName, "'beanName' must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
@@ -705,8 +693,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
if (value != null) {
if (value instanceof String) {
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
value = evaluateBeanDefinitionString(strVal, bd);
value = evaluateBeanDefinitionString(strVal, getMergedBeanDefinition(beanName));
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
return converter.convertIfNecessary(value, type);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -363,12 +363,11 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
* @param dependentBeanName the name of the dependent bean
*/
public void registerDependentBean(String beanName, String dependentBeanName) {
String canonicalName = canonicalName(beanName);
synchronized (this.dependentBeanMap) {
Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
Set<String> dependentBeans = this.dependentBeanMap.get(beanName);
if (dependentBeans == null) {
dependentBeans = new LinkedHashSet<String>(8);
this.dependentBeanMap.put(canonicalName, dependentBeans);
this.dependentBeanMap.put(beanName, dependentBeans);
}
dependentBeans.add(dependentBeanName);
}
@@ -378,7 +377,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
dependenciesForBean = new LinkedHashSet<String>(8);
this.dependenciesForBeanMap.put(dependentBeanName, dependenciesForBean);
}
dependenciesForBean.add(canonicalName);
dependenciesForBean.add(beanName);
}
}
@@ -456,7 +455,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
removeSingleton(beanName);
// Destroy the corresponding DisposableBean instance.
DisposableBean disposableBean;
DisposableBean disposableBean = null;
synchronized (this.disposableBeans) {
disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -123,6 +123,8 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
final FactoryBean factory, final String beanName, final boolean shouldPostProcess)
throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {
@@ -133,8 +135,7 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
return factory.getObject();
}
}, acc);
}
catch (PrivilegedActionException pae) {
} catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
@@ -1,12 +1,12 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* 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.
@@ -32,7 +32,7 @@ import org.springframework.beans.factory.BeanFactory;
* @since 1.1
*/
public interface InstantiationStrategy {
/**
* Return an instance of the bean with the given name in this factory.
* @param beanDefinition the bean definition
@@ -43,9 +43,9 @@ public interface InstantiationStrategy {
* @return a bean instance for this bean definition
* @throws BeansException if the instantiation failed
*/
Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner)
throws BeansException;
Object instantiate(
RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) throws BeansException;
/**
* Return an instance of the bean with the given name in this factory,
* creating it via the given constructor.
@@ -59,9 +59,10 @@ public interface InstantiationStrategy {
* @return a bean instance for this bean definition
* @throws BeansException if the instantiation failed
*/
Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner,
Constructor<?> ctor, Object[] args) throws BeansException;
Object instantiate(
RootBeanDefinition beanDefinition, String beanName, BeanFactory owner,
Constructor ctor, Object[] args) throws BeansException;
/**
* Return an instance of the bean with the given name in this factory,
* creating it via the given factory method.
@@ -77,7 +78,8 @@ public interface InstantiationStrategy {
* @return a bean instance for this bean definition
* @throws BeansException if the instantiation failed
*/
Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner,
Object instantiate(
RootBeanDefinition beanDefinition, String beanName, BeanFactory owner,
Object factoryBean, Method factoryMethod, Object[] args) throws BeansException;
}
@@ -24,7 +24,6 @@ import java.util.Set;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.util.Assert;
@@ -54,8 +53,6 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
private final Set<String> externallyManagedDestroyMethods = Collections.synchronizedSet(new HashSet<String>());
private BeanDefinitionHolder decoratedDefinition;
boolean isFactoryMethodUnique;
/** Package-visible field for caching the resolved constructor or factory method */
@@ -78,6 +75,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
final Object postProcessingLock = new Object();
/**
* Create a new RootBeanDefinition, to be configured through its bean
* properties and configuration methods.
@@ -226,9 +224,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
RootBeanDefinition(BeanDefinition original) {
super(original);
if (original instanceof RootBeanDefinition) {
RootBeanDefinition originalRbd = (RootBeanDefinition) original;
this.decoratedDefinition = originalRbd.decoratedDefinition;
this.isFactoryMethodUnique = originalRbd.isFactoryMethodUnique;
this.isFactoryMethodUnique = ((RootBeanDefinition) original).isFactoryMethodUnique;
}
}
@@ -293,14 +289,6 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
return this.externallyManagedDestroyMethods.contains(destroyMethod);
}
public void setDecoratedDefinition(BeanDefinitionHolder decoratedDefinition) {
this.decoratedDefinition = decoratedDefinition;
}
public BeanDefinitionHolder getDecoratedDefinition() {
return this.decoratedDefinition;
}
@Override
public RootBeanDefinition cloneBeanDefinition() {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -42,10 +42,12 @@ import org.springframework.util.StringUtils;
*/
public class SimpleInstantiationStrategy implements InstantiationStrategy {
public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
public Object instantiate(
RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (beanDefinition.getMethodOverrides().isEmpty()) {
Constructor<?> constructorToUse = (Constructor<?>) beanDefinition.resolvedConstructorOrFactoryMethod;
Constructor constructorToUse = (Constructor) beanDefinition.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class clazz = beanDefinition.getBeanClass();
if (clazz.isInterface()) {
@@ -58,8 +60,7 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy {
return clazz.getDeclaredConstructor((Class[]) null);
}
});
}
else {
} else {
constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
}
beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse;
@@ -89,8 +90,9 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy {
"Method Injection not supported in SimpleInstantiationStrategy");
}
public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner,
final Constructor<?> ctor, Object[] args) {
public Object instantiate(
RootBeanDefinition beanDefinition, String beanName, BeanFactory owner,
final Constructor ctor, Object[] args) {
if (beanDefinition.getMethodOverrides().isEmpty()) {
if (System.getSecurityManager() != null) {
@@ -115,14 +117,16 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy {
* the Method Injection specified in the given RootBeanDefinition.
* Instantiation should use the given constructor and parameters.
*/
protected Object instantiateWithMethodInjection(RootBeanDefinition beanDefinition,
String beanName, BeanFactory owner, Constructor ctor, Object[] args) {
protected Object instantiateWithMethodInjection(
RootBeanDefinition beanDefinition, String beanName, BeanFactory owner,
Constructor ctor, Object[] args) {
throw new UnsupportedOperationException(
"Method Injection not supported in SimpleInstantiationStrategy");
}
public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner,
public Object instantiate(
RootBeanDefinition beanDefinition, String beanName, BeanFactory owner,
Object factoryBean, final Method factoryMethod, Object[] args) {
try {
@@ -155,5 +159,4 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy {
"Factory method [" + factoryMethod + "] threw exception", ex.getTargetException());
}
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -621,7 +621,7 @@ public class BeanDefinitionParserDelegate {
NodeList nl = ele.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (isCandidateElement(node) && nodeNameEquals(node, META_ELEMENT)) {
if (node instanceof Element && nodeNameEquals(node, META_ELEMENT)) {
Element metaElement = (Element) node;
String key = metaElement.getAttribute(KEY_ATTRIBUTE);
String value = metaElement.getAttribute(VALUE_ATTRIBUTE);
@@ -680,7 +680,7 @@ public class BeanDefinitionParserDelegate {
NodeList nl = beanEle.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (isCandidateElement(node) && nodeNameEquals(node, CONSTRUCTOR_ARG_ELEMENT)) {
if (node instanceof Element && nodeNameEquals(node, CONSTRUCTOR_ARG_ELEMENT)) {
parseConstructorArgElement((Element) node, bd);
}
}
@@ -693,7 +693,7 @@ public class BeanDefinitionParserDelegate {
NodeList nl = beanEle.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (isCandidateElement(node) && nodeNameEquals(node, PROPERTY_ELEMENT)) {
if (node instanceof Element && nodeNameEquals(node, PROPERTY_ELEMENT)) {
parsePropertyElement((Element) node, bd);
}
}
@@ -706,7 +706,7 @@ public class BeanDefinitionParserDelegate {
NodeList nl = beanEle.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (isCandidateElement(node) && nodeNameEquals(node, QUALIFIER_ELEMENT)) {
if (node instanceof Element && nodeNameEquals(node, QUALIFIER_ELEMENT)) {
parseQualifierElement((Element) node, bd);
}
}
@@ -719,7 +719,7 @@ public class BeanDefinitionParserDelegate {
NodeList nl = beanEle.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (isCandidateElement(node) && nodeNameEquals(node, LOOKUP_METHOD_ELEMENT)) {
if (node instanceof Element && nodeNameEquals(node, LOOKUP_METHOD_ELEMENT)) {
Element ele = (Element) node;
String methodName = ele.getAttribute(NAME_ATTRIBUTE);
String beanRef = ele.getAttribute(BEAN_ELEMENT);
@@ -737,7 +737,7 @@ public class BeanDefinitionParserDelegate {
NodeList nl = beanEle.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (isCandidateElement(node) && nodeNameEquals(node, REPLACED_METHOD_ELEMENT)) {
if (node instanceof Element && nodeNameEquals(node, REPLACED_METHOD_ELEMENT)) {
Element replacedMethodEle = (Element) node;
String name = replacedMethodEle.getAttribute(NAME_ATTRIBUTE);
String callback = replacedMethodEle.getAttribute(REPLACER_ATTRIBUTE);
@@ -860,7 +860,7 @@ public class BeanDefinitionParserDelegate {
NodeList nl = ele.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (isCandidateElement(node) && nodeNameEquals(node, QUALIFIER_ATTRIBUTE_ELEMENT)) {
if (node instanceof Element && nodeNameEquals(node, QUALIFIER_ATTRIBUTE_ELEMENT)) {
Element attributeEle = (Element) node;
String attributeName = attributeEle.getAttribute(KEY_ATTRIBUTE);
String attributeValue = attributeEle.getAttribute(VALUE_ATTRIBUTE);
@@ -952,7 +952,7 @@ public class BeanDefinitionParserDelegate {
* <code>&lt;value&gt;</code> tag that might be created
*/
public Object parsePropertySubElement(Element ele, BeanDefinition bd, String defaultValueType) {
if (!isDefaultNamespace(ele)) {
if (!isDefaultNamespace(getNamespaceURI(ele))) {
return parseNestedCustomElement(ele, bd);
}
else if (nodeNameEquals(ele, BEAN_ELEMENT)) {
@@ -1384,6 +1384,10 @@ public class BeanDefinitionParserDelegate {
return originalDef;
}
public boolean isDefaultNamespace(String namespaceUri) {
return (!StringUtils.hasLength(namespaceUri) || BEANS_NAMESPACE_URI.equals(namespaceUri));
}
private BeanDefinitionHolder parseNestedCustomElement(Element ele, BeanDefinition containingBd) {
BeanDefinition innerDefinition = parseCustomElement(ele, containingBd);
if (innerDefinition == null) {
@@ -1400,48 +1404,36 @@ public class BeanDefinitionParserDelegate {
return new BeanDefinitionHolder(innerDefinition, id);
}
/**
* Get the namespace URI for the supplied node. The default implementation uses {@link Node#getNamespaceURI}.
* Gets the namespace URI for the supplied node. The default implementation uses {@link Node#getNamespaceURI}.
* Subclasses may override the default implementation to provide a different namespace identification mechanism.
* @param node the node
* @return the namespace URI of the the node.
*/
public String getNamespaceURI(Node node) {
return node.getNamespaceURI();
}
/**
* Ges the local name for the supplied {@link Node}. The default implementation calls {@link Node#getLocalName}.
* Subclasses may override the default implementation to provide a different mechanism for getting the local name.
* @param node the <code>Node</code>
*/
public String getLocalName(Node node) {
return node.getLocalName();
}
/**
* Determine whether the name of the supplied node is equal to the supplied name.
* <p>The default implementation checks the supplied desired name against both
* {@link Node#getNodeName()) and {@link Node#getLocalName()}.
* <p>Subclasses may override the default implementation to provide a different
* mechanism for comparing node names.
* Determines whether the name of the supplied node is equal to the supplied name.
* The default implementation checks the supplied desired name against both {@link Node#getNodeName)
* and {@link #getLoclName}.
* Subclasses may override the default implementation to provide a different mechanism for comparing node names.
* @param node the node to compare
* @param desiredName the name to check for
* @return <code>true</code> if the names are equal otherwise <code>false</code>.
*/
public boolean nodeNameEquals(Node node, String desiredName) {
return desiredName.equals(node.getNodeName()) || desiredName.equals(getLocalName(node));
}
public boolean isDefaultNamespace(String namespaceUri) {
return (!StringUtils.hasLength(namespaceUri) || BEANS_NAMESPACE_URI.equals(namespaceUri));
/**
* Gets the local name for the supplied {@link Node}. The default implementation calls {@link Node#getLocalName}.
* Subclasses may override the default implementation to provide a different mechanism for getting the local name.
* @param node the <code>Node</code>
* @return the local name of the supplied <code>Node</code>.
*/
public String getLocalName(Node node) {
return node.getLocalName();
}
public boolean isDefaultNamespace(Node node) {
return isDefaultNamespace(getNamespaceURI(node));
}
private boolean isCandidateElement(Node node) {
return (node instanceof Element && (isDefaultNamespace(node) || !isDefaultNamespace(node.getParentNode())));
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -122,13 +122,14 @@ public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocume
* @param root the DOM root element of the document
*/
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
if (delegate.isDefaultNamespace(delegate.getNamespaceURI(root))) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
String namespaceUri = delegate.getNamespaceURI(ele);
if (delegate.isDefaultNamespace(namespaceUri)) {
parseDefaultElement(ele, delegate);
}
else {
@@ -1,86 +0,0 @@
/*
* Copyright 2002-2010 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.propertyeditors;
import java.beans.PropertyEditorSupport;
import java.io.IOException;
import org.xml.sax.InputSource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceEditor;
import org.springframework.util.Assert;
/**
* Editor for <code>org.xml.sax.InputSource</code>, converting from a
* Spring resource location String to a SAX InputSource object.
*
* <p>Supports Spring-style URL notation: any fully qualified standard URL
* ("file:", "http:", etc) and Spring's special "classpath:" pseudo-URL.
*
* @author Juergen Hoeller
* @since 3.0.3
* @see org.xml.sax.InputSource
* @see org.springframework.core.io.ResourceEditor
* @see org.springframework.core.io.ResourceLoader
* @see org.springframework.beans.propertyeditors.URLEditor
* @see org.springframework.beans.propertyeditors.FileEditor
*/
public class InputSourceEditor extends PropertyEditorSupport {
private final ResourceEditor resourceEditor;
/**
* Create a new InputSourceEditor,
* using the default ResourceEditor underneath.
*/
public InputSourceEditor() {
this.resourceEditor = new ResourceEditor();
}
/**
* Create a new InputSourceEditor,
* using the given ResourceEditor underneath.
* @param resourceEditor the ResourceEditor to use
*/
public InputSourceEditor(ResourceEditor resourceEditor) {
Assert.notNull(resourceEditor, "ResourceEditor must not be null");
this.resourceEditor = resourceEditor;
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
this.resourceEditor.setAsText(text);
Resource resource = (Resource) this.resourceEditor.getValue();
try {
setValue(resource != null ? new InputSource(resource.getURL().toString()) : null);
}
catch (IOException ex) {
throw new IllegalArgumentException(
"Could not retrieve URL for " + resource + ": " + ex.getMessage());
}
}
@Override
public String getAsText() {
InputSource value = (InputSource) getValue();
return (value != null ? value.getSystemId() : "");
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -14,6 +14,7 @@
* limitations under the License.
*/
package org.springframework.beans.propertyeditors;
import java.beans.PropertyEditorSupport;
@@ -24,9 +25,9 @@ import org.springframework.core.io.ResourceEditor;
import org.springframework.util.Assert;
/**
* One-way PropertyEditor which can convert from a text String to a
* <code>java.io.InputStream</code>, interpreting the given String
* as Spring resource location (e.g. a URL String).
* One-way PropertyEditor, which can convert from a text string to a
* <code>java.io.InputStream</code>, allowing InputStream properties
* to be set directly as a text string.
*
* <p>Supports Spring-style URL notation: any fully qualified standard URL
* ("file:", "http:", etc) and Spring's special "classpath:" pseudo-URL.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -67,6 +67,7 @@ public class URIEditor extends PropertyEditorSupport {
/**
* Create a new URIEditor, converting "classpath:" locations into
* standard URIs (not trying to resolve them into physical resources).
*
* @param encode indicates whether Strings will be encoded or not
*/
public URIEditor(boolean encode) {
@@ -140,16 +141,14 @@ public class URIEditor extends PropertyEditorSupport {
* @throws java.net.URISyntaxException if URI conversion failed
*/
protected URI createURI(String value) throws URISyntaxException {
int colonIndex = value.indexOf(':');
if (this.encode && colonIndex != -1) {
int fragmentIndex = value.indexOf('#', colonIndex + 1);
String scheme = value.substring(0, colonIndex);
String ssp = value.substring(colonIndex + 1, (fragmentIndex > 0 ? fragmentIndex : value.length()));
String fragment = (fragmentIndex > 0 ? value.substring(fragmentIndex + 1) : null);
return new URI(scheme, ssp, fragment);
int idx = value.indexOf(':');
if (encode && idx != -1) {
String scheme = value.substring(0, idx);
String ssp = value.substring(idx + 1);
return new URI(scheme, ssp, null);
}
else {
// not encoding or the value contains no scheme - fallback to default
// not encoding or the value contains no scheme , fallback to default
return new URI(value);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -16,20 +16,15 @@
package org.springframework.beans.support;
import java.beans.PropertyEditor;
import java.io.File;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import org.xml.sax.InputSource;
import org.springframework.beans.PropertyEditorRegistrar;
import org.springframework.beans.PropertyEditorRegistry;
import org.springframework.beans.PropertyEditorRegistrySupport;
import org.springframework.beans.propertyeditors.ClassEditor;
import org.springframework.beans.propertyeditors.FileEditor;
import org.springframework.beans.propertyeditors.InputSourceEditor;
import org.springframework.beans.propertyeditors.InputStreamEditor;
import org.springframework.beans.propertyeditors.URIEditor;
import org.springframework.beans.propertyeditors.URLEditor;
@@ -82,33 +77,19 @@ public class ResourceEditorRegistrar implements PropertyEditorRegistrar {
*/
public void registerCustomEditors(PropertyEditorRegistry registry) {
ResourceEditor baseEditor = new ResourceEditor(this.resourceLoader);
doRegisterEditor(registry, Resource.class, baseEditor);
doRegisterEditor(registry, InputStream.class, new InputStreamEditor(baseEditor));
doRegisterEditor(registry, InputSource.class, new InputSourceEditor(baseEditor));
doRegisterEditor(registry, File.class, new FileEditor(baseEditor));
doRegisterEditor(registry, URL.class, new URLEditor(baseEditor));
registry.registerCustomEditor(Resource.class, baseEditor);
registry.registerCustomEditor(InputStream.class, new InputStreamEditor(baseEditor));
registry.registerCustomEditor(File.class, new FileEditor(baseEditor));
registry.registerCustomEditor(URL.class, new URLEditor(baseEditor));
ClassLoader classLoader = this.resourceLoader.getClassLoader();
doRegisterEditor(registry, Class.class, new ClassEditor(classLoader));
doRegisterEditor(registry, URI.class, new URIEditor(classLoader));
registry.registerCustomEditor(Class.class, new ClassEditor(classLoader));
registry.registerCustomEditor(URI.class, new URIEditor(classLoader));
if (this.resourceLoader instanceof ResourcePatternResolver) {
doRegisterEditor(registry, Resource[].class,
registry.registerCustomEditor(Resource[].class,
new ResourceArrayPropertyEditor((ResourcePatternResolver) this.resourceLoader));
}
}
/**
* Override default editor, if possible (since that's what we really mean to do here);
* otherwise register as a custom editor.
*/
private void doRegisterEditor(PropertyEditorRegistry registry, Class requiredType, PropertyEditor editor) {
if (registry instanceof PropertyEditorRegistrySupport) {
((PropertyEditorRegistrySupport) registry).overrideDefaultEditor(requiredType, editor);
}
else {
registry.registerCustomEditor(requiredType, editor);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -16,6 +16,15 @@
package org.springframework.beans.factory;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.security.AccessControlContext;
@@ -31,19 +40,12 @@ import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import javax.security.auth.Subject;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import static org.junit.Assert.*;
import org.junit.Test;
import test.beans.DerivedTestBean;
import test.beans.DummyFactory;
import test.beans.ITestBean;
import test.beans.LifecycleBean;
import test.beans.NestedTestBean;
import test.beans.TestBean;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.NotWritablePropertyException;
@@ -59,7 +61,6 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.config.TypedStringValue;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
@@ -71,7 +72,6 @@ import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.ConstructorDependenciesBean;
import org.springframework.beans.factory.xml.DependenciesBean;
import org.springframework.beans.propertyeditors.CustomNumberEditor;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.MethodParameter;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.ConversionServiceFactory;
@@ -80,6 +80,13 @@ import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.util.StopWatch;
import test.beans.DerivedTestBean;
import test.beans.DummyFactory;
import test.beans.ITestBean;
import test.beans.LifecycleBean;
import test.beans.NestedTestBean;
import test.beans.TestBean;
/**
* Tests properties population and autowire behavior.
*
@@ -89,7 +96,7 @@ import org.springframework.util.StopWatch;
* @author Sam Brannen
* @author Chris Beams
*/
public class DefaultListableBeanFactoryTests {
public final class DefaultListableBeanFactoryTests {
private static final Log factoryLog = LogFactory.getLog(DefaultListableBeanFactory.class);
@@ -723,20 +730,6 @@ public class DefaultListableBeanFactoryTests {
assertTrue("Test bean age is 48", tb.getAge() == 48);
}
@Test
public void testAliasCircle() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
lbf.registerAlias("test", "test2");
lbf.registerAlias("test2", "test3");
try {
lbf.registerAlias("test3", "test");
fail("Should have thrown IllegalStateException");
}
catch (IllegalStateException ex) {
// expected
}
}
@Test
public void testBeanDefinitionOverriding() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
@@ -1110,7 +1103,7 @@ public class DefaultListableBeanFactoryTests {
@Test
public void testAutowireWithNoDependencies() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class, new MutablePropertyValues());
lbf.registerBeanDefinition("rod", bd);
assertEquals(1, lbf.getBeanDefinitionCount());
Object registered = lbf.autowire(NoDependencies.class, AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT, false);
@@ -1187,7 +1180,7 @@ public class DefaultListableBeanFactoryTests {
@Test
public void testAutowireConstructor() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class, new MutablePropertyValues());
lbf.registerBeanDefinition("spouse", bd);
ConstructorDependenciesBean bean = (ConstructorDependenciesBean)
lbf.autowire(ConstructorDependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, true);
@@ -1199,7 +1192,7 @@ public class DefaultListableBeanFactoryTests {
@Test
public void testAutowireBeanByName() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class, new MutablePropertyValues());
lbf.registerBeanDefinition("spouse", bd);
DependenciesBean bean = (DependenciesBean)
lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, true);
@@ -1211,7 +1204,7 @@ public class DefaultListableBeanFactoryTests {
@Test
public void testAutowireBeanByNameWithDependencyCheck() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class, new MutablePropertyValues());
lbf.registerBeanDefinition("spous", bd);
try {
lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, true);
@@ -1225,49 +1218,17 @@ public class DefaultListableBeanFactoryTests {
@Test
public void testAutowireBeanByNameWithNoDependencyCheck() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class, new MutablePropertyValues());
lbf.registerBeanDefinition("spous", bd);
DependenciesBean bean = (DependenciesBean)
lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false);
assertNull(bean.getSpouse());
}
@Test(expected=NoSuchBeanDefinitionException.class)
public void testGetBeanByTypeWithAmbiguity() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
lbf.registerBeanDefinition("bd1", bd1);
lbf.registerBeanDefinition("bd2", bd2);
lbf.getBean(TestBean.class);
}
@Test
public void testGetBeanByTypeFiltersOutNonAutowireCandidates() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
RootBeanDefinition na1 = new RootBeanDefinition(TestBean.class);
na1.setAutowireCandidate(false);
lbf.registerBeanDefinition("bd1", bd1);
lbf.registerBeanDefinition("na1", na1);
TestBean actual = lbf.getBean(TestBean.class); // na1 was filtered
assertSame(lbf.getBean("bd1", TestBean.class), actual);
lbf.registerBeanDefinition("bd2", bd2);
try {
lbf.getBean(TestBean.class);
fail("Should have thrown NoSuchBeanDefinitionException");
} catch (NoSuchBeanDefinitionException ex) {
// expected
}
}
@Test
public void testAutowireBeanByType() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class, new MutablePropertyValues());
lbf.registerBeanDefinition("test", bd);
DependenciesBean bean = (DependenciesBean)
lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
@@ -1284,7 +1245,7 @@ public class DefaultListableBeanFactoryTests {
@Test
public void testAutowireBeanWithFactoryBeanByType() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
RootBeanDefinition bd = new RootBeanDefinition(LazyInitFactory.class);
RootBeanDefinition bd = new RootBeanDefinition(LazyInitFactory.class, new MutablePropertyValues());
lbf.registerBeanDefinition("factoryBean", bd);
LazyInitFactory factoryBean = (LazyInitFactory) lbf.getBean("&factoryBean");
assertNotNull("The FactoryBean should have been registered.", factoryBean);
@@ -1294,15 +1255,6 @@ public class DefaultListableBeanFactoryTests {
factoryBean, bean.getFactoryBean());
}
@Test
public void testGetTypeForAbstractFactoryBean() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
RootBeanDefinition bd = new RootBeanDefinition(FactoryBeanThatShouldntBeCalled.class);
bd.setAbstract(true);
lbf.registerBeanDefinition("factoryBean", bd);
assertNull(lbf.getType("factoryBean"));
}
/**
* Verifies that a dependency on a {@link FactoryBean} can <strong>not</strong>
* be autowired <em>by name</em>, as &amp; is an illegal character in
@@ -1312,7 +1264,7 @@ public class DefaultListableBeanFactoryTests {
@Test(expected=TypeMismatchException.class)
public void testAutowireBeanWithFactoryBeanByName() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
RootBeanDefinition bd = new RootBeanDefinition(LazyInitFactory.class);
RootBeanDefinition bd = new RootBeanDefinition(LazyInitFactory.class, new MutablePropertyValues());
lbf.registerBeanDefinition("factoryBean", bd);
LazyInitFactory factoryBean = (LazyInitFactory) lbf.getBean("&factoryBean");
assertNotNull("The FactoryBean should have been registered.", factoryBean);
@@ -1322,10 +1274,10 @@ public class DefaultListableBeanFactoryTests {
@Test
public void testAutowireBeanByTypeWithTwoMatches() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class, new MutablePropertyValues());
RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class, new MutablePropertyValues());
lbf.registerBeanDefinition("test", bd);
lbf.registerBeanDefinition("spouse", bd2);
lbf.registerBeanDefinition("test2", bd2);
try {
lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
fail("Should have thrown UnsatisfiedDependencyException");
@@ -1333,26 +1285,7 @@ public class DefaultListableBeanFactoryTests {
catch (UnsatisfiedDependencyException ex) {
// expected
assertTrue(ex.getMessage().indexOf("test") != -1);
assertTrue(ex.getMessage().indexOf("spouse") != -1);
}
}
@Test
public void testAutowireBeanByTypeWithTwoMatchesAndParameterNameDiscovery() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
lbf.setParameterNameDiscoverer(new LocalVariableTableParameterNameDiscoverer());
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
lbf.registerBeanDefinition("test", bd);
lbf.registerBeanDefinition("spouse", bd2);
try {
lbf.autowire(DependenciesBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
fail("Should have thrown UnsatisfiedDependencyException");
}
catch (UnsatisfiedDependencyException ex) {
// expected
assertTrue(ex.getMessage().indexOf("test") != -1);
assertTrue(ex.getMessage().indexOf("spouse") != -1);
assertTrue(ex.getMessage().indexOf("test2") != -1);
}
}
@@ -1379,7 +1312,7 @@ public class DefaultListableBeanFactoryTests {
@Test
public void testAutowireExistingBeanByName() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class, new MutablePropertyValues());
lbf.registerBeanDefinition("spouse", bd);
DependenciesBean existingBean = new DependenciesBean();
lbf.autowireBeanProperties(existingBean, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, true);
@@ -1391,7 +1324,7 @@ public class DefaultListableBeanFactoryTests {
@Test
public void testAutowireExistingBeanByNameWithDependencyCheck() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class, new MutablePropertyValues());
lbf.registerBeanDefinition("spous", bd);
DependenciesBean existingBean = new DependenciesBean();
try {
@@ -1406,7 +1339,7 @@ public class DefaultListableBeanFactoryTests {
@Test
public void testAutowireExistingBeanByNameWithNoDependencyCheck() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class, new MutablePropertyValues());
lbf.registerBeanDefinition("spous", bd);
DependenciesBean existingBean = new DependenciesBean();
lbf.autowireBeanProperties(existingBean, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false);
@@ -1416,7 +1349,7 @@ public class DefaultListableBeanFactoryTests {
@Test
public void testAutowireExistingBeanByType() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class, new MutablePropertyValues());
lbf.registerBeanDefinition("test", bd);
DependenciesBean existingBean = new DependenciesBean();
lbf.autowireBeanProperties(existingBean, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
@@ -1498,7 +1431,7 @@ public class DefaultListableBeanFactoryTests {
@Test
public void testConfigureBeanWithAutowiring() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class, new MutablePropertyValues());
lbf.registerBeanDefinition("spouse", bd);
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.add("age", "99");
@@ -1633,20 +1566,6 @@ public class DefaultListableBeanFactoryTests {
lbf.preInstantiateSingletons();
}
@Test
public void testPrototypeStringCreatedRepeatedly() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
RootBeanDefinition stringDef = new RootBeanDefinition(String.class);
stringDef.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
stringDef.getConstructorArgumentValues().addGenericArgumentValue(new TypedStringValue("value"));
lbf.registerBeanDefinition("string", stringDef);
String val1 = lbf.getBean("string", String.class);
String val2 = lbf.getBean("string", String.class);
assertEquals("value", val1);
assertEquals("value", val2);
assertNotSame(val1, val2);
}
@Test
public void testPrototypeWithArrayConversionForConstructor() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
@@ -1,93 +0,0 @@
package org.springframework.beans.factory;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.rootBeanDefinition;
import org.junit.Test;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
/**
* SPR-5475 exposed the fact that the error message displayed when incorrectly
* invoking a factory method is not instructive to the user and rather misleading.
*
* @author Chris Beams
*/
public class Spr5475Tests {
@Test
public void noArgFactoryMethodInvokedWithOneArg() {
assertExceptionMessageForMisconfiguredFactoryMethod(
rootBeanDefinition(Foo.class)
.setFactoryMethod("noArgFactory")
.addConstructorArgValue("bogusArg").getBeanDefinition(),
"Error creating bean with name 'foo': No matching factory method found: factory method 'noArgFactory(String)'. " +
"Check that a method with the specified name and arguments exists and that it is static.");
}
@Test
public void noArgFactoryMethodInvokedWithTwoArgs() {
assertExceptionMessageForMisconfiguredFactoryMethod(
rootBeanDefinition(Foo.class)
.setFactoryMethod("noArgFactory")
.addConstructorArgValue("bogusArg1")
.addConstructorArgValue("bogusArg2".getBytes()).getBeanDefinition(),
"Error creating bean with name 'foo': No matching factory method found: factory method 'noArgFactory(String,byte[])'. " +
"Check that a method with the specified name and arguments exists and that it is static.");
}
@Test
public void noArgFactoryMethodInvokedWithTwoArgsAndTypesSpecified() {
RootBeanDefinition def = new RootBeanDefinition(Foo.class);
def.setFactoryMethodName("noArgFactory");
ConstructorArgumentValues cav = new ConstructorArgumentValues();
cav.addIndexedArgumentValue(0, "bogusArg1", CharSequence.class.getName());
cav.addIndexedArgumentValue(1, "bogusArg2".getBytes());
def.setConstructorArgumentValues(cav);
assertExceptionMessageForMisconfiguredFactoryMethod(
def,
"Error creating bean with name 'foo': No matching factory method found: factory method 'noArgFactory(CharSequence,byte[])'. " +
"Check that a method with the specified name and arguments exists and that it is static.");
}
private void assertExceptionMessageForMisconfiguredFactoryMethod(BeanDefinition bd, String expectedMessage) {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
factory.registerBeanDefinition("foo", bd);
try {
factory.preInstantiateSingletons();
fail("should have failed with BeanCreationException due to incorrectly invoked factory method");
} catch (BeanCreationException ex) {
assertThat(ex.getMessage(), equalTo(expectedMessage));
}
}
@Test
public void singleArgFactoryMethodInvokedWithNoArgs() {
// calling a factory method that accepts arguments without any arguments emits an exception unlike cases
// where a no-arg factory method is called with arguments. Adding this test just to document the difference
assertExceptionMessageForMisconfiguredFactoryMethod(
rootBeanDefinition(Foo.class)
.setFactoryMethod("singleArgFactory").getBeanDefinition(),
"Error creating bean with name 'foo': " +
"Unsatisfied dependency expressed through constructor argument with index 0 of type [java.lang.String]: " +
"Ambiguous factory method argument types - did you specify the correct bean references as factory method arguments?");
}
static class Foo {
static Foo noArgFactory() {
return new Foo();
}
static Foo singleArgFactory(String arg) {
return new Foo();
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -954,7 +954,7 @@ public final class AutowiredAnnotationBeanPostProcessorTests {
public static class ExtendedResourceInjectionBean<T> extends ResourceInjectionBean {
@Autowired
public final ITestBean testBean3 = null;
protected ITestBean testBean3;
private T nestedTestBean;
@@ -1,65 +0,0 @@
/*
* Copyright 2002-2010 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.config;
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
/**
* @author Arjen Poutsma
*/
public class DeprecatedBeanWarnerTests {
private DefaultListableBeanFactory beanFactory;
private String beanName;
private BeanDefinition beanDefinition;
private DeprecatedBeanWarner warner;
@Test
public void postProcess() {
beanFactory = new DefaultListableBeanFactory();
BeanDefinition def = BeanDefinitionBuilder
.genericBeanDefinition(MyDeprecatedBean.class)
.getBeanDefinition();
String beanName = "deprecated";
beanFactory.registerBeanDefinition(beanName, def);
warner = new MyDeprecatedBeanWarner();
warner.postProcessBeanFactory(beanFactory);
assertEquals(beanName, this.beanName);
assertEquals(def, this.beanDefinition);
}
private class MyDeprecatedBeanWarner extends DeprecatedBeanWarner {
@Override
protected void logDeprecatedBean(String beanName, BeanDefinition beanDefinition) {
DeprecatedBeanWarnerTests.this.beanName = beanName;
DeprecatedBeanWarnerTests.this.beanDefinition = beanDefinition;
}
}
}
@@ -1,22 +0,0 @@
/*
* Copyright 2002-2010 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.config;
@Deprecated
public class MyDeprecatedBean {
}
@@ -1,24 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<!--
Test data for ObjectFactoryCreatingFactoryBeanTests
-->
<beans>
<bean id="prototypeTarget" class="java.util.Date" scope="prototype"/>
<bean id="prototypeFactory" class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean">
<property name="targetBeanName" value="prototypeTarget"/>
<bean id="prototype" class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean">
<property name="targetBeanName"><idref local="prototypeTarget"/></property>
</bean>
<bean id="factoryTestBean" class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBeanTests$FactoryTestBean">
<property name="objectFactory" ref="prototypeFactory"/>
<bean id="testBean" class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBeanTests$TestBean">
<property name="objectFactory"><ref local="prototype"/></property>
</bean>
<bean id="prototypeProvider" class="org.springframework.beans.factory.config.ProviderCreatingFactoryBean">
<property name="targetBeanName" value="prototypeTarget"/>
</bean>
<bean id="providerTestBean" class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBeanTests$ProviderTestBean">
<property name="provider" ref="prototypeProvider"/>
</bean>
</beans>
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -16,49 +16,43 @@
package org.springframework.beans.factory.config;
import java.util.Date;
import javax.inject.Provider;
import static org.easymock.EasyMock.*;
import org.junit.After;
import static org.junit.Assert.*;
import static test.util.TestResourceUtils.qualifiedResource;
import java.util.Date;
import org.junit.Before;
import org.junit.Test;
import static test.util.TestResourceUtils.*;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.Resource;
import org.springframework.util.SerializationTestUtils;
/**
* Unit tests for {@link ObjectFactoryCreatingFactoryBean}.
*
* @author Colin Sampaleanu
* @author Juergen Hoeller
* @author Rick Evans
* @author Chris Beams
* @since 2004-05-11
*/
public class ObjectFactoryCreatingFactoryBeanTests {
public final class ObjectFactoryCreatingFactoryBeanTests {
private static final Resource CONTEXT =
qualifiedResource(ObjectFactoryCreatingFactoryBeanTests.class, "context.xml");
private XmlBeanFactory beanFactory;
private BeanFactory beanFactory;
@Before
public void setUp() {
this.beanFactory = new XmlBeanFactory(CONTEXT);
this.beanFactory.setSerializationId("test");
}
@After
public void tearDown() {
this.beanFactory.setSerializationId(null);
}
@Test
public void testFactoryOperation() throws Exception {
FactoryTestBean testBean = beanFactory.getBean("factoryTestBean", FactoryTestBean.class);
public void testBasicOperation() throws BeansException {
TestBean testBean = (TestBean) beanFactory.getBean("testBean");
ObjectFactory<?> objectFactory = testBean.getObjectFactory();
Date date1 = (Date) objectFactory.getObject();
@@ -66,40 +60,6 @@ public class ObjectFactoryCreatingFactoryBeanTests {
assertTrue(date1 != date2);
}
@Test
public void testFactorySerialization() throws Exception {
FactoryTestBean testBean = beanFactory.getBean("factoryTestBean", FactoryTestBean.class);
ObjectFactory<?> objectFactory = testBean.getObjectFactory();
objectFactory = (ObjectFactory) SerializationTestUtils.serializeAndDeserialize(objectFactory);
Date date1 = (Date) objectFactory.getObject();
Date date2 = (Date) objectFactory.getObject();
assertTrue(date1 != date2);
}
@Test
public void testProviderOperation() throws Exception {
ProviderTestBean testBean = beanFactory.getBean("providerTestBean", ProviderTestBean.class);
Provider<?> provider = testBean.getProvider();
Date date1 = (Date) provider.get();
Date date2 = (Date) provider.get();
assertTrue(date1 != date2);
}
@Test
public void testProviderSerialization() throws Exception {
ProviderTestBean testBean = beanFactory.getBean("providerTestBean", ProviderTestBean.class);
Provider<?> provider = testBean.getProvider();
provider = (Provider) SerializationTestUtils.serializeAndDeserialize(provider);
Date date1 = (Date) provider.get();
Date date2 = (Date) provider.get();
assertTrue(date1 != date2);
}
@Test
public void testDoesNotComplainWhenTargetBeanNameRefersToSingleton() throws Exception {
final String targetBeanName = "singleton";
@@ -118,6 +78,7 @@ public class ObjectFactoryCreatingFactoryBeanTests {
assertSame(expectedSingleton, actualSingleton);
verify(beanFactory);
}
@Test
@@ -158,9 +119,10 @@ public class ObjectFactoryCreatingFactoryBeanTests {
}
public static class FactoryTestBean {
public static class TestBean {
public ObjectFactory<?> objectFactory;
private ObjectFactory<?> objectFactory;
public ObjectFactory<?> getObjectFactory() {
return objectFactory;
@@ -169,20 +131,7 @@ public class ObjectFactoryCreatingFactoryBeanTests {
public void setObjectFactory(ObjectFactory<?> objectFactory) {
this.objectFactory = objectFactory;
}
}
public static class ProviderTestBean {
private Provider<?> provider;
public Provider<?> getProvider() {
return provider;
}
public void setProvider(Provider<?> provider) {
this.provider = provider;
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -376,9 +376,6 @@ public final class PropertyResourceConfigurerTests {
cas.addGenericArgumentValue("${var}name${age}");
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.add("stringArray", new String[] {"${os.name}", "${age}"});
List<Object> friends = new ManagedList<Object>();
friends.add("na${age}me");
friends.add(new RuntimeBeanReference("${ref}"));
@@ -425,9 +422,6 @@ public final class PropertyResourceConfigurerTests {
assertEquals(tb2, tb1.getSpouse());
assertEquals(1, tb1.getSomeMap().size());
assertEquals("myValue", tb1.getSomeMap().get("myKey"));
assertEquals(2, tb2.getStringArray().length);
assertEquals(System.getProperty("os.name"), tb2.getStringArray()[0]);
assertEquals("98", tb2.getStringArray()[1]);
assertEquals(2, tb2.getFriends().size());
assertEquals("na98me", tb2.getFriends().iterator().next());
assertEquals(tb2, tb2.getFriends().toArray()[1]);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -30,33 +30,24 @@ import org.springframework.util.ClassUtils;
*/
public class URIEditorTests {
private void doTestURI(String uriSpec) {
@Test
public void standardURI() throws Exception {
PropertyEditor uriEditor = new URIEditor();
uriEditor.setAsText(uriSpec);
uriEditor.setAsText("mailto:juergen.hoeller@interface21.com");
Object value = uriEditor.getValue();
assertTrue(value instanceof URI);
URI uri = (URI) value;
assertEquals(uriSpec, uri.toString());
}
@Test
public void standardURI() throws Exception {
doTestURI("mailto:juergen.hoeller@interface21.com");
}
@Test
public void withNonExistentResource() throws Exception {
doTestURI("gonna:/freak/in/the/morning/freak/in/the.evening");
assertEquals(uri.toString(), uriEditor.getAsText());
}
@Test
public void standardURL() throws Exception {
doTestURI("http://www.springframework.org");
}
@Test
public void standardURLWithFragment() throws Exception {
doTestURI("http://www.springframework.org#1");
PropertyEditor uriEditor = new URIEditor();
uriEditor.setAsText("http://www.springframework.org");
Object value = uriEditor.getValue();
assertTrue(value instanceof URI);
URI uri = (URI) value;
assertEquals(uri.toString(), uriEditor.getAsText());
}
@Test
@@ -66,7 +57,7 @@ public class URIEditorTests {
Object value = uriEditor.getValue();
assertTrue(value instanceof URI);
URI uri = (URI) value;
assertEquals("http://www.springframework.org", uri.toString());
assertEquals(uri.toString(), uriEditor.getAsText());
}
@Test
@@ -104,6 +95,16 @@ public class URIEditorTests {
assertTrue(uri.getScheme().startsWith("classpath"));
}
@Test
public void withNonExistentResource() throws Exception {
PropertyEditor uriEditor = new URIEditor();
uriEditor.setAsText("gonna:/freak/in/the/morning/freak/in/the.evening");
Object value = uriEditor.getValue();
assertTrue(value instanceof URI);
URI uri = (URI) value;
assertEquals(uri.toString(), uriEditor.getAsText());
}
@Test
public void setAsTextWithNull() throws Exception {
PropertyEditor uriEditor = new URIEditor();
+2 -2
View File
@@ -4,12 +4,12 @@
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<packaging>jar</packaging>
<version>3.0.3.RELEASE</version>
<version>3.0.1.RELEASE-A</version>
<parent>
<groupId>org.springframework</groupId>
<artifactId>spring-parent</artifactId>
<relativePath>../org.springframework.spring-parent</relativePath>
<version>3.0.3.RELEASE</version>
<version>3.0.1.RELEASE-A</version>
</parent>
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -55,22 +55,6 @@ public class MailSendException extends MailException {
this.failedMessages = new LinkedHashMap<Object, Exception>();
}
/**
* Constructor for registration of failed messages, with the
* messages that failed as keys, and the thrown exceptions as values.
* <p>The messages should be the same that were originally passed
* to the invoked send method.
* @param msg the detail message
* @param cause the root cause from the mail API in use
* @param failedMessages Map of failed messages as keys and thrown
* exceptions as values
*/
public MailSendException(String msg, Throwable cause, Map<Object, Exception> failedMessages) {
super(msg, cause);
this.failedMessages = new LinkedHashMap<Object, Exception>(failedMessages);
this.messageExceptions = failedMessages.values().toArray(new Exception[failedMessages.size()]);
}
/**
* Constructor for registration of failed messages, with the
* messages that failed as keys, and the thrown exceptions as values.
@@ -80,7 +64,9 @@ public class MailSendException extends MailException {
* exceptions as values
*/
public MailSendException(Map<Object, Exception> failedMessages) {
this(null, null, failedMessages);
super(null);
this.failedMessages = new LinkedHashMap<Object, Exception>(failedMessages);
this.messageExceptions = failedMessages.values().toArray(new Exception[failedMessages.size()]);
}
@@ -125,12 +111,7 @@ public class MailSendException extends MailException {
return super.getMessage();
}
else {
StringBuilder sb = new StringBuilder();
String baseMessage = super.getMessage();
if (baseMessage != null) {
sb.append(baseMessage).append(". ");
}
sb.append("Failed messages: ");
StringBuilder sb = new StringBuilder("Failed messages: ");
for (int i = 0; i < this.messageExceptions.length; i++) {
Exception subEx = this.messageExceptions[i];
sb.append(subEx.toString());
@@ -148,8 +129,8 @@ public class MailSendException extends MailException {
return super.toString();
}
else {
StringBuilder sb = new StringBuilder(super.toString());
sb.append("; message exceptions (").append(this.messageExceptions.length).append(") are:");
StringBuilder sb = new StringBuilder(getClass().getName());
sb.append("; nested exceptions (").append(this.messageExceptions.length).append(") are:");
for (int i = 0; i < this.messageExceptions.length; i++) {
Exception subEx = this.messageExceptions[i];
sb.append('\n').append("Failed message ").append(i + 1).append(": ");
@@ -165,7 +146,7 @@ public class MailSendException extends MailException {
super.printStackTrace(ps);
}
else {
ps.println(super.toString() + "; message exception details (" +
ps.println(getClass().getName() + "; nested exception details (" +
this.messageExceptions.length + ") are:");
for (int i = 0; i < this.messageExceptions.length; i++) {
Exception subEx = this.messageExceptions[i];
@@ -181,7 +162,7 @@ public class MailSendException extends MailException {
super.printStackTrace(pw);
}
else {
pw.println(super.toString() + "; message exception details (" +
pw.println(getClass().getName() + "; nested exception details (" +
this.messageExceptions.length + ") are:");
for (int i = 0; i < this.messageExceptions.length; i++) {
Exception subEx = this.messageExceptions[i];
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -24,6 +24,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.activation.FileTypeMap;
import javax.mail.AuthenticationFailedException;
import javax.mail.MessagingException;
@@ -382,60 +383,40 @@ public class JavaMailSenderImpl implements JavaMailSender {
*/
protected void doSend(MimeMessage[] mimeMessages, Object[] originalMessages) throws MailException {
Map<Object, Exception> failedMessages = new LinkedHashMap<Object, Exception>();
Transport transport;
try {
transport = getTransport(getSession());
Transport transport = getTransport(getSession());
transport.connect(getHost(), getPort(), getUsername(), getPassword());
try {
for (int i = 0; i < mimeMessages.length; i++) {
MimeMessage mimeMessage = mimeMessages[i];
try {
if (mimeMessage.getSentDate() == null) {
mimeMessage.setSentDate(new Date());
}
String messageId = mimeMessage.getMessageID();
mimeMessage.saveChanges();
if (messageId != null) {
// Preserve explicitly specified message id...
mimeMessage.setHeader(HEADER_MESSAGE_ID, messageId);
}
transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
}
catch (MessagingException ex) {
Object original = (originalMessages != null ? originalMessages[i] : mimeMessage);
failedMessages.put(original, ex);
}
}
}
finally {
transport.close();
}
}
catch (AuthenticationFailedException ex) {
throw new MailAuthenticationException(ex);
}
catch (MessagingException ex) {
// Effectively, all messages failed...
for (int i = 0; i < mimeMessages.length; i++) {
Object original = (originalMessages != null ? originalMessages[i] : mimeMessages[i]);
failedMessages.put(original, ex);
}
throw new MailSendException("Mail server connection failed", ex, failedMessages);
throw new MailSendException("Mail server connection failed", ex);
}
try {
for (int i = 0; i < mimeMessages.length; i++) {
MimeMessage mimeMessage = mimeMessages[i];
try {
if (mimeMessage.getSentDate() == null) {
mimeMessage.setSentDate(new Date());
}
String messageId = mimeMessage.getMessageID();
mimeMessage.saveChanges();
if (messageId != null) {
// Preserve explicitly specified message id...
mimeMessage.setHeader(HEADER_MESSAGE_ID, messageId);
}
transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
}
catch (MessagingException ex) {
Object original = (originalMessages != null ? originalMessages[i] : mimeMessage);
failedMessages.put(original, ex);
}
}
}
finally {
try {
transport.close();
}
catch (MessagingException ex) {
if (!failedMessages.isEmpty()) {
throw new MailSendException("Failed to close server connection after message failures", ex,
failedMessages);
}
else {
throw new MailSendException("Failed to close server connection after message sending", ex);
}
}
}
if (!failedMessages.isEmpty()) {
throw new MailSendException(failedMessages);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -286,7 +286,7 @@ public class FreeMarkerConfigurationFactory {
}
if (!CollectionUtils.isEmpty(this.freemarkerVariables)) {
config.setAllSharedVariables(new SimpleHash(this.freemarkerVariables, config.getObjectWrapper()));
config.setAllSharedVariables(new SimpleHash(this.freemarkerVariables));
}
if (this.defaultEncoding != null) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* 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.
@@ -22,6 +22,7 @@ import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import javax.activation.FileTypeMap;
import javax.mail.Address;
import javax.mail.Message;
@@ -380,29 +381,8 @@ public class JavaMailSenderTests extends TestCase {
}
catch (MailSendException ex) {
// expected
ex.printStackTrace();
assertTrue(ex.getFailedMessages() != null);
assertEquals(1, ex.getFailedMessages().size());
assertSame(simpleMessage1, ex.getFailedMessages().keySet().iterator().next());
assertSame(ex.getCause(), ex.getFailedMessages().values().iterator().next());
}
}
public void testFailedMailServerClose() throws Exception {
MockJavaMailSender sender = new MockJavaMailSender();
sender.setHost("");
sender.setUsername("username");
sender.setPassword("password");
SimpleMailMessage simpleMessage1 = new SimpleMailMessage();
try {
sender.send(simpleMessage1);
fail("Should have thrown MailSendException");
}
catch (MailSendException ex) {
// expected
ex.printStackTrace();
assertTrue(ex.getFailedMessages() != null);
assertEquals(0, ex.getFailedMessages().size());
assertTrue(ex.getFailedMessages().isEmpty());
}
}
@@ -535,9 +515,6 @@ public class JavaMailSenderTests extends TestCase {
@Override
public synchronized void close() throws MessagingException {
if ("".equals(connectedHost)) {
throw new MessagingException("close failure");
}
this.closeCalled = true;
}
@@ -554,7 +531,7 @@ public class JavaMailSenderTests extends TestCase {
if (message.getSentDate() == null) {
throw new MessagingException("No sentDate specified");
}
if (message.getSubject() != null && message.getSubject().contains("custom")) {
if (message.getSubject() != null && message.getSubject().indexOf("custom") != -1) {
assertEquals(new Date(2005, 3, 1), message.getSentDate());
}
this.sentMessages.add(message);
@@ -10,12 +10,12 @@ Import-Template:
javax.naming.*;version="0";resolution:=optional,
javax.sql.*;version="0";resolution:=optional,
net.sf.ehcache.*;version="[1.3.0, 2.0.0)";resolution:=optional,
net.sf.jasperreports.*;version="[2.0.5, 4.0.0)";resolution:=optional,
net.sf.jasperreports.*;version="[2.0.5, 3.0.0)";resolution:=optional,
org.apache.commons.collections.*;version="[3.2.0, 4.0.0)";resolution:=optional,
org.apache.commons.logging.*;version="[1.1.1, 2.0.0)";resolution:=optional,
org.apache.velocity.*;version="[1.5.0, 2.0.0)";resolution:=optional,
org.quartz.*;version="[1.6.0, 2.0.0)";resolution:=optional,
org.springframework.beans.*;version=${spring.osgi.range};resolution:=optional,
org.springframework.beans.*;version="[3.0.0, 3.0.1)";resolution:=optional,
org.springframework.context.*;version=${spring.osgi.range},
org.springframework.core.*;version=${spring.osgi.range},
org.springframework.jdbc.*;version=${spring.osgi.range};resolution:=optional,
+41 -38
View File
@@ -1,38 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="src" path="src/main/resources"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.aop"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.beans"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.core"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.expression"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.instrument"/>
<classpathentry kind="lib" path="/org.springframework.asm/target/artifacts/org.springframework.asm.jar" sourcepath="/org.springframework.asm/target/artifacts/org.springframework.asm-sources.jar"/>
<classpathentry kind="var" path="IVY_CACHE/edu.emory.mathcs.backport/com.springsource.edu.emory.mathcs.backport/3.0.0/com.springsource.edu.emory.mathcs.backport-3.0.0.jar" sourcepath="/IVY_CACHE/edu.emory.mathcs.backport/com.springsource.edu.emory.mathcs.backport/3.0.0/com.springsource.edu.emory.mathcs.backport-sources-3.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.ejb/com.springsource.javax.ejb/3.0.0/com.springsource.javax.ejb-3.0.0.jar" sourcepath="/IVY_CACHE/javax.ejb/com.springsource.javax.ejb/3.0.0/com.springsource.javax.ejb-sources-3.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.inject/com.springsource.javax.inject/1.0.0/com.springsource.javax.inject-1.0.0.jar" sourcepath="/IVY_CACHE/javax.inject/com.springsource.javax.inject/1.0.0/com.springsource.javax.inject-sources-1.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.jms/com.springsource.javax.jms/1.1.0/com.springsource.javax.jms-1.1.0.jar" sourcepath="/IVY_CACHE/javax.jms/com.springsource.javax.jms/1.1.0/com.springsource.javax.jms-sources-1.1.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.persistence/com.springsource.javax.persistence/1.0.0/com.springsource.javax.persistence-1.0.0.jar" sourcepath="/IVY_CACHE/javax.persistence/com.springsource.javax.persistence/1.0.0/com.springsource.javax.persistence-sources-1.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.transaction/com.springsource.javax.transaction/1.1.0/com.springsource.javax.transaction-1.1.0.jar" sourcepath="/IVY_CACHE/javax.transaction/com.springsource.javax.transaction/1.1.0/com.springsource.javax.transaction-sources-1.1.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.validation/com.springsource.javax.validation/1.0.0.GA/com.springsource.javax.validation-1.0.0.GA.jar" sourcepath="/IVY_CACHE/javax.validation/com.springsource.javax.validation/1.0.0/com.springsource.javax.validation-sources-1.0.0.GA.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.xml.rpc/com.springsource.javax.xml.rpc/1.1.0/com.springsource.javax.xml.rpc-1.1.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/net.sourceforge.cglib/com.springsource.net.sf.cglib/2.2.0/com.springsource.net.sf.cglib-2.2.0.jar" sourcepath="/IVY_CACHE/net.sourceforge.cglib/com.springsource.net.sf.cglib/2.1.3/com.springsource.net.sf.cglib-sources-2.1.3.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-1.0.0.jar" sourcepath="/IVY_CACHE/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-sources-1.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.dbcp/1.2.2.osgi/com.springsource.org.apache.commons.dbcp-1.2.2.osgi.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.dbcp/1.2.2.osgi/com.springsource.org.apache.commons.dbcp-sources-1.2.2.osgi.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-1.1.1.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-sources-1.1.1.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.pool/1.5.3/com.springsource.org.apache.commons.pool-1.5.3.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.pool/1.5.3/com.springsource.org.apache.commons.pool-sources-1.5.3.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.log4j/com.springsource.org.apache.log4j/1.2.15/com.springsource.org.apache.log4j-1.2.15.jar" sourcepath="/IVY_CACHE/org.apache.log4j/com.springsource.org.apache.log4j/1.2.15/com.springsource.org.apache.log4j-sources-1.2.15.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.aspectj/com.springsource.org.aspectj.weaver/1.6.8.RELEASE/com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.beanshell/com.springsource.bsh/2.0.0.b4/com.springsource.bsh-2.0.0.b4.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.codehaus.groovy/com.springsource.org.codehaus.groovy/1.6.5/com.springsource.org.codehaus.groovy-1.6.5.jar" sourcepath="/IVY_CACHE/org.codehaus.groovy/com.springsource.org.codehaus.groovy/1.6.5/com.springsource.org.codehaus.groovy-sources-1.6.5.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.easymock/com.springsource.org.easymock/2.5.1/com.springsource.org.easymock-2.5.1.jar" sourcepath="/IVY_CACHE/org.easymock/com.springsource.org.easymock/2.5.1/com.springsource.org.easymock-sources-2.5.1.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.joda/com.springsource.org.joda.time/1.6.0/com.springsource.org.joda.time-1.6.0.jar" sourcepath="/IVY_CACHE/org.joda/com.springsource.org.joda.time/1.6.0/com.springsource.org.joda.time-sources-1.6.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.jruby/com.springsource.org.jruby/1.4.0/com.springsource.org.jruby-1.4.0.jar" sourcepath="/IVY_CACHE/org.jruby/com.springsource.org.jruby/1.4.0/com.springsource.org.jruby-sources-1.4.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-4.7.0.jar" sourcepath="/IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-sources-4.7.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.inject/com.springsource.org.atinject.tck/1.0.0/com.springsource.org.atinject.tck-1.0.0.jar" sourcepath="/IVY_CACHE/javax.inject/com.springsource.org.atinject.tck/1.0.0/com.springsource.org.atinject.tck-sources-1.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.hibernate/com.springsource.org.hibernate.validator/4.0.2.GA/com.springsource.org.hibernate.validator-4.0.2.GA.jar"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="src" path="src/main/resources"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.aop"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.beans"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.core"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.expression"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.instrument"/>
<classpathentry kind="lib" path="/org.springframework.asm/target/artifacts/org.springframework.asm.jar" sourcepath="/org.springframework.asm/target/artifacts/org.springframework.asm-sources.jar"/>
<classpathentry kind="var" path="IVY_CACHE/edu.emory.mathcs.backport/com.springsource.edu.emory.mathcs.backport/3.0.0/com.springsource.edu.emory.mathcs.backport-3.0.0.jar" sourcepath="/IVY_CACHE/edu.emory.mathcs.backport/com.springsource.edu.emory.mathcs.backport/3.0.0/com.springsource.edu.emory.mathcs.backport-sources-3.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.ejb/com.springsource.javax.ejb/3.0.0/com.springsource.javax.ejb-3.0.0.jar" sourcepath="/IVY_CACHE/javax.ejb/com.springsource.javax.ejb/3.0.0/com.springsource.javax.ejb-sources-3.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.inject/com.springsource.javax.inject/1.0.0/com.springsource.javax.inject-1.0.0.jar" sourcepath="/IVY_CACHE/javax.inject/com.springsource.javax.inject/1.0.0/com.springsource.javax.inject-sources-1.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.jms/com.springsource.javax.jms/1.1.0/com.springsource.javax.jms-1.1.0.jar" sourcepath="/IVY_CACHE/javax.jms/com.springsource.javax.jms/1.1.0/com.springsource.javax.jms-sources-1.1.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.persistence/com.springsource.javax.persistence/1.0.0/com.springsource.javax.persistence-1.0.0.jar" sourcepath="/IVY_CACHE/javax.persistence/com.springsource.javax.persistence/1.0.0/com.springsource.javax.persistence-sources-1.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.transaction/com.springsource.javax.transaction/1.1.0/com.springsource.javax.transaction-1.1.0.jar" sourcepath="/IVY_CACHE/javax.transaction/com.springsource.javax.transaction/1.1.0/com.springsource.javax.transaction-sources-1.1.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.validation/com.springsource.javax.validation/1.0.0.GA/com.springsource.javax.validation-1.0.0.GA.jar" sourcepath="/IVY_CACHE/javax.validation/com.springsource.javax.validation/1.0.0/com.springsource.javax.validation-sources-1.0.0.GA.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.xml.rpc/com.springsource.javax.xml.rpc/1.1.0/com.springsource.javax.xml.rpc-1.1.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/net.sourceforge.cglib/com.springsource.net.sf.cglib/2.2.0/com.springsource.net.sf.cglib-2.2.0.jar" sourcepath="/IVY_CACHE/net.sourceforge.cglib/com.springsource.net.sf.cglib/2.1.3/com.springsource.net.sf.cglib-sources-2.1.3.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-1.0.0.jar" sourcepath="/IVY_CACHE/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-sources-1.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.dbcp/1.2.2.osgi/com.springsource.org.apache.commons.dbcp-1.2.2.osgi.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.dbcp/1.2.2.osgi/com.springsource.org.apache.commons.dbcp-sources-1.2.2.osgi.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-1.1.1.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-sources-1.1.1.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.pool/1.4.0/com.springsource.org.apache.commons.pool-1.4.0.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.pool/1.4.0/com.springsource.org.apache.commons.pool-sources-1.4.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.log4j/com.springsource.org.apache.log4j/1.2.15/com.springsource.org.apache.log4j-1.2.15.jar" sourcepath="/IVY_CACHE/org.apache.log4j/com.springsource.org.apache.log4j/1.2.15/com.springsource.org.apache.log4j-sources-1.2.15.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.aspectj/com.springsource.org.aspectj.weaver/1.6.8.RELEASE/com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.beanshell/com.springsource.bsh/2.0.0.b4/com.springsource.bsh-2.0.0.b4.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.codehaus.groovy/com.springsource.org.codehaus.groovy/1.6.5/com.springsource.org.codehaus.groovy-1.6.5.jar" sourcepath="/IVY_CACHE/org.codehaus.groovy/com.springsource.org.codehaus.groovy/1.6.5/com.springsource.org.codehaus.groovy-sources-1.6.5.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.easymock/com.springsource.org.easymock/2.5.1/com.springsource.org.easymock-2.5.1.jar" sourcepath="/IVY_CACHE/org.easymock/com.springsource.org.easymock/2.5.1/com.springsource.org.easymock-sources-2.5.1.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.objectweb.asm/com.springsource.org.objectweb.asm/3.1.0/com.springsource.org.objectweb.asm-3.1.0.jar" sourcepath="IVY_CACHE/org.objectweb.asm/com.springsource.org.objectweb.asm/3.1.0/com.springsource.org.objectweb.asm-sources-3.1.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.objectweb.asm/com.springsource.org.objectweb.asm.commons/3.1.0/com.springsource.org.objectweb.asm.commons-3.1.0.jar" sourcepath="IVY_CACHE/org.objectweb.asm/com.springsource.org.objectweb.asm.commons/3.1.0/com.springsource.org.objectweb.asm.commons-sources-3.1.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.hibernate/com.springsource.org.hibernate.validator/4.0.0.GA/com.springsource.org.hibernate.validator-4.0.0.GA.jar" sourcepath="/IVY_CACHE/org.hibernate/com.springsource.org.hibernate.validator/4.0.0.GA/com.springsource.org.hibernate.validator-sources-4.0.0.GA.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.joda/com.springsource.org.joda.time/1.6.0/com.springsource.org.joda.time-1.6.0.jar" sourcepath="/IVY_CACHE/org.joda/com.springsource.org.joda.time/1.6.0/com.springsource.org.joda.time-sources-1.6.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.jruby/com.springsource.org.jruby/1.4.0/com.springsource.org.jruby-1.4.0.jar" sourcepath="/IVY_CACHE/org.jruby/com.springsource.org.jruby/1.4.0/com.springsource.org.jruby-sources-1.4.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-4.7.0.jar" sourcepath="/IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-sources-4.7.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.inject/com.springsource.org.atinject.tck/1.0.0/com.springsource.org.atinject.tck-1.0.0.jar" sourcepath="/IVY_CACHE/javax.inject/com.springsource.org.atinject.tck/1.0.0/com.springsource.org.atinject.tck-sources-1.0.0.jar"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
+1 -1
View File
@@ -62,7 +62,7 @@
<dependency org="org.apache.commons" name="com.springsource.org.apache.commons.dbcp" rev="1.2.2.osgi" conf="test->runtime"/>
<dependency org="org.apache.log4j" name="com.springsource.org.apache.log4j" rev="1.2.15" conf="test->runtime"/>
<dependency org="org.easymock" name="com.springsource.org.easymock" rev="2.5.1" conf="test->compile"/>
<dependency org="org.hibernate" name="com.springsource.org.hibernate.validator" rev="4.0.2.GA" conf="test->runtime"/>
<dependency org="org.hibernate" name="com.springsource.org.hibernate.validator" rev="4.0.0.GA" conf="test->runtime"/>
<dependency org="org.junit" name="com.springsource.org.junit" rev="${org.junit.version}" conf="test->runtime"/>
<dependency org="org.slf4j" name="com.springsource.slf4j.jcl" rev="${slf4j.version}" conf="test->runtime"/>
</dependencies>
+3 -3
View File
@@ -6,12 +6,12 @@
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<packaging>jar</packaging>
<version>3.0.3.RELEASE</version>
<version>3.0.1.RELEASE-A</version>
<parent>
<groupId>org.springframework</groupId>
<artifactId>spring-parent</artifactId>
<relativePath>../org.springframework.spring-parent</relativePath>
<version>3.0.3.RELEASE</version>
<version>3.0.1.RELEASE-A</version>
</parent>
<dependencies>
@@ -191,7 +191,7 @@
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.0.2.GA</version>
<version>4.0.0.GA</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -1,39 +0,0 @@
/*
* Copyright 2002-2010 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.context;
import org.springframework.util.StringValueResolver;
/**
* Interface to be implemented by any object that wishes to be notified of a
* <b>StringValueResolver</b> for the <b> resolution of embedded definition values.
*
* <p>This is an alternative to a full ConfigurableBeanFactory dependency via the
* ApplicationContextAware/BeanFactoryAware interfaces.
*
* @author Juergen Hoeller
* @since 3.0.3
* @see org.springframework.beans.factory.config.ConfigurableBeanFactory#resolveEmbeddedValue
*/
public interface EmbeddedValueResolverAware {
/**
* Set the StringValueResolver to use for resolving embedded definition values.
*/
void setEmbeddedValueResolver(StringValueResolver resolver);
}
@@ -82,8 +82,6 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
private boolean postProcessBeanDefinitionRegistryCalled = false;
private boolean postProcessBeanFactoryCalled = false;
/**
* Set the {@link SourceExtractor} to use for generated bean definitions
@@ -130,14 +128,6 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
* Derive further bean definitions from the configuration classes in the registry.
*/
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
if (this.postProcessBeanDefinitionRegistryCalled) {
throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called for this post-processor");
}
if (this.postProcessBeanFactoryCalled) {
throw new IllegalStateException(
"postProcessBeanFactory already called for this post-processor");
}
this.postProcessBeanDefinitionRegistryCalled = true;
processConfigBeanDefinitions(registry);
}
@@ -147,11 +137,6 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
* by replacing them with CGLIB-enhanced subclasses.
*/
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
if (this.postProcessBeanFactoryCalled) {
throw new IllegalStateException(
"postProcessBeanFactory already called for this post-processor");
}
this.postProcessBeanFactoryCalled = true;
if (!this.postProcessBeanDefinitionRegistryCalled) {
// BeanDefinitionRegistryPostProcessor hook apparently not supported...
// Simply call processConfigBeanDefinitions lazily at this point then.
@@ -45,12 +45,12 @@ import org.springframework.core.OrderComparator;
*
* @author Juergen Hoeller
* @since 1.2.3
* @see #getApplicationListeners(ApplicationEvent)
* @see #getApplicationListeners()
* @see SimpleApplicationEventMulticaster
*/
public abstract class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster, BeanFactoryAware {
private final ListenerRetriever defaultRetriever = new ListenerRetriever(false);
private final ListenerRetriever defaultRetriever = new ListenerRetriever();
private final Map<ListenerCacheKey, ListenerRetriever> retrieverCache =
new ConcurrentHashMap<ListenerCacheKey, ListenerRetriever>();
@@ -133,7 +133,7 @@ public abstract class AbstractApplicationEventMulticaster implements Application
return retriever.getApplicationListeners();
}
else {
retriever = new ListenerRetriever(true);
retriever = new ListenerRetriever();
LinkedList<ApplicationListener> allListeners = new LinkedList<ApplicationListener>();
synchronized (this.defaultRetriever) {
for (ApplicationListener listener : this.defaultRetriever.applicationListeners) {
@@ -221,12 +221,9 @@ public abstract class AbstractApplicationEventMulticaster implements Application
public final Set<String> applicationListenerBeans;
private final boolean preFiltered;
public ListenerRetriever(boolean preFiltered) {
public ListenerRetriever() {
this.applicationListeners = new LinkedHashSet<ApplicationListener>();
this.applicationListenerBeans = new LinkedHashSet<String>();
this.preFiltered = preFiltered;
}
public Collection<ApplicationListener> getApplicationListeners() {
@@ -238,9 +235,7 @@ public abstract class AbstractApplicationEventMulticaster implements Application
BeanFactory beanFactory = getBeanFactory();
for (String listenerBeanName : this.applicationListenerBeans) {
ApplicationListener listener = beanFactory.getBean(listenerBeanName, ApplicationListener.class);
if (!this.preFiltered && !allListeners.contains(listener)) {
allListeners.add(listener);
}
allListeners.add(listener);
}
}
OrderComparator.sort(allListeners);
@@ -22,9 +22,7 @@ import java.security.AccessControlException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -573,41 +571,23 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
*/
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<String>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
new LinkedList<BeanDefinitionRegistryPostProcessor>();
for (BeanFactoryPostProcessor postProcessor : getBeanFactoryPostProcessors()) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryPostProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
registryPostProcessors.add(registryPostProcessor);
}
else {
regularPostProcessors.add(postProcessor);
((BeanDefinitionRegistryPostProcessor) postProcessor).postProcessBeanDefinitionRegistry(registry);
}
}
Map<String, BeanDefinitionRegistryPostProcessor> beanMap =
beanFactory.getBeansOfType(BeanDefinitionRegistryPostProcessor.class, true, false);
List<BeanDefinitionRegistryPostProcessor> registryPostProcessorBeans =
new ArrayList<BeanDefinitionRegistryPostProcessor>(beanMap.values());
OrderComparator.sort(registryPostProcessorBeans);
for (BeanDefinitionRegistryPostProcessor postProcessor : registryPostProcessorBeans) {
Collection<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
beanFactory.getBeansOfType(BeanDefinitionRegistryPostProcessor.class, true, false).values();
for (BeanDefinitionRegistryPostProcessor postProcessor : registryPostProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(registryPostProcessorBeans, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
processedBeans.addAll(beanMap.keySet());
}
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(getBeanFactoryPostProcessors(), beanFactory);
}
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(getBeanFactoryPostProcessors(), beanFactory);
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames =
@@ -619,10 +599,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (isTypeMatch(ppName, PriorityOrdered.class)) {
if (isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (isTypeMatch(ppName, Ordered.class)) {
@@ -657,7 +634,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* Invoke the given BeanFactoryPostProcessor beans.
*/
private void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
List<BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
@@ -879,8 +856,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
*/
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
@@ -1007,16 +983,11 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
publishEvent(new ContextClosedEvent(this));
}
catch (Throwable ex) {
logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
logger.error("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
}
// Stop all Lifecycle beans, to avoid delays during individual destruction.
try {
getLifecycleProcessor().onClose();
}
catch (Throwable ex) {
logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
}
getLifecycleProcessor().onClose();
// Destroy all cached singletons in the context's BeanFactory.
destroyBeans();
@@ -1024,9 +995,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
// Close the state of this context itself.
closeBeanFactory();
// Let subclasses do some final clean-up if they wish...
onClose();
synchronized (this.activeMonitor) {
this.active = false;
}
@@ -22,14 +22,11 @@ import java.security.PrivilegedAction;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.util.StringValueResolver;
/**
* {@link org.springframework.beans.factory.config.BeanPostProcessor}
@@ -89,10 +86,6 @@ class ApplicationContextAwareProcessor implements BeanPostProcessor {
}
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(
new EmbeddedValueResolver(this.applicationContext.getBeanFactory()));
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
@@ -111,18 +104,4 @@ class ApplicationContextAwareProcessor implements BeanPostProcessor {
return bean;
}
private static class EmbeddedValueResolver implements StringValueResolver {
private final ConfigurableBeanFactory beanFactory;
public EmbeddedValueResolver(ConfigurableBeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
public String resolveStringValue(String strVal) {
return this.beanFactory.resolveEmbeddedValue(strVal);
}
}
}
@@ -34,7 +34,6 @@ import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContextException;
import org.springframework.context.Lifecycle;
import org.springframework.context.LifecycleProcessor;
import org.springframework.context.Phased;
@@ -152,7 +151,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
* @param beanName the name of the bean to start
*/
private void doStart(Map<String, ? extends Lifecycle> lifecycleBeans, String beanName) {
Lifecycle bean = lifecycleBeans.remove(beanName);
Lifecycle bean = lifecycleBeans.get(beanName);
if (bean != null && !this.equals(bean)) {
String[] dependenciesForBean = this.beanFactory.getDependenciesForBean(beanName);
for (String dependency : dependenciesForBean) {
@@ -162,16 +161,12 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
if (logger.isDebugEnabled()) {
logger.debug("Starting bean '" + beanName + "' of type [" + bean.getClass() + "]");
}
try {
bean.start();
}
catch (Throwable ex) {
throw new ApplicationContextException("Failed to start bean '" + beanName + "'", ex);
}
bean.start();
if (logger.isDebugEnabled()) {
logger.debug("Successfully started bean '" + beanName + "'");
}
}
lifecycleBeans.remove(beanName);
}
}
@@ -206,7 +201,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
private void doStop(Map<String, ? extends Lifecycle> lifecycleBeans, final String beanName,
final CountDownLatch latch, final Set<String> countDownBeanNames) {
Lifecycle bean = lifecycleBeans.remove(beanName);
Lifecycle bean = lifecycleBeans.get(beanName);
if (bean != null) {
String[] dependentBeans = this.beanFactory.getDependentBeans(beanName);
for (String dependentBean : dependentBeans) {
@@ -249,6 +244,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
logger.warn("Failed to stop bean '" + beanName + "'", ex);
}
}
lifecycleBeans.remove(beanName);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -31,14 +31,12 @@ import org.joda.time.ReadableInstant;
import org.joda.time.ReadablePartial;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.format.AnnotationFormatterFactory;
import org.springframework.format.Parser;
import org.springframework.format.Printer;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.DateTimeFormat.ISO;
import org.springframework.util.StringUtils;
import org.springframework.util.StringValueResolver;
/**
* Formats fields annotated with the {@link DateTimeFormat} annotation.
@@ -48,12 +46,9 @@ import org.springframework.util.StringValueResolver;
* @since 3.0
* @see DateTimeFormat
*/
public class JodaDateTimeFormatAnnotationFormatterFactory
implements AnnotationFormatterFactory<DateTimeFormat>, EmbeddedValueResolverAware {
public final class JodaDateTimeFormatAnnotationFormatterFactory implements AnnotationFormatterFactory<DateTimeFormat> {
private final Set<Class<?>> fieldTypes;
private StringValueResolver embeddedValueResolver;
public JodaDateTimeFormatAnnotationFormatterFactory() {
@@ -69,20 +64,11 @@ public class JodaDateTimeFormatAnnotationFormatterFactory
this.fieldTypes = Collections.unmodifiableSet(rawFieldTypes);
}
public final Set<Class<?>> getFieldTypes() {
public Set<Class<?>> getFieldTypes() {
return this.fieldTypes;
}
public void setEmbeddedValueResolver(StringValueResolver resolver) {
this.embeddedValueResolver = resolver;
}
protected String resolveEmbeddedValue(String value) {
return (this.embeddedValueResolver != null ? this.embeddedValueResolver.resolveStringValue(value) : value);
}
public Printer<?> getPrinter(DateTimeFormat annotation, Class<?> fieldType) {
DateTimeFormatter formatter = configureDateTimeFormatterFrom(annotation);
if (ReadableInstant.class.isAssignableFrom(fieldType)) {
@@ -106,26 +92,24 @@ public class JodaDateTimeFormatAnnotationFormatterFactory
}
// internal helpers
private DateTimeFormatter configureDateTimeFormatterFrom(DateTimeFormat annotation) {
if (StringUtils.hasLength(annotation.pattern())) {
return forPattern(resolveEmbeddedValue(annotation.pattern()));
return forPattern(annotation.pattern());
}
else if (annotation.iso() != ISO.NONE) {
return forIso(annotation.iso());
}
else {
return forStyle(resolveEmbeddedValue(annotation.style()));
return forStyle(annotation.style());
}
}
private DateTimeFormatter forPattern(String pattern) {
return org.joda.time.format.DateTimeFormat.forPattern(pattern);
}
private DateTimeFormatter forStyle(String style) {
return org.joda.time.format.DateTimeFormat.forStyle(style);
}
private DateTimeFormatter forIso(ISO iso) {
if (iso == ISO.DATE) {
return org.joda.time.format.ISODateTimeFormat.date();
@@ -138,4 +122,8 @@ public class JodaDateTimeFormatAnnotationFormatterFactory
}
}
private DateTimeFormatter forStyle(String style) {
return org.joda.time.format.DateTimeFormat.forStyle(style);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -25,8 +25,8 @@ import org.springframework.core.NamedInheritableThreadLocal;
/**
* A holder for a thread-local user {@link JodaTimeContext}.
*
* @author Keith Donald
* @since 3.0
* @author Keith Donald
*/
public final class JodaTimeContextHolder {
@@ -51,18 +51,18 @@ public final class JodaTimeContextHolder {
return jodaTimeContextHolder.get();
}
/**
* Obtain a DateTimeFormatter with user-specific settings applied to the given base Formatter.
* @param formatter the base formatter that establishes default formatting rules
* (generally user independent)
* @param locale the current user locale (may be <code>null</code> if not known)
* @return the user-specific DateTimeFormatter
* Gets the Formatter with the user-specific settings applied to thefrom the base <code>formatter</code>.
* @param formatter the base formatter that establishes default formatting rules, generally user independent
* @param locale the current user locale (may be null if not known)
* @return the user's DateTimeFormatter
*/
public static DateTimeFormatter getFormatter(DateTimeFormatter formatter, Locale locale) {
DateTimeFormatter formatterToUse = (locale != null ? formatter.withLocale(locale) : formatter);
if (locale != null) {
formatter = formatter.withLocale(locale);
}
JodaTimeContext context = getJodaTimeContext();
return (context != null ? context.getFormatter(formatterToUse) : formatterToUse);
return (context != null ? context.getFormatter(formatter) : formatter);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -22,7 +22,6 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.format.AnnotationFormatterFactory;
import org.springframework.format.Formatter;
import org.springframework.format.Parser;
@@ -30,7 +29,6 @@ import org.springframework.format.Printer;
import org.springframework.format.annotation.NumberFormat;
import org.springframework.format.annotation.NumberFormat.Style;
import org.springframework.util.StringUtils;
import org.springframework.util.StringValueResolver;
/**
* Formats fields annotated with the {@link NumberFormat} annotation.
@@ -39,52 +37,46 @@ import org.springframework.util.StringValueResolver;
* @since 3.0
* @see NumberFormat
*/
public class NumberFormatAnnotationFormatterFactory
implements AnnotationFormatterFactory<NumberFormat>, EmbeddedValueResolverAware {
public final class NumberFormatAnnotationFormatterFactory implements AnnotationFormatterFactory<NumberFormat> {
private final Set<Class<?>> fieldTypes;
private StringValueResolver embeddedValueResolver;
public NumberFormatAnnotationFormatterFactory() {
Set<Class<?>> rawFieldTypes = new HashSet<Class<?>>(7);
rawFieldTypes.add(Short.class);
rawFieldTypes.add(Integer.class);
rawFieldTypes.add(Long.class);
rawFieldTypes.add(Float.class);
rawFieldTypes.add(Double.class);
rawFieldTypes.add(BigDecimal.class);
rawFieldTypes.add(BigInteger.class);
this.fieldTypes = Collections.unmodifiableSet(rawFieldTypes);
this.fieldTypes = Collections.unmodifiableSet(createFieldTypes());
}
public final Set<Class<?>> getFieldTypes() {
public Set<Class<?>> getFieldTypes() {
return this.fieldTypes;
}
public void setEmbeddedValueResolver(StringValueResolver resolver) {
this.embeddedValueResolver = resolver;
}
protected String resolveEmbeddedValue(String value) {
return (this.embeddedValueResolver != null ? this.embeddedValueResolver.resolveStringValue(value) : value);
}
public Printer<Number> getPrinter(NumberFormat annotation, Class<?> fieldType) {
return configureFormatterFrom(annotation);
return configureFormatterFrom(annotation, fieldType);
}
public Parser<Number> getParser(NumberFormat annotation, Class<?> fieldType) {
return configureFormatterFrom(annotation);
return configureFormatterFrom(annotation, fieldType);
}
private Formatter<Number> configureFormatterFrom(NumberFormat annotation) {
// internal helpers
private Set<Class<?>> createFieldTypes() {
Set<Class<?>> fieldTypes = new HashSet<Class<?>>(7);
fieldTypes.add(Short.class);
fieldTypes.add(Integer.class);
fieldTypes.add(Long.class);
fieldTypes.add(Float.class);
fieldTypes.add(Double.class);
fieldTypes.add(BigDecimal.class);
fieldTypes.add(BigInteger.class);
return fieldTypes;
}
private Formatter<Number> configureFormatterFrom(NumberFormat annotation, Class<?> fieldType) {
if (StringUtils.hasLength(annotation.pattern())) {
return new NumberFormatter(resolveEmbeddedValue(annotation.pattern()));
return new NumberFormatter(annotation.pattern());
}
else {
Style style = annotation.style();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2009 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.
@@ -17,15 +17,12 @@
package org.springframework.format.support;
import java.lang.annotation.Annotation;
import java.text.ParseException;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.core.GenericTypeResolver;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.ConditionalGenericConverter;
@@ -36,7 +33,6 @@ import org.springframework.format.Formatter;
import org.springframework.format.FormatterRegistry;
import org.springframework.format.Parser;
import org.springframework.format.Printer;
import org.springframework.util.StringValueResolver;
/**
* A {@link org.springframework.core.convert.ConversionService} implementation
@@ -46,22 +42,7 @@ import org.springframework.util.StringValueResolver;
* @author Juergen Hoeller
* @since 3.0
*/
public class FormattingConversionService extends GenericConversionService
implements FormatterRegistry, EmbeddedValueResolverAware {
private StringValueResolver embeddedValueResolver;
private final Map<FieldFormatterKey, GenericConverter> cachedPrinters =
new ConcurrentHashMap<FieldFormatterKey, GenericConverter>();
private final Map<FieldFormatterKey, GenericConverter> cachedParsers =
new ConcurrentHashMap<FieldFormatterKey, GenericConverter>();
public void setEmbeddedValueResolver(StringValueResolver resolver) {
this.embeddedValueResolver = resolver;
}
public class FormattingConversionService extends GenericConversionService implements FormatterRegistry {
public void addFormatterForFieldType(Class<?> fieldType, Formatter<?> formatter) {
addConverter(new PrinterConverter(fieldType, formatter, this));
@@ -78,14 +59,13 @@ public class FormattingConversionService extends GenericConversionService
final Class<? extends Annotation> annotationType = (Class<? extends Annotation>)
GenericTypeResolver.resolveTypeArgument(annotationFormatterFactory.getClass(), AnnotationFormatterFactory.class);
if (annotationType == null) {
throw new IllegalArgumentException("Unable to extract parameterized Annotation type argument from AnnotationFormatterFactory [" +
annotationFormatterFactory.getClass().getName() + "]; does the factory parameterize the <A extends Annotation> generic type?");
}
if (this.embeddedValueResolver != null && annotationFormatterFactory instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) annotationFormatterFactory).setEmbeddedValueResolver(this.embeddedValueResolver);
}
throw new IllegalArgumentException(
"Unable to extract parameterized Annotation type argument from AnnotationFormatterFactory ["
+ annotationFormatterFactory.getClass().getName()
+ "]; does the factory parameterize the <A extends Annotation> generic type?");
}
Set<Class<?>> fieldTypes = annotationFormatterFactory.getFieldTypes();
for (final Class<?> fieldType : fieldTypes) {
addConverter(new ConditionalGenericConverter() {
public Set<ConvertiblePair> getConvertibleTypes() {
@@ -95,14 +75,8 @@ public class FormattingConversionService extends GenericConversionService
return (sourceType.getAnnotation(annotationType) != null);
}
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
FieldFormatterKey key = new FieldFormatterKey(sourceType.getAnnotation(annotationType), fieldType);
GenericConverter converter = cachedPrinters.get(key);
if (converter == null) {
Printer<?> printer = annotationFormatterFactory.getPrinter(key.getAnnotation(), key.getFieldType());
converter = new PrinterConverter(fieldType, printer, FormattingConversionService.this);
cachedPrinters.put(key, converter);
}
return converter.convert(source, sourceType, targetType);
Printer<?> printer = annotationFormatterFactory.getPrinter(sourceType.getAnnotation(annotationType), sourceType.getType());
return new PrinterConverter(fieldType, printer, FormattingConversionService.this).convert(source, sourceType, targetType);
}
public String toString() {
return "@" + annotationType.getName() + " " + fieldType.getName() + " -> " +
@@ -117,14 +91,8 @@ public class FormattingConversionService extends GenericConversionService
return (targetType.getAnnotation(annotationType) != null);
}
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
FieldFormatterKey key = new FieldFormatterKey(targetType.getAnnotation(annotationType), fieldType);
GenericConverter converter = cachedParsers.get(key);
if (converter == null) {
Parser<?> printer = annotationFormatterFactory.getParser(key.getAnnotation(), key.getFieldType());
converter = new ParserConverter(fieldType, printer, FormattingConversionService.this);
cachedParsers.put(key, converter);
}
return converter.convert(source, sourceType, targetType);
Parser<?> parser = annotationFormatterFactory.getParser(targetType.getAnnotation(annotationType), targetType.getType());
return new ParserConverter(fieldType, parser, FormattingConversionService.this).convert(source, sourceType, targetType);
}
public String toString() {
return String.class.getName() + " -> @" + annotationType.getName() + " " +
@@ -135,39 +103,6 @@ public class FormattingConversionService extends GenericConversionService
}
private static final class FieldFormatterKey {
private final Annotation annotation;
private final Class<?> fieldType;
public FieldFormatterKey(Annotation annotation, Class<?> fieldType) {
this.annotation = annotation;
this.fieldType = fieldType;
}
public Annotation getAnnotation() {
return annotation;
}
public Class<?> getFieldType() {
return fieldType;
}
public boolean equals(Object o) {
if (!(o instanceof FieldFormatterKey)) {
return false;
}
FieldFormatterKey key = (FieldFormatterKey) o;
return this.annotation.equals(key.annotation) && this.fieldType.equals(key.fieldType);
}
public int hashCode() {
return this.annotation.hashCode() + 29 * this.fieldType.hashCode();
}
}
private static class PrinterConverter implements GenericConverter {
private Class<?> fieldType;
@@ -231,22 +166,23 @@ public class FormattingConversionService extends GenericConversionService
if (text == null || text.length() == 0) {
return null;
}
Object result;
try {
result = this.parser.parse(text, LocaleContextHolder.getLocale());
} catch (ParseException e) {
throw new IllegalArgumentException("Unable to parse '" + text + "'", e);
Object result = this.parser.parse(text, LocaleContextHolder.getLocale());
TypeDescriptor resultType = TypeDescriptor.valueOf(result.getClass());
if (!resultType.isAssignableTo(targetType)) {
result = this.conversionService.convert(result, resultType, targetType);
}
return result;
}
TypeDescriptor resultType = TypeDescriptor.valueOf(result.getClass());
if (!resultType.isAssignableTo(targetType)) {
result = this.conversionService.convert(result, resultType, targetType);
catch (Exception ex) {
throw new ConversionFailedException(sourceType, targetType, source, ex);
}
return result;
}
public String toString() {
return String.class.getName() + " -> " + this.fieldType.getName() + ": " + this.parser;
}
}
}
@@ -24,7 +24,6 @@ import java.util.Set;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.core.convert.support.ConversionServiceFactory;
import org.springframework.format.AnnotationFormatterFactory;
import org.springframework.format.FormatterRegistry;
@@ -34,7 +33,6 @@ import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.datetime.joda.JodaTimeFormattingConfigurer;
import org.springframework.format.number.NumberFormatAnnotationFormatterFactory;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringValueResolver;
/**
* A factory for a {@link FormattingConversionService} that installs default
@@ -48,15 +46,13 @@ import org.springframework.util.StringValueResolver;
* @since 3.0
*/
public class FormattingConversionServiceFactoryBean
implements FactoryBean<FormattingConversionService>, EmbeddedValueResolverAware, InitializingBean {
implements FactoryBean<FormattingConversionService>, InitializingBean {
private static final boolean jodaTimePresent = ClassUtils.isPresent(
"org.joda.time.LocalDate", FormattingConversionService.class.getClassLoader());
"org.joda.time.DateTime", FormattingConversionService.class.getClassLoader());
private Set<?> converters;
private StringValueResolver embeddedValueResolver;
private FormattingConversionService conversionService;
@@ -70,13 +66,8 @@ public class FormattingConversionServiceFactoryBean
this.converters = converters;
}
public void setEmbeddedValueResolver(StringValueResolver embeddedValueResolver) {
this.embeddedValueResolver = embeddedValueResolver;
}
public void afterPropertiesSet() {
this.conversionService = new FormattingConversionService();
this.conversionService.setEmbeddedValueResolver(this.embeddedValueResolver);
ConversionServiceFactory.addDefaultConverters(this.conversionService);
ConversionServiceFactory.registerConverters(this.converters, this.conversionService);
installFormatters(this.conversionService);

Some files were not shown because too many files have changed in this diff Show More