Commit Graph

623 Commits

Author SHA1 Message Date
Sam Brannen
384ee69300 Introduce getAliasedClassArray() in AnnotationAttributes
Issue: SPR-11393
2015-06-04 15:23:53 -04:00
Sam Brannen
e5dc6e964c Introduce getAliasedStringArray() in AnnotationAttributes
Issue: SPR-11393
2015-06-03 21:26:43 -04:00
izeye
b8d7d46da7 Fix typo 2015-06-01 09:21:38 +02:00
Sam Brannen
518c85b107 Support synthesized annotations in MethodParameter 2015-05-29 22:48:55 +02:00
Sam Brannen
1afc938da1 Introduce synthesizeAnnotationArray() in AnnotationUtils 2015-05-29 22:45:34 +02:00
Sam Brannen
9f717871e6 Introduce getAnnotation() in AnnotatedElementUtils
This commit introduces a "synthesized annotation" alternative to
getAnnotationAttributes() in AnnotatedElementUtils, analogous to the
recently introduced findAnnotation() methods.

Issue: SPR-13082
2015-05-29 22:04:10 +02:00
Sam Brannen
9afcd17c71 Introduce getAnnotationAttributes(..,Class) in AnnoElUtils 2015-05-29 21:36:00 +02:00
Sam Brannen
46be176875 Allow AnnoConfigEx to propagate from getRepeatableAnnotation()
Issue: SPR-13084
2015-05-29 21:17:33 +02:00
Sam Brannen
7018747cec Remove trailing whitespace in Java source code 2015-05-29 02:03:44 +02:00
Sam Brannen
e30c9b2ef3 Synthesize annotation from a map of attributes
Spring Framework 4.2 RC1 introduced support for synthesizing an
annotation from an existing annotation in order to provide additional
functionality above and beyond that provided by Java. Specifically,
such synthesized annotations provide support for @AliasFor semantics.
As luck would have it, the same principle can be used to synthesize an
annotation from any map of attributes, and in particular, from an
instance of AnnotationAttributes.

The following highlight the major changes in this commit toward
achieving this goal.

- Introduced AnnotationAttributeExtractor abstraction and refactored
  SynthesizedAnnotationInvocationHandler to delegate to an
  AnnotationAttributeExtractor.

- Extracted code from SynthesizedAnnotationInvocationHandler into new
  AbstractAliasAwareAnnotationAttributeExtractor and
  DefaultAnnotationAttributeExtractor implementation classes.

- Introduced MapAnnotationAttributeExtractor for synthesizing an
  annotation that is backed by a map or AnnotationAttributes instance.

- Introduced a variant of synthesizeAnnotation() in AnnotationUtils
  that accepts a map.

- Introduced findAnnotation(*) methods in AnnotatedElementUtils that
  synthesize merged AnnotationAttributes back into an annotation of the
  target type.

The following classes have been refactored to use the new support for
synthesizing AnnotationAttributes back into an annotation.

- ApplicationListenerMethodAdapter
- TestAnnotationUtils
- AbstractTestContextBootstrapper
- ActiveProfilesUtils
- ContextLoaderUtils
- DefaultActiveProfilesResolver
- DirtiesContextTestExecutionListener
- TestPropertySourceAttributes
- TestPropertySourceUtils
- TransactionalTestExecutionListener
- MetaAnnotationUtils
- MvcUriComponentsBuilder
- RequestMappingHandlerMapping

In addition, this commit also includes changes to ensure that arrays
returned by synthesized annotations are properly cloned first.

Issue: SPR-13067
2015-05-29 01:38:51 +02:00
Sam Brannen
f41de12cf6 Ensure synthesized nested annotation arrays retain correct type
Prior to this commit, when a nested array of annotations was
synthesized while adapting values within an AnnotationAttributes map,
the array was improperly replaced with an array of type Annotation[]
instead of an array of the concrete annotation type, which can lead to
unexpected run-time exceptions.

This commit fixes this bug by replacing annotations in the existing
array with synthesized versions of those annotations, thereby retaining
the original array's component type.

Issue: SPR-13077
2015-05-27 17:55:10 +02:00
Sam Brannen
a2f152ce8b Support nested annotations in AnnotationAttributes
This commit introduces support in AnnotationAttributes for retrieving
nested annotations that is on par with the existing type-safe support
for retrieving nested AnnotationAttributes.

Issue: SPR-13074
2015-05-27 17:03:01 +02:00
Sam Brannen
0ac0e2ce20 Document public API in AnnotationAttributes
AnnotationAttributes has existed for several years, but none of the
"get" methods that make up its public API are documented. In many
cases, the behavior can be inferred from the name of the method, but
for some methods there are "hidden gems" and unexpected behavior
lurking behind the scenes.

This commit addresses this issue by documenting all public methods. In
addition, the hidden support for converting single elements into
single-element arrays has also been documented and tested.

