Compare commits

...

155 Commits

Author SHA1 Message Date
Chris Beams 4f9593da1c Fix typo in reference documentation
Issue: SPR-9321
2012-04-13 20:39:35 +03:00
Chris Beams aac21fdcec Update reference doc copyright year to 2012 2012-04-13 20:35:05 +03:00
Chris Beams dfd75352d3 Ignore spring-build 'docbook' directory 2011-12-22 22:23:45 +01:00
Chris Beams 6316448453 Increment version to 3.0.8.BUILD-SNAPSHOT 2011-12-22 22:23:45 +01:00
Chris Beams 40015e3de3 Release Spring Framework 3.0.7.RELEASE 2011-12-22 22:23:34 +01:00
Chris Beams 5e448af903 Update doc publication urls to static.s2.org 2011-12-22 22:17:56 +01:00
Chris Beams 1f3ce640c9 Add source directories to quell Eclipse errors 2011-12-22 18:15:18 +01:00
Juergen Hoeller cca44f411e added test for correct handling of ParseException from Formatter for String->String case (SPR-8944) 2011-12-22 15:19:59 +01:00
Juergen Hoeller 9b0412f35f fixed NamedParameterJdbcTemplate to use correct maximum type for queryForInt/Long (SPR-8652) 2011-12-22 13:12:22 +01:00
Juergen Hoeller 7eee3b9926 extended test time limits (in order o make the 3.0.x CI build plan happy) 2011-12-22 13:00:15 +01:00
Juergen Hoeller b5a279d2c8 final preparations for 3.0.7 2011-12-22 03:05:56 +01:00
Juergen Hoeller 0862a29066 "file-encoding" attribute value is being applied correctly (SPR-8024) 2011-12-22 03:05:40 +01:00
Juergen Hoeller 8d83f6966e Hibernate synchronization properly unbinds Session even in case of afterCompletion exception (SPR-8757) 2011-12-22 02:58:25 +01:00
Juergen Hoeller ce5117c9ed prepared for 3.0.7 release 2011-12-22 02:29:12 +01:00
Juergen Hoeller 836e3c9253 refined collection element conversion (SPR-8674) 2011-12-22 02:14:55 +01:00
Juergen Hoeller 2006eecb18 IntelliJ IDEA 11 project setup 2011-12-21 22:36:45 +01:00
Chris Beams 91287828f7 Preserve empty src/main/java dirs for ant build
Following the move to git, empty dirs are not tracked. Add .gitignore
files as necessary to keep the ant build happy.
2011-12-19 17:07:40 +01:00
Chris Beams efd2fc7688 Increment version to 3.0.7.BUILD-SNAPSHOT 2011-12-19 15:35:48 +01:00
Juergen Hoeller 74b5487a28 IntelliJ IDEA 11 project setup 2011-12-19 15:35:48 +01:00
Chris Beams 2882ae29b2 Add spring-build 2.5.2
spring-build was previously included via an svn:external. Adding
directly to the source tree under Git to avoid the need for a git
submodule.

In order to build from any earlier commit, it is recommended to
export spring-build or symlink an existing copy into the root
of the spring-framework project and then build normally.

    $ svn export https://src.springsource.org/svn/spring-build/tags/project-build-2.5.2 spring-build
