Commit Graph

692 Commits

Author SHA1 Message Date
Chris Beams 20f87ab98d Introduce ConfigurableEnvironment#merge
Prior to this change, AbstractApplicationContext#setParent replaced the
child context's Environment with the parent's Environment if available.
This has the negative effect of potentially changing the type of the
child context's Environment, and in any case causes property sources
added directly against the child environment to be ignored. This
situation could easily occur if a WebApplicationContext child had a
non-web ApplicationContext set as its parent. In this case the parent
Environment type would (likely) be StandardEnvironment, while the child
Environment type would (likely) be StandardServletEnvironment. By
directly inheriting the parent environment, critical property sources
such as ServletContextPropertySource are lost entirely.

This commit introduces the concept of merging an environment through
the new ConfigurableEnvironment#merge method. Instead of replacing the
child's environment with the parent's,
AbstractApplicationContext#setParent now merges property sources as
well as active and default profile names from the parent into the
child. In this way, distinct environment objects are maintained with
specific types and property sources preserved. See #merge Javadoc for
additional details.

Issue: SPR-9446
Backport-Issue: SPR-9444, SPR-9439
Backport-Commit: 9fcfd7e827
2012-06-27 23:06:04 +02:00
Chris Beams c25a1bcb60 Reduce log level for message re: missing annotation
Previously (since Spring 3.1.1) RecursiveAnnotationAttributesVisitor
logs at level WARN when ASM parsing encounters an annotation or an (enum
used within an annotation) that cannot be classloaded. This is not
necessarily indicative of an error, e.g. JSR-305 annotations such as
@Nonnull may be used only for static analysis purposes, but because
these annotations have runtime retention, they remain present in the
bytecode. Per section 9.6.1.2 of the JLS, "An annotation that is present
in the binary may or may not be available at run-time via the reflective
libraries of the Java platform."

This commit lowers the log level of these messages from warn to debug,
but leaves at warn level other messages dealing with the ability
reflectively read enum values from within annotations.

Issue: SPR-9447
Backport-Issue: SPR-9233
Backport-Commit: f55a4a1ac5
2012-06-27 23:06:04 +02:00
Juergen Hoeller bf8fa6e268 moved getInputStream() not-null requirement to InputStreamSource itself 2012-03-14 16:40:47 +01:00
Juergen Hoeller d22c8aca49 moved getInputStream() not-null requirement to InputStreamSource itself 2012-03-14 16:12:57 +01:00
Chris Beams 7d72ab59ae Return null correctly from MutablePropertySources#get
Prior to this commit, MutablePropertySources#get(String) would throw
IndexArrayOutOfBoundsException if the named property source does not
actually exist. This is a violation of the PropertySource#get contract
as described in its Javadoc.

The implementation now correctly checks for the existence of the named
property source, returning null if non-existent and otherwise returning
the associated PropertySource.

Other changes

 - Rename PropertySourcesTests => MutablePropertySourcesTests
 - Polish MutablePropertySourcesTests for style, formatting
 - Refactor MutablePropertySources for consistency

Issue: SPR-9185
Backport-Issue: SPR-9179
Backport-Commit: 15d1d824b5
2012-02-29 14:47:47 +01:00
Chris Beams 40a6769309 Avoid infinite loop in AbstractResource#contentLength
Due to changes made in commit 2fa87a71 for SPR-9118,
AbstractResource#contentLength would fall into an infinite loop unless
the method were overridden by a subclass (which it is in the majority of
use cases).

This commit:

 - fixes the infinite recursion by refactoring to a while loop

 - asserts that the value returned from #getInputStream is not null in
   order to avoid NullPointerException

 - tests both of the above

 - adds Javadoc to the Resource interface to clearly document that the
   contract for any implementation is that #getInputStream must not
   return null

Issue: SPR-9163
Backport-Issue: SPR-9161
Backport-Commit: 7ca5fba05f
2012-02-24 14:47:02 +01:00
Chris Beams 7535e24deb Warn re Environment construction and instance vars
- Add warning regarding access to default instance variable values
   during AbstractEnvironment#customizePropertySources callback

 - Polish AbstractEnvironment Javadoc and formatting