Issue: SPR-13072
2015-05-27 16:15:25 +02:00
Sam Brannen
197f6594f4 Simplify annotation attribute override algorithm
Issue: SPR-11513
2015-05-24 17:59:30 +02:00
Sam Brannen
c80932490f Complete documentation of synthesized annotations
Issue: SPR-11512
2015-05-24 16:42:09 +02:00
Sam Brannen
b6f2d95c3e Cache computed values in SynthesizedAnnotationInvocationHandler
Issue: SPR-11512
2015-05-24 15:58:20 +02:00
Sam Brannen
8ecae8697a Cache attribute methods in AnnotationUtils
Issue: SPR-11512
2015-05-24 15:58:20 +02:00
Sam Brannen
d5974a18ab Polish AnnotationUtils 2015-05-24 15:58:19 +02:00
Sam Brannen
a1fc2097a1 Document SynthesizedAnnotationInvocationHandler constructor
Issue: SPR-11512
2015-05-24 15:58:07 +02:00
Sam Brannen
c13f689537 Document isSynthesizable() in AnnotationUtils
Issue: SPR-11512
2015-05-24 00:13:53 +02:00
Sam Brannen
7f22f09890 PolishingPolish SynthesizedAnnotationInvocationHandler 2015-05-23 23:58:35 +02:00
Sam Brannen
def7663ec4 Implement hashCode() for synthesized annotations
Issue: SPR-13066
2015-05-23 23:46:48 +02:00
Sam Brannen
ae5c8285a6 Polish SynthesizedAnnotationInvocationHandler 2015-05-23 22:40:05 +02:00
Sam Brannen
7e2e9a80d0 Document getAttributeMethods() in AnnotationUtils
Issue: SPR-11512
2015-05-23 22:29:12 +02:00
Sam Brannen
7bf609f111 Implement equals() for synthesized annotations
Issue: SPR-13065
2015-05-23 22:29:12 +02:00
Sam Brannen
62d1b4b6e8 Document getAttributeAliasMap() in AnnotationUtils
This commit also introduces a cache for attribute alias metadata.

Issue: SPR-11512
2015-05-23 20:30:03 +02:00
Sam Brannen
f5e096e2a0 Document @AliasFor
Issue: SPR-11512
2015-05-23 19:52:03 +02:00
Sam Brannen
b9e13ea308 Align AnnotationAttributes.toString() with contract in Map 2015-05-23 18:25:50 +02:00
Sam Brannen
f380689230 Don't use Java 8's Method.getParameterCount() 2015-05-23 18:18:03 +02:00
Sam Brannen
1e50d8d5c2 Implement toString() for synthesized annotations
Issue: SPR-13064
2015-05-23 18:09:39 +02:00
Sam Brannen
ab92f4ed3a Document SynthesizedAnnotation support
Issue: SPR-11512
2015-05-23 01:01:39 +02:00
Sam Brannen
bd787769be Introduce "synthesizable" cache in AnnotationUtils
Issue: SPR-11512
2015-05-22 21:40:36 +02:00
Sam Brannen
2e4dabb349 Polishing 2015-05-22 21:37:50 +02:00
Sam Brannen
ca09b1ff20 Introduce putIfAbsent() in AnnotationAttributes
Issue: SPR-13060
2015-05-22 15:52:49 +02:00
Sebastien Deleuze
5255e7ae21 Support CompletableFuture in @MessageMapping handler methods
Issue: SPR-12207
2015-05-22 11:30:56 +02:00
Juergen Hoeller
792b7b9d11 ByteBufferConverter explicitly declares applicability to byte[]
Includes an optimization for simple ByteBuffer duplication.

Issue: SPR-13056
2015-05-22 11:19:17 +02:00
Stephane Nicoll
39b2fbbccf Make SynthetizedAnnotation public
Enable public visibility on SynthetizedAnnotation to allow annotation
outside its package to be proxied properly. This commit is pending a
unit test that actually reproduces the problem.

Issue: SPR-13057
2015-05-22 10:21:23 +02:00
Sam Brannen
ca66e076d1 Support annotation attribute aliases and overrides via @AliasFor
This commit introduces first-class support for aliases for annotation
attributes. Specifically, this commit introduces a new @AliasFor
annotation that can be used to declare a pair of aliased attributes
within a single annotation or an alias from an attribute in a custom
composed annotation to an attribute in a meta-annotation.

To support @AliasFor within annotation instances, AnnotationUtils has
been overhauled to "synthesize" any annotations returned by "get" and
"find" searches. A SynthesizedAnnotation is an annotation that is
wrapped in a JDK dynamic proxy which provides run-time support for
@AliasFor semantics. SynthesizedAnnotationInvocationHandler is the
actual handler behind the proxy.