2011-12-19 15:35:48 +01:00
Juergen Hoeller 4a7b96c4ca take element/key/value objects into account for the best possible type descriptor 2011-12-12 00:44:38 +00:00
Juergen Hoeller 7398e0ea97 polishing 2011-12-11 23:07:27 +00:00
Juergen Hoeller beaad20795 DataBinder etc 2011-12-11 22:11:50 +00:00
Juergen Hoeller 1bd84db56e polishing (alignment with 3.1 GA) 2011-12-11 22:06:59 +00:00
Juergen Hoeller 6316a45927 backported fix for SPR-8697 from 3.1 RC2 2011-12-11 22:06:28 +00:00
Juergen Hoeller e298c202af @Transactional qualifiers match against transaction manager definitions in parent contexts as well (SPR-7679) 2011-12-11 13:27:08 +00:00
Juergen Hoeller 288408e89f fixed assertion message 2011-12-09 16:01:30 +00:00
Juergen Hoeller 53a244d408 JmsInvokerClientInterceptor/FactoryBean always uses createConnection/createSession when on JMS 1.1 2011-12-09 12:07:45 +00:00
Juergen Hoeller 8213d0cb50 restored DataBinder's ability to bind to an auto-growing List with unknown element type (SPR-8828) 2011-12-07 21:25:54 +00:00
Juergen Hoeller b9868a498e ConversionService etc 2011-12-07 00:02:16 +00:00
Juergen Hoeller df7bdfa7c6 polishing 2011-12-06 22:50:48 +00:00
Juergen Hoeller f8402e9f82 ResourceHttpRequestHandler sends content without content-type header if no media type found (SPR-7713) 2011-12-06 22:50:33 +00:00
Juergen Hoeller 7eeb654eec ConversionService is able to work with "Collections.emptyList()" as target type (again; SPR-7293) 2011-12-06 21:18:13 +00:00
Juergen Hoeller b558c62953 polishing 2011-12-05 21:21:32 +00:00
Juergen Hoeller d64dd1943f consistent specification of standard meta-annotations 2011-12-03 15:47:29 +00:00
Juergen Hoeller bffa50e31a Portlet session mutex uses global session attribute to be shared among all portlets in the session (SPR-8888) 2011-12-02 12:03:43 +00:00
Juergen Hoeller 143cb50986 ConversionService prevents Converter from trying to convert to a subtype of its actual target type (SPR-8718) 2011-12-02 11:18:31 +00:00
Juergen Hoeller b3ccc438af conversion fixes etc 2011-12-01 18:50:11 +00:00
Juergen Hoeller 94513c1a28 fixed nested element conversion with a DataBinder + ConversionService + PropertyEditor (SPR-8674) 2011-12-01 18:49:53 +00:00
Juergen Hoeller c9607fdaf2 CollectionCollection/MapToMapConverter preserve original Collection/Map if no converted elements (SPR-8714) 2011-12-01 17:49:43 +00:00
Juergen Hoeller 7c108c1e77 updated H2 error codes in sql-error-codes.xml (SPR-8235, SPR-7480) 2011-12-01 14:07:04 +00:00
Juergen Hoeller 77372d7cdb fixed NamedParameterJdbcTemplate to use correct maximum type for queryForInt/Long (SPR-8652) 2011-12-01 13:59:24 +00:00
Juergen Hoeller 173f307ec9 backported header matching fix for correct processing of negated header conditions (SPR-8862) 2011-12-01 13:52:47 +00:00
Juergen Hoeller 2c987b0ffb backported DefaultResponseErrorHandler IOException fix (SPR-8713) 2011-12-01 13:33:51 +00:00
Juergen Hoeller 46a4ac9628 fixed ServletServerHttpRequest to reconstruct from "request.getParameterMap()" for form POST only (SPR-8688) 2011-12-01 13:27:25 +00:00
Juergen Hoeller c2997f4dd9 backported Java 6 visibility bridge method pair (SPR-8660) 2011-12-01 13:12:59 +00:00
Juergen Hoeller 0150000d8b backported TaskExecutorAdapter fix (SPR-8772) 2011-12-01 13:04:55 +00:00
Juergen Hoeller cad5eb836c allow for JDO 3.0 as well (SPR-8655) 2011-12-01 12:59:53 +00:00
Juergen Hoeller c82dab6497 backported public signatures in GenericTypeResolver (SPR-8005) 2011-12-01 12:52:33 +00:00
Juergen Hoeller e6f4e16219 backports from 3.1 RC2 2011-11-28 22:58:06 +00:00
Juergen Hoeller d0032f43c7 AbstractCachingViewResolver allows for caching unresolved view names ("cacheUnresolved"=true; SPR-8524) 2011-11-28 22:35:48 +00:00
Juergen Hoeller 8a43dd172c fixed getAsText javadoc (SPR-7890) 2011-11-28 21:14:47 +00:00
Juergen Hoeller 11aaefffbf refined Resource "exists()" check for HTTP URLs to always return false for 404 status (SPR-7881) 2011-11-28 21:12:08 +00:00
Juergen Hoeller c6b36cc207 JPA EntityManagerFactoryUtils silently ignores IllegalArgumentExceptions from setHint calls (SPR-7947) 2011-11-28 20:54:44 +00:00
Juergen Hoeller 5856db6f72 LinkedCaseInsensitiveMap overrides putAll method as well (for IBM JDK 1.6 compatibility; SPR-7969) 2011-11-28 20:48:10 +00:00
Juergen Hoeller 3c5e02a54a JDO PersistenceManager synchronization performs close attempt after completion (if necessary; SPR-8846) 2011-11-28 19:38:38 +00:00
Juergen Hoeller db0c921313 TransactionSynchronizationManager eagerly cleans up void ResourceHolders on any access (SPR-8844, SPR-8845) 2011-11-28 18:54:20 +00:00
Juergen Hoeller 641bc35a50 fixed setRootObject check in StandardEvaluationContext (SPR-8241) 2011-11-28 17:34:57 +00:00
Juergen Hoeller c166803d41 added "forwarder" property to ConnectorServerFactoryBean, accepting an MBeanServerForwarder (SPR-8820) 2011-11-28 17:17:56 +00:00
Juergen Hoeller 12e1784a99 Servlet/PortletContextResource's getFile prefers "file:" URL resolution over calling getRealPath (SPR-8461) 2011-11-28 16:51:52 +00:00
Juergen Hoeller bfabd58106 fixed "formMultiSelect"/"formCheckboxes" FreeMarker macros to compare against actual field value (SPR-7721) 2011-11-28 14:42:10 +00:00
Juergen Hoeller 540845e613 added getObjectMapper() accessor to MappingJacksonHttpMessageConverter (SPR-8605) 2011-11-28 14:35:08 +00:00
Juergen Hoeller 8e7982397c SimpleJdbcTestUtils executeSqlScript properly closes its LineNumberReader after use (SPR-8872) 2011-11-28 13:33:13 +00:00
Juergen Hoeller 84890ebc0d prepared for 3.0.7 2011-10-20 12:11:36 +00:00
Juergen Hoeller a9f28575b1 optimized DefaultListableBeanFactory's PropertyDescriptor caching for concurrent access (SPR-7863) 2011-10-20 12:06:40 +00:00
Juergen Hoeller a730bf47df LocaleEditor and StringToLocaleConverter do not restrict variant part through validation (SPR-8637) 2011-10-20 11:54:52 +00:00
Juergen Hoeller b5ec65cef6 fixed GenericTypeResolver to consistently return null if not resolvable (SPR-8698) 2011-10-20 11:21:39 +00:00
Juergen Hoeller 965c12b0f8 RmiClientInterceptor detects nested SocketException as connect failure as well (SPR-8628) 2011-10-20 11:10:23 +00:00
Juergen Hoeller 7187029ef6 added proper "contentLength()" implementation to ByteArrayResource (SPR-8709) 2011-10-20 11:03:41 +00:00
Juergen Hoeller 6363bb4b5b fixed Hibernate Validator import range 2011-08-18 23:15:16 +00:00
Juergen Hoeller 58ea5a702d backported autogrow fix: converted Collection differs from original Collection 2011-08-18 20:31:27 +00:00
Chris Beams 97b988ade8 Update pom versions to 3.0.6.BUILD-SNAPSHOT 2011-08-18 19:34:46 +00:00
Chris Beams 227234288f Backport rename JMX tests to avoid jmxremote_optional error
Issue: SPR-8089, SPR-8093, SPR-8458
2011-08-18 19:33:55 +00:00
Juergen Hoeller 05a7b65d43 backported NotificationListenerTests fixes 2011-08-18 19:05:31 +00:00
Juergen Hoeller cee6cb859d added test for month sequence (SPR-7807) 2011-08-17 21:01:39 +00:00
Juergen Hoeller 19c6a4e209 RequiredAnnotationBeanPostProcessor's skip attribute accepts "true" as String value as well (SPR-8617) 2011-08-16 22:41:45 +00:00
Juergen Hoeller b9089a8f9d final preparations for 3.0.6 2011-08-15 21:31:25 +00:00
Juergen Hoeller 7a20ed7d70 fixed timeout assertion 2011-08-15 21:29:15 +00:00
Juergen Hoeller 99588950d2 polishing 2011-08-15 21:24:41 +00:00
Juergen Hoeller a2129a132f consistent "connectTimeout" and "readTimeout" properties (SPR-8615) 2011-08-15 20:57:14 +00:00
Rossen Stoyanchev 0f1c10bc1c SPR-8612 Allow use of explicit status code in HTTP 1.0 compatibility mode 2011-08-15 13:02:48 +00:00
Juergen Hoeller 585745de32 added "connectTimeout" and "readTimeout" properties to SimpleClientHttpRequestFactory (SPR-8614) 2011-08-12 22:59:14 +00:00
Juergen Hoeller 65077d262c overridden @PersistenceContext annotations on subclass methods are being processed correctly (SPR-8594) 2011-08-12 13:54:44 +00:00
Juergen Hoeller da36c2b8b8 polishing 2011-08-12 10:03:28 +00:00
Juergen Hoeller 8f01770f29 backported "formatters" property to FormattingConversionServiceFactoryBean 2011-08-12 10:03:12 +00:00
Juergen Hoeller c51b9a7be2 removed GenericConversionService logging in order to avoid toString side effects (and to avoid isTraceEnabled overhead; SPR-8297) 2011-08-04 17:23:50 +00:00
Juergen Hoeller 3ffc0a2da2 SpringBeanAutowiringSupport is able to process @Value annotations on any given target instance (SPR-8574) 2011-08-03 10:20:04 +00:00
Juergen Hoeller acac25b2eb polishing 2011-08-02 19:19:22 +00:00
Juergen Hoeller cb0c0c503f ContentNegotiatingViewResolver properly handles invalid accept headers (SPR-7712) 2011-08-02 19:15:06 +00:00
Juergen Hoeller 215ccc2e10 final preparations for 3.0.6 2011-07-28 20:45:14 +00:00
Juergen Hoeller d95cbe23ee added support for web.xml context-param "springJspExpressionSupport" (explicit "true"/"false") 2011-07-28 20:26:07 +00:00
Juergen Hoeller ac1ffff9db general polishing (backported from 3.1) 2011-07-28 14:27:08 +00:00
Juergen Hoeller c0257aba9b accepts description subelement within map entry as well (as per the XSD; SPR-8563) 2011-07-28 11:14:26 +00:00
Juergen Hoeller 79aa661dd6 DefaultListableBeanFactory allows for init methods to register further bean definitions (again; SPR-7757) 2011-07-27 22:52:00 +00:00
Juergen Hoeller 18540debf6 backported locking enhancements for @MVC processing (SPR-7703) 2011-07-27 22:38:32 +00:00
Juergen Hoeller 7605707c18 backported @PathVariable matching fix (SPR-8543) 2011-07-27 22:31:17 +00:00
Juergen Hoeller d48c3b5d4f HtmlUtils properly escapes single quotes as well 2011-07-27 21:22:39 +00:00
Juergen Hoeller b122cf87df HtmlUtils properly escapes single quotes as well 2011-07-27 20:36:14 +00:00
Juergen Hoeller 183523d045 updated ResourceHttpRequestHandlerTests 2011-07-26 09:23:57 +00:00
Juergen Hoeller a4f62bb863 moved OpenSessionInViewTests back to orm module 2011-07-26 01:12:01 +00:00
Juergen Hoeller 80def4b695 copy css and js resources as well 2011-07-26 01:08:46 +00:00
Juergen Hoeller 42e18e6c4e fixed OpenEntityManagerInViewTests through the addition of a local copy of our Servlet API mocks; restoredOpenPersistenceManagerInViewTests 2011-07-26 00:52:15 +00:00
Juergen Hoeller d8767774c9 replaced TypeDescriptor synchronization with volatile variables (SPR-8559) 2011-07-25 16:31:46 +00:00
Juergen Hoeller f67e726be7 restored OpenEntityManagerInViewTests 2011-07-25 12:15:47 +00:00
Juergen Hoeller 41b9a461df ResourceHttpRequestHandler detects invalid directory traversal in given path (SPR-8515) 2011-07-25 10:57:39 +00:00
Juergen Hoeller 037497cb4f fixed ignored test 2011-07-21 10:35:05 +00:00
Juergen Hoeller 3ecb6b1a03 refined JBoss 6.0 note 2011-07-21 09:51:34 +00:00
Juergen Hoeller 6b92f66ebd final preparations for 3.0.6 release 2011-07-21 09:09:54 +00:00
Juergen Hoeller 070a723ef2 added "acceptProxyClasses" flag to RemoteInvocationSerializingExporter 2011-07-21 09:05:59 +00:00
Juergen Hoeller d4be29e661 updated javadoc for server-specific LoadTimeWeavers 2011-07-21 08:37:42 +00:00
Juergen Hoeller 3a3f15f144 improved ExposeInvocationInterceptor error message with respect to advice ordering (SPR-8544) 2011-07-21 07:39:11 +00:00
Juergen Hoeller 3edf8566ed fixed @ExceptionHandler exception type matching (ExceptionDepthComparator; SPR-8231) 2011-07-21 07:38:30 +00:00
Juergen Hoeller a2f00f205a collection/array conversion returns original collection if possible (SPR-8538); backported smarter element conversion check from 3.1 2011-07-20 19:57:40 +00:00
Juergen Hoeller 340a8b28f9 ConvertiblePair implements equals and hashCode (SPR-8459) 2011-07-19 15:54:36 +00:00
Juergen Hoeller 83c5753ae1 updated dependencies 2011-07-18 21:46:08 +00:00
Juergen Hoeller 67bb044a6f fixed whitespace 2011-07-18 21:33:45 +00:00
Juergen Hoeller 9ddfb375cb polishing 2011-07-18 20:49:58 +00:00
Juergen Hoeller 6fc6a9e80c fixed @Rule execution order in SpringJUnit4ClassRunner to match standard JUnit 4 behavior (SPR-8537) 2011-07-18 20:49:26 +00:00
Juergen Hoeller f18fa08aa0 ConfigurationClassPostProcessor supports use of same processor instance with several factories (SPR-8527) 2011-07-18 20:45:02 +00:00
Juergen Hoeller aa4ecdb79e fixed AccessControlContext applicability check 2011-07-15 14:43:33 +00:00
Juergen Hoeller 8041f6abdd polishing 2011-07-13 23:03:50 +00:00
Juergen Hoeller 210c77ddb0 SimpleClientHttpRequest uses fixed-length streaming mode (always sets content-length header); partial backport from 3.1 M2 2011-07-13 23:03:35 +00:00
Juergen Hoeller 24cb345b6c backported HttpHeadersTests update 2011-07-13 23:02:08 +00:00
Juergen Hoeller 0fdd7550b8 an EntityManagerFactoryBean is only deserializable through a SerializedEntityManagerFactoryBeanReference 2011-07-11 13:50:59 +00:00
Juergen Hoeller f1fb0e5330 prototype-based TargetSource is only deserializable through a SingletonTargetSource 2011-07-11 13:38:45 +00:00
Juergen Hoeller d4c2f63160 fixed package declaration 2011-07-04 22:05:21 +00:00
Juergen Hoeller b167f3f7a6 added JBoss dependency (SPR-8505); updated WebSphere dependency 2011-07-04 21:38:25 +00:00
Juergen Hoeller 63fe7bdd34 switched from readResolve to readObject 2011-07-04 21:21:56 +00:00
Juergen Hoeller 270db64243 optimized debug logging in case of non-convertible collection (SPR-8499) 2011-07-04 09:59:58 +00:00
Juergen Hoeller 15fd972417 DataBinder etc 2011-07-03 22:38:48 +00:00
Juergen Hoeller 10d9860457 ContextLoader and FrameworkServlet support "contextId" parameter for custom serialization id 2011-07-03 22:38:11 +00:00
Juergen Hoeller 01eab03dca added "autoGrowNestedPaths" property to ConfigurableWebBindingInitializer 2011-07-03 21:25:05 +00:00
Juergen Hoeller eb50eec85b DataBinder uses a default limit of 256 for array/collection auto-growing (SPR-7842) 2011-07-03 20:39:19 +00:00
Juergen Hoeller 4faa5af3f8 backported bridge method detection for class hierarchies with mixed visibilities (SPR-7900) 2011-06-22 21:25:50 +00:00
Juergen Hoeller 218e64cc80 DefaultListableBeanFactory etc 2011-06-22 20:58:23 +00:00
Juergen Hoeller b82edcca04 DefaultListableBeanFactory is only deserializable through a SerializedBeanFactoryReference 2011-06-22 20:55:44 +00:00
Juergen Hoeller d8a4949faf getBean(name, type) attempts type conversion if necessary (SPR-8480) 2011-06-22 20:53:38 +00:00
Costin Leau 22739bebf3 + fix incorrect junit version in ivy.xml 2011-06-17 07:55:57 +00:00
Juergen Hoeller fece2c1125 restored support for String-to-ContextResource conversion (SPR-8383) 2011-06-15 15:46:41 +00:00
Juergen Hoeller 8b55b34d79 consistent dependency on Hibernate Validator 4.1.0.GA 2011-06-14 21:39:41 +00:00
Juergen Hoeller d1e998bedd refined WebLogic RMI descriptor to only mark 'getTargetInterfaceName' method as idempotent (SPR-8369) 2011-06-14 15:10:00 +00:00
Juergen Hoeller 2ddb14ae5b refined EntityManagerFactory proxy exception (SPR-4383) 2011-06-14 15:03:34 +00:00
Juergen Hoeller ae74fbdd4b prepared for 3.0.6 release 2011-06-14 00:13:15 +00:00
Juergen Hoeller 28769e906f ConversionService, CachedConnectionFactory, etc 2011-06-14 00:06:51 +00:00
Juergen Hoeller 47c21bf73b fixed NamedParameterJdbcTemplate's handling of arrays as query parameters (SPR-7699) 2011-06-14 00:03:57 +00:00
Juergen Hoeller 59fda2dbab restored original GenericConversionService behavior with respect to empty collections/maps; restored original FormattingConversionService behavior with respect to the use of subtypes; fixed collection element resolution when using a ConversionService with a DataBinder 2011-06-13 23:57:37 +00:00
Juergen Hoeller 43f8eca91b restored original GenericConversionService behavior with respect to empty collections/maps; restored original FormattingConversionService behavior with respect to the use of subtypes; fixed collection element resolution when using a ConversionService with a DataBinder 2011-06-13 23:40:22 +00:00
Juergen Hoeller 6cb6bd751e revised JMS CachedConnectionFactory to avoid unnecessary rollback calls on Session return (SPR-8437); fixed JMS CachedConnectionFactory to fully synchronize its Session list (SPR-8436) 2011-06-13 22:33:02 +00:00
Juergen Hoeller 58d68cef98 restored original ConversionService behavior with respect to empty collections/maps (SPR-7728) 2011-06-13 22:03:00 +00:00
Juergen Hoeller 5f3f30fdb4 revised JMS CachedConnectionFactory to avoid unnecessary rollback calls on Session return (SPR-8437); fixed JMS CachedConnectionFactory to fully synchronize its Session list (SPR-8436) 2011-06-13 21:43:56 +00:00
Juergen Hoeller 7a6b2cfe1f shortened build properties "org.junit.version" to "junit.version" and "org.testng.version" to "testng.version"; reverted SLF4J version back to 1.5.3 (for Hibernate 3.3.1 compatibility) 2011-06-09 13:51:30 +00:00
Juergen Hoeller a8ab9af002 updated dependencies 2011-06-08 22:50:20 +00:00
Juergen Hoeller ca19b14f13 first bunch of backports from 3.1 M2 to 3.0.6 2011-06-08 22:49:41 +00:00
Juergen Hoeller 175f6d4bc5 2011-06-08 13:25:01 +00:00
Chris Beams 0206845341 Spring 3.0.5 2010-10-20 23:33:02 +00:00
371 changed files with 14425 additions and 3899 deletions
+9 -3
View File
@@ -1,7 +1,13 @@
.springBeans
.DS_Store
target
integration-repo
ivy-cache
spring-build
jmx.log
.springBeans
.DS_Store
jxl.log
jmx.log
org.springframework.jdbc/derby.log
org.springframework.spring-parent/.classpath
org.springframework.spring-parent/.project
org.springframework.test/test-output/
spring-build/lib/docbook
@@ -3,10 +3,10 @@
<!-- Main targets -->
<target name="publish-documentation" depends="publish-documentation.init">
<sshexec host="spring02.managed.contegix.com" username="${username}" keyfile="${key.file}" passphrase="${passphrase}"
<sshexec host="static.springsource.org" username="${username}" keyfile="${key.file}" passphrase="${passphrase}"
command="mkdir /opt/www/domains/springframework.org/www/htdocs/spring/docs/${bundle.version}"/>
<scp remoteToDir="${username}@spring02.managed.contegix.com:/opt/www/domains/springframework.org/www/htdocs/spring/docs/${bundle.version}"
<scp remoteToDir="${username}@static.springsource.org:/opt/www/domains/springframework.org/www/htdocs/spring/docs/${bundle.version}"
keyfile="${key.file}" passphrase="${passphrase}" sftp="true" verbose="true">
<fileset dir="${package.output.dir}">
<include name="changelog.txt" />
@@ -16,7 +16,7 @@
<fileset dir="${package.docs.dir}" />
</scp>
<sshexec host="spring02.managed.contegix.com" username="${username}" keyfile="${key.file}" passphrase="${passphrase}"
<sshexec host="static.springsource.org" username="${username}" keyfile="${key.file}" passphrase="${passphrase}"
command="rm /opt/www/domains/springframework.org/www/htdocs/spring/docs/3.0.x ; ln -s /opt/www/domains/springframework.org/www/htdocs/spring/docs/${bundle.version} /opt/www/domains/springframework.org/www/htdocs/spring/docs/3.0.x"/>
</target>
@@ -3,6 +3,91 @@ SPRING FRAMEWORK CHANGELOG
http://www.springsource.org
Changes in version 3.0.7 (2011-12-22)
-------------------------------------
* fixed GenericTypeResolver to consistently return null if not resolvable
* added proper "contentLength()" implementation to ByteArrayResource
* refined Resource "exists()" check for HTTP URLs to always return false for 404 status
* LocaleEditor and StringToLocaleConverter do not restrict variant part through validation
* LinkedCaseInsensitiveMap overrides putAll method as well (for IBM JDK 1.6 compatibility)
* ConversionService prevents Converter from trying to convert to a subtype of its actual target type
* ConversionService is able to work with "Collections.emptyList()" as target type (again)
* CollectionCollection/MapToMapConverter preserve original Collection/Map if no converted elements
* fixed nested element conversion with a DataBinder + ConversionService + PropertyEditor
* restored DataBinder's ability to bind to an auto-growing List with unknown element type
* optimized DefaultListableBeanFactory's PropertyDescriptor caching for concurrent access
* context:property-placeholder's "file-encoding" attribute value is being applied correctly
* SpringValidatorAdapter accepts non-indexed set paths (for Hibernate Validator compatibility)
* fixed AbstractAsyncExecutionAspect's setExecutor method to correctly wrap in a TaskExecutorAdapter
* @Transactional qualifiers match against transaction manager definitions in parent contexts as well
* TransactionSynchronizationManager eagerly cleans up void ResourceHolders on any access
* updated H2 error codes in sql-error-codes.xml
* fixed NamedParameterJdbcTemplate to use correct maximum type for queryForInt/Long
* SimpleJdbcTestUtils executeSqlScript properly closes its LineNumberReader after use
* Hibernate synchronization properly unbinds Session even in case of afterCompletion exception
* JDO PersistenceManager synchronization performs close attempt after completion (if necessary)
* JPA EntityManagerFactoryUtils silently ignores IllegalArgumentExceptions from setHint calls
* added "forwarder" property to ConnectorServerFactoryBean, accepting an MBeanServerForwarder
* JmsInvokerClientInterceptor/FactoryBean always uses createConnection/createSession when on JMS 1.1
* RmiClientInterceptor detects nested SocketException as connect failure as well
* Servlet/PortletContextResource's getFile prefers "file:" URL resolution over calling getRealPath
* Portlet session mutex uses global session attribute to be shared among all portlets in the session
* fixed ServletServerHttpRequest to reconstruct from "request.getParameterMap()" for form POST only
* fixed @RequestMapping header matching to correctly process negated header conditions
* added "getObjectMapper()" accessor to MappingJacksonHttpMessageConverter
* ResourceHttpRequestHandler sends content without content-type header if no media type found
* AbstractCachingViewResolver allows for caching unresolved view names ("cacheUnresolved"=true)
* fixed "formMultiSelect"/"formCheckboxes" FreeMarker macros to compare against actual field value
Changes in version 3.0.6 (2011-08-18)
-------------------------------------
* fixed aspects bundle to declare dependencies for @Async aspect as well
* ProxyCreationContext uses "ThreadLocal.remove()" over "ThreadLocal.set(null)" as well
* DefaultListableBeanFactory is only deserializable through a SerializedBeanFactoryReference
* DefaultListableBeanFactory's getBean(name, type) attempts type conversion if necessary
* DefaultListableBeanFactory allows for init methods to register further bean definitions (again)
* XmlBeanDefinitionReader accepts description subelement within map entry as well (as per the XSD)
* ConfigurationClassPostProcessor supports use of same processor instance with several factories
* fixed potential InjectionMetadata NPE when using SpringBeanAutowiringInterceptor
* SpringBeanAutowiringSupport is able to process @Value annotations on any given target instance
* overridden @PersistenceContext annotations on subclass methods are being processed correctly
* BeanDefinitionVisitor now actually visits factory method names
* restored support for String-to-ContextResource conversion
* restored original GenericConversionService behavior with respect to empty collections/maps
* restored original FormattingConversionService behavior with respect to the use of subtypes
* added "formatters" property to FormattingConversionServiceFactoryBean
* collection/array conversion returns original collection if possible (instead of first element)
* fixed collection element resolution when using a ConversionService with a DataBinder
* DataBinder uses a default limit of 256 for array/collection auto-growing
* added "autoGrowNestedPaths" property to ConfigurableWebBindingInitializer
* Servlet/PortletRequestDataBinder perform unwrapping for MultipartRequest as well
* fixed AbstractBindingResult to avoid NPE in "hashCode()" if target is null
* fixed several HttpHeaders issues (charset handling, quoting/unquoting)
* SimpleClientHttpRequest uses fixed-length streaming mode (always sets content-length header)
* added "connectTimeout" and "readTimeout" properties to Simple/CommonsClientHttpRequestFactory
* explicit status code in RedirectView respected in HTTP 1.0 compatibility mode
* FormHttpMessageConverter correctly processes POST requests
* ResourceHttpRequestHandler does not set Content-Length header for 304 response
* ResourceHttpRequestHandler detects invalid directory traversal in given path
* LocaleChangeInterceptor validates locale values in order to prevent XSS vulnerability
* HtmlUtils properly escapes single quotes as well
* added support for web.xml context-param "springJspExpressionSupport" (explicit "true"/"false")
* ContextLoader and FrameworkServlet support "contextId" parameter for custom serialization id
* RemoteExporter uses an opaque proxy for 'serviceInterface' (no AOP interfaces exposed)
* added "acceptProxyClasses" flag to RemoteInvocationSerializingExporter
* refined WebLogic RMI descriptor to only mark 'getTargetInterfaceName' method as idempotent
* EhCacheManagerFactoryBean properly closes "ehcache.xml" input stream, if any
* revised JMS CachedConnectionFactory to avoid unnecessary rollback calls on Session return
* fixed JMS CachedConnectionFactory to fully synchronize its Session list
* fixed NamedParameterJdbcTemplate's handling of arrays as query parameters
* fixed JPA 2.0 timeout hints to correctly specify milliseconds
* updated Quartz package to support Quartz 1.8 as well (note: not supporting Quartz 2.0 yet)
* fixed @Rule execution order in SpringJUnit4ClassRunner to match standard JUnit 4 behavior
Changes in version 3.0.5 (2010-10-20)
-------------------------------------
+3 -3
View File
@@ -1,6 +1,6 @@
SPRING FRAMEWORK 3.0.5 (October 2010)
-------------------------------------
http://www.springframework.org
SPRING FRAMEWORK 3.0.7 (December 2011)
--------------------------------------
http://www.springsource.org
1. INTRODUCTION
+30 -30
View File
@@ -1,30 +1,30 @@
version=3.0.5
# osgi ranges
spring.osgi.range.nq=${version:[=.=.=, =.=.+1)}
spring.osgi.range="${spring.osgi.range.nq}"
aj.osgi.range="[1.5.4, 2.0.0)"
#
release.type=integration
natural.name=spring-framework
project.name=Spring Framework
project.key=SPR
ivy.cache.dir=${basedir}/../ivy-cache
integration.repo.dir=${basedir}/../integration-repo
license.dir=${basedir}/../build-spring-framework/resources
javadoc.exclude.package.names=org/springframework/samples/**
javadoc.max.memory=256M
test.vm.args=-Xmx1024M -XX:MaxPermSize=512M -XX:+HeapDumpOnOutOfMemoryError
compiler.args=-enableJavadoc -warn:none
# For when releasing
#release.type=release
#build.stamp=RELEASE
# For when releasing milestones
#release.type=milestone
#build.stamp=M1
# For development in trunk
#release.type=integration
#build.stamp=BUILD-SNAPSHOT
version=3.0.8
# osgi ranges
spring.osgi.range.nq=${version:[=.=.=, =.=.+1)}
spring.osgi.range="${spring.osgi.range.nq}"
aj.osgi.range="[1.5.4, 2.0.0)"
#
#release.type=integration
natural.name=spring-framework
project.name=Spring Framework
project.key=SPR
ivy.cache.dir=${basedir}/../ivy-cache
integration.repo.dir=${basedir}/../integration-repo
license.dir=${basedir}/../build-spring-framework/resources
javadoc.exclude.package.names=org/springframework/samples/**
javadoc.max.memory=256M
test.vm.args=-Xmx1024M -XX:MaxPermSize=512M -XX:+HeapDumpOnOutOfMemoryError
compiler.args=-enableJavadoc -warn:none
# For when releasing
#release.type=release
#build.stamp=RELEASE
# For when releasing milestones
#release.type=milestone
#build.stamp=M1
# For development in trunk
release.type=integration
build.stamp=BUILD-SNAPSHOT
+5 -6
View File
@@ -1,6 +1,5 @@
#common dependency versions
aspectj.version=1.6.8.RELEASE
commons.pool.version=1.5.3
slf4j.version=1.5.6
org.testng.version=5.10.0
org.junit.version=4.7.0
#common dependency versions
aspectj.version=1.6.8.RELEASE
slf4j.version=1.5.3
junit.version=4.7.0
testng.version=5.10.0
+2 -2
View File
@@ -30,14 +30,14 @@
<dependency org="net.sourceforge.cglib" name="com.springsource.net.sf.cglib" rev="2.2.0" conf="optional, bytecode-proxy->compile"/>
<dependency org="org.aopalliance" name="com.springsource.org.aopalliance" rev="1.0.0" conf="compile->compile"/>
<dependency org="org.apache.commons" name="com.springsource.org.apache.commons.logging" rev="1.1.1" conf="compile, commons-logging->compile"/>
<dependency org="org.apache.commons" name="com.springsource.org.apache.commons.pool" rev="${commons.pool.version}" conf="optional, pooling->compile"/>
<dependency org="org.apache.commons" name="com.springsource.org.apache.commons.pool" rev="1.5.3" conf="optional, pooling->compile"/>
<dependency org="org.aspectj" name="com.springsource.org.aspectj.weaver" rev="${aspectj.version}" conf="optional, aspectj->compile"/>
<dependency org="org.springframework" name="org.springframework.beans" rev="latest.integration" conf="compile->compile"/>
<dependency org="org.springframework" name="org.springframework.core" rev="latest.integration" conf="compile->compile"/>
<!-- test dependencies -->
<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.junit" name="com.springsource.org.junit" rev="${org.junit.version}" conf="test->runtime"/>
<dependency org="org.junit" name="com.springsource.org.junit" rev="${junit.version}" conf="test->runtime"/>
<dependency org="org.springframework" name="org.springframework.asm" rev="latest.integration" conf="test->runtime"/>
</dependencies>
+2 -2
View File
@@ -4,12 +4,12 @@
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<packaging>jar</packaging>
<version>3.0.5.BUILD-SNAPSHOT</version>
<version>3.0.8.BUILD-SNAPSHOT</version>
<parent>
<groupId>org.springframework</groupId>
<artifactId>spring-parent</artifactId>
<relativePath>../org.springframework.spring-parent</relativePath>
<version>3.0.5.BUILD-SNAPSHOT</version>
<version>3.0.8.BUILD-SNAPSHOT</version>
</parent>
<dependencies>
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2011 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,7 +46,12 @@ public class ProxyCreationContext {
* @param beanName the name of the bean, or <code>null</code> to reset it
*/
static void setCurrentProxiedBeanName(String beanName) {
currentProxiedBeanName.set(beanName);
if (beanName != null) {
currentProxiedBeanName.set(beanName);
}
else {
currentProxiedBeanName.remove();
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2011 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.
@@ -70,8 +70,9 @@ public class ExposeInvocationInterceptor implements MethodInterceptor, Ordered,
MethodInvocation mi = invocation.get();
if (mi == null)
throw new IllegalStateException(
"No MethodInvocation found: Check that an AOP invocation is in progress, " +
"and that the ExposeInvocationInterceptor is in the interceptor chain.");
"No MethodInvocation found: Check that an AOP invocation is in progress, and that the " +
"ExposeInvocationInterceptor is upfront in the interceptor chain. Specifically, note that " +
"advices with order HIGHEST_PRECEDENCE will execute before ExposeInvocationInterceptor!");
return mi;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2011 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,7 +16,9 @@
package org.springframework.aop.target;
import java.io.IOException;
import java.io.NotSerializableException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamException;
import org.springframework.beans.BeansException;
@@ -91,6 +93,11 @@ public abstract class AbstractPrototypeBasedTargetSource extends AbstractBeanFac
// Serialization support
//---------------------------------------------------------------------
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
throw new NotSerializableException("A prototype-based TargetSource itself is not deserializable - " +
"just a disconnected SingletonTargetSource is");
}
/**
* Replaces this object with a SingletonTargetSource on serialization.
* Protected as otherwise it won't be invoked for subclasses.
+2 -2
View File
@@ -4,12 +4,12 @@
<groupId>org.springframework</groupId>
<artifactId>spring-asm</artifactId>
<packaging>jar</packaging>
<version>3.0.5.BUILD-SNAPSHOT</version>
<version>3.0.8.BUILD-SNAPSHOT</version>
<parent>
<groupId>org.springframework</groupId>
<artifactId>spring-parent</artifactId>
<relativePath>../org.springframework.spring-parent</relativePath>
<version>3.0.5.BUILD-SNAPSHOT</version>
<version>3.0.8.BUILD-SNAPSHOT</version>
</parent>
+1 -1
View File
@@ -34,7 +34,7 @@
<dependency org="org.springframework" name="org.springframework.context" rev="latest.integration" conf="test->runtime"/>
<dependency org="org.springframework" name="org.springframework.context.support" rev="latest.integration" conf="test->runtime"/>
<dependency org="javax.persistence" name="com.springsource.javax.persistence" rev="1.0.0" conf="optional, orm->compile"/>
<dependency org="org.junit" name="com.springsource.org.junit" rev="${org.junit.version}" conf="test->compile"/>
<dependency org="org.junit" name="com.springsource.org.junit" rev="${junit.version}" conf="test->compile"/>
<dependency org="javax.mail" name="com.springsource.javax.mail" rev="1.4.0" conf="optional, test->compile"/>
</dependencies>
+2 -2
View File
@@ -4,12 +4,12 @@
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<packaging>jar</packaging>
<version>3.0.5.BUILD-SNAPSHOT</version>
<version>3.0.8.BUILD-SNAPSHOT</version>
<parent>
<groupId>org.springframework</groupId>
<artifactId>spring-parent</artifactId>
<relativePath>../org.springframework.spring-parent</relativePath>
<version>3.0.5.BUILD-SNAPSHOT</version>
<version>3.0.8.BUILD-SNAPSHOT</version>
</parent>
<dependencies>
@@ -45,7 +45,7 @@ public abstract aspect AbstractAsyncExecutionAspect {
this.asyncExecutor = (AsyncTaskExecutor) executor;
}
else {
this.asyncExecutor = new TaskExecutorAdapter(asyncExecutor);
this.asyncExecutor = new TaskExecutorAdapter(executor);
}
}
+1 -1
View File
@@ -30,7 +30,7 @@
<dependency org="org.springframework" name="org.springframework.core" rev="latest.integration" conf="compile->compile"/>
<!-- test dependencies -->
<dependency org="org.apache.log4j" name="com.springsource.org.apache.log4j" rev="1.2.15" conf="test->runtime"/>
<dependency org="org.junit" name="com.springsource.org.junit" rev="${org.junit.version}" conf="test->runtime"/>
<dependency org="org.junit" name="com.springsource.org.junit" rev="${junit.version}" conf="test->runtime"/>
<dependency org="org.easymock" name="com.springsource.org.easymock" rev="2.5.1" conf="test->compile"/>
<dependency org="org.springframework" name="org.springframework.asm" rev="latest.integration" conf="compile->compile"/>
</dependencies>
+2 -2
View File
@@ -4,12 +4,12 @@
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<packaging>jar</packaging>
<version>3.0.5.BUILD-SNAPSHOT</version>
<version>3.0.8.BUILD-SNAPSHOT</version>
<parent>
<groupId>org.springframework</groupId>
<artifactId>spring-parent</artifactId>
<relativePath>../org.springframework.spring-parent</relativePath>
<version>3.0.5.BUILD-SNAPSHOT</version>
<version>3.0.8.BUILD-SNAPSHOT</version>
</parent>
<dependencies>
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2011 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.
@@ -92,4 +92,15 @@ public interface BeanWrapper extends ConfigurablePropertyAccessor {
*/
boolean isAutoGrowNestedPaths();
/**
* Specify a limit for array and collection auto-growing.
* <p>Default is unlimited on a plain BeanWrapper.
*/
void setAutoGrowCollectionLimit(int autoGrowCollectionLimit);
/**
* Return the limit for array and collection auto-growing.
*/
int getAutoGrowCollectionLimit();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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.
@@ -120,6 +120,8 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
private boolean autoGrowNestedPaths = false;
private int autoGrowCollectionLimit = Integer.MAX_VALUE;
/**
* Create new empty BeanWrapperImpl. Wrapped instance needs to be set afterwards.
@@ -184,6 +186,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
setWrappedInstance(object, nestedPath, superBw.getWrappedInstance());
setExtractOldValueForEditor(superBw.isExtractOldValueForEditor());
setAutoGrowNestedPaths(superBw.isAutoGrowNestedPaths());
setAutoGrowCollectionLimit(superBw.getAutoGrowCollectionLimit());
setConversionService(superBw.getConversionService());
setSecurityContext(superBw.acc);
}
@@ -251,22 +254,38 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
}
/**
* If this BeanWrapper should "auto grow" nested paths.
* When true, auto growth is triggered on nested paths when null values are encountered.
* When true, auto growth is triggered on collection properties when out of bounds indexes are accessed.
* Default is false.
* Set whether this BeanWrapper should attempt to "auto-grow" a nested path that contains a null value.
* <p>If "true", a null path location will be populated with a default object value and traversed
* instead of resulting in a {@link NullValueInNestedPathException}. Turning this flag on also
* enables auto-growth of collection elements when accessing an out-of-bounds index.
* <p>Default is "false" on a plain BeanWrapper.
*/
public void setAutoGrowNestedPaths(boolean autoGrowNestedPaths) {
this.autoGrowNestedPaths = autoGrowNestedPaths;
}
/**
* If this BeanWrapper should "auto grow" nested paths.
* Return whether "auto-growing" of nested paths has been activated.
*/
public boolean isAutoGrowNestedPaths() {
return this.autoGrowNestedPaths;
}
/**
* Specify a limit for array and collection auto-growing.
* <p>Default is unlimited on a plain BeanWrapper.
*/
public void setAutoGrowCollectionLimit(int autoGrowCollectionLimit) {
this.autoGrowCollectionLimit = autoGrowCollectionLimit;
}
/**
* Return the limit for array and collection auto-growing.
*/
public int getAutoGrowCollectionLimit() {
return this.autoGrowCollectionLimit;
}
/**
* Set the security context used during the invocation of the wrapped instance methods.
* Can be null.
@@ -592,9 +611,9 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
private Object setDefaultValue(PropertyTokenHolder tokens) {
PropertyValue pv = createDefaultPropertyValue(tokens);
setPropertyValue(tokens, pv);
return pv.getValue();
return getPropertyValue(tokens);
}
private PropertyValue createDefaultPropertyValue(PropertyTokenHolder tokens) {
Class type = getPropertyType(tokens.canonicalName);
if (type == null) {
@@ -604,7 +623,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
Object defaultValue = newValue(type, tokens.canonicalName);
return new PropertyValue(tokens.canonicalName, defaultValue);
}
private Object newValue(Class<?> type, String name) {
try {
if (type.isArray()) {
@@ -634,7 +653,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
"Could not instantiate property type [" + type.getName() + "] to auto-grow nested property path: " + ex);
}
}
/**
* Create a new nested BeanWrapper instance.
* <p>Default implementation creates a BeanWrapperImpl instance.
@@ -834,15 +853,16 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
return array;
}
int length = Array.getLength(array);
if (index >= length) {
if (index >= length && index < this.autoGrowCollectionLimit) {
Class<?> componentType = array.getClass().getComponentType();
Object newArray = Array.newInstance(componentType, index + 1);
System.arraycopy(array, 0, newArray, 0, length);
for (int i = length; i < Array.getLength(newArray); i++) {
Array.set(newArray, i, newValue(componentType, name));
}
// TODO this is not efficient because conversion may create a copy ... set directly because we know it is assignable.
setPropertyValue(name, newArray);
return newArray;
return getPropertyValue(name);
}
else {
return array;
@@ -856,7 +876,8 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
if (!this.autoGrowNestedPaths) {
return;
}
if (index >= collection.size()) {
int size = collection.size();
if (index >= size && index < this.autoGrowCollectionLimit) {
Class elementType = GenericCollectionTypeResolver.getCollectionReturnType(pd.getReadMethod(), nestingLevel);
if (elementType != null) {
for (int i = collection.size(); i < index + 1; i++) {
@@ -932,13 +953,13 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
"Cannot access indexed value in property referenced " +
"in indexed property path '" + propertyName + "': returned null");
}
else if (propValue.getClass().isArray()) {
if (propValue.getClass().isArray()) {
PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
Class requiredType = propValue.getClass().getComponentType();
int arrayIndex = Integer.parseInt(key);
Object oldValue = null;
try {
if (isExtractOldValueForEditor()) {
if (isExtractOldValueForEditor() && arrayIndex < Array.getLength(propValue)) {
oldValue = Array.get(propValue, arrayIndex);
}
Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(), requiredType,
@@ -962,23 +983,30 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
}
Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(), requiredType,
new PropertyTypeDescriptor(pd, new MethodParameter(pd.getReadMethod(), -1), requiredType));
if (index < list.size()) {
list.set(index, convertedValue);
}
else if (index >= list.size()) {
for (int i = list.size(); i < index; i++) {
int size = list.size();
if (index >= size && index < this.autoGrowCollectionLimit) {
for (int i = 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 +
size + ", accessed using property path '" + propertyName +
"': List does not support filling up gaps with null elements");
}
}
list.add(convertedValue);
}
else {
try {
list.set(index, convertedValue);
}
catch (IndexOutOfBoundsException ex) {
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
"Invalid list index in property path '" + propertyName + "'", ex);
}
}
}
else if (propValue instanceof Map) {
PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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.
@@ -21,6 +21,7 @@ import java.beans.PropertyEditor;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
@@ -136,7 +137,10 @@ class TypeConverterDelegate {
ConversionService conversionService = this.propertyEditorRegistry.getConversionService();
if (editor == null && conversionService != null && convertedValue != null) {
TypeDescriptor sourceTypeDesc = TypeDescriptor.forObject(convertedValue);
TypeDescriptor targetTypeDesc = typeDescriptor.forElementType(requiredType);
TypeDescriptor targetTypeDesc = typeDescriptor;
if (requiredType != null && !requiredType.isAssignableFrom(typeDescriptor.getType())) {
targetTypeDesc = typeDescriptor.forElementType(requiredType);
}
if (conversionService.canConvert(sourceTypeDesc, targetTypeDesc)) {
return (T) conversionService.convert(convertedValue, sourceTypeDesc, targetTypeDesc);
}
@@ -223,7 +227,8 @@ class TypeConverterDelegate {
}
if (editor != null) {
msg.append(": PropertyEditor [").append(editor.getClass().getName()).append(
"] returned inappropriate value");
"] returned inappropriate value of type [").append(
ClassUtils.getDescriptiveType(convertedValue)).append("]");
throw new IllegalArgumentException(msg.toString());
}
else {
@@ -459,11 +464,20 @@ class TypeConverterDelegate {
protected Collection convertToTypedCollection(
Collection original, String propertyName, Class requiredType, TypeDescriptor typeDescriptor) {
boolean originalAllowed = requiredType.isInstance(original);
if (!originalAllowed && !Collection.class.isAssignableFrom(requiredType)) {
if (!Collection.class.isAssignableFrom(requiredType)) {
return original;
}
boolean approximable = CollectionFactory.isApproximableCollectionType(requiredType);
if (!approximable && !canCreateCopy(requiredType)) {
if (logger.isDebugEnabled()) {
logger.debug("Custom Collection type [" + original.getClass().getName() +
"] does not allow for creating a copy - injecting original Collection as-is");
}
return original;
}
boolean originalAllowed = requiredType.isInstance(original);
MethodParameter methodParam = typeDescriptor.getMethodParameter();
Class elementType = null;
if (methodParam != null) {
@@ -488,14 +502,14 @@ class TypeConverterDelegate {
catch (Throwable ex) {
if (logger.isDebugEnabled()) {
logger.debug("Cannot access Collection of type [" + original.getClass().getName() +
"] - injecting original Collection as-is", ex);
"] - injecting original Collection as-is: " + ex);
}
return original;
}
Collection convertedCopy;
try {
if (CollectionFactory.isApproximableCollectionType(requiredType)) {
if (approximable) {
convertedCopy = CollectionFactory.createApproximateCollection(original, original.size());
}
else {
@@ -505,7 +519,7 @@ class TypeConverterDelegate {
catch (Throwable ex) {
if (logger.isDebugEnabled()) {
logger.debug("Cannot create copy of Collection type [" + original.getClass().getName() +
"] - injecting original Collection as-is", ex);
"] - injecting original Collection as-is: " + ex);
}
return original;
}
@@ -528,7 +542,7 @@ class TypeConverterDelegate {
catch (Throwable ex) {
if (logger.isDebugEnabled()) {
logger.debug("Collection type [" + original.getClass().getName() +
"] seems to be read-only - injecting original Collection as-is", ex);
"] seems to be read-only - injecting original Collection as-is: " + ex);
}
return original;
}
@@ -541,11 +555,20 @@ class TypeConverterDelegate {
protected Map convertToTypedMap(
Map original, String propertyName, Class requiredType, TypeDescriptor typeDescriptor) {
boolean originalAllowed = requiredType.isInstance(original);
if (!originalAllowed && !Map.class.isAssignableFrom(requiredType)) {
if (!Map.class.isAssignableFrom(requiredType)) {
return original;
}
boolean approximable = CollectionFactory.isApproximableMapType(requiredType);
if (!approximable && !canCreateCopy(requiredType)) {
if (logger.isDebugEnabled()) {
logger.debug("Custom Map type [" + original.getClass().getName() +
"] does not allow for creating a copy - injecting original Map as-is");
}
return original;
}
boolean originalAllowed = requiredType.isInstance(original);
Class keyType = null;
Class valueType = null;
MethodParameter methodParam = typeDescriptor.getMethodParameter();
@@ -572,14 +595,14 @@ class TypeConverterDelegate {
catch (Throwable ex) {
if (logger.isDebugEnabled()) {
logger.debug("Cannot access Map of type [" + original.getClass().getName() +
"] - injecting original Map as-is", ex);
"] - injecting original Map as-is: " + ex);
}
return original;
}
Map convertedCopy;
try {
if (CollectionFactory.isApproximableMapType(requiredType)) {
if (approximable) {
convertedCopy = CollectionFactory.createApproximateMap(original, original.size());
}
else {
@@ -589,7 +612,7 @@ class TypeConverterDelegate {
catch (Throwable ex) {
if (logger.isDebugEnabled()) {
logger.debug("Cannot create copy of Map type [" + original.getClass().getName() +
"] - injecting original Map as-is", ex);
"] - injecting original Map as-is: " + ex);
}
return original;
}
@@ -617,7 +640,7 @@ class TypeConverterDelegate {
catch (Throwable ex) {
if (logger.isDebugEnabled()) {
logger.debug("Map type [" + original.getClass().getName() +
"] seems to be read-only - injecting original Map as-is", ex);
"] seems to be read-only - injecting original Map as-is: " + ex);
}
return original;
}
@@ -638,4 +661,9 @@ class TypeConverterDelegate {
null);
}
private boolean canCreateCopy(Class requiredType) {
return (!requiredType.isInterface() && !Modifier.isAbstract(requiredType.getModifiers()) &&
Modifier.isPublic(requiredType.getModifiers()) && ClassUtils.hasConstructor(requiredType));
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2011 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,7 @@
package org.springframework.beans.factory.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -46,16 +47,25 @@ import java.lang.annotation.Target;
* declared value type. In case of a Map, the keys must be declared as
* type String and will be resolved to the corresponding bean names.
*
* <p>Please do consult the javadoc for the {@link AutowiredAnnotationBeanPostProcessor}
* <p>Note that actual injection is performed through a
* {@link org.springframework.beans.factory.config.BeanPostProcessor
* BeanPostProcessor} which in turn means that you <em>cannot</em>
* use {@code @Autowired} to inject references into
* {@link org.springframework.beans.factory.config.BeanPostProcessor
* BeanPostProcessor} or {@link BeanFactoryPostProcessor} types. Please
* consult the javadoc for the {@link AutowiredAnnotationBeanPostProcessor}
* class (which, by default, checks for the presence of this annotation).
*
* @author Juergen Hoeller
* @author Mark Fisher
* @since 2.5
* @see AutowiredAnnotationBeanPostProcessor
* @see Qualifier
* @see Value
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
/**
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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.
@@ -50,6 +50,7 @@ import org.springframework.beans.factory.config.InstantiationAwareBeanPostProces
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.BridgeMethodResolver;
import org.springframework.core.GenericTypeResolver;
import org.springframework.core.MethodParameter;
import org.springframework.core.Ordered;
@@ -61,8 +62,11 @@ import org.springframework.util.ReflectionUtils;
/**
* {@link org.springframework.beans.factory.config.BeanPostProcessor} implementation
* that autowires annotated fields, setter methods and arbitrary config methods.
* Such members to be injected are detected through a Java 5 annotation:
* by default, Spring's {@link Autowired} annotation.
* Such members to be injected are detected through a Java 5 annotation: by default,
* Spring's {@link Autowired @Autowired} and {@link Value @Value} annotations.
*
* <p>Also supports JSR-330's {@link javax.inject.Inject @Inject} annotation,
* if available, as a direct alternative to Spring's own <code>@Autowired</code>.
*
* <p>Only one constructor (at max) of any given bean class may carry this
* annotation with the 'required' parameter set to <code>true</code>,
@@ -77,27 +81,25 @@ import org.springframework.util.ReflectionUtils;
* <p>Fields are injected right after construction of a bean, before any
* config methods are invoked. Such a config field does not have to be public.
*
* <p>Config methods may have an arbitrary name and any number of arguments;
* each of those arguments will be autowired with a matching bean in the
* Spring container. Bean property setter methods are effectively just
* a special case of such a general config method. Such config methods
* do not have to be public.
*
* <p>Also supports JSR-330's {@link javax.inject.Inject} annotation, if available.
* <p>Config methods may have an arbitrary name and any number of arguments; each of
* those arguments will be autowired with a matching bean in the Spring container.
* Bean property setter methods are effectively just a special case of such a
* general config method. Config methods do not have to be public.
*
* <p>Note: A default AutowiredAnnotationBeanPostProcessor will be registered
* by the "context:annotation-config" and "context:component-scan" XML tags.
* Remove or turn off the default annotation configuration there if you intend
* to specify a custom AutowiredAnnotationBeanPostProcessor bean definition.
* <p><b>NOTE:</b> Annotation injection will be performed <i>before</i> XML injection; thus
* the latter configuration will override the former for properties wired through
* both approaches.
*
* <p><b>NOTE:</b> Annotation injection will be performed <i>before</i> XML injection;
* thus the latter configuration will override the former for properties wired through
* both approaches.
*
* @author Juergen Hoeller
* @author Mark Fisher
* @since 2.5
* @see #setAutowiredAnnotationType
* @see Autowired
* @see Value
*/
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
@@ -115,8 +117,8 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
private ConfigurableListableBeanFactory beanFactory;
private final Map<Class<?>, Constructor[]> candidateConstructorsCache =
new ConcurrentHashMap<Class<?>, Constructor[]>();
private final Map<Class<?>, Constructor<?>[]> candidateConstructorsCache =
new ConcurrentHashMap<Class<?>, Constructor<?>[]>();
private final Map<Class<?>, InjectionMetadata> injectionMetadataCache =
new ConcurrentHashMap<Class<?>, InjectionMetadata>();
@@ -305,7 +307,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
}
private InjectionMetadata findAutowiringMetadata(Class clazz) {
private InjectionMetadata findAutowiringMetadata(Class<?> clazz) {
// Quick check on the concurrent map first, with minimal locking.
InjectionMetadata metadata = this.injectionMetadataCache.get(clazz);
if (metadata == null) {
@@ -320,7 +322,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
return metadata;
}
private InjectionMetadata buildAutowiringMetadata(Class clazz) {
private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();
Class<?> targetClass = clazz;
@@ -340,7 +342,9 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
}
}
for (Method method : targetClass.getDeclaredMethods()) {
Annotation annotation = findAutowiredAnnotation(method);
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
Annotation annotation = BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod) ?
findAutowiredAnnotation(bridgedMethod) : findAutowiredAnnotation(method);
if (annotation != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isWarnEnabled()) {
@@ -534,7 +538,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
arguments = resolveCachedArguments(beanName);
}
else {
Class[] paramTypes = method.getParameterTypes();
Class<?>[] paramTypes = method.getParameterTypes();
arguments = new Object[paramTypes.length];
DependencyDescriptor[] descriptors = new DependencyDescriptor[paramTypes.length];
Set<String> autowiredBeanNames = new LinkedHashSet<String>(paramTypes.length);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2007 the original author or authors.
* Copyright 2002-2011 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.
@@ -34,10 +34,10 @@ import java.lang.annotation.Target;
* @author Ramnivas Laddad
* @since 2.0
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Configurable {
/**
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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.
@@ -168,21 +168,23 @@ public class InjectionMetadata {
*/
protected boolean checkPropertySkipping(PropertyValues pvs) {
if (this.skip == null) {
synchronized (pvs) {
if (this.skip == null) {
if (this.pd != null && pvs != null) {
if (pvs.contains(this.pd.getName())) {
// Explicit value provided as part of the bean definition.
this.skip = true;
return true;
}
else if (pvs instanceof MutablePropertyValues) {
((MutablePropertyValues) pvs).registerProcessedProperty(this.pd.getName());
if (pvs != null) {
synchronized (pvs) {
if (this.skip == null) {
if (this.pd != null) {
if (pvs.contains(this.pd.getName())) {
// Explicit value provided as part of the bean definition.
this.skip = true;
return true;
}
else if (pvs instanceof MutablePropertyValues) {
((MutablePropertyValues) pvs).registerProcessedProperty(this.pd.getName());
}
}
}
this.skip = false;
}
}
this.skip = false;
}
return this.skip;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2011 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,9 +31,10 @@ import java.lang.annotation.Target;
* @author Mark Fisher
* @author Juergen Hoeller
* @since 2.5
* @see Autowired
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Qualifier {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2011 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.
@@ -164,8 +164,11 @@ public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanP
* @return <code>true</code> to skip the bean; <code>false</code> to process it
*/
protected boolean shouldSkip(ConfigurableListableBeanFactory beanFactory, String beanName) {
return (beanFactory != null && beanFactory.containsBeanDefinition(beanName) &&
Boolean.TRUE.equals(beanFactory.getBeanDefinition(beanName).getAttribute(SKIP_REQUIRED_CHECK_ATTRIBUTE)));
if (beanFactory == null || !beanFactory.containsBeanDefinition(beanName)) {
return false;
}
Object value = beanFactory.getBeanDefinition(beanName).getAttribute(SKIP_REQUIRED_CHECK_ATTRIBUTE);
return (value != null && (Boolean.TRUE.equals(value) || Boolean.valueOf(value.toString())));
}
/**
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2011 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,7 @@
package org.springframework.beans.factory.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -31,13 +32,25 @@ import java.lang.annotation.Target;
* <p>A common use case is to assign default field values using
* "#{systemProperties.myProp}" style expressions.
*
* <p>Note that actual processing of the {@code @Value} annotation is performed
* by a {@link org.springframework.beans.factory.config.BeanPostProcessor
* BeanPostProcessor} which in turn means that you <em>cannot</em> use
* {@code @Value} within
* {@link org.springframework.beans.factory.config.BeanPostProcessor
* BeanPostProcessor} or {@link BeanFactoryPostProcessor} types. Please
* consult the javadoc for the {@link AutowiredAnnotationBeanPostProcessor}
* class (which, by default, checks for the presence of this annotation).
*
* @author Juergen Hoeller
* @since 3.0
* @see AutowiredAnnotationBeanPostProcessor
* @see Autowired
* @see org.springframework.beans.factory.config.BeanExpressionResolver
* @see org.springframework.beans.factory.support.AutowireCandidateResolver#getSuggestedValue
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Value {
/**
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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.
@@ -115,7 +115,7 @@ public class BeanDefinitionVisitor {
}
protected void visitFactoryMethodName(BeanDefinition beanDefinition) {
String factoryMethodName = beanDefinition.getFactoryBeanName();
String factoryMethodName = beanDefinition.getFactoryMethodName();
if (factoryMethodName != null) {
String resolvedName = resolveStringValue(factoryMethodName);
if (!factoryMethodName.equals(resolvedName)) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2011 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.
@@ -173,7 +173,7 @@ public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, Single
* @param requiredType type of the property
* @param propertyEditorClass the {@link PropertyEditor} class to register
*/
void registerCustomEditor(Class requiredType, Class<? extends PropertyEditor> propertyEditorClass);
void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass);
/**
* Initialize the given PropertyEditorRegistry with the custom editors
@@ -28,7 +28,6 @@ import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
@@ -144,7 +143,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
/** Cache of filtered PropertyDescriptors: bean Class -> PropertyDescriptor array */
private final Map<Class, PropertyDescriptor[]> filteredPropertyDescriptorsCache =
new HashMap<Class, PropertyDescriptor[]>();
new ConcurrentHashMap<Class, PropertyDescriptor[]>();
/**
@@ -567,7 +566,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
}
@Override
protected Class predictBeanType(String beanName, RootBeanDefinition mbd, Class[] typesToMatch) {
protected Class predictBeanType(String beanName, RootBeanDefinition mbd, Class... typesToMatch) {
Class beanClass;
if (mbd.getFactoryMethodName() != null) {
beanClass = getTypeForFactoryMethod(beanName, mbd, typesToMatch);
@@ -1201,22 +1200,25 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
* @see #isExcludedFromDependencyCheck
*/
protected PropertyDescriptor[] filterPropertyDescriptorsForDependencyCheck(BeanWrapper bw) {
synchronized (this.filteredPropertyDescriptorsCache) {
PropertyDescriptor[] filtered = this.filteredPropertyDescriptorsCache.get(bw.getWrappedClass());
if (filtered == null) {
List<PropertyDescriptor> pds =
new LinkedList<PropertyDescriptor>(Arrays.asList(bw.getPropertyDescriptors()));
for (Iterator<PropertyDescriptor> it = pds.iterator(); it.hasNext();) {
PropertyDescriptor pd = it.next();
if (isExcludedFromDependencyCheck(pd)) {
it.remove();
PropertyDescriptor[] filtered = this.filteredPropertyDescriptorsCache.get(bw.getWrappedClass());
if (filtered == null) {
synchronized (this.filteredPropertyDescriptorsCache) {
filtered = this.filteredPropertyDescriptorsCache.get(bw.getWrappedClass());
if (filtered == null) {
List<PropertyDescriptor> pds =
new LinkedList<PropertyDescriptor>(Arrays.asList(bw.getPropertyDescriptors()));
for (Iterator<PropertyDescriptor> it = pds.iterator(); it.hasNext();) {
PropertyDescriptor pd = it.next();
if (isExcludedFromDependencyCheck(pd)) {
it.remove();
}
}
filtered = pds.toArray(new PropertyDescriptor[pds.size()]);
this.filteredPropertyDescriptorsCache.put(bw.getWrappedClass(), filtered);
}
filtered = pds.toArray(new PropertyDescriptor[pds.size()]);
this.filteredPropertyDescriptorsCache.put(bw.getWrappedClass(), filtered);
}
return filtered;
}
return filtered;
}
/**
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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,6 +42,7 @@ import org.springframework.beans.PropertyEditorRegistry;
import org.springframework.beans.PropertyEditorRegistrySupport;
import org.springframework.beans.SimpleTypeConverter;
import org.springframework.beans.TypeConverter;
import org.springframework.beans.TypeMismatchException;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanCurrentlyInCreationException;
import org.springframework.beans.factory.BeanDefinitionStoreException;
@@ -166,6 +167,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
private final ThreadLocal<Object> prototypesCurrentlyInCreation =
new NamedThreadLocal<Object>("Prototype beans currently in creation");
/**
* Create a new AbstractBeanFactory.
*/
@@ -189,7 +191,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
@@ -346,7 +348,16 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
try {
return getTypeConverter().convertIfNecessary(bean, requiredType);
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type [" +
ClassUtils.getQualifiedName(requiredType) + "]", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
@@ -682,7 +693,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
return this.propertyEditorRegistrars;
}
public void registerCustomEditor(Class requiredType, Class<? extends PropertyEditor> propertyEditorClass) {
public void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass) {
Assert.notNull(requiredType, "Required type must not be null");
Assert.isAssignable(PropertyEditor.class, propertyEditorClass);
this.customEditors.put(requiredType, propertyEditorClass);
@@ -1253,7 +1264,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
}
}
private Class doResolveBeanClass(RootBeanDefinition mbd, Class... typesToMatch) throws ClassNotFoundException {
if (!ObjectUtils.isEmpty(typesToMatch)) {
ClassLoader tempClassLoader = getTempClassLoader();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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,7 +16,9 @@
package org.springframework.beans.factory.support;
import java.io.IOException;
import java.io.NotSerializableException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.lang.annotation.Annotation;
@@ -541,7 +543,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
}
/**
* Considers all beans as eligible for metdata caching
* Considers all beans as eligible for metadata caching
* if the factory's configuration has been marked as frozen.
* @see #freezeConfiguration()
*/
@@ -554,9 +556,11 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
if (this.logger.isInfoEnabled()) {
this.logger.info("Pre-instantiating singletons in " + this);
}
synchronized (this.beanDefinitionMap) {
for (String beanName : this.beanDefinitionNames) {
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
@@ -570,7 +574,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
}, getAccessControlContext());
}
else {
isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean) factory).isEagerInit();
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
@@ -664,8 +669,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
destroySingleton(beanName);
}
// Reset all bean definitions that have the given bean as parent
// (recursively).
// Reset all bean definitions that have the given bean as parent (recursively).
for (String bdName : this.beanDefinitionNames) {
if (!beanName.equals(bdName)) {
BeanDefinition bd = this.beanDefinitionMap.get(bdName);
@@ -711,7 +715,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);
BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
@@ -944,6 +948,11 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
// Serialization support
//---------------------------------------------------------------------
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
throw new NotSerializableException("DefaultListableBeanFactory itself is not deserializable - " +
"just a SerializedBeanFactoryReference is");
}
protected Object writeReplace() throws ObjectStreamException {
if (this.serializationId != null) {
return new SerializedBeanFactoryReference(this.serializationId);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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.
@@ -1176,7 +1176,10 @@ public class BeanDefinitionParserDelegate {
}
else {
// Child element is what we're looking for.
if (valueEle != null) {
if (nodeNameEquals(candidateEle, DESCRIPTION_ELEMENT)) {
// the element is a <description> -> ignore it
}
else if (valueEle != null) {
error("<entry> element must not contain more than one value sub-element", entryEle);
}
else {
@@ -1422,7 +1425,7 @@ public class BeanDefinitionParserDelegate {
/**
* 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()}.
* {@link Node#getNodeName()} and {@link Node#getLocalName()}.
* <p>Subclasses may override the default implementation to provide a different
* mechanism for comparing node names.
* @param node the node to compare
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2011 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.
@@ -34,10 +34,6 @@ public class CurrencyEditor extends PropertyEditorSupport {
setValue(Currency.getInstance(text));
}
/**
* This implementation returns <code>null</code> to indicate that
* there is no appropriate text representation.
*/
@Override
public String getAsText() {
Currency value = (Currency) getValue();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2011 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.
@@ -77,7 +77,10 @@ public class CustomDateEditor extends PropertyEditorSupport {
* thrown if the String does not exactly match the length specified. This is useful
* because SimpleDateFormat does not enforce strict parsing of the year part,
* not even with <code>setLenient(false)</code>. Without an "exactDateLength"
* specified, the "01/01/05" would get parsed to "01/01/0005".
* specified, the "01/01/05" would get parsed to "01/01/0005". However, even
* with an "exactDateLength" specified, prepended zeros in the day or month
* part may still allow for a shorter year part, so consider this as just
* one more assertion that gets you closer to the intended date format.
* @param dateFormat DateFormat to use for parsing and rendering
* @param allowEmpty if empty strings should be allowed
* @param exactDateLength the exact expected length of the date String
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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.
@@ -34,6 +34,7 @@ import org.springframework.beans.propertyeditors.InputSourceEditor;
import org.springframework.beans.propertyeditors.InputStreamEditor;
import org.springframework.beans.propertyeditors.URIEditor;
import org.springframework.beans.propertyeditors.URLEditor;
import org.springframework.core.io.ContextResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceEditor;
import org.springframework.core.io.ResourceLoader;
@@ -84,6 +85,7 @@ public class ResourceEditorRegistrar implements PropertyEditorRegistrar {
public void registerCustomEditors(PropertyEditorRegistry registry) {
ResourceEditor baseEditor = new ResourceEditor(this.resourceLoader);
doRegisterEditor(registry, Resource.class, baseEditor);
doRegisterEditor(registry, ContextResource.class, baseEditor);
doRegisterEditor(registry, InputStream.class, new InputStreamEditor(baseEditor));
doRegisterEditor(registry, InputSource.class, new InputSourceEditor(baseEditor));
doRegisterEditor(registry, File.class, new FileEditor(baseEditor));
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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,10 +19,11 @@ package org.springframework.beans;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* @author Keith Donald
* @author Juergen Hoeller
@@ -117,6 +118,19 @@ public class BeanWrapperAutoGrowingTests {
assertNotNull(wrapper.getPropertyValue("list[3]"));
}
@Test
public void getPropertyValueAutoGrowListFailsAgainstLimit() {
wrapper.setAutoGrowCollectionLimit(2);
try {
assertNotNull(wrapper.getPropertyValue("list[4]"));
fail("Should have thrown InvalidPropertyException");
}
catch (InvalidPropertyException ex) {
// expected
assertTrue(ex.getRootCause() instanceof IndexOutOfBoundsException);
}
}
@Test
public void getPropertyValueAutoGrowMultiDimensionalList() {
assertNotNull(wrapper.getPropertyValue("multiList[0][0]"));
@@ -155,6 +155,18 @@
</property>
</bean>
<!-- The <description> element below caused parsing exception prior to resolution of SPR-8563 -->
<bean id="mapWithDescriptionInEntry" class="org.springframework.beans.factory.xml.HasMap">
<property name="map">
<map>
<entry key="e1">
<description>A map entry with a description</description>
<value>v1</value>
</entry>
</map>
</property>
</bean>
<bean id="fooKey" class="java.lang.String">
<constructor-arg value="foo"/>
</bean>
+1 -1
View File
@@ -51,7 +51,7 @@
<dependency org="org.hsqldb" name="com.springsource.org.hsqldb" rev="1.8.0.9" conf="test->runtime"/>
<dependency org="org.apache.poi" name="com.springsource.org.apache.poi" rev="3.0.2.FINAL" conf="test->compile"/>
<dependency org="org.easymock" name="com.springsource.org.easymock" rev="2.5.1" conf="test->compile"/>
<dependency org="org.junit" name="com.springsource.org.junit" rev="${org.junit.version}" conf="test->runtime"/>
<dependency org="org.junit" name="com.springsource.org.junit" rev="${junit.version}" conf="test->runtime"/>
</dependencies>
</ivy-module>
+2 -2
View File
@@ -4,12 +4,12 @@
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<packaging>jar</packaging>
<version>3.0.5.BUILD-SNAPSHOT</version>
<version>3.0.8.BUILD-SNAPSHOT</version>
<parent>
<groupId>org.springframework</groupId>
<artifactId>spring-parent</artifactId>
<relativePath>../org.springframework.spring-parent</relativePath>
<version>3.0.5.BUILD-SNAPSHOT</version>
<version>3.0.8.BUILD-SNAPSHOT</version>
</parent>
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2011 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,6 +17,7 @@
package org.springframework.cache.ehcache;
import java.io.IOException;
import java.io.InputStream;
import net.sf.ehcache.CacheException;
import net.sf.ehcache.CacheManager;
@@ -97,23 +98,17 @@ public class EhCacheManagerFactoryBean implements FactoryBean<CacheManager>, Ini
public void afterPropertiesSet() throws IOException, CacheException {
logger.info("Initializing EHCache CacheManager");
if (this.shared) {
// Shared CacheManager singleton at the VM level.
if (this.configLocation != null) {
this.cacheManager = CacheManager.create(this.configLocation.getInputStream());
if (this.configLocation != null) {
InputStream is = this.configLocation.getInputStream();
try {
this.cacheManager = (this.shared ? CacheManager.create(is) : new CacheManager(is));
}
else {
this.cacheManager = CacheManager.create();
finally {
is.close();
}
}
else {
// Independent CacheManager instance (the default).
if (this.configLocation != null) {
this.cacheManager = new CacheManager(this.configLocation.getInputStream());
}
else {
this.cacheManager = new CacheManager();
}
this.cacheManager = (this.shared ? CacheManager.create() : new CacheManager());
}
if (this.cacheManagerName != null) {
this.cacheManager.setName(this.cacheManagerName);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2011 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.
@@ -40,6 +40,13 @@ public class LocalTaskExecutorThreadPool implements ThreadPool {
private Executor taskExecutor;
public void setInstanceId(String schedInstId) {
}
public void setInstanceName(String schedName) {
}
public void initialize() throws SchedulerConfigException {
// Absolutely needs thread-bound TaskExecutor to initialize.
this.taskExecutor = SchedulerFactoryBean.getConfigTimeTaskExecutor();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2011 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,7 @@
package org.springframework.scheduling.quartz;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
@@ -34,7 +35,6 @@ import org.quartz.SchedulerListener;
import org.quartz.Trigger;
import org.quartz.TriggerListener;
import org.quartz.spi.ClassLoadHelper;
import org.quartz.xml.JobSchedulingDataProcessor;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.ResourceLoader;
@@ -240,9 +240,25 @@ public abstract class SchedulerAccessor implements ResourceLoaderAware {
if (this.jobSchedulingDataLocations != null) {
ClassLoadHelper clh = new ResourceLoaderClassLoadHelper(this.resourceLoader);
clh.initialize();
JobSchedulingDataProcessor dataProcessor = new JobSchedulingDataProcessor(clh, true, true);
for (String location : this.jobSchedulingDataLocations) {
dataProcessor.processFileAndScheduleJobs(location, getScheduler(), this.overwriteExistingJobs);
try {
// Quartz 1.8 or higher?
Class dataProcessorClass = getClass().getClassLoader().loadClass("org.quartz.xml.XMLSchedulingDataProcessor");
logger.debug("Using Quartz 1.8 XMLSchedulingDataProcessor");
Object dataProcessor = dataProcessorClass.getConstructor(ClassLoadHelper.class).newInstance(clh);
Method processFileAndScheduleJobs = dataProcessorClass.getMethod("processFileAndScheduleJobs", String.class, Scheduler.class);
for (String location : this.jobSchedulingDataLocations) {
processFileAndScheduleJobs.invoke(dataProcessor, location, getScheduler());
}
}
catch (ClassNotFoundException ex) {
// Quartz 1.6
Class dataProcessorClass = getClass().getClassLoader().loadClass("org.quartz.xml.JobSchedulingDataProcessor");
logger.debug("Using Quartz 1.6 JobSchedulingDataProcessor");
Object dataProcessor = dataProcessorClass.getConstructor(ClassLoadHelper.class, boolean.class, boolean.class).newInstance(clh, true, true);
Method processFileAndScheduleJobs = dataProcessorClass.getMethod("processFileAndScheduleJobs", String.class, Scheduler.class, boolean.class);
for (String location : this.jobSchedulingDataLocations) {
processFileAndScheduleJobs.invoke(dataProcessor, location, getScheduler(), this.overwriteExistingJobs);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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.
@@ -74,9 +74,9 @@ import org.springframework.util.CollectionUtils;
* automatically apply to Scheduler operations performed within those scopes.
* Alternatively, you may add transactional advice for the Scheduler itself.
*
* <p><b>Note:</b> This version of Spring's SchedulerFactoryBean requires
* Quartz 1.5.x or 1.6.x. The "jobSchedulingDataLocation" feature requires
* Quartz 1.6.1 or higher (as of Spring 2.5.5).
* <p><b>Note:</b> This version of Spring's SchedulerFactoryBean supports Quartz 1.x,
* more specifically Quartz 1.5 or higher. The "jobSchedulingDataLocation" feature
* requires Quartz 1.6.1 or higher (as of Spring 2.5.5).
*
* @author Juergen Hoeller
* @since 18.02.2004
+1 -1
View File
@@ -65,7 +65,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.junit" name="com.springsource.org.junit" rev="${org.junit.version}" conf="test->runtime"/>
<dependency org="org.junit" name="com.springsource.org.junit" rev="${junit.version}" conf="test->runtime"/>
<dependency org="org.slf4j" name="com.springsource.slf4j.jcl" rev="${slf4j.version}" conf="test->runtime"/>
</dependencies>
+2 -2
View File
@@ -6,12 +6,12 @@
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<packaging>jar</packaging>
<version>3.0.5.BUILD-SNAPSHOT</version>
<version>3.0.8.BUILD-SNAPSHOT</version>
<parent>
<groupId>org.springframework</groupId>
<artifactId>spring-parent</artifactId>
<relativePath>../org.springframework.spring-parent</relativePath>
<version>3.0.5.BUILD-SNAPSHOT</version>
<version>3.0.8.BUILD-SNAPSHOT</version>
</parent>
<dependencies>
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2011 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,6 +58,7 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.BridgeMethodResolver;
import org.springframework.core.MethodParameter;
import org.springframework.core.Ordered;
import org.springframework.jndi.support.SimpleJndiBeanFactory;
@@ -303,7 +304,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
}
private InjectionMetadata findResourceMetadata(final Class clazz) {
private InjectionMetadata findResourceMetadata(final Class<?> clazz) {
// Quick check on the concurrent map first, with minimal locking.
InjectionMetadata metadata = this.injectionMetadataCache.get(clazz);
if (metadata == null) {
@@ -338,40 +339,41 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
}
}
for (Method method : targetClass.getDeclaredMethods()) {
if (webServiceRefClass != null && method.isAnnotationPresent(webServiceRefClass) &&
method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
throw new IllegalStateException("@WebServiceRef annotation is not supported on static methods");
}
if (method.getParameterTypes().length != 1) {
throw new IllegalStateException("@WebServiceRef annotation requires a single-arg method: " + method);
}
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
currElements.add(new WebServiceRefElement(method, pd));
}
else if (ejbRefClass != null && method.isAnnotationPresent(ejbRefClass) &&
method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
throw new IllegalStateException("@EJB annotation is not supported on static methods");
}
if (method.getParameterTypes().length != 1) {
throw new IllegalStateException("@EJB annotation requires a single-arg method: " + method);
}
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
currElements.add(new EjbRefElement(method, pd));
}
else if (method.isAnnotationPresent(Resource.class) &&
method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
throw new IllegalStateException("@Resource annotation is not supported on static methods");
}
Class[] paramTypes = method.getParameterTypes();
if (paramTypes.length != 1) {
throw new IllegalStateException("@Resource annotation requires a single-arg method: " + method);
}
if (!ignoredResourceTypes.contains(paramTypes[0].getName())) {
method = BridgeMethodResolver.findBridgedMethod(method);
Method mostSpecificMethod = BridgeMethodResolver.findBridgedMethod(ClassUtils.getMostSpecificMethod(method, clazz));
if (method.equals(mostSpecificMethod)) {
if (webServiceRefClass != null && method.isAnnotationPresent(webServiceRefClass)) {
if (Modifier.isStatic(method.getModifiers())) {
throw new IllegalStateException("@WebServiceRef annotation is not supported on static methods");
}
if (method.getParameterTypes().length != 1) {
throw new IllegalStateException("@WebServiceRef annotation requires a single-arg method: " + method);
}
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
currElements.add(new ResourceElement(method, pd));
currElements.add(new WebServiceRefElement(method, pd));
}
else if (ejbRefClass != null && method.isAnnotationPresent(ejbRefClass)) {
if (Modifier.isStatic(method.getModifiers())) {
throw new IllegalStateException("@EJB annotation is not supported on static methods");
}
if (method.getParameterTypes().length != 1) {
throw new IllegalStateException("@EJB annotation requires a single-arg method: " + method);
}
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
currElements.add(new EjbRefElement(method, pd));
}
else if (method.isAnnotationPresent(Resource.class)) {
if (Modifier.isStatic(method.getModifiers())) {
throw new IllegalStateException("@Resource annotation is not supported on static methods");
}
Class<?>[] paramTypes = method.getParameterTypes();
if (paramTypes.length != 1) {
throw new IllegalStateException("@Resource annotation requires a single-arg method: " + method);
}
if (!ignoredResourceTypes.contains(paramTypes[0].getName())) {
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
currElements.add(new ResourceElement(method, pd));
}
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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,6 +17,7 @@
package org.springframework.context.annotation;
import java.io.IOException;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
@@ -80,9 +81,9 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
private boolean setMetadataReaderFactoryCalled = false;
private boolean postProcessBeanDefinitionRegistryCalled = false;
private final Set<Integer> registriesPostProcessed = new HashSet<Integer>();
private boolean postProcessBeanFactoryCalled = false;
private final Set<Integer> factoriesPostProcessed = new HashSet<Integer>();
/**
@@ -130,15 +131,16 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
* Derive further bean definitions from the configuration classes in the registry.
*/
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
if (this.postProcessBeanDefinitionRegistryCalled) {
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called for this post-processor");
"postProcessBeanDefinitionRegistry already called for this post-processor against " + registry);
}
if (this.postProcessBeanFactoryCalled) {
if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called for this post-processor");
"postProcessBeanFactory already called for this post-processor against " + registry);
}
this.postProcessBeanDefinitionRegistryCalled = true;
this.registriesPostProcessed.add(registryId);
processConfigBeanDefinitions(registry);
}
@@ -147,12 +149,13 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
* by replacing them with CGLIB-enhanced subclasses.
*/
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
if (this.postProcessBeanFactoryCalled) {
int factoryId = System.identityHashCode(beanFactory);
if (this.factoriesPostProcessed.contains(factoryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called for this post-processor");
"postProcessBeanFactory already called for this post-processor against " + beanFactory);
}
this.postProcessBeanFactoryCalled = true;
if (!this.postProcessBeanDefinitionRegistryCalled) {
this.factoriesPostProcessed.add((factoryId));
if (!this.registriesPostProcessed.contains((factoryId))) {
// BeanDefinitionRegistryPostProcessor hook apparently not supported...
// Simply call processConfigBeanDefinitions lazily at this point then.
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2011 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,7 +53,7 @@ abstract class AbstractPropertyLoadingBeanDefinitionParser extends AbstractSingl
String fileEncoding = element.getAttribute("file-encoding");
if (StringUtils.hasLength(fileEncoding)) {
builder.addPropertyReference("fileEncoding", fileEncoding);
builder.addPropertyValue("fileEncoding", fileEncoding);
}
String order = element.getAttribute("order");
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2011 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.
@@ -38,12 +38,9 @@ class PropertyPlaceholderBeanDefinitionParser extends AbstractPropertyLoadingBea
@Override
protected void doParse(Element element, BeanDefinitionBuilder builder) {
super.doParse(element, builder);
builder.addPropertyValue("ignoreUnresolvablePlaceholders",
Boolean.valueOf(element.getAttribute("ignore-unresolvable")));
String systemPropertiesModeName = element.getAttribute("system-properties-mode");
if (StringUtils.hasLength(systemPropertiesModeName)) {
builder.addPropertyValue("systemPropertiesModeName", "SYSTEM_PROPERTIES_MODE_"+systemPropertiesModeName);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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.
@@ -34,10 +34,11 @@ import org.springframework.util.StringValueResolver;
/**
* {@link org.springframework.beans.factory.config.BeanPostProcessor}
* implementation that passes the ApplicationContext to beans that
* implement the {@link ResourceLoaderAware}, {@link MessageSourceAware},
* {@link ApplicationEventPublisherAware} and/or
* implement the {@link EmbeddedValueResolverAware}, {@link ResourceLoaderAware},
* {@link MessageSourceAware}, {@link ApplicationEventPublisherAware} and/or
* {@link ApplicationContextAware} interfaces.
* If all of them are implemented, they are satisfied in the given order.
*
* <p>Implemented interfaces are satisfied in order of their mention above.
*
* <p>Application contexts will automatically register this with their
* underlying bean factory. Applications do not use this directly.
@@ -45,6 +46,7 @@ import org.springframework.util.StringValueResolver;
* @author Juergen Hoeller
* @author Costin Leau
* @since 10.10.2003
* @see org.springframework.context.EmbeddedValueResolverAware
* @see org.springframework.context.ResourceLoaderAware
* @see org.springframework.context.MessageSourceAware
* @see org.springframework.context.ApplicationEventPublisherAware
@@ -68,7 +70,8 @@ class ApplicationContextAwareProcessor implements BeanPostProcessor {
AccessControlContext acc = null;
if (System.getSecurityManager() != null &&
(bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
(bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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.
@@ -40,13 +40,14 @@ import org.springframework.instrument.classloading.weblogic.WebLogicLoadTimeWeav
* "<code>loadTimeWeaver</code>"; the most convenient way to achieve this is
* Spring's <code>&lt;context:load-time-weaver&gt;</code> XML tag.
*
* <p>This class implements a runtime environment check for obtaining the
* appropriate weaver implementation: As of Spring 2.5, it detects Sun's
* GlassFish, Oracle's OC4J, BEA's WebLogic 10,
* <p>This class implements a runtime environment check for obtaining
* the appropriate weaver implementation: As of Spring 3.0, it detects
* Oracle WebLogic 10, Oracle OC4J 10, GlassFish 3, JBoss AS 5 and 6,
* {@link InstrumentationSavingAgent Spring's VM agent} and any
* {@link ClassLoader} supported by Spring's {@link ReflectiveLoadTimeWeaver}
* (for example the
* {@link org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader}).
* {@link org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader}
* for Tomcat 5, 6 and 7).
*
* @author Juergen Hoeller
* @author Ramnivas Laddad
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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.
@@ -36,6 +36,7 @@ import org.springframework.format.Formatter;
import org.springframework.format.FormatterRegistry;
import org.springframework.format.Parser;
import org.springframework.format.Printer;
import org.springframework.util.StringUtils;
import org.springframework.util.StringValueResolver;
/**
@@ -63,6 +64,15 @@ public class FormattingConversionService extends GenericConversionService
}
public void addFormatter(Formatter<?> formatter) {
Class<?> fieldType = GenericTypeResolver.resolveTypeArgument(formatter.getClass(), Formatter.class);
if (fieldType == null) {
throw new IllegalArgumentException("Unable to extract parameterized field type argument from Formatter [" +
formatter.getClass().getName() + "]; does the formatter parameterize the <T> generic type?");
}
addFormatterForFieldType(fieldType, formatter);
}
public void addFormatterForFieldType(Class<?> fieldType, Formatter<?> formatter) {
addConverter(new PrinterConverter(fieldType, formatter, this));
addConverter(new ParserConverter(fieldType, formatter, this));
@@ -95,7 +105,7 @@ 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);
FieldFormatterKey key = new FieldFormatterKey(sourceType.getAnnotation(annotationType), sourceType.getType());
GenericConverter converter = cachedPrinters.get(key);
if (converter == null) {
Printer<?> printer = annotationFormatterFactory.getPrinter(key.getAnnotation(), key.getFieldType());
@@ -117,7 +127,7 @@ 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);
FieldFormatterKey key = new FieldFormatterKey(targetType.getAnnotation(annotationType), sourceType.getType());
GenericConverter converter = cachedParsers.get(key);
if (converter == null) {
Parser<?> printer = annotationFormatterFactory.getParser(key.getAnnotation(), key.getFieldType());
@@ -228,7 +238,7 @@ public class FormattingConversionService extends GenericConversionService
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
String text = (String) source;
if (text == null || text.length() == 0) {
if (!StringUtils.hasText(text)) {
return null;
}
Object result;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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.
@@ -27,6 +27,7 @@ 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.Formatter;
import org.springframework.format.FormatterRegistry;
import org.springframework.format.Parser;
import org.springframework.format.Printer;
@@ -55,35 +56,77 @@ public class FormattingConversionServiceFactoryBean
private Set<?> converters;
private Set<?> formatters;
private StringValueResolver embeddedValueResolver;
private FormattingConversionService conversionService;
/**
* Configure the set of custom converter objects that should be added:
* implementing {@link org.springframework.core.convert.converter.Converter},
* Configure the set of custom converter objects that should be added.
* @param converters instances of any of the following:
* {@link org.springframework.core.convert.converter.Converter},
* {@link org.springframework.core.convert.converter.ConverterFactory},
* or {@link org.springframework.core.convert.converter.GenericConverter}.
* {@link org.springframework.core.convert.converter.GenericConverter}
*/
public void setConverters(Set<?> converters) {
this.converters = converters;
}
/**
* Configure the set of custom formatter objects that should be added.
* @param formatters instances of {@link Formatter} or {@link AnnotationFormatterFactory}
*/
public void setFormatters(Set<?> formatters) {
this.formatters = formatters;
}
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);
registerFormatters();
}
private void registerFormatters() {
if (this.formatters != null) {
for (Object formatter : this.formatters) {
if (formatter instanceof Formatter<?>) {
this.conversionService.addFormatter((Formatter<?>) formatter);
}
else if (formatter instanceof AnnotationFormatterFactory<?>) {
this.conversionService.addFormatterForFieldAnnotation((AnnotationFormatterFactory<?>) formatter);
}
else {
throw new IllegalArgumentException(
"Custom formatters must be implementations of Formatter or AnnotationFormatterFactory");
}
}
}
installFormatters(this.conversionService);
}
/**
* Install Formatters and Converters into the new FormattingConversionService using the FormatterRegistry SPI.
* Subclasses may override to customize the set of formatters and/or converters that are installed.
*/
protected void installFormatters(FormatterRegistry registry) {
registry.addFormatterForFieldAnnotation(new NumberFormatAnnotationFormatterFactory());
if (jodaTimePresent) {
new JodaTimeFormattingConfigurer().installJodaTimeFormatting(registry);
}
else {
registry.addFormatterForFieldAnnotation(new NoJodaDateTimeFormatAnnotationFormatterFactory());
}
}
// implementing FactoryBean
public FormattingConversionService getObject() {
return this.conversionService;
@@ -98,23 +141,6 @@ public class FormattingConversionServiceFactoryBean
}
// subclassing hooks
/**
* Install Formatters and Converters into the new FormattingConversionService using the FormatterRegistry SPI.
* Subclasses may override to customize the set of formatters and/or converters that are installed.
*/
protected void installFormatters(FormatterRegistry registry) {
registry.addFormatterForFieldAnnotation(new NumberFormatAnnotationFormatterFactory());
if (jodaTimePresent) {
new JodaTimeFormattingConfigurer().installJodaTimeFormatting(registry);
}
else {
registry.addFormatterForFieldAnnotation(new NoJodaDateTimeFormatAnnotationFormatterFactory());
}
}
/**
* Dummy AnnotationFormatterFactory that simply fails if @DateTimeFormat is being used
* without the JodaTime library being present.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2011 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,10 +25,14 @@ import org.springframework.util.ClassUtils;
/**
* {@link LoadTimeWeaver} implementation for JBoss's instrumentable ClassLoader.
* Supports JBoss AS 5 and 6.
*
* <p><b>NOTE:</b> Requires JBoss AS version 5.0.0 or higher.
*
* <p>Thanks to Ales Justin and Marius Bogoevici for the initial prototype.</p>
* <p><b>NOTE:</b> On JBoss 6.0, to avoid the container loading the classes before the
* application actually starts, one needs to add a <tt>WEB-INF/jboss-scanning.xml</tt>
* file to the application archive - with the following content:
* <pre>&lt;scanning xmlns="urn:jboss:scanning:1.0"/&gt;</pre>
*
* <p>Thanks to Ales Justin and Marius Bogoevici for the initial prototype.
*
* @author Costin Leau
* @since 3.0
@@ -70,4 +74,5 @@ public class JBossLoadTimeWeaver implements LoadTimeWeaver {
public ClassLoader getThrowawayClassLoader() {
return new SimpleThrowawayClassLoader(getInstrumentableClassLoader());
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2011 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.
@@ -27,6 +27,7 @@ import javax.management.ObjectName;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import javax.management.remote.MBeanServerForwarder;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
@@ -63,6 +64,8 @@ public class ConnectorServerFactoryBean extends MBeanRegistrationSupport
private Map<String, Object> environment = new HashMap<String, Object>();
private MBeanServerForwarder forwarder;
private ObjectName objectName;
private boolean threaded = false;
@@ -97,6 +100,13 @@ public class ConnectorServerFactoryBean extends MBeanRegistrationSupport
}
}
/**
* Set an MBeanServerForwarder to be applied to the <code>JMXConnectorServer</code>.
*/
public void setForwarder(MBeanServerForwarder forwarder) {
this.forwarder = forwarder;
}
/**
* Set the <code>ObjectName</code> used to register the <code>JMXConnectorServer</code>
* itself with the <code>MBeanServer</code>, as <code>ObjectName</code> instance
@@ -143,6 +153,11 @@ public class ConnectorServerFactoryBean extends MBeanRegistrationSupport
// Create the connector server now.
this.connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, this.environment, this.server);
// Set the given MBeanServerForwarder, if any.
if (this.forwarder != null) {
this.connectorServer.setMBeanServerForwarder(this.forwarder);
}
// Do we want to register the connector with the MBean server?
if (this.objectName != null) {
doRegister(this.connectorServer, this.objectName);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2011 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.
@@ -57,7 +57,7 @@ public class CodebaseAwareObjectInputStream extends ConfigurableObjectInputStrea
/**
* Create a new CodebaseAwareObjectInputStream for the given InputStream and codebase.
* @param in the InputStream to read from
* @param in the InputStream to read from
* @param codebaseUrl the codebase URL to load classes from if not found locally
* (can consist of multiple URLs, separated by spaces)
* @see java.io.ObjectInputStream#ObjectInputStream(java.io.InputStream)
@@ -68,7 +68,7 @@ public class CodebaseAwareObjectInputStream extends ConfigurableObjectInputStrea
/**
* Create a new CodebaseAwareObjectInputStream for the given InputStream and codebase.
* @param in the InputStream to read from
* @param in the InputStream to read from
* @param classLoader the ClassLoader to use for loading local classes
* (may be <code>null</code> to indicate RMI's default ClassLoader)
* @param codebaseUrl the codebase URL to load classes from if not found locally
@@ -82,6 +82,22 @@ public class CodebaseAwareObjectInputStream extends ConfigurableObjectInputStrea
this.codebaseUrl = codebaseUrl;
}
/**
* Create a new CodebaseAwareObjectInputStream for the given InputStream and codebase.
* @param in the InputStream to read from
* @param classLoader the ClassLoader to use for loading local classes
* (may be <code>null</code> to indicate RMI's default ClassLoader)
* @param acceptProxyClasses whether to accept deserialization of proxy classes
* (may be deactivated as a security measure)
* @see java.io.ObjectInputStream#ObjectInputStream(java.io.InputStream)
*/
public CodebaseAwareObjectInputStream(
InputStream in, ClassLoader classLoader, boolean acceptProxyClasses) throws IOException {
super(in, classLoader, acceptProxyClasses);
this.codebaseUrl = null;
}
@Override
protected Class resolveFallbackIfPossible(String className, ClassNotFoundException ex)
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2011 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.
@@ -57,6 +57,8 @@ public abstract class RemoteInvocationSerializingExporter extends RemoteInvocati
private String contentType = CONTENT_TYPE_SERIALIZED_OBJECT;
private boolean acceptProxyClasses = true;
private Object proxy;
@@ -70,12 +72,27 @@ public abstract class RemoteInvocationSerializingExporter extends RemoteInvocati
}
/**
* Return the content type to use for sending remote invocation responses.
* Return the content type to use for sending remote invocation responses.
*/
public String getContentType() {
return this.contentType;
}
/**
* Set whether to accept deserialization of proxy classes.
* <p>Default is "true". May be deactivated as a security measure.
*/
public void setAcceptProxyClasses(boolean acceptProxyClasses) {
this.acceptProxyClasses = acceptProxyClasses;
}
/**
* Return whether to accept deserialization of proxy classes.
*/
public boolean isAcceptProxyClasses() {
return this.acceptProxyClasses;
}
public void afterPropertiesSet() {
prepare();
@@ -102,7 +119,7 @@ public abstract class RemoteInvocationSerializingExporter extends RemoteInvocati
* @throws java.io.IOException if creation of the ObjectInputStream failed
*/
protected ObjectInputStream createObjectInputStream(InputStream is) throws IOException {
return new CodebaseAwareObjectInputStream(is, getBeanClassLoader(), null);
return new CodebaseAwareObjectInputStream(is, getBeanClassLoader(), isAcceptProxyClasses());
}
/**
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2011 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,6 +18,7 @@ package org.springframework.remoting.rmi;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.SocketException;
import java.rmi.ConnectException;
import java.rmi.ConnectIOException;
import java.rmi.NoSuchObjectException;
@@ -211,8 +212,8 @@ public abstract class RmiClientInterceptorUtils {
public static boolean isConnectFailure(RemoteException ex) {
return (ex instanceof ConnectException || ex instanceof ConnectIOException ||
ex instanceof UnknownHostException || ex instanceof NoSuchObjectException ||
ex instanceof StubNotFoundException || isCorbaConnectFailure(ex.getCause()) ||
ORACLE_CONNECTION_EXCEPTION.equals(ex.getClass().getName()));
ex instanceof StubNotFoundException || ex.getCause() instanceof SocketException ||
isCorbaConnectFailure(ex.getCause()) || ORACLE_CONNECTION_EXCEPTION.equals(ex.getClass().getName()));
}
/**
@@ -7,5 +7,5 @@
-->
<rmi name="org.springframework.remoting.rmi.RmiInvocationWrapper">
<cluster clusterable="true"/>
<method name="*" idempotent="true"/>
<method name="getTargetInterfaceName" idempotent="true"/>
</rmi>
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2011 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.
@@ -166,6 +166,7 @@ public abstract class RemoteExporter extends RemotingSupport {
}
}
proxyFactory.setTarget(getService());
proxyFactory.setOpaque(true);
return proxyFactory.getProxy(getBeanClassLoader());
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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,8 +19,8 @@ package org.springframework.validation;
import java.beans.PropertyEditor;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -28,6 +28,7 @@ import java.util.Set;
import org.springframework.beans.PropertyEditorRegistry;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
/**
@@ -130,7 +131,7 @@ public abstract class AbstractBindingResult extends AbstractErrors implements Bi
}
public String[] resolveMessageCodes(String errorCode, String field) {
Class fieldType = getFieldType(field);
Class<?> fieldType = getFieldType(field);
return getMessageCodesResolver().resolveMessageCodes(
errorCode, getObjectName(), fixedField(field), fieldType);
}
@@ -236,7 +237,7 @@ public abstract class AbstractBindingResult extends AbstractErrors implements Bi
* @see #getActualFieldValue
*/
@Override
public Class getFieldType(String field) {
public Class<?> getFieldType(String field) {
Object value = getActualFieldValue(fixedField(field));
if (value != null) {
return value.getClass();
@@ -268,11 +269,11 @@ public abstract class AbstractBindingResult extends AbstractErrors implements Bi
* @see org.springframework.web.servlet.mvc.SimpleFormController
*/
public Map<String, Object> getModel() {
Map<String, Object> model = new HashMap<String, Object>(2);
// Errors instance, even if no errors.
model.put(MODEL_KEY_PREFIX + getObjectName(), this);
Map<String, Object> model = new LinkedHashMap<String, Object>(2);
// Mapping from name to target object.
model.put(getObjectName(), getTarget());
// Errors instance, even if no errors.
model.put(MODEL_KEY_PREFIX + getObjectName(), this);
return model;
}
@@ -285,10 +286,10 @@ public abstract class AbstractBindingResult extends AbstractErrors implements Bi
* {@link #getPropertyEditorRegistry() PropertyEditorRegistry}'s
* editor lookup facility, if available.
*/
public PropertyEditor findEditor(String field, Class valueType) {
public PropertyEditor findEditor(String field, Class<?> valueType) {
PropertyEditorRegistry editorRegistry = getPropertyEditorRegistry();
if (editorRegistry != null) {
Class valueTypeToUse = valueType;
Class<?> valueTypeToUse = valueType;
if (valueTypeToUse == null) {
valueTypeToUse = getFieldType(field);
}
@@ -337,13 +338,13 @@ public abstract class AbstractBindingResult extends AbstractErrors implements Bi
}
BindingResult otherResult = (BindingResult) other;
return (getObjectName().equals(otherResult.getObjectName()) &&
getTarget().equals(otherResult.getTarget()) &&
ObjectUtils.nullSafeEquals(getTarget(), otherResult.getTarget()) &&
getAllErrors().equals(otherResult.getAllErrors()));
}
@Override
public int hashCode() {
return getObjectName().hashCode() * 29 + getTarget().hashCode();
return getObjectName().hashCode();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2011 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,6 +46,8 @@ public class BeanPropertyBindingResult extends AbstractPropertyBindingResult imp
private final boolean autoGrowNestedPaths;
private final int autoGrowCollectionLimit;
private transient BeanWrapper beanWrapper;
@@ -55,7 +57,7 @@ public class BeanPropertyBindingResult extends AbstractPropertyBindingResult imp
* @param objectName the name of the target object
*/
public BeanPropertyBindingResult(Object target, String objectName) {
this(target, objectName, true);
this(target, objectName, true, Integer.MAX_VALUE);
}
/**
@@ -63,11 +65,13 @@ public class BeanPropertyBindingResult extends AbstractPropertyBindingResult imp
* @param target the target bean to bind onto
* @param objectName the name of the target object
* @param autoGrowNestedPaths whether to "auto-grow" a nested path that contains a null value
* @param autoGrowCollectionLimit the limit for array and collection auto-growing
*/
public BeanPropertyBindingResult(Object target, String objectName, boolean autoGrowNestedPaths) {
public BeanPropertyBindingResult(Object target, String objectName, boolean autoGrowNestedPaths, int autoGrowCollectionLimit) {
super(objectName);
this.target = target;
this.autoGrowNestedPaths = autoGrowNestedPaths;
this.autoGrowCollectionLimit = autoGrowCollectionLimit;
}
@@ -87,6 +91,7 @@ public class BeanPropertyBindingResult extends AbstractPropertyBindingResult imp
this.beanWrapper = createBeanWrapper();
this.beanWrapper.setExtractOldValueForEditor(true);
this.beanWrapper.setAutoGrowNestedPaths(this.autoGrowNestedPaths);
this.beanWrapper.setAutoGrowCollectionLimit(this.autoGrowCollectionLimit);
}
return this.beanWrapper;
}
@@ -94,7 +94,7 @@ public interface BindingResult extends Errors {
* is given but should be specified in any case for consistency checking)
* @return the registered editor, or <code>null</code> if none
*/
PropertyEditor findEditor(String field, Class valueType);
PropertyEditor findEditor(String field, Class<?> valueType);
/**
* Return the underlying PropertyEditorRegistry.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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.
@@ -105,6 +105,9 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
/** Default object name used for binding: "target" */
public static final String DEFAULT_OBJECT_NAME = "target";
/** Default limit for array and collection growing: 256 */
public static final int DEFAULT_AUTO_GROW_COLLECTION_LIMIT = 256;
/**
* We'll create a lot of DataBinder instances: Let's use a static logger.
@@ -127,6 +130,8 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
private boolean autoGrowNestedPaths = true;
private int autoGrowCollectionLimit = DEFAULT_AUTO_GROW_COLLECTION_LIMIT;
private String[] allowedFields;
private String[] disallowedFields;
@@ -199,6 +204,22 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
return this.autoGrowNestedPaths;
}
/**
* Specify the limit for array and collection auto-growing.
* <p>Default is 256, preventing OutOfMemoryErrors in case of large indexes.
* Raise this limit if your auto-growing needs are unusually high.
*/
public void setAutoGrowCollectionLimit(int autoGrowCollectionLimit) {
this.autoGrowCollectionLimit = autoGrowCollectionLimit;
}
/**
* Return the current limit for array and collection auto-growing.
*/
public int getAutoGrowCollectionLimit() {
return this.autoGrowCollectionLimit;
}
/**
* Initialize standard JavaBean property access for this DataBinder.
* <p>This is the default; an explicit call just leads to eager initialization.
@@ -207,7 +228,8 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
public void initBeanPropertyAccess() {
Assert.state(this.bindingResult == null,
"DataBinder is already initialized - call initBeanPropertyAccess before other configuration methods");
this.bindingResult = new BeanPropertyBindingResult(getTarget(), getObjectName(), isAutoGrowNestedPaths());
this.bindingResult = new BeanPropertyBindingResult(
getTarget(), getObjectName(), isAutoGrowNestedPaths(), getAutoGrowCollectionLimit());
if (this.conversionService != null) {
this.bindingResult.initConversion(this.conversionService);
}
@@ -509,17 +531,14 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
return this.conversionService;
}
@SuppressWarnings("unchecked")
public void registerCustomEditor(Class requiredType, PropertyEditor propertyEditor) {
getPropertyEditorRegistry().registerCustomEditor(requiredType, propertyEditor);
}
@SuppressWarnings("unchecked")
public void registerCustomEditor(Class requiredType, String field, PropertyEditor propertyEditor) {
getPropertyEditorRegistry().registerCustomEditor(requiredType, field, propertyEditor);
}
@SuppressWarnings("unchecked")
public PropertyEditor findCustomEditor(Class requiredType, String propertyPath) {
return getPropertyEditorRegistry().findCustomEditor(requiredType, propertyPath);
}
@@ -700,8 +719,7 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
* @throws BindException if there were any errors in the bind operation
* @see BindingResult#getModel()
*/
@SuppressWarnings("unchecked")
public Map close() throws BindException {
public Map<?, ?> close() throws BindException {
if (getBindingResult().hasErrors()) {
throw new BindException(getBindingResult());
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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,6 +19,7 @@ package org.springframework.beans;
import java.io.InputStream;
import java.util.Map;
import org.springframework.core.io.ContextResource;
import org.springframework.core.io.Resource;
/**
@@ -29,6 +30,8 @@ public class ResourceTestBean {
private Resource resource;
private ContextResource contextResource;
private InputStream inputStream;
private Resource[] resourceArray;
@@ -47,22 +50,30 @@ public class ResourceTestBean {
}
public void setResource(Resource resource) {
this.resource = resource;
}
public void setInputStream(InputStream inputStream) {
this.inputStream = inputStream;
}
public Resource getResource() {
return resource;
}
public void setResource(Resource resource) {
this.resource = resource;
}
public ContextResource getContextResource() {
return contextResource;
}
public void setContextResource(ContextResource contextResource) {
this.contextResource = contextResource;
}
public InputStream getInputStream() {
return inputStream;
}
public void setInputStream(InputStream inputStream) {
this.inputStream = inputStream;
}
public Resource[] getResourceArray() {
return resourceArray;
}
@@ -65,7 +65,7 @@ public class AnnotationProcessorPerformanceTests {
}
sw.stop();
//System.out.println(sw.getTotalTimeMillis());
assertTrue("Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 4000);
assertTrue("Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 5000);
}
@Test
@@ -92,7 +92,7 @@ public class AnnotationProcessorPerformanceTests {
}
sw.stop();
//System.out.println(sw.getTotalTimeMillis());
assertTrue("Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 4000);
assertTrue("Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 5000);
}
@Test
@@ -118,7 +118,7 @@ public class AnnotationProcessorPerformanceTests {
}
sw.stop();
//System.out.println(sw.getTotalTimeMillis());
assertTrue("Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 4000);
assertTrue("Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 5000);
}
@Test
@@ -145,7 +145,7 @@ public class AnnotationProcessorPerformanceTests {
}
sw.stop();
//System.out.println(sw.getTotalTimeMillis());
assertTrue("Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 4000);
assertTrue("Prototype creation took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 5000);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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 javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.ejb.EJB;
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.beans.BeansException;
@@ -43,6 +42,8 @@ import org.springframework.jndi.support.SimpleJndiBeanFactory;
import org.springframework.mock.jndi.ExpectedLookupTemplate;
import org.springframework.util.SerializationTestUtils;
import static org.junit.Assert.*;
/**
* @author Juergen Hoeller
* @author Chris Beams
@@ -229,6 +230,7 @@ public class CommonAnnotationBeanPostProcessorTests {
bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(ExtendedResourceInjectionBean.class));
bf.registerBeanDefinition("annotatedBean2", new RootBeanDefinition(NamedResourceInjectionBean.class));
bf.registerBeanDefinition("annotatedBean3", new RootBeanDefinition(ConvertedResourceInjectionBean.class));
TestBean tb = new TestBean();
bf.registerSingleton("testBean", tb);
TestBean tb2 = new TestBean();
@@ -238,6 +240,7 @@ public class CommonAnnotationBeanPostProcessorTests {
TestBean tb4 = new TestBean();
bf.registerSingleton("testBean4", tb4);
NestedTestBean tb6 = new NestedTestBean();
bf.registerSingleton("value", "5");
bf.registerSingleton("xy", tb6);
bf.registerAlias("xy", "testBean9");
@@ -255,6 +258,9 @@ public class CommonAnnotationBeanPostProcessorTests {
NamedResourceInjectionBean bean2 = (NamedResourceInjectionBean) bf.getBean("annotatedBean2");
assertSame(tb6, bean2.testBean);
ConvertedResourceInjectionBean bean3 = (ConvertedResourceInjectionBean) bf.getBean("annotatedBean3");
assertSame(5, bean3.value);
bf.destroySingletons();
assertTrue(bean.destroyCalled);
assertTrue(bean.destroy2Called);
@@ -591,6 +597,13 @@ public class CommonAnnotationBeanPostProcessorTests {
}
private static class ConvertedResourceInjectionBean {
@Resource(name="value")
private int value;
}
private static class NullFactory {
public static Object create() {
@@ -7,6 +7,9 @@
<property name="resource">
<value>test.properties</value>
</property>
<property name="contextResource">
<value>testBeans.properties</value>
</property>
<property name="inputStream">
<value>classpath:org/springframework/beans/factory/xml/test.properties</value>
</property>
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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,9 +18,9 @@ package org.springframework.context.support;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.beans.ResourceTestBean;
@@ -33,6 +33,8 @@ import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import static org.junit.Assert.*;
/**
* @author Keith Donald
* @author Juergen Hoeller
@@ -123,4 +125,14 @@ public class ConversionServiceFactoryBeanTests {
public static class Baz {
}
public static class ComplexConstructorArgument {
public ComplexConstructorArgument(Map<String, Class> map) {
assertTrue(!map.isEmpty());
assertTrue(map.keySet().iterator().next() instanceof String);
assertTrue(map.values().iterator().next() instanceof Class);
}
}
}
@@ -20,4 +20,12 @@
</property>
</bean>
<bean class="org.springframework.context.support.ConversionServiceFactoryBeanTests$ComplexConstructorArgument">
<constructor-arg>
<map>
<entry key="mykey" value="java.util.Date"/>
</map>
</constructor-arg>
</bean>
</beans>
@@ -24,4 +24,12 @@
</property>
</bean>
<bean class="org.springframework.context.support.ConversionServiceFactoryBeanTests$ComplexConstructorArgument">
<constructor-arg>
<map>
<entry key="mykey" value="java.util.Date"/>
</map>
</constructor-arg>
</bean>
</beans>
@@ -0,0 +1,161 @@
/*
* Copyright 2002-2011 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.format.support;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.text.ParseException;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import org.junit.Test;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.format.AnnotationFormatterFactory;
import org.springframework.format.Formatter;
import org.springframework.format.Parser;
import org.springframework.format.Printer;
import org.springframework.format.annotation.NumberFormat;
import org.springframework.format.annotation.NumberFormat.Style;
import static org.junit.Assert.*;
/**
* @author Rossen Stoyanchev
*/
public class FormattingConversionServiceFactoryBeanTests {
@Test
public void testDefaultFormatters() throws Exception {
FormattingConversionServiceFactoryBean factory = new FormattingConversionServiceFactoryBean();
factory.afterPropertiesSet();
FormattingConversionService fcs = factory.getObject();
TypeDescriptor descriptor = new TypeDescriptor(TestBean.class.getDeclaredField("percent"));
Object value = fcs.convert("5%", TypeDescriptor.valueOf(String.class), descriptor);
assertEquals(.05, value);
value = fcs.convert(.05, descriptor, TypeDescriptor.valueOf(String.class));
assertEquals("5%", value);
}
@Test
public void testCustomFormatter() throws Exception {
FormattingConversionServiceFactoryBean factory = new FormattingConversionServiceFactoryBean();
Set<Object> formatters = new HashSet<Object>();
formatters.add(new TestBeanFormatter());
formatters.add(new SpecialIntAnnotationFormatterFactory());
factory.setFormatters(formatters);
factory.afterPropertiesSet();
FormattingConversionService fcs = factory.getObject();
TestBean testBean = fcs.convert("5", TestBean.class);
assertEquals(5, testBean.getSpecialInt());
assertEquals("5", fcs.convert(testBean, String.class));
TypeDescriptor descriptor = new TypeDescriptor(TestBean.class.getDeclaredField("specialInt"));
Object value = fcs.convert(":5", TypeDescriptor.valueOf(String.class), descriptor);
assertEquals(5, value);
value = fcs.convert(5, descriptor, TypeDescriptor.valueOf(String.class));
assertEquals(":5", value);
}
@Test
public void testInvalidFormatter() throws Exception {
FormattingConversionServiceFactoryBean factory = new FormattingConversionServiceFactoryBean();
Set<Object> formatters = new HashSet<Object>();
formatters.add(new Object());
factory.setFormatters(formatters);
try {
factory.afterPropertiesSet();
fail("Expected formatter to be rejected");
}
catch (IllegalArgumentException ex) {
// expected
}
}
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
private @interface SpecialInt {
}
private static class TestBean {
@SuppressWarnings("unused")
@NumberFormat(style = Style.PERCENT)
private double percent;
@SpecialInt
private int specialInt;
public int getSpecialInt() {
return specialInt;
}
public void setSpecialInt(int field) {
this.specialInt = field;
}
}
private static class TestBeanFormatter implements Formatter<TestBean> {
public String print(TestBean object, Locale locale) {
return String.valueOf(object.getSpecialInt());
}
public TestBean parse(String text, Locale locale) throws ParseException {
TestBean object = new TestBean();
object.setSpecialInt(Integer.parseInt(text));
return object;
}
}
private static class SpecialIntAnnotationFormatterFactory implements AnnotationFormatterFactory<SpecialInt> {
private final Set<Class<?>> fieldTypes = new HashSet<Class<?>>(1);
public SpecialIntAnnotationFormatterFactory() {
fieldTypes.add(Integer.class);
}
public Set<Class<?>> getFieldTypes() {
return fieldTypes;
}
public Printer<?> getPrinter(SpecialInt annotation, Class<?> fieldType) {
return new Printer<Integer>() {
public String print(Integer object, Locale locale) {
return ":" + object.toString();
}
};
}
public Parser<?> getParser(SpecialInt annotation, Class<?> fieldType) {
return new Parser<Integer>() {
public Integer parse(String text, Locale locale) throws ParseException {
return Integer.parseInt(text.substring(1));
}
};
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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.
@@ -27,12 +27,11 @@ import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.junit.After;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.ConfigurablePropertyAccessor;
import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.beans.factory.support.RootBeanDefinition;
@@ -41,11 +40,14 @@ import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.ConversionServiceFactory;
import org.springframework.format.Printer;
import org.springframework.format.datetime.joda.DateTimeParser;
import org.springframework.format.datetime.joda.JodaDateTimeFormatAnnotationFormatterFactory;
import org.springframework.format.datetime.joda.ReadablePartialPrinter;
import org.springframework.format.number.NumberFormatter;
import static org.junit.Assert.*;
/**
* @author Keith Donald
* @author Juergen Hoeller
@@ -93,7 +95,13 @@ public class FormattingConversionServiceTests {
@Test
public void testFormatFieldForAnnotation() throws Exception {
formattingService.addFormatterForFieldAnnotation(new JodaDateTimeFormatAnnotationFormatterFactory());
doTestFormatFieldForAnnotation(Model.class);
doTestFormatFieldForAnnotation(Model.class, false);
}
@Test
public void testFormatFieldForAnnotationWithDirectFieldAccess() throws Exception {
formattingService.addFormatterForFieldAnnotation(new JodaDateTimeFormatAnnotationFormatterFactory());
doTestFormatFieldForAnnotation(Model.class, true);
}
@Test
@@ -108,7 +116,7 @@ public class FormattingConversionServiceTests {
context.refresh();
context.getBeanFactory().initializeBean(formattingService, "formattingService");
formattingService.addFormatterForFieldAnnotation(new JodaDateTimeFormatAnnotationFormatterFactory());
doTestFormatFieldForAnnotation(ModelWithPlaceholders.class);
doTestFormatFieldForAnnotation(ModelWithPlaceholders.class, false);
}
@Test
@@ -123,10 +131,10 @@ public class FormattingConversionServiceTests {
context.getBeanFactory().registerSingleton("ppc", ppc);
context.refresh();
formattingService = context.getBean("formattingService", FormattingConversionService.class);
doTestFormatFieldForAnnotation(ModelWithPlaceholders.class);
doTestFormatFieldForAnnotation(ModelWithPlaceholders.class, false);
}
private void doTestFormatFieldForAnnotation(Class<?> modelClass) throws Exception {
private void doTestFormatFieldForAnnotation(Class<?> modelClass, boolean directFieldAccess) throws Exception {
formattingService.addConverter(new Converter<Date, Long>() {
public Long convert(Date source) {
return source.getTime();
@@ -159,26 +167,30 @@ public class FormattingConversionServiceTests {
assertEquals(new LocalDate(2009, 11, 2), new LocalDate(dates.get(2)));
Object model = BeanUtils.instantiate(modelClass);
BeanWrapper accessor = PropertyAccessorFactory.forBeanPropertyAccess(model);
ConfigurablePropertyAccessor accessor = directFieldAccess ? PropertyAccessorFactory.forDirectFieldAccess(model) :
PropertyAccessorFactory.forBeanPropertyAccess(model);
accessor.setConversionService(formattingService);
accessor.setPropertyValue("dates", "10-31-09,11-1-09,11-2-09");
dates = (List<Date>) accessor.getPropertyValue("dates");
assertEquals(new LocalDate(2009, 10, 31), new LocalDate(dates.get(0)));
assertEquals(new LocalDate(2009, 11, 1), new LocalDate(dates.get(1)));
assertEquals(new LocalDate(2009, 11, 2), new LocalDate(dates.get(2)));
accessor.setPropertyValue("dates[0]", "10-30-09");
accessor.setPropertyValue("dates[1]", "10-1-09");
accessor.setPropertyValue("dates[2]", "10-2-09");
dates = (List<Date>) accessor.getPropertyValue("dates");
assertEquals(new LocalDate(2009, 10, 30), new LocalDate(dates.get(0)));
assertEquals(new LocalDate(2009, 10, 1), new LocalDate(dates.get(1)));
assertEquals(new LocalDate(2009, 10, 2), new LocalDate(dates.get(2)));
if (!directFieldAccess) {
accessor.setPropertyValue("dates[0]", "10-30-09");
accessor.setPropertyValue("dates[1]", "10-1-09");
accessor.setPropertyValue("dates[2]", "10-2-09");
dates = (List<Date>) accessor.getPropertyValue("dates");
assertEquals(new LocalDate(2009, 10, 30), new LocalDate(dates.get(0)));
assertEquals(new LocalDate(2009, 10, 1), new LocalDate(dates.get(1)));
assertEquals(new LocalDate(2009, 10, 2), new LocalDate(dates.get(2)));
}
}
@Test
public void testPrintNull() throws ParseException {
formattingService.addFormatterForFieldType(Number.class, new NumberFormatter());
assertEquals("", formattingService.convert(null, TypeDescriptor.valueOf(Integer.class), TypeDescriptor.valueOf(String.class)));
assertEquals("", formattingService
.convert(null, TypeDescriptor.valueOf(Integer.class), TypeDescriptor.valueOf(String.class)));
}
@Test
@@ -190,7 +202,8 @@ public class FormattingConversionServiceTests {
@Test
public void testParseEmptyString() throws ParseException {
formattingService.addFormatterForFieldType(Number.class, new NumberFormatter());
assertNull(formattingService.convert("", TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class)));
assertNull(formattingService
.convert("", TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class)));
}
@Test
@@ -208,14 +221,35 @@ public class FormattingConversionServiceTests {
assertNull(formattingService.convert("", TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class)));
}
@Test
public void testFormatFieldForAnnotationWithSubclassAsFieldType() throws Exception {
formattingService.addFormatterForFieldAnnotation(new JodaDateTimeFormatAnnotationFormatterFactory() {
public Printer<?> getPrinter(org.springframework.format.annotation.DateTimeFormat annotation, Class<?> fieldType) {
assertEquals(MyDate.class, fieldType);
return super.getPrinter(annotation, fieldType);
}
});
formattingService.addConverter(new Converter<MyDate, Long>() {
public Long convert(MyDate source) {
return source.getTime();
}
});
formattingService.addConverter(new Converter<MyDate, Date>() {
public Date convert(MyDate source) {
return source;
}
});
formattingService.convert(new MyDate(), new TypeDescriptor(ModelWithSubclassField.class.getField("date")),
TypeDescriptor.valueOf(String.class));
}
public static class Model {
@SuppressWarnings("unused")
@org.springframework.format.annotation.DateTimeFormat(style="S-")
public Date date;
@SuppressWarnings("unused")
@org.springframework.format.annotation.DateTimeFormat(pattern="M-d-yy")
public List<Date> dates;
@@ -231,11 +265,9 @@ public class FormattingConversionServiceTests {
public static class ModelWithPlaceholders {
@SuppressWarnings("unused")
@org.springframework.format.annotation.DateTimeFormat(style="${dateStyle}")
public Date date;
@SuppressWarnings("unused")
@org.springframework.format.annotation.DateTimeFormat(pattern="${datePattern}")
public List<Date> dates;
@@ -248,4 +280,15 @@ public class FormattingConversionServiceTests {
}
}
public static class MyDate extends Date {
}
private static class ModelWithSubclassField {
@org.springframework.format.annotation.DateTimeFormat(style = "S-")
public MyDate date;
}
}
@@ -32,7 +32,7 @@ import org.junit.Ignore;
* @author Rob Harrop
*/
@Ignore // see https://issuetracker.springsource.com/browse/BRITS-235
public class RemoteMBeanClientInterceptorTests extends MBeanClientInterceptorTests {
public class RemoteMBeanClientInterceptorTestsIgnore extends MBeanClientInterceptorTests {
private static final String SERVICE_URL = "service:jmx:jmxmp://localhost:9876";
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2011 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.jmx.export;
import java.util.HashMap;
import java.util.Map;
import javax.management.Attribute;
import javax.management.AttributeChangeNotification;
import javax.management.MalformedObjectNameException;
@@ -27,7 +26,6 @@ import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.ObjectName;
import org.junit.Ignore;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.jmx.AbstractMBeanServerTests;
import org.springframework.jmx.JmxTestBean;
@@ -38,16 +36,17 @@ import org.springframework.jmx.support.ObjectNameManager;
/**
* @author Rob Harrop
* @author Mark Fisher
* @author Sam Brannen
*/
@Ignore // Getting CCEs regarding ObjectName being cast to String
public class NotificationListenerTests extends AbstractMBeanServerTests {
@SuppressWarnings({"rawtypes", "unchecked"})
public void testRegisterNotificationListenerForMBean() throws Exception {
ObjectName objectName = ObjectName.getInstance("spring:name=Test");
JmxTestBean bean = new JmxTestBean();
Map beans = new HashMap();
beans.put(objectName, bean);
Map<String, Object> beans = new HashMap<String, Object>();
beans.put(objectName.getCanonicalName(), bean);
CountingAttributeChangeNotificationListener listener = new CountingAttributeChangeNotificationListener();
@@ -66,12 +65,13 @@ public class NotificationListenerTests extends AbstractMBeanServerTests {
assertEquals("Listener not notified", 1, listener.getCount(attributeName));
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public void testRegisterNotificationListenerWithWildcard() throws Exception {
ObjectName objectName = ObjectName.getInstance("spring:name=Test");
JmxTestBean bean = new JmxTestBean();
Map beans = new HashMap();
beans.put(objectName, bean);
Map<String, Object> beans = new HashMap<String, Object>();
beans.put(objectName.getCanonicalName(), bean);
CountingAttributeChangeNotificationListener listener = new CountingAttributeChangeNotificationListener();
@@ -94,7 +94,7 @@ public class NotificationListenerTests extends AbstractMBeanServerTests {
String objectName = "spring:name=Test";
JmxTestBean bean = new JmxTestBean();
Map beans = new HashMap();
Map<String, Object> beans = new HashMap<String, Object>();
beans.put(objectName, bean);
CountingAttributeChangeNotificationListener listener = new CountingAttributeChangeNotificationListener();
@@ -108,12 +108,13 @@ public class NotificationListenerTests extends AbstractMBeanServerTests {
MBeanExporter exporter = new MBeanExporter();
exporter.setServer(server);
exporter.setBeans(beans);
exporter.setNotificationListeners(new NotificationListenerBean[]{listenerBean});
exporter.setNotificationListeners(new NotificationListenerBean[] { listenerBean });
exporter.afterPropertiesSet();
// update the attribute
String attributeName = "Name";
server.setAttribute(ObjectNameManager.getInstance("spring:name=Test"), new Attribute(attributeName, "Rob Harrop"));
server.setAttribute(ObjectNameManager.getInstance("spring:name=Test"), new Attribute(attributeName,
"Rob Harrop"));
assertEquals("Listener not notified", 1, listener.getCount(attributeName));
assertEquals("Handback object not transmitted correctly", handback, listener.getLastHandback(attributeName));
@@ -123,8 +124,8 @@ public class NotificationListenerTests extends AbstractMBeanServerTests {
ObjectName objectName = ObjectName.getInstance("spring:name=Test");
JmxTestBean bean = new JmxTestBean();
Map beans = new HashMap();
beans.put(objectName, bean);
Map<String, Object> beans = new HashMap<String, Object>();
beans.put(objectName.getCanonicalName(), bean);
CountingAttributeChangeNotificationListener listener = new CountingAttributeChangeNotificationListener();
@@ -134,7 +135,7 @@ public class NotificationListenerTests extends AbstractMBeanServerTests {
MBeanExporter exporter = new MBeanExporter();
exporter.setServer(server);
exporter.setBeans(beans);
exporter.setNotificationListeners(new NotificationListenerBean[]{listenerBean});
exporter.setNotificationListeners(new NotificationListenerBean[] { listenerBean });
exporter.afterPropertiesSet();
// update the attribute
@@ -144,12 +145,13 @@ public class NotificationListenerTests extends AbstractMBeanServerTests {
assertEquals("Listener not notified", 1, listener.getCount(attributeName));
}
@SuppressWarnings("serial")
public void testRegisterNotificationListenerWithFilter() throws Exception {
ObjectName objectName = ObjectName.getInstance("spring:name=Test");
JmxTestBean bean = new JmxTestBean();
Map beans = new HashMap();
beans.put(objectName, bean);
Map<String, Object> beans = new HashMap<String, Object>();
beans.put(objectName.getCanonicalName(), bean);
CountingAttributeChangeNotificationListener listener = new CountingAttributeChangeNotificationListener();
@@ -160,8 +162,7 @@ public class NotificationListenerTests extends AbstractMBeanServerTests {
if (notification instanceof AttributeChangeNotification) {
AttributeChangeNotification changeNotification = (AttributeChangeNotification) notification;
return "Name".equals(changeNotification.getAttributeName());
}
else {
} else {
return false;
}
}
@@ -170,7 +171,7 @@ public class NotificationListenerTests extends AbstractMBeanServerTests {
MBeanExporter exporter = new MBeanExporter();
exporter.setServer(server);
exporter.setBeans(beans);
exporter.setNotificationListeners(new NotificationListenerBean[]{listenerBean});
exporter.setNotificationListeners(new NotificationListenerBean[] { listenerBean });
exporter.afterPropertiesSet();
// update the attributes
@@ -188,11 +189,11 @@ public class NotificationListenerTests extends AbstractMBeanServerTests {
try {
new NotificationListenerBean().afterPropertiesSet();
fail("Must have thrown an IllegalArgumentException (no NotificationListener supplied)");
}
catch (IllegalArgumentException expected) {
} catch (IllegalArgumentException expected) {
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public void testRegisterNotificationListenerWithBeanNameAndBeanNameInBeansMap() throws Exception {
String beanName = "testBean";
ObjectName objectName = ObjectName.getInstance("spring:name=Test");
@@ -203,7 +204,7 @@ public class NotificationListenerTests extends AbstractMBeanServerTests {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
factory.registerSingleton(beanName, testBean);
Map beans = new HashMap();
Map<String, Object> beans = new HashMap<String, Object>();
beans.put(beanName, beanName);
Map listenerMappings = new HashMap();
@@ -222,6 +223,7 @@ public class NotificationListenerTests extends AbstractMBeanServerTests {
assertEquals("Listener not notified", 1, listener.getCount("Age"));
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public void testRegisterNotificationListenerWithBeanNameAndBeanInstanceInBeansMap() throws Exception {
String beanName = "testBean";
ObjectName objectName = ObjectName.getInstance("spring:name=Test");
@@ -232,7 +234,7 @@ public class NotificationListenerTests extends AbstractMBeanServerTests {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
factory.registerSingleton(beanName, testBean);
Map beans = new HashMap();
Map<String, Object> beans = new HashMap<String, Object>();
beans.put(beanName, testBean);
Map listenerMappings = new HashMap();
@@ -251,6 +253,7 @@ public class NotificationListenerTests extends AbstractMBeanServerTests {
assertEquals("Listener not notified", 1, listener.getCount("Age"));
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public void testRegisterNotificationListenerWithBeanNameBeforeObjectNameMappedToSameBeanInstance() throws Exception {
String beanName = "testBean";
ObjectName objectName = ObjectName.getInstance("spring:name=Test");
@@ -261,7 +264,7 @@ public class NotificationListenerTests extends AbstractMBeanServerTests {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
factory.registerSingleton(beanName, testBean);
Map beans = new HashMap();
Map<String, Object> beans = new HashMap<String, Object>();
beans.put(beanName, testBean);
Map listenerMappings = new HashMap();
@@ -281,6 +284,7 @@ public class NotificationListenerTests extends AbstractMBeanServerTests {
assertEquals("Listener should have been notified exactly once", 1, listener.getCount("Age"));
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public void testRegisterNotificationListenerWithObjectNameBeforeBeanNameMappedToSameBeanInstance() throws Exception {
String beanName = "testBean";
ObjectName objectName = ObjectName.getInstance("spring:name=Test");
@@ -291,7 +295,7 @@ public class NotificationListenerTests extends AbstractMBeanServerTests {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
factory.registerSingleton(beanName, testBean);
Map beans = new HashMap();
Map<String, Object> beans = new HashMap<String, Object>();
beans.put(beanName, testBean);
Map listenerMappings = new HashMap();
@@ -311,6 +315,7 @@ public class NotificationListenerTests extends AbstractMBeanServerTests {
assertEquals("Listener should have been notified exactly once", 1, listener.getCount("Age"));
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public void testRegisterNotificationListenerWithTwoBeanNamesMappedToDifferentBeanInstances() throws Exception {
String beanName1 = "testBean1";
String beanName2 = "testBean2";
@@ -328,7 +333,7 @@ public class NotificationListenerTests extends AbstractMBeanServerTests {
factory.registerSingleton(beanName1, testBean1);
factory.registerSingleton(beanName2, testBean2);
Map beans = new HashMap();
Map<String, Object> beans = new HashMap<String, Object>();
beans.put(beanName1, testBean1);
beans.put(beanName2, testBean2);
@@ -357,8 +362,8 @@ public class NotificationListenerTests extends AbstractMBeanServerTests {
ObjectName objectName = ObjectName.getInstance("spring:name=Test");
JmxTestBean bean = new JmxTestBean();
Map beans = new HashMap();
beans.put(objectName, bean);
Map<String, Object> beans = new HashMap<String, Object>();
beans.put(objectName.getCanonicalName(), bean);
MBeanExporter exporter = new MBeanExporter();
exporter.setServer(server);
@@ -391,9 +396,9 @@ public class NotificationListenerTests extends AbstractMBeanServerTests {
JmxTestBean bean = new JmxTestBean();
JmxTestBean bean2 = new JmxTestBean();
Map beans = new HashMap();
beans.put(objectName, bean);
beans.put(objectName2, bean2);
Map<String, Object> beans = new HashMap<String, Object>();
beans.put(objectName.getCanonicalName(), bean);
beans.put(objectName2.getCanonicalName(), bean2);
MBeanExporter exporter = new MBeanExporter();
exporter.setServer(server);
@@ -406,7 +411,7 @@ public class NotificationListenerTests extends AbstractMBeanServerTests {
registrar.setServer(server);
registrar.setNotificationListener(listener);
//registrar.setMappedObjectNames(new Object[] {objectName, objectName2});
registrar.setMappedObjectNames(new String[] {"spring:name=Test", "spring:name=Test2"});
registrar.setMappedObjectNames(new String[] { "spring:name=Test", "spring:name=Test2" });
registrar.afterPropertiesSet();
// update the attribute
@@ -422,6 +427,7 @@ public class NotificationListenerTests extends AbstractMBeanServerTests {
}
@SuppressWarnings({"rawtypes", "unchecked"})
private static class CountingAttributeChangeNotificationListener implements NotificationListener {
private Map attributeCounts = new HashMap();
@@ -438,8 +444,7 @@ public class NotificationListenerTests extends AbstractMBeanServerTests {
if (currentCount != null) {
int count = currentCount.intValue() + 1;
this.attributeCounts.put(attributeName, new Integer(count));
}
else {
} else {
this.attributeCounts.put(attributeName, new Integer(1));
}
@@ -35,7 +35,7 @@ import org.springframework.jmx.AbstractMBeanServerTests;
* @author Rob Harrop
*/
@Ignore // see https://issuetracker.springsource.com/browse/BRITS-235
public class ConnectorServerFactoryBeanTests extends AbstractMBeanServerTests {
public class ConnectorServerFactoryBeanTestsIgnore extends AbstractMBeanServerTests {
private static final String OBJECT_NAME = "spring:type=connector,name=test";
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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,8 +16,6 @@
package org.springframework.scheduling.support;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
@@ -30,8 +28,11 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.springframework.scheduling.TriggerContext;
import static org.junit.Assert.*;
/**
* @author Dave Syer
* @author Mark Fisher
@@ -670,6 +671,28 @@ public class CronTriggerTests {
assertEquals(trigger1, trigger2);
}
@Test
public void testMonthSequence() throws Exception {
CronTrigger trigger = new CronTrigger("0 30 23 30 1/3 ?", timeZone);
calendar.set(2010, 11, 30);
Date date = calendar.getTime();
// set expected next trigger time
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 30);
calendar.set(Calendar.SECOND, 0);
calendar.add(Calendar.MONTH, 1);
TriggerContext context1 = getTriggerContext(date);
assertEquals(calendar.getTime(), date = trigger.nextExecutionTime(context1));
// Next trigger is 3 months latter
calendar.add(Calendar.MONTH, 3);
TriggerContext context2 = getTriggerContext(date);
assertEquals(calendar.getTime(), date = trigger.nextExecutionTime(context2));
// Next trigger is 3 months latter
calendar.add(Calendar.MONTH, 3);
TriggerContext context3 = getTriggerContext(date);
assertEquals(calendar.getTime(), date = trigger.nextExecutionTime(context3));
}
private void assertMatchesNextSecond(CronTrigger trigger, Calendar calendar) {
Date date = calendar.getTime();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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,14 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.text.ParseException;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
@@ -34,6 +41,7 @@ import org.springframework.beans.BeanWithObjectProperty;
import org.springframework.beans.DerivedTestBean;
import org.springframework.beans.ITestBean;
import org.springframework.beans.IndexedTestBean;
import org.springframework.beans.InvalidPropertyException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.NotWritablePropertyException;
import org.springframework.beans.NullValueInNestedPathException;
@@ -45,6 +53,7 @@ import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.context.support.StaticMessageSource;
import org.springframework.core.convert.support.ConversionServiceFactory;
import org.springframework.format.Formatter;
import org.springframework.format.number.NumberFormatter;
import org.springframework.format.support.FormattingConversionService;
import org.springframework.util.StringUtils;
@@ -366,6 +375,28 @@ public class DataBinderTests extends TestCase {
}
}
public void testBindingErrorWithStringFormatter() {
TestBean tb = new TestBean();
DataBinder binder = new DataBinder(tb);
FormattingConversionService conversionService = new FormattingConversionService();
ConversionServiceFactory.addDefaultConverters(conversionService);
conversionService.addFormatterForFieldType(String.class, new Formatter<String>() {
public String parse(String text, Locale locale) throws ParseException {
throw new ParseException(text, 0);
}
public String print(String object, Locale locale) {
return object;
}
});
binder.setConversionService(conversionService);
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.add("name", "test");
binder.bind(pvs);
assertTrue(binder.getBindingResult().hasFieldErrors("name"));
assertEquals("test", binder.getBindingResult().getFieldValue("name"));
}
public void testBindingWithFormatterAgainstList() {
BeanWithIntegerList tb = new BeanWithIntegerList();
DataBinder binder = new DataBinder(tb);
@@ -1486,7 +1517,6 @@ public class DataBinderTests extends TestCase {
MutablePropertyValues mpvs = new MutablePropertyValues();
mpvs.add("name", name);
mpvs.add("beanName", beanName);
binder.bind(mpvs);
assertEquals(name, testBean.getName());
@@ -1495,6 +1525,76 @@ public class DataBinderTests extends TestCase {
assertEquals("beanName", disallowedFields[0]);
}
public void testAutoGrowWithinDefaultLimit() throws Exception {
TestBean testBean = new TestBean();
DataBinder binder = new DataBinder(testBean, "testBean");
MutablePropertyValues mpvs = new MutablePropertyValues();
mpvs.add("friends[4]", "");
binder.bind(mpvs);
assertEquals(5, testBean.getFriends().size());
}
public void testAutoGrowBeyondDefaultLimit() throws Exception {
TestBean testBean = new TestBean();
DataBinder binder = new DataBinder(testBean, "testBean");
MutablePropertyValues mpvs = new MutablePropertyValues();
mpvs.add("friends[256]", "");
try {
binder.bind(mpvs);
fail("Should have thrown InvalidPropertyException");
}
catch (InvalidPropertyException ex) {
// expected
assertTrue(ex.getRootCause() instanceof IndexOutOfBoundsException);
}
}
public void testAutoGrowWithinCustomLimit() throws Exception {
TestBean testBean = new TestBean();
DataBinder binder = new DataBinder(testBean, "testBean");
binder.setAutoGrowCollectionLimit(10);
MutablePropertyValues mpvs = new MutablePropertyValues();
mpvs.add("friends[4]", "");
binder.bind(mpvs);
assertEquals(5, testBean.getFriends().size());
}
public void testAutoGrowBeyondCustomLimit() throws Exception {
TestBean testBean = new TestBean();
DataBinder binder = new DataBinder(testBean, "testBean");
binder.setAutoGrowCollectionLimit(10);
MutablePropertyValues mpvs = new MutablePropertyValues();
mpvs.add("friends[16]", "");
try {
binder.bind(mpvs);
fail("Should have thrown InvalidPropertyException");
}
catch (InvalidPropertyException ex) {
// expected
assertTrue(ex.getRootCause() instanceof IndexOutOfBoundsException);
}
}
public void testNestedGrowingList() {
Form form = new Form();
DataBinder binder = new DataBinder(form, "form");
MutablePropertyValues mpv = new MutablePropertyValues();
mpv.add("f[list][0]", "firstValue");
mpv.add("f[list][1]", "secondValue");
binder.bind(mpv);
assertFalse(binder.getBindingResult().hasErrors());
List<Object> list = (List<Object>) form.getF().get("list");
assertEquals("firstValue", list.get(0));
assertEquals("secondValue", list.get(1));
assertEquals(2, list.size());
}
private static class BeanWithIntegerList {
@@ -1589,4 +1689,94 @@ public class DataBinderTests extends TestCase {
}
}
private static class GrowingList<E> extends AbstractList<E> {
private List<E> list;
public GrowingList() {
this.list = new ArrayList<E>();
}
public List<E> getWrappedList() {
return list;
}
public E get(int index) {
if (index >= list.size()) {
for (int i = list.size(); i < index; i++) {
list.add(null);
}
list.add(null);
return null;
}
else {
return list.get(index);
}
}
public int size() {
return list.size();
}
public boolean add(E o) {
return list.add(o);
}
public void add(int index, E element) {
list.add(index, element);
}
public boolean addAll(int index, Collection<? extends E> c) {
return list.addAll(index, c);
}
public void clear() {
list.clear();
}
public int indexOf(Object o) {
return list.indexOf(o);
}
public Iterator<E> iterator() {
return list.iterator();
}
public int lastIndexOf(Object o) {
return list.lastIndexOf(o);
}
public ListIterator<E> listIterator() {
return list.listIterator();
}
public ListIterator<E> listIterator(int index) {
return list.listIterator(index);
}
public E remove(int index) {
return list.remove(index);
}
public E set(int index, E element) {
return list.set(index, element);
}
}
private static class Form {
private final Map<String, Object> f;
public Form() {
f = new HashMap<String, Object>();
f.put("list", new GrowingList<Object>());
}
public Map<String, Object> getF() {
return f;
}
}
}
@@ -7,7 +7,8 @@
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">
<context:property-placeholder
location="classpath*:/org/springframework/context/config/test-*.properties,classpath*:/org/springframework/context/config/empty-*.properties,classpath*:/org/springframework/context/config/missing-*.properties" />
location="classpath*:/org/springframework/context/config/test-*.properties,classpath*:/org/springframework/context/config/empty-*.properties,classpath*:/org/springframework/context/config/missing-*.properties"
file-encoding="ISO-8859-1"/>
<bean id="foo" class="java.lang.String">
<constructor-arg value="${foo}" />
+1 -1
View File
@@ -27,7 +27,7 @@ Import-Template:
org.apache.commons.logging.*;version="[1.1.1, 2.0.0)",
org.aspectj.weaver.*;version=${aj.osgi.range};resolution:=optional,
org.codehaus.groovy.*;version="[1.5.0, 2.0.0)";resolution:=optional,
org.hibernate.validator.*;version="[4.1.0, 5.0.0)";resolution:=optional,
org.hibernate.validator.*;version="[4.0.0, 5.0.0)";resolution:=optional,
org.joda.*;version="[1.6.0, 2.0.0)";resolution:=optional,
org.jruby.*;version="[1.1.0, 2.0.0)";resolution:=optional,
org.omg.CORBA.*;version="0";resolution:=optional,
+1 -1
View File
@@ -31,7 +31,7 @@
<dependency org="org.springframework" name="org.springframework.asm" rev="latest.integration" conf="optional->compile"/>
<!-- test dependencies -->
<dependency org="javax.servlet" name="com.springsource.javax.servlet" rev="2.5.0" conf="test->compile"/>
<dependency org="org.junit" name="com.springsource.org.junit" rev="${org.junit.version}" conf="test->runtime"/>
<dependency org="org.junit" name="com.springsource.org.junit" rev="${junit.version}" conf="test->runtime"/>
<dependency org="org.easymock" name="com.springsource.org.easymock" rev="2.5.1" conf="test->compile"/>
<dependency org="org.custommonkey.xmlunit" name="com.springsource.org.custommonkey.xmlunit" rev="1.2.0" conf="test->compile"/>
<dependency org="org.codehaus.woodstox" name="com.springsource.com.ctc.wstx" rev="3.2.7" conf="test->compile"/>
+2 -2
View File
@@ -6,12 +6,12 @@
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<packaging>jar</packaging>
<version>3.0.5.BUILD-SNAPSHOT</version>
<version>3.0.8.BUILD-SNAPSHOT</version>
<parent>
<groupId>org.springframework</groupId>
<artifactId>spring-parent</artifactId>
<relativePath>../org.springframework.spring-parent</relativePath>
<version>3.0.5.BUILD-SNAPSHOT</version>
<version>3.0.8.BUILD-SNAPSHOT</version>
</parent>
<dependencies>
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2011 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.
@@ -35,7 +35,7 @@ import org.springframework.util.Assert;
public abstract class AttributeAccessorSupport implements AttributeAccessor, Serializable {
/** Map with String keys and Object values */
private final Map<String, Object> attributes = new LinkedHashMap<String, Object>();
private final Map<String, Object> attributes = new LinkedHashMap<String, Object>(0);
public void setAttribute(String name, Object value) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2011 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,6 +25,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
@@ -210,4 +211,22 @@ public abstract class BridgeMethodResolver {
return ReflectionUtils.findMethod(type, bridgeMethod.getName(), bridgeMethod.getParameterTypes());
}
/**
* Compare the signatures of the bridge method and the method which it bridges. If
* the parameter and return types are the same, it is a 'visibility' bridge method
* introduced in Java 6 to fix http://bugs.sun.com/view_bug.do?bug_id=6342411.
* See also http://stas-blogspot.blogspot.com/2010/03/java-bridge-methods-explained.html
* @return whether signatures match as described
*/
public static boolean isVisibilityBridgeMethodPair(Method bridgeMethod, Method bridgedMethod) {
Assert.isTrue(bridgeMethod != null);
Assert.isTrue(bridgedMethod != null);
if (bridgeMethod == bridgedMethod) {
return true;
}
return Arrays.equals(bridgeMethod.getParameterTypes(), bridgedMethod.getParameterTypes()) &&
bridgeMethod.getReturnType().equals(bridgedMethod.getReturnType());
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2011 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,6 +18,7 @@ package org.springframework.core;
import java.io.IOException;
import java.io.InputStream;
import java.io.NotSerializableException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamClass;
import java.lang.reflect.Proxy;
@@ -36,16 +37,33 @@ public class ConfigurableObjectInputStream extends ObjectInputStream {
private final ClassLoader classLoader;
private final boolean acceptProxyClasses;
/**
* Create a new ConfigurableObjectInputStream for the given InputStream and ClassLoader.
* @param in the InputStream to read from
* @param in the InputStream to read from
* @param classLoader the ClassLoader to use for loading local classes
* @see java.io.ObjectInputStream#ObjectInputStream(java.io.InputStream)
*/
public ConfigurableObjectInputStream(InputStream in, ClassLoader classLoader) throws IOException {
this(in, classLoader, true);
}
/**
* Create a new ConfigurableObjectInputStream for the given InputStream and ClassLoader.
* @param in the InputStream to read from
* @param classLoader the ClassLoader to use for loading local classes
* @param acceptProxyClasses whether to accept deserialization of proxy classes
* (may be deactivated as a security measure)
* @see java.io.ObjectInputStream#ObjectInputStream(java.io.InputStream)
*/
public ConfigurableObjectInputStream(
InputStream in, ClassLoader classLoader, boolean acceptProxyClasses) throws IOException {
super(in);
this.classLoader = classLoader;
this.acceptProxyClasses = acceptProxyClasses;
}
@@ -68,6 +86,9 @@ public class ConfigurableObjectInputStream extends ObjectInputStream {
@Override
protected Class resolveProxyClass(String[] interfaces) throws IOException, ClassNotFoundException {
if (!this.acceptProxyClasses) {
throw new NotSerializableException("Not allowed to accept serialized proxy classes");
}
if (this.classLoader != null) {
// Use the specified ClassLoader to resolve local proxy classes.
Class[] resolvedInterfaces = new Class[interfaces.length];
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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.
@@ -68,7 +68,7 @@ public class ExceptionDepthComparator implements Comparator<Class<? extends Thro
}
// If we've gone as far as we can go and haven't found it...
if (Throwable.class.equals(exceptionToMatch)) {
return -1;
return Integer.MAX_VALUE;
}
return getDepth(declaredException, exceptionToMatch.getSuperclass(), depth + 1);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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.
@@ -41,7 +41,6 @@ import org.springframework.util.Assert;
* @author Rob Harrop
* @since 2.5.2
* @see GenericCollectionTypeResolver
* @see JdkVersion
*/
public abstract class GenericTypeResolver {
@@ -175,7 +174,7 @@ public abstract class GenericTypeResolver {
return doResolveTypeArguments(ownerClass, (Class) rawType, genericIfc);
}
}
else if (genericIfc.isAssignableFrom((Class) ifc)) {
else if (ifc != null && genericIfc.isAssignableFrom((Class) ifc)) {
return doResolveTypeArguments(ownerClass, (Class) ifc, genericIfc);
}
return null;
@@ -214,7 +213,7 @@ public abstract class GenericTypeResolver {
* @param typeVariableMap the TypeVariable Map to resolved against
* @return the type if it resolves to a Class, or <code>Object.class</code> otherwise
*/
static Class resolveType(Type genericType, Map<TypeVariable, Type> typeVariableMap) {
public static Class<?> resolveType(Type genericType, Map<TypeVariable, Type> typeVariableMap) {
Type rawType = getRawType(genericType, typeVariableMap);
return (rawType instanceof Class ? (Class) rawType : Object.class);
}
@@ -247,7 +246,7 @@ public abstract class GenericTypeResolver {
* {@link Class} for the specified {@link Class}. Searches all super types,
* enclosing types and interfaces.
*/
static Map<TypeVariable, Type> getTypeVariableMap(Class clazz) {
public static Map<TypeVariable, Type> getTypeVariableMap(Class clazz) {
Reference<Map<TypeVariable, Type>> ref = typeVariableCache.get(clazz);
Map<TypeVariable, Type> typeVariableMap = (ref != null ? ref.get() : null);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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.
@@ -80,13 +80,13 @@ public class TypeDescriptor {
private Object value;
private TypeDescriptor elementType;
private volatile TypeDescriptor elementType;
private TypeDescriptor mapKeyType;
private volatile TypeDescriptor mapKeyType;
private TypeDescriptor mapValueType;
private volatile TypeDescriptor mapValueType;
private Annotation[] annotations;
private volatile Annotation[] annotations;
/**
@@ -266,7 +266,7 @@ public class TypeDescriptor {
/**
* Return the element type as a type descriptor.
*/
public synchronized TypeDescriptor getElementTypeDescriptor() {
public TypeDescriptor getElementTypeDescriptor() {
if (this.elementType == null) {
this.elementType = forElementType(resolveElementType());
}
@@ -281,7 +281,7 @@ public class TypeDescriptor {
*/
public TypeDescriptor getElementTypeDescriptor(Object element) {
TypeDescriptor elementType = getElementTypeDescriptor();
return (elementType != TypeDescriptor.UNKNOWN ? elementType : forObject(element));
return (!TypeDescriptor.UNKNOWN.equals(elementType) ? elementType : forObject(element));
}
/**
@@ -309,7 +309,7 @@ public class TypeDescriptor {
/**
* Returns map key type as a type descriptor.
*/
public synchronized TypeDescriptor getMapKeyTypeDescriptor() {
public TypeDescriptor getMapKeyTypeDescriptor() {
if (this.mapKeyType == null) {
this.mapKeyType = forElementType(resolveMapKeyType());
}
@@ -317,14 +317,14 @@ public class TypeDescriptor {
}
/**
* Return the map key type as a type descriptor. If the key type is null
* Return the map key type as a type descriptor. If the key type is <code>null</code>
* (cannot be determined), the type descriptor is derived from the key argument.
* @param key the key
* @return the map key type descriptor
*/
public TypeDescriptor getMapKeyTypeDescriptor(Object key) {
TypeDescriptor keyType = getMapKeyTypeDescriptor();
return (keyType != TypeDescriptor.UNKNOWN ? keyType : TypeDescriptor.forObject(key));
return (!TypeDescriptor.UNKNOWN.equals(keyType) ? keyType : TypeDescriptor.forObject(key));
}
/**
@@ -338,7 +338,7 @@ public class TypeDescriptor {
/**
* Returns map value type as a type descriptor.
*/
public synchronized TypeDescriptor getMapValueTypeDescriptor() {
public TypeDescriptor getMapValueTypeDescriptor() {
if (this.mapValueType == null) {
this.mapValueType = forElementType(resolveMapValueType());
}
@@ -353,13 +353,13 @@ public class TypeDescriptor {
*/
public TypeDescriptor getMapValueTypeDescriptor(Object value) {
TypeDescriptor valueType = getMapValueTypeDescriptor();
return (valueType != TypeDescriptor.UNKNOWN ? valueType : TypeDescriptor.forObject(value));
return (!TypeDescriptor.UNKNOWN.equals(valueType) ? valueType : TypeDescriptor.forObject(value));
}
/**
* Obtain the annotations associated with the wrapped parameter/field, if any.
*/
public synchronized Annotation[] getAnnotations() {
public Annotation[] getAnnotations() {
if (this.annotations == null) {
this.annotations = resolveAnnotations();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2011 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,11 +16,11 @@
package org.springframework.core.convert.converter;
import java.util.Set;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.util.Assert;
import java.util.Set;
/**
* Generic converter interface for converting between two or more types.
*
@@ -87,6 +87,24 @@ public interface GenericConverter {
public Class<?> getTargetType() {
return this.targetType;
}
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || obj.getClass() != ConvertiblePair.class) {
return false;
}
ConvertiblePair other = (ConvertiblePair) obj;
return this.sourceType.equals(other.sourceType) && this.targetType.equals(other.targetType);
}
@Override
public int hashCode() {
return this.sourceType.hashCode() * 31 + this.targetType.hashCode();
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2011 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,7 @@ import java.util.Set;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.core.convert.converter.ConditionalGenericConverter;
import org.springframework.util.ObjectUtils;
/**
@@ -32,7 +32,7 @@ import org.springframework.util.ObjectUtils;
* @author Keith Donald
* @since 3.0
*/
final class ArrayToArrayConverter implements GenericConverter {
final class ArrayToArrayConverter implements ConditionalGenericConverter {
private final CollectionToArrayConverter helperConverter;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2011 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.
@@ -49,7 +49,8 @@ final class ArrayToCollectionConverter implements ConditionalGenericConverter {
}
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
return this.conversionService.canConvert(sourceType.getElementTypeDescriptor(), targetType.getElementTypeDescriptor());
return ConversionUtils.canConvertElements(
sourceType.getElementTypeDescriptor(), targetType.getElementTypeDescriptor(), this.conversionService);
}
@SuppressWarnings("unchecked")
@@ -58,12 +59,21 @@ final class ArrayToCollectionConverter implements ConditionalGenericConverter {
return null;
}
int length = Array.getLength(source);
Collection target = CollectionFactory.createCollection(targetType.getType(), length);
for (int i = 0; i < length; i++) {
Object sourceElement = Array.get(source, i);
Object targetElement = this.conversionService.convert(sourceElement, sourceType.getElementTypeDescriptor(), targetType.getElementTypeDescriptor(sourceElement));
target.add(targetElement);
Collection<Object> target = CollectionFactory.createCollection(targetType.getType(), length);
if (targetType.getElementTypeDescriptor() == null) {
for (int i = 0; i < length; i++) {
Object sourceElement = Array.get(source, i);
target.add(sourceElement);
}
}
else {
for (int i = 0; i < length; i++) {
Object sourceElement = Array.get(source, i);
Object targetElement = this.conversionService.convert(sourceElement,
sourceType.getElementTypeDescriptor(sourceElement), targetType.getElementTypeDescriptor());
target.add(targetElement);
}
}
return target;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2011 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,40 +16,48 @@
package org.springframework.core.convert.support;
import java.util.Arrays;
import java.lang.reflect.Array;
import java.util.Collections;
import java.util.Set;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.ConditionalGenericConverter;
import org.springframework.util.ObjectUtils;
/**
* Converts an Array to an Object by returning the first array element after converting it to the desired targetType.
* This implementation first adapts the source Array to a List, then delegates to {@link CollectionToObjectConverter} to perform the target Object conversion.
*
* @author Keith Donald
* @since 3.0
*/
final class ArrayToObjectConverter implements ConditionalGenericConverter {
private final CollectionToObjectConverter helperConverter;
private final ConversionService conversionService;
public ArrayToObjectConverter(ConversionService conversionService) {
this.helperConverter = new CollectionToObjectConverter(conversionService);
this.conversionService = conversionService;
}
public Set<ConvertiblePair> getConvertibleTypes() {
return Collections.singleton(new ConvertiblePair(Object[].class, Object.class));
}
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
return this.helperConverter.matches(sourceType, targetType);
return ConversionUtils.canConvertElements(sourceType.getElementTypeDescriptor(), targetType, this.conversionService);
}
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
return this.helperConverter.convert(Arrays.asList(ObjectUtils.toObjectArray(source)), sourceType, targetType);
if (source == null) {
return null;
}
if (sourceType.isAssignableTo(targetType)) {
return source;
}
if (Array.getLength(source) == 0) {
return null;
}
Object firstElement = Array.get(source, 0);
return this.conversionService.convert(firstElement, sourceType.getElementTypeDescriptor(firstElement), targetType);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2011 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.
@@ -49,7 +49,7 @@ final class CollectionToArrayConverter implements ConditionalGenericConverter {
}
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
return this.conversionService.canConvert(sourceType.getElementTypeDescriptor(), targetType.getElementTypeDescriptor());
return ConversionUtils.canConvertElements(sourceType.getElementTypeDescriptor(), targetType.getElementTypeDescriptor(), this.conversionService);
}
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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.
@@ -49,26 +49,37 @@ final class CollectionToCollectionConverter implements ConditionalGenericConvert
}
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
return this.conversionService.canConvert(sourceType.getElementTypeDescriptor(), targetType.getElementTypeDescriptor());
return ConversionUtils.canConvertElements(
sourceType.getElementTypeDescriptor(), targetType.getElementTypeDescriptor(), this.conversionService);
}
@SuppressWarnings("unchecked")
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (source == null) {
return null;
}
boolean copyRequired = !targetType.getType().isInstance(source);
Collection<?> sourceCollection = (Collection<?>) source;
if (sourceCollection.isEmpty()) {
if (!copyRequired && sourceCollection.isEmpty()) {
return sourceCollection;
}
Collection target = CollectionFactory.createCollection(targetType.getType(), sourceCollection.size());
for (Object sourceElement : sourceCollection) {
Object targetElement = this.conversionService.convert(sourceElement,
sourceType.getElementTypeDescriptor(sourceElement),
targetType.getElementTypeDescriptor(sourceElement));
target.add(targetElement);
Collection<Object> target = CollectionFactory.createCollection(targetType.getType(), sourceCollection.size());
if (targetType.getElementTypeDescriptor() == null) {
for (Object element : sourceCollection) {
target.add(element);
}
}
return target;
else {
for (Object sourceElement : sourceCollection) {
Object targetElement = this.conversionService.convert(sourceElement,
sourceType.getElementTypeDescriptor(sourceElement), targetType.getElementTypeDescriptor());
target.add(targetElement);
if (sourceElement != targetElement) {
copyRequired = true;
}
}
}
return (copyRequired ? target : source);
}
}

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