Issue: SPR-9013
2012-02-16 21:31:10 +01:00
Chris Beams 41ade68b50 Fix @PropertySource bug with multiple values
Prior to this commit, specifying a named @PropertySource with multiple
values would not work as expected. e.g.:

  @PropertySource(
      name = "ps",
      value = { "classpath:a.properties", "classpath:b.properties" })

In this scenario, the implementation would register a.properties with
the name "ps", and subsequently register b.properties with the name
"ps", overwriting the entry for a.properties.

To fix this behavior, a CompositePropertySource type has been introduced
which accepts a single name and a set of PropertySource objects to
iterate over. ConfigurationClassParser's @PropertySource parsing routine
has been updated to use this composite approach when necessary, i.e.
when both an explicit name and more than one location have been
specified.

Note that if no explicit name is specified, the generated property
source names are enough to distinguish the instances and avoid
overwriting each other; this is why the composite wrapper is not used
in these cases.

Issue: SPR-9127
2012-02-16 18:25:03 +01:00
Juergen Hoeller 6fd476e2c5 extracted ResourceUtils.useCachesIfNecessary(URLConnection) method (SPR-9117) 2012-02-14 21:55:29 +01:00
Juergen Hoeller 2fa87a71fa use custom InputStream traversal instead of a full byte array (SPR-9118) 2012-02-14 21:16:10 +01:00
Juergen Hoeller fe57f74c1a PathMatchingResourcePatternResolver preserves caching for JNLP jar connections (SPR-9117) 2012-02-14 18:26:56 +01:00
Juergen Hoeller 81861ca7a8 Resource "contentLength()" implementations work with OSGi bundle resources and JBoss VFS resources (SPR-9118) 2012-02-14 14:46:45 +01:00
Chris Beams 1d9d3e6ff7 Fix false negative test failure in ResourceTests
Prior to changes in commit 57851de88e,
AbstractResource#getFilename threw IllegalStateException unless
overridden by a subclass. Following that change, this method now throws
null instead, but ResourceTests#testAbstractResourceExceptions had not
been updated to reflect, resulting in a false negative failure. This has
now been fixed.

Issue: SPR-9043
2012-02-13 15:52:37 +01:00
Chris Beams e25f1cbca9 Infer AnnotationAttributes method return types
- Drop 'expectedType' parameter from #getClass and #getEnum methods and
   rely on compiler inference based on type of assigned variable, e.g.

     public @interface Example {
         Color color();
         Class<? extends UserType> userType();
         int order() default 0;
     }

     AnnotationAttributes example =
        AnnotationUtils.getAnnotationAttributes(Example.class, true, true);

     Color color = example.getEnum("color");
     Class<? extends UserType> userType = example.getClass("userType");

   or in cases where there is no variable assignment (and thus no
   inference possible), use explicit generic type, e.g.

     bean.setColor(example.<Color>getEnum("color"));

 - Rename #get{Int=>Number} and update return type from int to
   <N extends Number>, allowing invocations such as:

     int order = example.getNumber("order");

These changes reduce the overall number of methods exposed by
AnnotationAttributes, while at the same time providing comprehensive
access to all possible annotation attribute types -- that is, instead of
requiring explicit #getInt, #getFloat, #getDouble methods, the
single #getNumber method is capabable of handling them all, and without
any casting required. And the obvious additional benefit is more concise
invocation as no redundant 'expectedType' parameters are required.
2012-02-13 15:01:05 +01:00
Juergen Hoeller 9e21d2f741 TypeDescriptor equals implementation accepts annotations in any order (SPR-9084) 2012-02-11 19:15:41 +01:00
Juergen Hoeller 1bd260adaf polishing 2012-02-11 19:15:38 +01:00
Juergen Hoeller 57851de88e clarified Resource's "getFilename" method to consistently return null if resource type does not have a filename (SPR-9043) 2012-02-11 19:15:37 +01:00
Chris Beams 45ad183331 Consider security in ClassUtils#getMostSpecificMethod
Recent changes in ExtendedBeanInfo involve invoking
ClassUtils#getMostSpecificMethod when determining JavaBeans get/set
pairs; if Java security settings control disallow reflective access,
this results in an AccessControlException.