In addition, the contract for @AliasFor is fully validated, and an
AnnotationConfigurationException is thrown in case invalid
configuration is detected.

For example, @ContextConfiguration from the spring-test module is now
declared as follows:

    public @interface ContextConfiguration {

        @AliasFor(attribute = "locations")
        String[] value() default {};

        @AliasFor(attribute = "value")
        String[] locations() default {};

        // ...
    }

The following annotations and their related support classes have been
modified to use @AliasFor.

- @ManagedResource
- @ContextConfiguration
- @ActiveProfiles
- @TestExecutionListeners
- @TestPropertySource
- @Sql
- @ControllerAdvice
- @RequestMapping

Similarly, support for AnnotationAttributes has been reworked to
support @AliasFor as well. This allows for fine-grained control over
exactly which attributes are overridden within an annotation hierarchy.
In fact, it is now possible to declare an alias for the 'value'
attribute of a meta-annotation.

For example, given the revised declaration of @ContextConfiguration
above, one can now develop a composed annotation with a custom
attribute override as follows.

    @ContextConfiguration
    public @interface MyTestConfig {

        @AliasFor(
           annotation = ContextConfiguration.class,
           attribute = "locations"
        )
        String[] xmlFiles();

        // ...
    }

Consequently, the following are functionally equivalent.

- @MyTestConfig(xmlFiles = "test.xml")
- @ContextConfiguration("test.xml")
- @ContextConfiguration(locations = "test.xml").

Issue: SPR-11512, SPR-11513
2015-05-22 00:01:07 +02:00
Juergen Hoeller
b4095c3e1d Class identity comparisons wherever possible
Issue: SPR-12926
2015-05-20 14:34:16 +02:00
Juergen Hoeller
008c9a3b45 Test for ByteBuffer-to-ByteBuffer conversion (fresh copy)
ByteBufferConverter also defensively returns the rewind result now.

Issue: SPR-13031
2015-05-18 16:17:11 +02:00
Juergen Hoeller
1e7d954fcb MethodMetadata exposes method return type
Issue: SPR-13024
2015-05-18 16:16:58 +02:00
Stephane Nicoll
0612bc7bc5 Harmonize default converters
Provide Converter implementations for Charset, Currency and TimeZone as
related PropertyEditors are available for those.

Issue: SPR-13020
2015-05-15 15:23:57 +02:00
Sam Brannen
477d4c5126 Document "present" terminology in AnnotationUtils
Prior to this commit, the documentation in AnnotationUtils was
inconsistent, and at times even misleading, with regard to finding
annotations that are "present" or "directly present" on annotated
elements.

This commit defines the terminology used within AnnotationUtils and
introduces the explicit notion of "meta-present" to denote that
annotations are present within annotation hierarchies above annotated
elements.

Issue: SPR-13030
2015-05-14 21:25:54 +02:00
Sam Brannen
ebed52cc22 Favor local, composed annotations in AnnotatedElementUtils
This commit updates the "get semantics" search algorithm used in
`AnnotatedElementUtils` so that locally declared 'composed annotations'
are favored over inherited annotations.

Specifically, the internal `searchWithGetSemantics()` method now
searches locally declared annotations before searching inherited
annotations.

All TODOs in `AnnotatedElementUtilsTests` have been completed, and all
ignored tests have been reinstated.

Issue: SPR-11598
2015-05-13 16:06:36 +02:00
Juergen Hoeller
0711d6d0df Polishing 2015-05-13 15:04:26 +02:00
Juergen Hoeller
e83d495cbb SimpleAliasRegistry prevents NPE for alias resolved to null
Issue: SPR-13016
2015-05-12 22:04:44 +02:00
Sam Brannen
52153bd454 Document search scope in Ann*[Element]Utils
This commit improves the documentation for AnnotationUtils and
AnnotatedElementUtils by explaining that the scope of most annotation
searches is limited to finding the first such annotation, resulting in
additional such annotations being silently ignored.

Issue: SPR-13015
2015-05-12 21:06:27 +02:00
Juergen Hoeller
64a01d64c5 Polishing 2015-05-11 14:42:45 +02:00
Sam Brannen
fcf75c90b1 Fix broken AnnotationAttributesTests
Issue: SPR-13007
2015-05-10 13:10:04 +02:00
Philippe Marschall
994d86992c Avoid eager formatting in pre-condition checks
In general, the Spring Framework aims to construct error message
strings only if an actual error has occurred. This seems to be the
common pattern in the codebase and saves both CPU and memory. However,
there are some places where eager error message formatting occurs
unnecessarily.

This commit addresses this issue in the following classes:
AdviceModeImportSelector, AnnotationAttributes, and
ReadOnlySystemAttributesMap.

The change in ReadOnlySystemAttributesMap also avoids a potential
NullPointerException.

Issue: SPR-13007
2015-05-10 12:36:01 +02:00