This change defends against this (comparatively rare) scenario by
catching the exception and falling back to returning the method
originally supplied by the user.

This change was a result of noticing CallbacksSecurityTests failing
following the ExtendedBeanInfo modifications mentioned above

Issue: SPR-8949
2012-02-10 00:13:24 +01:00
Juergen Hoeller 0db257cbe3 restored preference for covariant return type if applicable 2012-02-09 12:24:13 +01:00
Juergen Hoeller 35c2869875 INSTANCE constant should be marked as final (SPR-9101) 2012-02-09 11:56:06 +01:00
Juergen Hoeller 4aa8b96687 write method parameter type preferred over read method parameter type for property conversion (fixing regression; SPR-8964) 2012-02-08 17:51:06 +01:00
Juergen Hoeller 17bbc623c1 optimized converter lookup to avoid contention in JDK proxy check (SPR-9084) 2012-02-08 17:08:57 +01:00
Juergen Hoeller c55362c35e Provider injection works with generically typed collections of beans as well (SPR-9030) 2012-02-08 16:29:00 +01:00
Chris Beams d9f7fdd120 Support reading nested annotations via ASM
Background

  Spring 3.1 introduced the @ComponentScan annotation, which can accept
  an optional array of include and/or exclude @Filter annotations, e.g.

     @ComponentScan(
         basePackages = "com.acme.app",
         includeFilters = { @Filter(MyStereotype.class), ... }
     )
     @Configuration
     public class AppConfig { ... }

  @ComponentScan and other annotations related to @Configuration class
  processing such as @Import, @ImportResource and the @Enable*
  annotations are parsed using reflection in certain code paths, e.g.
  when registered directly against AnnotationConfigApplicationContext,
  and via ASM in other code paths, e.g. when a @Configuration class is
  discovered via an XML bean definition or when included via the
  @Import annotation.

  The ASM-based approach is designed to avoid premature classloading of
  user types and is instrumental in providing tooling support (STS, etc).

  Prior to this commit, the ASM-based routines for reading annotation
  attributes were unable to recurse into nested annotations, such as in
  the @Filter example above. Prior to Spring 3.1 this was not a problem,
  because prior to @ComponentScan, there were no cases of nested
  annotations in the framework.

  This limitation manifested itself in cases where users encounter
  the ASM-based annotation parsing code paths AND declare
  @ComponentScan annotations with explicit nested @Filter annotations.
  In these cases, the 'includeFilters' and 'excludeFilters' attributes
  are simply empty where they should be populated, causing the framework
  to ignore the filter directives and provide incorrect results from
  component scanning.

  The purpose of this change then, is to introduce the capability on the
  ASM side to recurse into nested annotations and annotation arrays. The
  challenge in doing so is that the nested annotations themselves cannot
  be realized as annotation instances, so must be represented as a
  nested Map (or, as described below, the new AnnotationAttributes type).

  Furthermore, the reflection-based annotation parsing must also be
  updated to treat nested annotations in a similar fashion; even though
  the reflection-based approach has no problem accessing nested
  annotations (it just works out of the box), for substitutability
  against the AnnotationMetadata SPI, both ASM- and reflection-based
  implementations should return the same results in any case. Therefore,
  the reflection-based StandardAnnotationMetadata has also been updated
  with an optional 'nestedAnnotationsAsMap' constructor argument that is
  false by default to preserve compatibility in the rare case that
  StandardAnnotationMetadata is being used outside the core framework.
  Within the framework, all uses of StandardAnnotationMetadata have been
  updated to set this new flag to true, meaning that nested annotation
  results will be consistent regardless the parsing approach used.

  Spr9031Tests corners this bug and demonstrates that nested @Filter
  annotations can be parsed and read in both the ASM- and
  reflection-based paths.

Major changes

 - AnnotationAttributes has been introduced as a concrete
   LinkedHashMap<String, Object> to be used anywhere annotation
   attributes are accessed, providing error reporting on attribute
   lookup and convenient type-safe access to common annotation types
   such as String, String[], boolean, int, and nested annotation and
   annotation arrays, with the latter two also returned as
   AnnotationAttributes instances.

 - AnnotationUtils#getAnnotationAttributes methods now return
   AnnotationAttributes instances, even though for binary compatibility
   the signatures of these methods have been preserved as returning
   Map<String, Object>.

 - AnnotationAttributes#forMap provides a convenient mechanism for
   adapting any Map<String, Object> into an AnnotationAttributes
   instance. In the case that the Map is already actually of
   type AnnotationAttributes, it is simply casted and returned.
   Otherwise, the map is supplied to the AnnotationAttributes(Map)
   constructor and wrapped in common collections style.

 - The protected MetadataUtils#attributesFor(Metadata, Class) provides
   further convenience in the many locations throughout the
   .context.annotation packagage that depend on annotation attribute
   introspection.

 - ASM-based core.type.classreading package reworked

   Specifically, AnnotationAttributesReadingVisitor has been enhanced to
   support recursive reading of annotations and annotation arrays, for
   example in @ComponentScan's nested array of @Filter annotations,
   ensuring that nested AnnotationAttributes objects are populated as
   described above.

   AnnotationAttributesReadingVisitor has also been refactored for
   clarity, being broken up into several additional ASM
   AnnotationVisitor implementations. Given that all types are
   package-private here, these changes represent no risk to binary
   compatibility.

 - Reflection-based StandardAnnotationMetadata updated

   As described above, the 'nestedAnnotationsAsMap' constructor argument
   has been added, and all framework-internal uses of this class have
   been updated to set this flag to true.

Issue: SPR-7979, SPR-8719, SPR-9031
2012-02-07 21:57:49 +01:00
Chris Beams 41c405998e Convert CRLF=>LF on files missed earlier
Complete pass with `dos2unix` found additional files missed on earlier
related commit.

Issue: SPR-5608
2011-12-22 14:06:44 +01:00
Chris Beams 88913f2b23 Convert CRLF (dos) to LF (unix)
Prior to this change, roughly 5% (~300 out of 6000+) of files under the
source tree had CRLF line endings as opposed to the majority which have
LF endings.

This change normalizes these files to LF for consistency going forward.

Command used:

$ git ls-files | xargs file | grep CRLF | cut -d":" -f1 | xargs dos2unix

Issue: SPR-5608
2011-12-21 14:52:47 +01:00
Chris Beams 153d38f1c8 Polish Javadoc 2011-12-12 23:42:39 +00:00
Chris Beams 48836e2ebb Allow parameters in FactoryBean-returning @Bean methods
Prior to this change, an assumption was made in
AbstractAutowireCapableBeanFactory that any factory-method would have
zero parameters.  This may not be the case in @Bean methods.

We now look for the factory-method by name in a more flexible fashion
that accomodates the possibility of method parameters.

There remains at least one edge cases here where things could still fail,
for example a @Configuration class could have two FactoryBean-returning
methods of the same name, but each with different generic FactoryBean
types and different parameter lists. In this case, the implementation
may infer and return the wrong object type, as it currently returns
the first match for the given factory-method name.  The complexity cost
of ensuring that this never happens is not likely worth the trouble
given the very low likelihood of such an arrangement.

Issue: SPR-8762
2011-12-10 19:32:02 +00:00
Chris Beams 06d06d4aa9 Mention SystemEnvironmentPropertySource in related Javadoc
Issue: SPR-8869
2011-12-10 19:30:57 +00:00
Juergen Hoeller 569426dfdf restored DataBinder's ability to bind to an auto-growing List with unknown element type (SPR-8828) 2011-12-07 21:27:26 +00:00
Juergen Hoeller e0d922d352 ConversionService is able to work with "Collections.emptyList()" as target type (again; SPR-7293) 2011-12-06 21:17:25 +00:00
Juergen Hoeller 33b53b7cca alignment with 3.0.7 backports (SPR-8674) 2011-12-01 18:51:36 +00:00
Juergen Hoeller 71e0a506b9 polishing 2011-12-01 15:12:26 +00:00
Juergen Hoeller dc41daa3db renamed 'isJava6VisibilityBridgeMethodPair' to 'isVisibilityBridgeMethodPair' (SPR-8660) 2011-12-01 13:14:06 +00:00
Juergen Hoeller ffa4784628 polishing (SPR-8005) 2011-12-01 12:53:47 +00:00
Sam Brannen 951514a576 removed unused imports 2011-11-29 21:29:15 +00:00
Juergen Hoeller d6d169ac56 resolved package dependency tangles 2011-11-29 01:16:09 +00:00
Juergen Hoeller fa9a7b18c6 refined Resource "exists()" check for HTTP URLs to always return false for 404 status (SPR-7881) 2011-11-28 21:11:57 +00:00
Juergen Hoeller b391629de1 LinkedCaseInsensitiveMap overrides putAll method as well (for IBM JDK 1.6 compatibility; SPR-7969) 2011-11-28 20:48:02 +00:00
Juergen Hoeller aa7fcb5431 polishing 2011-11-28 18:38:26 +00:00
Chris Beams c6a0f1ef25 Polish logging for core.env package 2011-11-26 05:20:32 +00:00
Chris Beams 143db0d8de Introduce SystemEnvironmentPropertySource
Properties such as 'spring.profiles.active' cannot be specified at the
command line under Bash and other shells due to variable naming
constraints. This change allows for exchanging underscores for periods
as well as capitalizing property names for more idiomatic naming when
dealing with environment variables.

For example, Spring will respect equally either of the following:

    spring.profiles.active=p1 java -classpath ... MyApp

    SPRING_PROFILES_ACTIVE=p1 java -classpath ... MyApp

The former is not possible under Bash, while the latter is. No code or
configuration changes are required; SystemEnvironmentPropertySource
adapts for these varations automatically.

SystemEnvironmentPropertySource is added by default as
"systemEnvironment" to StandardEnvironment and all subtypes, taking the
place of the plain MapPropertySource that was in use before this change.

Issue: SPR-8869
2011-11-26 05:20:25 +00:00
Chris Beams 2c26a23c46 Rename EnvironmentTests => StandardEnvironmentTests 2011-11-26 05:20:20 +00:00
Chris Beams a53d592f62 Use 'name' vs 'key' consistently in PropertySource 2011-11-26 05:20:17 +00:00
Rossen Stoyanchev b5bcfa0ae3 SPR-8858 Fix in AntPathMatcher.combine(..)
Currently the combine method consolidates "/*" and "/hotel" 
into "/hotel". However if the first pattern contains URI template 
variables, the consolidation seems wrong. The fix is to prevent
the consolidation if the first pattern contains "{".
2011-11-23 17:53:18 +00:00
Juergen Hoeller e2d9142c5a LocaleEditor and StringToLocaleConverter do not restrict variant part through validation (SPR-8637) 2011-10-20 11:53:02 +00:00
Juergen Hoeller 0c9e3fb3bd polishing 2011-10-20 11:21:54 +00:00
Juergen Hoeller 36616a0c2c fixed GenericTypeResolver to consistently return null if not resolvable (SPR-8698) 2011-10-20 11:17:42 +00:00
Juergen Hoeller f7b9eb8fe3 added proper "contentLength()" implementation to ByteArrayResource (SPR-8709) 2011-10-20 10:59:44 +00:00
Juergen Hoeller 0dfb617d8a refer to correct openSession() method for Hibernate 4.0 (SPR-8776) 2011-10-20 10:23:49 +00:00