Compare commits

..

1119 Commits

Author SHA1 Message Date
Arjen Poutsma 379fdcb27b Released Spring Framework 3.0.0-M3 2009-05-06 13:00:45 +00:00
Juergen Hoeller bc85b54a87 final preparations for M3 release 2009-05-06 10:16:17 +00:00
Keith Donald 843ef7e33d convert addition 2009-05-06 09:57:29 +00:00
Keith Donald 08a4004a51 embedded db support 2009-05-06 09:28:10 +00:00
Keith Donald 4bfcd16130 polish 2009-05-06 09:14:25 +00:00
Juergen Hoeller 0320445316 moved ScheduledTaskRegistrar to new config package (where the scheduling namespace will live as well) 2009-05-06 08:47:18 +00:00
Keith Donald 6771a22988 polish 2009-05-06 08:38:47 +00:00
Keith Donald c25760f5db polish 2009-05-06 08:19:21 +00:00
Keith Donald f64dcd379e polish 2009-05-06 08:17:29 +00:00
Keith Donald 567dd1eefb package 2009-05-06 08:04:29 +00:00
Keith Donald 442e7343d6 polish 2009-05-06 07:56:52 +00:00
Sam Brannen d159195b79 [SPR-5145] Updated package.html files regarding upgrade to JUnit 4.5. 2009-05-06 07:37:25 +00:00
Keith Donald bc9ad5685d eliminated dependency on jdbc core 2009-05-06 07:36:24 +00:00
Sam Brannen c0c9501005 [SPR-5145] Updated reference manual regarding upgrade to JUnit 4.5; additional improvements in the testing chapter as well. 2009-05-06 06:25:03 +00:00
Sam Brannen 94ceacf843 Reinserted blank line for consistent formatting of the change log. 2009-05-06 05:03:20 +00:00
Sam Brannen 1ec455bab3 Added TestContext framework changes to the change log. 2009-05-06 05:01:05 +00:00
Juergen Hoeller b2319fa38b reactivated ThrowsAdviceInterceptorTests 2009-05-05 21:49:23 +00:00
Juergen Hoeller c356d99621 prepared for 3.0 M3 release 2009-05-05 21:42:33 +00:00
Juergen Hoeller 1b5a433f22 added ScheduledTaskRegistrar etc 2009-05-05 18:40:43 +00:00
Juergen Hoeller 47fc8be59f added test for custom controller stereotype 2009-05-05 18:37:43 +00:00
Juergen Hoeller c7f8d1be62 reactivated ignored tests in revised form 2009-05-05 18:34:35 +00:00
Juergen Hoeller 636d1db36d avoid NPE for definitions without bean class specified 2009-05-05 18:33:20 +00:00
Juergen Hoeller b88edd1dfc polishing 2009-05-05 18:28:21 +00:00
Juergen Hoeller e57543a8f3 turned CountingBeforeAdvice into top-level class 2009-05-05 18:27:22 +00:00
Juergen Hoeller 250ef281a4 reverted non-public proxy interface change 2009-05-05 14:53:01 +00:00
Arjen Poutsma 9fe2b5d211 Moved DefaultHandlerExceptionResolver to fix a tangle. 2009-05-05 13:41:03 +00:00
Juergen Hoeller cef7a2b965 exclude non-public interfaces when autodetecting proxy interfaces 2009-05-05 12:37:18 +00:00
Juergen Hoeller 9d8c99fa1b minimized local MockServletContext dependencies 2009-05-05 12:35:33 +00:00
Juergen Hoeller d446afad33 added local Servlet API mocks 2009-05-05 12:26:11 +00:00
Juergen Hoeller b15e77d5d0 renamed "contextProperties" attribute to "contextParameters" (matching web.xml naming); "contextParameters" contains Servlet/PortletConfig parameters as well; added default "servletContext" and "servletConfig" environment beans; added default "portletContext" and "portletConfig" environment beans; added default web scope "application", wrapping a ServletContext/PortletContext; MockPortletSession supports destruction of session attributes on invalidation 2009-05-05 12:12:01 +00:00
Arjen Poutsma 0a0938fdd6 SPR-5426 - Allow for custom processing or result objects returned from handler/controller methods 2009-05-05 11:40:36 +00:00
Juergen Hoeller a6124793fc polishing 2009-05-05 09:36:53 +00:00
Juergen Hoeller 6930859e82 removed StandardScopes pseudo-enum (superseded by meta-annotated scopes) 2009-05-05 09:32:55 +00:00
Juergen Hoeller 9b4f9106c5 polishing 2009-05-05 09:26:04 +00:00
Sam Brannen 9daae23e17 [SPR-5145] Updated reference manual regarding deprecation of the legacy JUnit 3.8 code base.
[SPR-5713] Updated reference manual with an example demonstrating the new 'value' alias for @ContextConfiguration's 'locations' attribute.
2009-05-05 08:02:22 +00:00
Sam Brannen 781da89d92 [SPR-5713] Added 'value' alias for @ContextConfiguration's 'locations' attribute. 2009-05-05 07:37:14 +00:00
Sam Brannen a6a8b29d19 Fixed typo in JavaDoc 2009-05-04 06:02:59 +00:00
Sam Brannen a637912762 [SPR-5710] Subclasses of SpringJUnit4ClassRunner can now override the default ContextLoader class via the new getDefaultContextLoaderClassName(Class) method. 2009-05-02 23:24:48 +00:00
Thomas Risberg 0383f705ae clean-up of the @Bean content 2009-05-01 20:14:23 +00:00
Thomas Risberg 05f1d08028 re-arranged the @Bean content 2009-05-01 19:48:08 +00:00
Thomas Risberg b1577c28e2 removed some JavaConfig references 2009-04-30 04:35:30 +00:00
Thomas Risberg 9aaea34262 fixed DOCTYPE to refer to the root_element used 2009-04-30 04:16:07 +00:00
Sam Brannen 62c991f9d6 [SPR-5145] Updated reference manual regarding upgrade to JUnit 4.5; additional improvements in the testing chapter as well. 2009-04-30 01:04:39 +00:00
Sam Brannen 17858915ab Corrected grammar and spelling mistakes in reference manual. 2009-04-30 01:03:44 +00:00
Sam Brannen db486e147b Added Eclipse project settings to the reference documentation so that the documentation can be more easily edited and built within Eclipse. 2009-04-30 00:59:09 +00:00
Sam Brannen d3af831334 Now parameterizing with <?> where appropriate. 2009-04-30 00:58:08 +00:00
Sam Brannen 6327b3484b [SPR-5145] Improved test suite for SpringJUnit4ClassRunner: added specific unit tests for test timeouts, repeated tests, and expected exceptions. 2009-04-29 21:29:53 +00:00
Thomas Risberg 41423a9ab9 added some JavaConfig content 2009-04-29 21:14:01 +00:00
Thomas Risberg 15b33684a7 fixed JavaDoc 2009-04-29 21:12:45 +00:00
Sam Brannen 0fbafc0274 Removed unused package. 2009-04-29 19:01:39 +00:00
Sam Brannen 751e0f0eb7 [SPR-5145] Completed migration to JUnit 4.5: SpringJUnit4ClassRunner now extends BlockJUnit4ClassRunner and uses custom Statements; removed obsolete SpringMethodRoadie and SpringTestMethod classes. 2009-04-29 08:21:23 +00:00
Sam Brannen b36f95bcee Corrected typos and sorted Eclipse classpath. 2009-04-28 21:45:14 +00:00
Sam Brannen e5d2570c8d [SPR-5145] Adding custom JUnit 4.5 Statements. 2009-04-28 07:29:24 +00:00
Juergen Hoeller 8583026151 revised target class check for non-Spring CGLIB proxy variants (SPR-5694) 2009-04-27 22:54:39 +00:00
Juergen Hoeller a2fdb68a0b fixed potential race condition through additional synchronization (SPR-5658) 2009-04-27 22:53:40 +00:00
Sam Brannen 2796e72de1 Updated JavaDoc for @TestExecutionListeners. 2009-04-27 22:49:34 +00:00
Mark Pollack 30967d3b20 Update docs to use of @Bean inside a @Component 2009-04-27 05:40:11 +00:00
Mark Pollack c2f4f97fa5 Update docs to use of @Bean inside a @Component 2009-04-27 05:37:45 +00:00
Juergen Hoeller cea8f7f69e custom stereotype annotations can be meta-annotated with @Service, @Controller etc as well; @Scope and @Transactional are now supported as meta-annotations on custom annotations 2009-04-26 11:41:06 +00:00
Juergen Hoeller ac16101f98 polishing 2009-04-26 11:39:00 +00:00
Juergen Hoeller 423809543a polishing 2009-04-24 11:25:27 +00:00
Juergen Hoeller 77112ba80e updated AnnotationMetadata tests for change in Class exposure 2009-04-24 11:24:47 +00:00
Juergen Hoeller b5d21108da @Configuration parsing fully relies on Spring's MetadataReader abstraction now 2009-04-24 11:16:46 +00:00
Keith Donald 37e1333a41 polish 2009-04-23 19:01:41 +00:00
Keith Donald 3a457dcec9 embedded database factory bean 2009-04-23 18:56:26 +00:00
Scott Andrews f6e869163f updating Eclipse .classpath settings for Freemarker 2.3.15 upgrade 2009-04-23 14:13:03 +00:00
Keith Donald eb4d1bf20e deleted old test data source factory 2009-04-22 21:29:47 +00:00
Keith Donald d896a53ca8 polish 2009-04-22 21:16:22 +00:00
Keith Donald adcbe27852 added pre destroy 2009-04-22 21:14:06 +00:00
Keith Donald e783211f88 polish 2009-04-22 19:41:27 +00:00
Keith Donald ec463a32ba added DataSourceFactory strategy; promoted EmbeddedDatabaseConfigurer strategy to public API; added ability to add any number of SQL scripts for db population 2009-04-22 19:31:46 +00:00
Andy Clement d34a2c5d02 SPR-5663: test and fix: inconsistency between canRead() and read() on ReflectivePropertyResolver 2009-04-22 17:57:24 +00:00
Keith Donald b1000cd5c6 embedded 2009-04-22 17:47:44 +00:00
Keith Donald 2e45a19be3 embedded database support initial commit; moved from spring-test; ResourceDatabasePopulator duplicate code with test.jdbc package that needs review 2009-04-22 17:07:20 +00:00
Arjen Poutsma 6fbd198420 SPR-4518 - @RequestMapping methods returning null have an implicit ModelAndView created 2009-04-22 12:57:30 +00:00
Arjen Poutsma c1667687d5 SPR-5634 - OXM does not permit targetClass and mapping file for CastorMarshaller 2009-04-22 12:08:57 +00:00
Arjen Poutsma de18d64b5c Upgraded to Rome 1.0 2009-04-22 11:44:59 +00:00
Juergen Hoeller ea9d8925a2 next cut of JavaConfig metadata reading revision: using cached MetadataReaders 2009-04-22 10:46:24 +00:00
Andy Clement 4c42597cbc SPR-5673: fix for problems with expressions that use the same symbols as are used in the template prefix/suffix 2009-04-22 00:10:47 +00:00
Arjen Poutsma dfa4b3e397 Javadoc 2009-04-21 22:16:32 +00:00
Arjen Poutsma afa461892f SPR-5690 - Request header filtering in @RequestMapping 2009-04-21 22:03:51 +00:00
Keith Donald b8b74db01a test datasource factory initial commit; needs review from Juergen on how to best make DataSource available as a Spring bean when desired 2009-04-21 21:31:16 +00:00
Chris Beams 4d509cebdb Temporarily ignoring GroovyScriptFactoryTests#testResourceScriptFromTag in order to allow more important fixes to roll out. 2009-04-21 18:14:08 +00:00
Chris Beams 7ba4c563a6 Fixing build breakage with GroovyScriptFactoryTests.
The problem was that the Messenger object was not being proxed (assertTrue(AopUtils.isAopProxy(messenger)) was returning false).  The cause for this seemed to be that the
pointcut was malformed / out of date, reading execution(* org.springframework.scripting.Messenger.*(..)), when the groovy Messenger class is actually declared in the org.springframework.scripting.groovy package.
I tried updating the fully-qualified package name in the pointcut expression, and this caused AspectJ matching errors saying that there was not such type that matches that FQ name.
So as a final resort, I removed the full-qualification entirely and went with execution(* *..Messenger.*(..)).  All tests pass now, but it raises the question, why was AJ having matching errors?  Is it because
the pointcut matching is being done before the groovy class is loaded?  There could be a potential bug here.
2009-04-21 17:20:39 +00:00
Chris Beams 7d10d05b27 (temporarily) increasing visibility of the ConfigurationClassAnnotation interface in an attempt to resolve the issue encountered at http://is.gd/tCud 2009-04-21 16:24:54 +00:00
Arjen Poutsma dc90319279 MediaType.parseMediaTypes now accepts null and "" 2009-04-21 13:41:15 +00:00
Ben Hale 6be62f30f1 Updated spring-build 2009-04-20 12:16:50 +00:00
Juergen Hoeller 10d8abea3b EntityResolvers and DefaultNamespaceHandlerResolver support concurrent access now (SPR-5679) 2009-04-20 12:07:00 +00:00
Juergen Hoeller e54a44b577 refined sequence of registration calls 2009-04-20 11:20:01 +00:00
Juergen Hoeller 9306d6dbaa serialize full Pattern objects 2009-04-20 11:14:28 +00:00
Juergen Hoeller 14bd475519 revised support for annotated factory methods (merged @FactoryMethod functionality into JavaConfig facility) 2009-04-19 23:45:31 +00:00
Juergen Hoeller 736169aa2a revised WebApplicationContext lookup 2009-04-19 22:28:31 +00:00
Juergen Hoeller 4cf573ba98 updated to FreeMarker 2.3.15 (SPR-4962) 2009-04-19 22:22:56 +00:00
Juergen Hoeller 58a458986f polishing 2009-04-19 20:36:33 +00:00
Juergen Hoeller 64321755b6 moved Scope annotation to local test package 2009-04-19 20:35:32 +00:00
Juergen Hoeller c230c188be exposed public getModel accessor (SPR-5686) 2009-04-19 19:51:25 +00:00
Juergen Hoeller bc9b256179 fixed "org.hibernate.ejb" version range 2009-04-19 19:36:26 +00:00
Juergen Hoeller 1b9b513820 AspectJ matchesMethodExecution call needs to be synchronized (SPR-5687) 2009-04-19 19:33:23 +00:00
Arjen Poutsma 6495bdd8c8 Added AspectJ dependency 2009-04-18 09:06:04 +00:00
Chris Beams c78f9d14fa Fixed whitespace and added private modifiers to @Value-annotated fields in the @Configuration example 2009-04-18 00:22:03 +00:00
Thomas Risberg 8aface8e5d fixed JavaDoc 2009-04-17 19:43:11 +00:00
Juergen Hoeller 3e63951a57 relaxed @AspectJ detection check (for CGLIB subclasses to still be recognized as an aspect) 2009-04-17 17:32:29 +00:00
Juergen Hoeller 56a48272e6 avoiding synchronization as far as possible (SPR-5668) 2009-04-17 17:28:31 +00:00
Juergen Hoeller 7048689269 polishing 2009-04-17 17:23:50 +00:00
Juergen Hoeller 8ee0363776 mergePropertiesIntoMap copies non-String values as well (SPR-5669) 2009-04-17 12:21:57 +00:00
Arjen Poutsma c225b44f34 SPR-5636 - @RequestMapping matching should be insensitive to trailing slashes 2009-04-17 09:41:04 +00:00
Arjen Poutsma acc84925d3 SPR-5631 - Implicit /** mapping on type-level @RequestMapping 2009-04-17 09:28:08 +00:00
Arjen Poutsma 02e96e01af Changed variable names from path to pattern 2009-04-17 08:26:18 +00:00
Andy Clement b98c7e48ef filled in some basic details on the type conversion support. No TODOs left in this section now. Also properly added the selection/projection sections. 2009-04-17 05:14:07 +00:00
Andy Clement 9d6ae6c532 minor fix 2009-04-17 05:02:05 +00:00
Andy Clement d119411098 removed unnecessary class. improvements to map projection/selection 2009-04-16 19:21:50 +00:00
Arjen Poutsma 1c26d027a7 Increased debug level of mapping info 2009-04-16 13:25:46 +00:00
Arjen Poutsma 6121da988b Working on SPR-5631 - Implicit /** mapping on type-level @RequestMapping 2009-04-16 13:23:24 +00:00
Scott Andrews 4fb901c657 adding 'target' to svn:ignore 2009-04-16 13:23:17 +00:00
Arjen Poutsma ead837938a Added Copyright plugin info 2009-04-16 13:20:33 +00:00
Arjen Poutsma 19e5b7d668 Updated combine method on AntPatchMatcher to reflect usage in unit tests. 2009-04-16 12:53:36 +00:00
Andy Clement 2f27bd5da7 changed to [] from {} for projection and selection (including first and last selection). addresses the problem of clashes with template prefix/suffix 2009-04-15 23:54:52 +00:00
Juergen Hoeller d27cbee69c fixed JasperReports exporter parameter initialization for multi-format views 2009-04-15 23:18:57 +00:00
Juergen Hoeller 310a3a2d71 officially deprecated ClassUtils.forName variant without ClassLoader 2009-04-15 22:33:56 +00:00
Juergen Hoeller 2798a8500c always use application ClassLoader 2009-04-15 22:30:24 +00:00
Juergen Hoeller 1b5812da20 storing type information as specified (SPR-5556, SPR-5562); explicit XML array element in spring-beans-3.0.xsd (SPR-5543) 2009-04-15 22:27:32 +00:00
Arjen Poutsma 5a561bcd07 Minor changes to OXM chapter 2009-04-15 10:11:52 +00:00
Thomas Risberg 1facd45c5e switched to use XInclude 2009-04-14 21:37:40 +00:00
Andy Clement 338a7ee2de SPR-5673: more intelligence in TemplateAwareExpressionParser. Supports prefix/suffix escaping and nesting of prefixes/suffixes 2009-04-14 21:26:56 +00:00
Thomas Risberg 298a5c4a8b rearranged content in "New in Spring 3.0" 2009-04-14 17:24:56 +00:00
Thomas Risberg ab52fdf07b added/modified some links 2009-04-14 14:12:28 +00:00
Ben Hale 6fc16d1e33 [SPR-5675] Added spring-expressions to the library file 2009-04-14 13:18:35 +00:00
Ben Hale af2e117244 [DMSSUP-8] Removed import-scope:=application for aspectj 2009-04-14 08:23:48 +00:00
Mark Pollack 823cc6e691 polishing 2009-04-14 07:07:01 +00:00
Mark Pollack aa36118e1c Finish REST docs, add docs for @FactoryMethod, add links in 'new-in-3' 2009-04-14 06:59:22 +00:00
Thomas Risberg 0c5ab54dce added more content to new in Spring 3 2009-04-14 04:43:15 +00:00
Thomas Risberg a4b1adbc60 fixed typo of language 2009-04-14 04:35:40 +00:00
Thomas Risberg 0e77054854 added content to new in Spring 3 2009-04-14 04:02:10 +00:00
Mark Pollack 7f06639be2 Add REST feed view docs, included edits from Thomas R. 2009-04-13 22:11:15 +00:00
Andy Clement 2f5ba83416 more tests - about 82% coverage now. focused on testing reflection helper since it is rather complex. some asserts also added. 2009-04-13 20:51:52 +00:00
Thomas Risberg 19ec3654df added the rest chapter to the build 2009-04-13 17:46:21 +00:00
Thomas Risberg 38e5deefda added language element to programlisting for syntax highlighting 2009-04-13 15:04:07 +00:00
Thomas Risberg 077d7f4bce added language element to programlisting for syntax highlighting 2009-04-13 14:27:47 +00:00
Thomas Risberg f4b4f28fc2 added language element to programlisting for syntax highlighting 2009-04-13 13:12:38 +00:00
Colin Sampaleanu b7ab939d55 forgot to update eclipse project when updating hibernate versions 2009-04-13 05:25:57 +00:00
Colin Sampaleanu dc592837be allow petclinic unit tests to work. slf4j impl was needed 2009-04-13 05:23:44 +00:00
Colin Sampaleanu 31f61628ff updte hibernate dependencies in integration-test project to same as
those in orm project
2009-04-13 05:03:55 +00:00
Juergen Hoeller ee5e76c48c officially deprecated AbstractJpaTests 2009-04-12 21:16:12 +00:00
Juergen Hoeller 9baf9cdc2f reintroduced "removeApplicationListener" method as well 2009-04-12 20:59:52 +00:00
Andy Clement af6457a67d More tests. First pass on messages review. 2009-04-12 16:45:00 +00:00
Costin Leau f6ecffdba7 + osgi manifest updates 2009-04-11 20:57:09 +00:00
Mark Pollack d16d8984a8 REST documentation 2009-04-11 05:59:12 +00:00
Mark Pollack 4fc77944ad More REST documentation 2009-04-11 04:49:11 +00:00
Keith Donald 5a87334168 made conversion service pluggable 2009-04-10 20:52:16 +00:00
Keith Donald 1d22b9fb88 activated DefaultConversionService in EL, linking convert and EL 2009-04-10 20:47:04 +00:00
Keith Donald 8b52b7eeef autobox tests 2009-04-10 19:19:53 +00:00
Keith Donald ebb203a251 removed custom converter for m3 to add back in rc1; also ensure type descriptor get type always returns wrapper types if primitive 2009-04-10 15:57:18 +00:00
Keith Donald b988f1a539 javadoc 2009-04-10 15:21:16 +00:00
Keith Donald 76f63f8b64 map-to-map tests 2009-04-10 15:07:23 +00:00
Juergen Hoeller 5649f2f31d fixed generic registerCustomEditor signature 2009-04-10 13:44:23 +00:00
Juergen Hoeller 20fc42add0 avoid PortletSession.getAttributeMap() since it is immutable (SPR-5649) 2009-04-10 10:51:45 +00:00
Andy Clement 38c7f566e5 Fixed StandardTypeLocator to only know about java.lang.* out of the box. Doc fixes related to that. 2009-04-10 03:20:09 +00:00
Andy Clement f36b9eb088 finally some comparator logic that makes sense :) 2009-04-10 02:21:25 +00:00
Andy Clement 46c5340f57 More tests, corrections in standard comparator, more helper methods in StandardEvaluationContext. 2009-04-10 00:03:53 +00:00
Andy Clement ba613f2e35 allow for null 2009-04-09 22:04:08 +00:00
Andy Clement 00cecd0dd0 more tests, minor fixes. some findbugs issues addressed. 2009-04-09 22:03:38 +00:00
Juergen Hoeller a9f4eeeabf fixed javadoc 2009-04-09 18:24:07 +00:00
Juergen Hoeller 73dd6c28a3 reintroduced "removeAllListeners()" method since Spring DM uses it 2009-04-09 18:18:54 +00:00
Andy Clement 707d2ed72a Changed signature of convertValue() to keep the Sun compiler happy 2009-04-09 16:00:53 +00:00
Mark Pollack 362629d03b Change version from 3.0.0.M3 to 3.0.0.BUILD-SNAPSHOT (again) 2009-04-09 14:38:35 +00:00
Keith Donald 3e4810f670 polish 2009-04-09 14:09:10 +00:00
Keith Donald a0cab10ccc polish 2009-04-09 14:01:40 +00:00
Arjen Poutsma 7e3e79ca22 SPR-5653: RestTemplate handles redirects incorrectly 2009-04-09 11:03:35 +00:00
Juergen Hoeller 859497b171 @Resource names may use ${...} placeholders (SPR-5656) 2009-04-09 09:14:06 +00:00
Andy Clement 3cac9267e9 Commented out the sections on list projection and #this. 2009-04-09 05:44:35 +00:00
Andy Clement f20dcf275f Corrected some typos, code samples and changed a bit of wording. All code samples are now SpEL testcases. 2009-04-09 01:56:34 +00:00
Andy Clement 9a8bb5f709 More tests and some fixes. Also created tests based on the documentation examples. 2009-04-09 01:43:07 +00:00
Keith Donald 9ce71f67ff conversion service helper tests - part 1 2009-04-08 22:10:26 +00:00
Keith Donald d966965a4c default converter tests 2009-04-08 19:58:19 +00:00
Mark Pollack 5e46fab34d Start of REST documentation 2009-04-08 19:29:02 +00:00
Mark Pollack b132e964be add paragraph on SpEL, reorganize section layout. 2009-04-08 14:06:01 +00:00
Thomas Risberg a3cbb05ed5 added language element to programlisting for syntax highlighting 2009-04-08 13:38:36 +00:00
Andy Clement cfc65b0cc7 Removed unnecessary code. Increased test coverage from 70>75% - still some way to go 2009-04-08 04:50:43 +00:00
Andy Clement 30bed7b54a Corrected exception message inserts 2009-04-08 04:49:47 +00:00
Andy Clement 4a7f7bb24a more tests 2009-04-08 04:48:35 +00:00
Andy Clement 76fcc81bc6 New method to return string representation of typeDescriptor 2009-04-08 04:47:54 +00:00
Mark Pollack f917ba89d6 Spring Expression Language docs 2009-04-08 03:37:28 +00:00
Thomas Risberg fc899e5881 added spring leaf for notes 2009-04-07 22:12:31 +00:00
Thomas Risberg 51526d6541 added JMS to overview 2009-04-07 17:30:44 +00:00
Thomas Risberg fb8ec6ed97 added some styling and color coded syntax highlighting to beans chapter 2009-04-07 16:54:36 +00:00
Mark Pollack 5f5bee1022 Spring Expression Language docs 2009-04-07 04:45:05 +00:00
Mark Pollack 1f00e639e0 Spring Expression Language docs 2009-04-07 04:42:51 +00:00
Chris Beams d08d73f274 Renamed ConfigurationPostProcessorTests -> ConfigurationClassPostProcessorTests 2009-04-06 21:29:30 +00:00
Chris Beams 254bf7e403 Fixed SPR-5655 - dm Server issues with ConfigurationClassPostProcessor attempting to read .class files with ASM with incorrect class loader 2009-04-06 21:23:37 +00:00
Thomas Risberg b14d760c9b an outline of the Getting Started chapter 2009-04-06 20:10:04 +00:00
Chris Beams e500348ca7 Fixed mystyped dependency on org.antlr 3.0.1 in context's Eclipse .classpath 2009-04-06 19:43:41 +00:00
Thomas Risberg eb90bbeadc added the OXM chapter from Spring WS 2009-04-06 19:43:18 +00:00
Andy Clement a9f30fe377 Improving test coverage, more language consistency 2009-04-06 19:04:04 +00:00
Thomas Risberg 55bdd07580 revised overview graphics to match new modules 2009-04-06 16:12:50 +00:00
Mark Pollack f64bedb9e1 Polishing. Add description of literal expressions. 2009-04-05 16:25:26 +00:00
Mark Pollack 51f741ccec Initial pass of docs for he Spring expression language. 2009-04-05 09:38:19 +00:00
Andy Clement c695d00dbe More test coverage for the expression AST 2009-04-04 01:04:31 +00:00
Andy Clement c4de2ba006 include missing package component 2009-04-04 00:06:01 +00:00
Andy Clement 4c5854d017 objects flowing around in expression evaluation are now TypedValue's - these carry generics info, used for conversions. 2009-04-03 23:39:14 +00:00
Andy Clement f6c1144e8d tests for TypeDescriptor - just basic so far 2009-04-03 23:38:31 +00:00
Andy Clement bdecf6720e extra factory method and type descriptor for NULL defined 2009-04-03 23:38:18 +00:00
Andy Clement 5a0522e203 fixed support for -1 parameterIndex to access the method return type 2009-04-03 23:37:59 +00:00
Thomas Risberg aced98bf23 added reference docs to the build 2009-04-03 15:59:02 +00:00
Mark Pollack 8fba89c634 Change antlr version to be 3.0.1 so that is consistent across the project 2009-04-03 14:31:25 +00:00
Mark Pollack 8f76197485 Change version from 3.0.0.M3 to 3.0.0.BUILD-SNAPSHOT 2009-04-03 14:03:48 +00:00
Arjen Poutsma 07e6d9d966 More refinements for combine() 2009-04-03 11:35:18 +00:00
Arjen Poutsma 5dbae2c979 More tests for combine() 2009-04-03 11:14:37 +00:00
Arjen Poutsma 56ddc76712 Added combine method to PathMatcher, for combining two patterns. 2009-04-03 10:44:57 +00:00
Thomas Risberg 6e7e107621 mostly changes to Preface and Introduction chapters 2009-04-03 04:08:08 +00:00
Andy Clement 959cc95c3f design change - no longer surfacing typeDescriptor through property accessor. conversion done internally in property write() code 2009-04-01 23:27:49 +00:00
Andy Clement 00018e511d implement new interface method 2009-04-01 21:58:24 +00:00
Andy Clement 1289f1069c new packages added 2009-04-01 21:47:35 +00:00
Andy Clement 54865c0c1f initial typeDescriptor awareness in the EL. some basic testing of using GenericConversionService 2009-04-01 21:38:51 +00:00
Arjen Poutsma 65afc80821 Working on SPR-5631 2009-04-01 21:07:46 +00:00
Andy Clement accf974727 use type descriptor to determine collection element type 2009-04-01 16:52:12 +00:00
Arjen Poutsma cd164a5d9b Polishing 2009-04-01 13:31:51 +00:00
Arjen Poutsma ed5647a270 Fixing the build... 2009-04-01 08:58:23 +00:00
Thomas Risberg 8a6e51922a started "new in Spring 3" chapter; added some overview to introduction chapter 2009-04-01 03:35:39 +00:00
Juergen Hoeller 4ebd08515c polishing 2009-03-31 20:43:28 +00:00
Juergen Hoeller 0f35fe9d3c first cut of changelog for M3 2009-03-31 20:39:39 +00:00
Juergen Hoeller 9dd70ca9fe polishing 2009-03-31 20:34:57 +00:00
Juergen Hoeller 72cc060eaf request handler methods with @ModelAttribute annotation always return a model attribute (SPR-4867) 2009-03-31 20:34:42 +00:00
Juergen Hoeller 50f49ffca4 requires Portlet API 2.0 now 2009-03-31 20:32:50 +00:00
Juergen Hoeller b5ca53eedf request handler methods with @ModelAttribute annotation always return a model attribute (for Portlet MVC as well) 2009-03-31 20:31:45 +00:00
Juergen Hoeller b85d45725d @Value values may use ${...} placeholders (driven by PropertyPlaceholderConfigurer); @Autowired uses field/parameter name as fallback qualifier value (SPR-5152) 2009-03-31 20:27:42 +00:00
Juergen Hoeller 2524ca33d5 FacesRequestAttributes (as used by RequestContextHolder) can access global Portlet session (SPR-5637) 2009-03-31 20:16:35 +00:00
Mark Pollack e93bf49268 Add Michael Isvy's documentation on @CookieValue and @RequestHeader annotations. 2009-03-31 17:57:52 +00:00
Keith Donald 1b1eb82adc added todos left 2009-03-31 17:56:08 +00:00
Keith Donald 10a1d5042a polish 2009-03-31 17:52:58 +00:00
Keith Donald b9caa6c60f polish 2009-03-31 17:52:16 +00:00
Keith Donald ce8718ebf2 polish 2009-03-31 17:50:26 +00:00
Keith Donald 199c9bb9c5 removed typed value 2009-03-31 16:51:09 +00:00
Keith Donald d38c0d301c polish 2009-03-31 15:55:42 +00:00
Keith Donald 7f6fc4e82e polish 2009-03-31 15:44:25 +00:00
Keith Donald ea9df82d2a ignore failing tests 2009-03-31 15:12:33 +00:00
Keith Donald 518f98d4c3 polish 2009-03-31 15:06:22 +00:00
Juergen Hoeller eabad33aa2 Hessian service exporter sets content type "application/x-hessian" (SPR-5621) 2009-03-31 14:36:46 +00:00
Juergen Hoeller aa8bd6313b added "unregisterManagedResource" method to MBeanExporter/MBeanExportOperations (SPR-5517) 2009-03-31 14:28:14 +00:00
Mark Pollack 5885c703f2 Add ability to publish to S3 maven milestone repository for maven central style artifacts by adding slightly modified spring-build targets to publish-maven.xml 2009-03-31 03:05:28 +00:00
Mark Pollack 7ad5dd1bd6 Use maven ant task to install parent pom instead of using maven from the command line as a workaround for http://jira.codehaus.org/browse/MANTTASKS-87 2009-03-31 01:51:01 +00:00
Mark Pollack 6f64ce8147 Adding additional project information to POM. 2009-03-31 00:50:52 +00:00
Arjen Poutsma 3df99a17f5 Ignoring broken tests 2009-03-30 23:25:15 +00:00
Arjen Poutsma 3ebb5ccdaf Fixing build. @Override on interface implementation methods is not allowed in Java 5, Keith! 2009-03-30 22:56:16 +00:00
Keith Donald ae4f80cf60 type descriptor initial commit 2009-03-30 22:39:16 +00:00
Andy Clement c057638bd0 Indexed objects (arrays/maps/lists) now settable 2009-03-30 19:40:20 +00:00
Andy Clement 401b7f66c4 Indexed objects (arrays/maps/lists) now settable 2009-03-30 19:40:09 +00:00
Mark Pollack fa68b4b9a7 maven deployment script development 2009-03-30 17:45:13 +00:00
Mark Pollack a80cb4f6e9 maven deployment script development 2009-03-30 17:41:26 +00:00
Arjen Poutsma f09f4e8dd2 SPR-4677: Allow annotated methods on a Controller to be marked as exception handlers 2009-03-30 17:20:55 +00:00
Chris Beams 1b13d8fadf Added test using custom properties file with util:properties and dereferenced with @Value("#{...}") 2009-03-30 17:17:44 +00:00
Arjen Poutsma ea37cdc006 Javadoc 2009-03-30 16:46:01 +00:00
Chris Beams cebc85067a polishing @Configuration tests 2009-03-30 16:02:04 +00:00
Chris Beams cc713ad524 RESOLVED - issue SPR-5600: Make naming of @Configuration class processing-related artifacts consistent 2009-03-30 15:26:21 +00:00
Mark Pollack 24e8dccd44 updated spring-library to include web.portlet in .libd and ivy files 2009-03-30 14:45:31 +00:00
Mark Pollack 4c7c30985f Change antlr version to be 3.0.1 so that is consistent across the project 2009-03-30 14:42:34 +00:00
Mark Pollack 351fba1a04 POM maintenance
Place parent pom in publicly accessible directory (org.sf.spring-parent).  
Create a component list pom in org.sf.spring-library.
2009-03-29 09:56:38 +00:00
Chris Beams 68051ec72b Updated BeanMethodTests to reflect change from IllegalArgumentException -> IllegalStateException 2009-03-28 22:29:28 +00:00
Chris Beams 69a762e86a resolved:
+ Provide @Primary annotation (SPR-5590)
+ Provide @Lazy annotation (SPR-5591)
+ Test @Bean initMethod/destroyMethod functionality (SPR-5592)
+ Test @Bean dependsOn functionality (SPR-5593)
2009-03-28 22:21:50 +00:00
Arjen Poutsma 5bcdf81656 Javadoc 2009-03-28 21:20:18 +00:00
Arjen Poutsma 04b3edca33 SPR-5625 - Allow for exceptions to be annotated with a @ResponseStatus annotation 2009-03-28 11:19:45 +00:00
Arjen Poutsma 3ade31bb51 Added tests for returned ModelAndView 2009-03-28 11:07:18 +00:00
Mark Pollack a9c8ba407c POM maintenance 2009-03-28 01:41:11 +00:00
Mark Pollack 5f21cbd9da POM maintenance 2009-03-27 21:28:51 +00:00
Arjen Poutsma 161c926054 SPR-5624 - A default HandlerExceptionResolver that resolves standard Spring exceptions 2009-03-27 19:53:42 +00:00
Arjen Poutsma f92b7f1011 Added readInternal template method 2009-03-27 17:57:41 +00:00
Juergen Hoeller bcf6f23225 declarative destroy-method="..." specifications get validated at bean creation time (SPR-5602) 2009-03-27 17:45:53 +00:00
Arjen Poutsma d14cc0d7a2 - Renamed writeToInternal to writeInternal
- Added separate exceptions for reading and writing HttpMessages
2009-03-27 17:43:29 +00:00
Juergen Hoeller 82fd947712 polishing 2009-03-27 17:41:03 +00:00
Juergen Hoeller fbfbb88032 introduced "matchesName" method on BeanDefinitionHolder 2009-03-27 17:40:25 +00:00
Juergen Hoeller 565c1c1320 added Groovy file settings 2009-03-27 17:33:50 +00:00
Juergen Hoeller 2e378a8049 added further generic property resolution test 2009-03-27 17:31:15 +00:00
Juergen Hoeller 225eb6bcd9 refined version ranges in OSGi manifests 2009-03-27 17:29:48 +00:00
Juergen Hoeller 7e4a230793 removed Axis 1.x support 2009-03-27 17:28:25 +00:00
Arjen Poutsma ee0a294fe8 Made looping over handlerExceptionResolvers more explicit. 2009-03-27 16:44:19 +00:00
Arjen Poutsma 61b76b2adc Javadoc 2009-03-27 16:26:31 +00:00
Mark Pollack 74326a93d2 Fix SPEL tests when using maven. With the maven test runner expression.spel.SetValueTests is run before expression.spel.EvaluationTests. The order is reversed in eclipse/spring-build. Static variables are modifed in SetValueTests that cause EvaluationTests to fail if it is run first. Make a simple fix so SetValueTests uses a local evaluation context variable instead of a static variable. 2009-03-27 16:05:38 +00:00
Arjen Poutsma f9541d1e28 DispatcherServlet.processHandlerException checks whether the ModelAndView is empty before rendering it. 2009-03-27 15:41:03 +00:00
Mark Pollack 2a35aee2c9 change javax.el revision to be 1.0 to be consistent across the project. 2009-03-27 15:07:33 +00:00
Scott Andrews c488f3768c updating eclipse classpath settings 2009-03-27 14:21:04 +00:00
Arjen Poutsma 337323a114 SPR-5617 - Optional Ivy dependencies are mandatory in the OXM bundle's manifest 2009-03-27 10:29:18 +00:00
Chris Beams aee7f1ce53 RESOLVED - issue SPR-5596: Test @Autowired @Configuration class constructors 2009-03-27 05:36:29 +00:00
Chris Beams 1697932c57 consolidated context.annotation.support -> context.annotation 2009-03-27 04:57:13 +00:00
Chris Beams 2c0c523d70 don't assert that CGLIB must be present unless there is at least one @Configuration class found 2009-03-27 03:10:41 +00:00
Chris Beams af058e599d fixing tests in .test package that were failing due to missing CGLIB dependency 2009-03-27 02:10:41 +00:00
Juergen Hoeller 160e04c15a AspectJ update 2009-03-27 00:10:31 +00:00
Juergen Hoeller 89d1c99277 AspectJ update 2009-03-27 00:08:38 +00:00
Juergen Hoeller 62785abc72 polishing 2009-03-27 00:07:25 +00:00
Juergen Hoeller 341ec4ed41 updated to JRuby 1.2 and Hessian 3.2.1 2009-03-27 00:02:20 +00:00
Juergen Hoeller ef41a12fea updated to JRuby 1.2 (remaining compatible with JRuby 1.1 and above) 2009-03-27 00:01:41 +00:00
Juergen Hoeller 07fba932ac updated to Hessian 3.2.1 (remaining compatible with Hessian 3.1.3 and above) 2009-03-27 00:00:31 +00:00
Juergen Hoeller 81e683b3ee CachedIntrospectionResults always caches bean classes except in case of custom BeanInfo (SPR-4876) 2009-03-26 23:15:23 +00:00
Chris Beams 6698ed8420 IN PROGRESS - issue SPR-5599: Hook @Configuration class processing into <context:component-scan/> and <context:annotation-config/> through AnnotationConfigUtils#registerAnnotationConfigProcessors 2009-03-26 19:52:50 +00:00
Chris Beams 826c733c9e SPR-5616: updated spring-library to include asm and oxm bundles in .libd and ivy files 2009-03-26 14:07:53 +00:00
Ben Hale ce24868209 [SPR-5618] Added an Ignored-Existing-Headers directive 2009-03-26 13:57:50 +00:00
Chris Beams 77b2c4e199 SPR-5615 - Improved error message: s/is no interface/is not an interface 2009-03-26 13:56:14 +00:00
Juergen Hoeller 88e336cf56 FreeMarkerView and ResourceBundle/XmlViewResolver can be initialized with ServletContext only (e.g. for testing) 2009-03-26 13:52:28 +00:00
Juergen Hoeller 40b06b5f19 fixed broken "setManagedInterfaces" interface assertion (SPR-5615) 2009-03-26 13:49:21 +00:00
Ben Hale fe99003b45 Made WebApplicationContextUtils:registerWebApplicationScopes public. Changed core's org.springframework.asm OSGi import to proper version numbers 2009-03-26 09:53:14 +00:00
Scott Andrews 99fa91d56e SPR-5605 spring:url tag should use htmlEscape instead of escapeXml for entity encoding 2009-03-26 04:37:26 +00:00
Scott Andrews 0dfba993e8 updating eclipse classpath for test dependencies 2009-03-26 04:30:37 +00:00
Arjen Poutsma 035eea01e8 SPR-5409 - Support for PUTting and POSTing non-form data 2009-03-25 16:33:27 +00:00
Thomas Risberg 93c56f19df added a config property to control defaulting of primitive property when receiving null value from result (SPR-5588) 2009-03-25 15:26:39 +00:00
Arjen Poutsma 476a0ed76e polishing 2009-03-25 12:15:11 +00:00
Thomas Risberg 4dc4ce3275 changed MapSqlParameterSource to SqlParameterSource in executeFunction and executeObject methods for SimpleJdbcCall (SPR-5570) 2009-03-25 12:14:55 +00:00
Thomas Risberg 360434d0d1 defaulting primitive property when receiving null value from result in BeanPropertyRowMapper (SPR-5588) 2009-03-25 12:12:42 +00:00
Arjen Poutsma 665b284443 Added some leftover tests 2009-03-25 11:26:39 +00:00
Arjen Poutsma d75291714a SPR-5604: OXM bundle's BSN is incorrect 2009-03-25 09:57:59 +00:00
Mark Pollack 0152d8d21d SPR-5385, SPR-5301 - initial pass completed of POMs for maven central repository upload. N.B. Can not build spring with these POMs.
Cleanup remains to meet maven central metadata requirements
2009-03-25 08:06:34 +00:00
Chris Beams e5f4b4937c Re-adding ConfigurationPostProcessorTests after its brief removal in r814. @Ignore-ing the testCglibClassesAreLoadedJustInTimeForEnhancement() method as it turns out this was one of the culprits in the recent build breakage. The classloader hacking causes subtle downstream effects, breaking unrelated tests. The test method is still useful, but should only be run on a manual basis to ensure CGLIB is not prematurely classloaded, and should not be run as part of the automated build. 2009-03-25 06:01:17 +00:00
Chris Beams 2db0f122c1 fixed two build-breaking issues:
+ reverted ClassMetadataReadingVisitor to revision 794
+ eliminated ConfigurationPostProcessorTests until further investigation determines why it causes downstream tests to fail (such as the seemingly unrelated ClassPathXmlApplicationContextTests)
2009-03-25 03:14:35 +00:00
Keith Donald 8d63a34652 set value tests 2009-03-24 19:55:39 +00:00
Arjen Poutsma c178888efd SPR-5537: ReSTful URLs with content type extension do not work properly 2009-03-24 17:36:18 +00:00
Mark Pollack 0b463c0838 SPR-5385, SPR-5301 - partial work committed. 2009-03-24 05:56:56 +00:00
Juergen Hoeller 6ca253e3e6 RmiServiceExporter and RmiRegistryFactoryBean synchronize registry lookup/creation 2009-03-24 00:05:21 +00:00
Keith Donald be61846331 pruned bean references support as it was not used 2009-03-23 21:33:15 +00:00
Keith Donald c546ca68d8 upgrade to latest spring build 2009-03-23 19:27:00 +00:00
Keith Donald cbcb88399c made asm an eclipse project 2009-03-23 19:26:01 +00:00
Arjen Poutsma dc0a82bb93 Added test for multiple template variables in one path segment. 2009-03-23 16:37:58 +00:00
Juergen Hoeller 423c4113ee ConstructorArgumentValues exposed indexed arguments in the order of definition (SPR-5554) 2009-03-23 16:06:24 +00:00
Arjen Poutsma a004ed1c51 SPR-5571: typo in RestTemplate javadoc 2009-03-23 14:54:48 +00:00
Juergen Hoeller dab23a71f9 polishing 2009-03-23 14:39:25 +00:00
Juergen Hoeller df99929e21 added TaskScheduler interface and Trigger abstraction; added ConcurrentTaskScheduler and ThreadPoolTaskScheduler; added CommonJ TimerManagerTaskScheduler; added CronTrigger implementation for cron expression support 2009-03-23 14:38:55 +00:00
Juergen Hoeller 26f0671250 TimerTaskExecutor creates non-daemon Timer and uses bean name as default Timer name 2009-03-23 14:35:16 +00:00
Juergen Hoeller d42e24a752 polishing 2009-03-23 14:15:47 +00:00
Juergen Hoeller 4344832a47 qualifier annotations and @Value can be used at method level as well (applying to all parameters);
fixed EL evaluation of prepared constructor arguments for repeated prototype creation
2009-03-23 14:13:41 +00:00
Juergen Hoeller 4708446d4a fixed CachingMapDecorator to support garbage-collected weak references (again) 2009-03-23 11:34:51 +00:00
Juergen Hoeller 84cc32525f type variable cache uses weak values 2009-03-23 11:32:03 +00:00
Juergen Hoeller 38182f302a added superfluous cast as a workaround for the Sun Javac compiler 2009-03-23 11:30:00 +00:00
Juergen Hoeller 7fb59f3226 implement ASM ClassVisitor interface directly 2009-03-23 11:29:29 +00:00
Juergen Hoeller f19fdde61b polishing 2009-03-23 11:28:49 +00:00
Juergen Hoeller 6d7bf17394 polishing 2009-03-23 11:20:18 +00:00
Juergen Hoeller c82a66b59c SessionAwareMessageListener supports generic declaration of concrete JMS Message type 2009-03-23 11:19:25 +00:00
Chris Beams 147709fa9e Tweaks to package-info.java files 2009-03-23 07:36:44 +00:00
Chris Beams 22b25e0d7b Consolidated Util and MutableAnnotationUtils classes into existing AsmUtils 2009-03-23 07:01:01 +00:00
Chris Beams 7f96f57375 polishing 2009-03-23 06:23:01 +00:00
Chris Beams 1284bd585f + JavaDoc updates
+ added objectweb.asm back to .classpath to satisfy transitive need from groovy tests
+ package.html -> package-info.java
2009-03-23 05:28:58 +00:00
Chris Beams bafe6b3ff9 + Removed org.springframework.config.java module 2009-03-23 04:52:47 +00:00
Chris Beams cd50e45645 + Moving .config.java module -> .context 2009-03-23 04:48:04 +00:00
Chris Beams 63b5c48461 + Pruned empty directories 2009-03-23 04:25:20 +00:00
Chris Beams e3b93c3b79 + Pruned empty directories 2009-03-23 04:24:35 +00:00
Chris Beams ef02c61e58 + Repackaged src and test from .config.java.* -> .context.annotation.* 2009-03-23 04:23:25 +00:00
Chris Beams 3f196517f9 + Repackaging test codebase from .config.java.* -> .context.annotation.* 2009-03-23 04:14:20 +00:00
Chris Beams b8f712621d + Added isCglibClassName() to AopUtils for checking bean class names before classloading
+ Added tests for @Aspect support in @Configuration classes
+ Added tests for @Inherited @Configuration behavior
2009-03-23 03:59:07 +00:00
Chris Beams c9ab18e7e7 Made ConfigurationModel semantics explicit by having it extend LinkedHashSet<ConfigurationClass> 2009-03-22 22:59:10 +00:00
Chris Beams 8a5c2a6a56 + Added tests for custom @Bean naming and aliasing
+ Eliminated BeanDefinitionRegistrar and BeanRegistrar types
+ Simplified ConfigurationEnhancer logic
+ Updated JavaDoc for ConfigurationModel and related classes
+ Updated JavaDoc for all ASM visitors
2009-03-22 22:39:04 +00:00
Chris Beams 2bbc4e48ad + Added unit test for BeanMethod 2009-03-22 02:38:44 +00:00
Chris Beams 72fae2ea19 + Source attribution is now consistent across all registered Problems
+ Various pruning of dead code and polish
2009-03-22 01:43:31 +00:00
Chris Beams 8b4ad4575c Circular @Imports are now handled by registering a Problem (CircularImportProblem) as an error with the current ProblemReporter. This eliminates the need for CircularImportException and is a more tooling-friendly approach. 2009-03-21 21:43:44 +00:00
Chris Beams 3ae3de19a9 + Updated all projects to use the re-introduced org.springframework.asm instead of org.objectweb.asm (.java, template.mf, ivy.xml, and .classpath files have been updated)
+ Finished support for @Import, including detection of circular imports
2009-03-21 19:00:57 +00:00
Ben Hale 9182cab52f [SPR-5459] Added jarjar'd asm packaging 2009-03-20 12:15:06 +00:00
Thomas Risberg abbdc1144a Added the Spring Framework reference documentation 2009-03-18 20:00:49 +00:00
Colin Sampaleanu d4ba002b00 update hibernate and openjpa dependencies to match the orm module
variants. Note that tests are still broken
2009-03-15 03:07:05 +00:00
Mark Pollack 13dfa11def Add support for @ScopedProxy for factory beans using the @FactoryBean annotation within a @Component
Add missing unit tests
2009-03-13 18:14:40 +00:00
Colin Sampaleanu bf31766ff8 fix ecliipse jar imports to match recent changes (hibernate, openjpa) to
ivy dependenies
2009-03-13 05:39:32 +00:00
Chris Beams 5b4fc2de36 removing unnecessary eclipse 'Project Facets' metadata 2009-03-13 04:16:58 +00:00
Thomas Risberg 9b1edea8a0 added tests for custom SQLException translation, polished (SPR-4899) 2009-03-12 21:32:40 +00:00
Thomas Risberg a3942c5c1b changed exception class thrown for problems configuring GenericSqlQuery class (SPR-3986) 2009-03-12 21:30:42 +00:00
Thomas Risberg 49549d66ae added the option of providing a database specific custom SQLExceptionTranslator to provide customized translation for any SQLException before the error codes translation happens (SPR-4899) 2009-03-12 17:22:02 +00:00
Thomas Risberg 943e359c4a switched tests to use JUnit4 2009-03-12 06:29:33 +00:00
Thomas Risberg 7ccb0b6e66 added a concrete GenericSqlQuery class to make it possible to configure in application context (SPR-3986) 2009-03-12 04:38:56 +00:00
Thomas Risberg 4145c299ef fixed missing tabs in application context file (SPR-3987) 2009-03-12 04:35:45 +00:00
Thomas Risberg 2855e5c086 moved the application context file to correct directory (SPR-3987) 2009-03-12 02:17:49 +00:00
Thomas Risberg 8fdc57ecbd added a concrete GenericStoredProcedure class to make it possible to configure using application context (SPR-3987) 2009-03-11 23:01:22 +00:00
Thomas Risberg a0139abf1e added a DuplicatKeyException catagory for SQLException translation (SPR-5125) 2009-03-09 23:26:54 +00:00
Keith Donald d9f5a7a6c8 custom converters 2009-03-09 02:28:22 +00:00
Keith Donald 0ef0ff60f0 super converter implementation 2009-03-08 08:47:10 +00:00
Chris Beams b04009357a ignoring clover prefs 2009-03-07 21:51:41 +00:00
Chris Beams 4f8b812e29 ignoring clover prefs 2009-03-07 21:50:53 +00:00
Chris Beams 0494320266 Eliminated all compilation warnings 2009-03-07 21:47:48 +00:00
Chris Beams dc191bec2d Whitespace and license polish 2009-03-07 21:41:45 +00:00
Mark Pollack a2c87ae67a Initial cut of feature to create factory beans using the @FactoryBean annotation within a @Component 2009-03-07 07:48:53 +00:00
Mark Pollack fc9c3009fe Initial cut of feature to create factory beans using the @FactoryBean annotation within a @Component 2009-03-07 07:42:25 +00:00
Chris Beams 6281948cf9 Dependency updates 2009-03-07 06:37:19 +00:00
Chris Beams f953fd5b22 + Further documentation and pruning.
+ Added testing-related TODOs where appropriate
2009-03-07 06:36:18 +00:00
Chris Beams 3130351233 Removed empty .internal package 2009-03-07 06:17:12 +00:00
Chris Beams 5de6e2c395 + Eliminated support for @Extension methods for now
+ Consolidated all remaining supporting classes into .support package, eliminating .internal.*
+ 7 public types remain
2009-03-07 06:14:46 +00:00
Chris Beams faffd98621 Javadoc polish & pruning dead code 2009-03-07 05:49:12 +00:00
Chris Beams 3231f458c8 + Added 'proxyMode' attribute to @Scope annotation
+ Eliminated @ScopedProxy in favor of @Scope(proxyMode=NO|INTERFACES|TARGET_CLASS)
2009-03-07 04:54:31 +00:00
Chris Beams 9735c8024c @Scope is now allowed on methods (for use in conjunction with @Bean) 2009-03-07 03:37:10 +00:00
Chris Beams 100ba6599f + Eliminated UsageError/Validatable/MalformedConfigurationException in favor of existing Problem/ProblemReporter types
+ Pruned a number of attributes from the @Bean and @Configuration annotations
2009-03-07 03:22:22 +00:00
Rossen Stoyanchev c41c64389f Add (missing) dependencies on oxm project and xmlunit library 2009-03-07 00:08:49 +00:00
Keith Donald 3a7b4bf1b0 basic conversion service impl; still need super converters, custom converters, and conversion of generic collection elements 2009-03-06 23:48:17 +00:00
Keith Donald c1f3ec0c5b turned on debug logging 2009-03-06 20:33:43 +00:00
Keith Donald b04134cffb removed aopalliance errant dependency; removed unused import 2009-03-06 20:25:34 +00:00
Keith Donald 622357291c assert of length 1 2009-03-06 20:22:05 +00:00
Chris Beams 11657b54e0 Removing accidentally committed clover-related eclipse metadata 2009-03-06 20:20:40 +00:00
Keith Donald 3d318ea387 javadoc polishing 2009-03-06 20:20:34 +00:00
Chris Beams 9216b3e8e1 Removed Validator interface and inlined its implementations 2009-03-06 20:17:17 +00:00
Keith Donald c278e1e943 convert system spi and api 2009-03-06 20:08:33 +00:00
Chris Beams f83019afed Re-enabled support for @ScopedProxy 2009-03-06 19:33:53 +00:00
Chris Beams 048b7f638f + Moved @Bean into base package, next to @Configuration
+ Removed .ext package
+ Further reduced visibility of types wherever possible
+ Eliminated package cycles
2009-03-06 07:18:42 +00:00
Chris Beams 00ecbde244 Simplifying packaging 2009-03-06 07:11:01 +00:00
Chris Beams dfab514568 polish 2009-03-06 07:05:38 +00:00
Chris Beams 2e7e982487 + Renamed Scopes -> StandardScopes
+ Renamed ConfigurationPostProcessor -> ConfigurationClassPostProcessor
+ JavaDoc and polish for AbstractConfigurationClassProcessor
2009-03-06 06:55:53 +00:00
Chris Beams 8610c0bce8 + Added .clover to svn:ignore
+ Updated ivy Spring dependencies from 2.5.6 -> latest.integration
+ Added src/test/resources directory to appease Spring Build
2009-03-06 03:27:12 +00:00
Chris Beams b985011b24 + Fleshed out, documented, tested and polished the ConfigurationPostProcessor implementation
+ Removed @FactoryMethod indirection and extension point in favor of direct processing of @Bean annotations
2009-03-06 03:12:53 +00:00
Chris Beams 43b2a40343 Initial work to ensure CGLIB classes are not eagerly loaded (CGLIB should only be required if Spring users wish to process @Configuration classes) 2009-03-06 00:38:30 +00:00
Chris Beams 93b558b1ce eliminated dead code 2009-03-05 20:22:06 +00:00
Chris Beams 04314a62e6 Updated ivy and template.mf dependency metadata; added src/main/resources to quiet a spurious build error. 2009-03-05 20:18:08 +00:00
Chris Beams eaf3a7cec4 + Adding POC tooling integration points, namely AbstractConfigurationPostProcessor and allowing for tooling-specified ClassLoader for use with ASM parsing
+ Eliminated ModelMethod in favor of BeanMethod throughout
2009-03-05 20:08:15 +00:00
Arjen Poutsma 61a1c4d0c6 Added SourceHttpMessageConverter as a default. 2009-03-03 11:38:38 +00:00
Arjen Poutsma ca01cb4df6 SPR-5539: Add XML HttpMessageConverters 2009-03-03 11:34:41 +00:00
Arjen Poutsma 2a790ad25b Javadoc 2009-03-03 10:42:43 +00:00
Arjen Poutsma cbd5ddbb0d SPR-5536: RestTemplate does not do HTTP GET if it should 2009-03-03 09:32:48 +00:00
Arjen Poutsma b08ad44230 SPR-5536: RestTemplate does not do HTTP GET if it should 2009-03-03 09:32:05 +00:00
Chris Beams 6631092870 Removed JSTL-related errors from petclinic search and show JSPs 2009-03-03 02:31:45 +00:00
Chris Beams e834711bc0 + Removed old testsuite.iml (favor integration-testsuite.iml)
+ Updated integration-tests/.classpath to point to javax.jdo 2.1.0 instead of 2.0.0
2009-03-03 00:02:18 +00:00
Chris Beams 6b6b8e50a3 Removed dm Server as targeted runtime for petclinic 2009-03-03 00:01:15 +00:00
Arjen Poutsma b96b72fbaf Typos 2009-03-02 20:22:55 +00:00
Arjen Poutsma 03f3bf09d6 SPR-5449: XStreamMarshaller.setImplicitCollection(Map) is insufficient 2009-03-02 11:19:26 +00:00
Chris Beams ff83255ace Adding eclipse metadata 2009-03-01 21:04:30 +00:00
Chris Beams e3153f705f + Renamed @Factory -> @FactoryMethod
+ callbackType -> interceptor
+ registrarType -> registrar
+ validatorTypes -> validators
2009-02-28 06:57:52 +00:00
Chris Beams f9918f9b2e Formatting pass, primarily to align with Spring's convention of hard tab indentation. 2009-02-28 06:18:46 +00:00
Chris Beams f8270428df + Removed requirement for enhanced subclasses to implement InitializingBean. This was in support of injecting @ExternalValue fields, but is no longer necessary in light of @Value
+ Added formatting rules
2009-02-28 06:10:17 +00:00
Chris Beams 3dac5d82b1 Pruned empty .model package 2009-02-28 04:56:26 +00:00
Chris Beams c0c8117d51 + Eliminated .util package
+ Renamed DefaultScopes -> Scopes
+ Renamed MalformedJavaConfigurationException -> MalformedConfigurationException
2009-02-28 04:55:04 +00:00
Chris Beams f43e1110e9 Pruned empty .factory package 2009-02-28 03:44:48 +00:00
Chris Beams c593f06397 Consolidating types and reducing visibility wherever possible. Non-internal public API is now at 18 types (21 including internal packages). 2009-02-28 03:43:35 +00:00
Chris Beams 6deb1acab4 Refactoring and repackaging 2009-02-28 03:08:06 +00:00
Chris Beams d4fdad2202 + Further repackaging and consolidation
+ Tested compatibility with @Value (works, but noticed and filed an unrelated-to-javaconfig improvement. See SPR-5530)
2009-02-28 01:35:04 +00:00
Chris Beams 2689751c2b Repackaging to remove remaining cycles and increase cohesion 2009-02-27 22:54:35 +00:00
Chris Beams 191b829a6c added 'target' directory to svn:ignore 2009-02-27 03:35:09 +00:00
Chris Beams e48fe0d892 Initial cut at migrating JavaConfig essentials into Core. test.basic.BasicTests successfully excercises the simplest possible @Configuration class (contains a single @Bean method). 39 classes were pulled in from from JavaConfig to support this use case. 2009-02-27 01:35:44 +00:00
Arjen Poutsma e8b353e703 Fixing Spring Build 2009-02-25 19:12:12 +00:00
Chris Beams 719a25a006 Updating Eclipse classpath to reflect new dependencies on mortbay resources. 2009-02-25 15:44:38 +00:00
Arjen Poutsma c1ea5a3ab8 Fixing Petclinic 2009-02-25 14:32:51 +00:00
Juergen Hoeller a1ea7f1820 polishing 2009-02-25 13:57:58 +00:00
Juergen Hoeller e10c843809 finalized changelog for M2 release 2009-02-25 13:55:30 +00:00
Juergen Hoeller e989292e2a updated compile and test dependencies 2009-02-25 13:42:45 +00:00
Juergen Hoeller 96e00d6594 clarified applicability of @Order 2009-02-25 13:41:57 +00:00
Arjen Poutsma 5367ec0ff7 Javadoc 2009-02-25 12:12:14 +00:00
Arjen Poutsma d83b601de0 Javadoc 2009-02-25 11:18:20 +00:00
Juergen Hoeller 516cc02d23 added Commons DBCP as test dependency 2009-02-25 10:08:50 +00:00
Juergen Hoeller 6d66e43402 updated code style settings 2009-02-25 10:08:23 +00:00
Juergen Hoeller 092de0107c improved NoClassDefFoundError handling during constructor resolution (SPR-5522) 2009-02-25 10:07:57 +00:00
Ben Hale b80362f8d1 project-build upgrade 2009-02-25 09:39:00 +00:00
Juergen Hoeller 160249c012 generified FactoryBeans and further Java 5 code style updates 2009-02-25 00:34:22 +00:00
Juergen Hoeller 555fa3b4c8 revised OXM package: no provider-specific exceptions anymore, etc 2009-02-25 00:28:15 +00:00
Arjen Poutsma 866ee1150e Added Form converter as a default 2009-02-24 16:21:07 +00:00
Arjen Poutsma 778a00a595 javadoc 2009-02-24 16:20:26 +00:00
Arjen Poutsma 2fde8ef4d9 Fixed URI encoding in URIEditor to be RFC 2396 compliant 2009-02-24 15:12:54 +00:00
Arjen Poutsma eb47a4b5be SPR-5516: RestTemplate should encode the url variables 2009-02-24 15:01:01 +00:00
Arjen Poutsma 4c0edc2b9d SPR-5515: NPE when passing null as a request to RestTemplate.postForLocation 2009-02-24 14:01:07 +00:00
Arjen Poutsma 2d0705467a Added Form converter 2009-02-24 12:59:59 +00:00
Arjen Poutsma e35201fc78 Javadoc 2009-02-24 12:36:22 +00:00
Juergen Hoeller c46b0ae271 polishing 2009-02-24 12:20:41 +00:00
Juergen Hoeller 760cab8fea refactored HTTP support into top-level package "org.springframework.http"; revised RestTemplate facility in package "org.springframework.web.client" 2009-02-24 11:46:00 +00:00
Juergen Hoeller 882c195221 polishing 2009-02-24 00:27:36 +00:00
Juergen Hoeller 0b4e7cc5ed deprecated support for JMS 1.0.2 providers 2009-02-24 00:26:37 +00:00
Arjen Poutsma 11e7ad21b0 Added tests 2009-02-23 23:44:49 +00:00
Arjen Poutsma 332607ad6c Fixed issue in parsing of invalid MediaTypes from java.net.HttpUrlConnection (*; q=.2) 2009-02-23 22:02:10 +00:00
Arjen Poutsma bc8941084a Added MultiValueMap 2009-02-23 17:15:00 +00:00
Arjen Poutsma e22f267dba Added ServerHttpRequest/Response to web.http, and Servlet-based implementations. 2009-02-23 11:49:09 +00:00
Arjen Poutsma b2fdd7f1fe Added UriTemplate class 2009-02-22 14:54:09 +00:00
Arjen Poutsma ca535bb1d0 SPR-5260: RestTemplate 2009-02-22 14:51:00 +00:00
Arjen Poutsma cdd37d7e8b Character encoding tests 2009-02-22 14:46:12 +00:00
Arjen Poutsma e9d548e62f Fixed problem when headers were written after ClientHttpRequest.execute() 2009-02-22 14:35:28 +00:00
Arjen Poutsma 0db40dd676 Fixing tests 2009-02-22 10:15:32 +00:00
Arjen Poutsma 1bc5188953 Fixing tests 2009-02-22 10:03:40 +00:00
Juergen Hoeller dc1edccc56 prototype beans receive independent collection/array even when based on single value (SPR-5512) 2009-02-21 18:04:08 +00:00
Arjen Poutsma 2de9e2a38d Added HTTP conversion abstraction for RestTemplate 2009-02-21 13:34:55 +00:00
Arjen Poutsma 4a02cd96ea Added HTTP abstraction for RestTemplate 2009-02-21 11:52:38 +00:00
Juergen Hoeller 5fed34bdb4 testing the exception message when conversion of a generic collection element fails 2009-02-20 17:12:29 +00:00
Arjen Poutsma 171b855d10 Added JUnit 4.5 2009-02-20 14:58:19 +00:00
Juergen Hoeller 84ea67669a ModelAndView's "cleared" state gets preserved in case of plain model Map access 2009-02-20 11:48:26 +00:00
Juergen Hoeller eb1631f458 SimpleAliasRegistry detects resolved aliases that loop back to the original name (SPR-5419); PropertyPlaceholderConfigurer does not modify Map in case of equal String keys (SPR-5318); inner class names in Java source style ("java.lang.Thread.State") supported as well (SPR-5210) 2009-02-19 16:17:35 +00:00
Juergen Hoeller ff8e7a1289 further M2 revisions 2009-02-19 00:29:21 +00:00
Juergen Hoeller 4cc42bf16f added "flush()" method to TransactionStatus and TransactionSynchronization interfaces; test context manager automatically flushes transactions before rolling back; general polishing of transaction management code 2009-02-19 00:24:05 +00:00
Juergen Hoeller dd7d299aa4 updated for execution of integration tests 2009-02-19 00:16:20 +00:00
Juergen Hoeller 56bd995d9c "url" macro in "spring.ftl" performs standard Servlet URL encoding automatically 2009-02-18 23:55:32 +00:00
Juergen Hoeller d3d0111439 polishing 2009-02-18 23:51:03 +00:00
Juergen Hoeller 85bc98ea4b MethodInvocations and ProceedingJoinPoints always expose original method (not bridge); ProceedingJoinPoint resolves parameter names using ASM-based parameter name discovery 2009-02-18 23:45:14 +00:00
Juergen Hoeller 02164ab6a7 always use static imports with '*' 2009-02-17 19:10:35 +00:00
Juergen Hoeller 43caa57296 optimized OrderComparator usage 2009-02-17 18:19:57 +00:00
Juergen Hoeller 9871e94cad SimpleAliasRegistry's "getAliases" method returns transitive aliases now; @Qualifier value matching takes chained aliases of target beans into account as well 2009-02-17 18:18:33 +00:00
Juergen Hoeller 35c36dda4b fixed HTTP invoker to support resolution of multi-level primitive array classes again 2009-02-17 17:50:14 +00:00
Juergen Hoeller 57874a6050 SmartApplicationListener interface supports source type checking; SimpleApplicationEventMulticaster caches information about event/source matches 2009-02-17 17:46:14 +00:00
Arjen Poutsma aff17ca9e5 Uncommented test case 2009-02-16 13:42:05 +00:00
Juergen Hoeller 35040a6572 prepared for 3.0 M2 release 2009-02-16 01:51:18 +00:00
Juergen Hoeller 5a09a2d642 polishing 2009-02-16 01:43:49 +00:00
Juergen Hoeller d56419dad9 default post-processors use their default component order now 2009-02-16 01:43:24 +00:00
Juergen Hoeller 46cbaa9729 pre-converted property values are preserved more eagerly for re-created beans (SPR-5293) 2009-02-16 01:36:13 +00:00
Juergen Hoeller 15bbd575a9 bridge method resolution works with Hibernate-generated CGLIB proxies as well (SPR-5414) 2009-02-16 01:35:35 +00:00
Juergen Hoeller 213b528ffe ASM-based AnnotationMetadata fully resolves class arguments and enums into Java types (SPR-5477, SPR-5479) 2009-02-15 21:50:01 +00:00
Juergen Hoeller 90b5c3a8dd @RequestMapping type-level param constraints taken into account consistently 2009-02-15 21:31:20 +00:00
Juergen Hoeller a25e24f37e generified TransactionCallback; WebSphereUowTransactionManager preserves original exception in case of rollback (SPR-5270) 2009-02-15 19:48:18 +00:00
Chris Beams d0b03604c8 Remapped static resources as /petclinic/static/images/...
Renamed tutorial from petclinic.html -> tutorial.html
2009-02-14 21:50:51 +00:00
Chris Beams 3ddd08942c Polishing the new RESTful interface to the petclinic webapp (SPR-5487):
* Eliminated redundant 'clinic' servlet mapping (was: http://localhost:8080/petclinic/clinic/owners; now: http://localhost:8080/petclinic/owners)
* A parameterless GET for /owners now returns the list of all owners, rather than an error.
* /owners/form is now /owners/search (distinguishes the 'search form' resource from the 'edit owner form' resource)
* Eliminated any need for redirects, <welcome-file-list/>, and index.jsp. Deleted all of them.
* Updated /owners/{oid}/edit to submit using PUT instead of POST
* Updated URI for edit pet form from /owners/{oid}/pets/{pid} to /owners/{oid}/pets/{pid}/edit (the edit form is a distinct resource)
* Updated /owners/{oid}/pets/{pid}/edit to submit using PUT instead of POST

Changes unrelated to the web interface:

* Partitioned up JSPs into new owners, pets, and vets folders.
* Renamed those JSPs, e.g. ownerForm.jsp -> owners/form.jsp; findOwners.jsp -> owners/search.jsp; owners.jsp -> owners/list.jsp
* Updated various controllers to respect the changes to the URI templates, etc.
* Updated .classpath to include all necessary projects and libs to run the webapp successfully in WTP
* Updated JSP error checking rules to relax validation of fragments like header.jsp and footer.jsp
2009-02-14 09:11:14 +00:00
Chris Beams da2175c0b7 * Updated Eclipse classpath metadata
* Fixed (or suppressed as necessary) JSP errors in petclinic
2009-02-14 03:09:59 +00:00
Juergen Hoeller fe462916b1 TypeUtils detects variations of ParameterizedType/GenericArrayType assignability as well 2009-02-13 12:17:48 +00:00
Juergen Hoeller d8651a88ec UrlResource eagerly closes HTTP connections in case of "getInputStream()" failure (SPR-5338) 2009-02-13 12:16:11 +00:00
Juergen Hoeller c8080be4e5 completed documentation on session destruction callbacks 2009-02-13 11:51:53 +00:00
Juergen Hoeller 6b2d4a81a0 optional boolean parameters in MVC handler methods resolve to "false" if not present 2009-02-13 11:46:55 +00:00
Arjen Poutsma 721f2ca63e Test for SPR-5362 2009-02-13 10:32:22 +00:00
Ben Hale 4252d40708 Upgrade to spring-build 2009-02-13 10:30:33 +00:00
Juergen Hoeller 2674b13b06 fixed MessageListenerAdapter's "getSubscriptionName()" to work without delegate as well (SPR-5309) 2009-02-13 09:15:43 +00:00
Juergen Hoeller 796392db1a ReflectionUtils findMethod detects methods on "java.lang.Object" as well 2009-02-13 09:14:08 +00:00
Juergen Hoeller ffb9625abf polishing 2009-02-13 09:11:03 +00:00
Juergen Hoeller e58d036c73 generic collection type resolution respects upper bound as well 2009-02-13 09:09:56 +00:00
Ben Hale 483104f0fa Updated to new version of spring-build 2009-02-13 08:56:49 +00:00
Juergen Hoeller 647495edd3 avoid NPE in PathMatchingResourcePatternResolver when initialized with null ClassLoader 2009-02-12 23:46:17 +00:00
Juergen Hoeller d6ed6fcd3f refined OSGi version constraints for "javax.annotation" and "junit.framework" 2009-02-12 23:36:56 +00:00
Juergen Hoeller ad266a347e DefaultLobHandler uses explicit Blob/Clob access for reading when "wrapAsLob"=true 2009-02-12 23:30:28 +00:00
Juergen Hoeller 08dd18df58 revised expression parser API design 2009-02-12 23:03:58 +00:00
Juergen Hoeller 2bdb62f4c2 added IntelliJ settings for integration-tests module 2009-02-12 22:12:27 +00:00
Juergen Hoeller f4b466dfdd made SpringBeanAutowiringInterceptor callback signature compatible with WebSphere 2009-02-12 18:05:37 +00:00
Juergen Hoeller ac104d4da0 polishing 2009-02-12 17:41:46 +00:00
Juergen Hoeller fb057bb5f6 generified NumberUtils signature 2009-02-12 17:40:51 +00:00
Juergen Hoeller 8669b3293c fixed JmsException/JmsUtils to fully avoid NPEs in case of cause messages being null 2009-02-12 17:33:57 +00:00
Juergen Hoeller 777a104d48 added @Async annotation, AsyncExecutionInterceptor, AsyncAnnotationAdvisor 2009-02-10 11:24:05 +00:00
Arjen Poutsma 21a442b253 Solved concurrency issue 2009-02-09 22:10:47 +00:00
Juergen Hoeller 5a04ed502b registered plain singletons will be fully matched according to their qualifiers; "systemProperties" bean is not considered a default match for type Properties anymore (SPR-5355) 2009-02-09 22:06:07 +00:00
Juergen Hoeller 6086bb37e7 updated to Hibernate 3.3 + Hibernate EntityManager 3.4 (requires SFL4J <= 1.5.3!) as well as OpenJPA 1.1 2009-02-09 21:40:53 +00:00
Juergen Hoeller 0794756fba revised advice ordering (for async execution interceptor) 2009-02-09 18:32:21 +00:00
Juergen Hoeller fc6d7358ef polishing 2009-02-09 18:28:04 +00:00
Juergen Hoeller 60392d6e74 ApplicationListener beans get obtained on demand, supporting non-singletons as well; ApplicationListeners will be called in the order according to the Ordered contract; generified ApplicationListener interface 2009-02-09 18:26:30 +00:00
Juergen Hoeller 6609386e41 polishing 2009-02-09 15:38:17 +00:00
Juergen Hoeller 205df56ee4 support for WebSphere's ResourceAdapter-managed transactions 2009-02-09 15:36:20 +00:00
Arjen Poutsma f5e5fc1662 Added content negotiation and MarshallingView to petclinic 2009-02-06 16:12:13 +00:00
Arjen Poutsma fae0110536 Added content negotiation and MarshallingView to petclinic 2009-02-06 15:54:57 +00:00
Arjen Poutsma df563dfcd6 SPR-5452: Content negotiation 2009-02-06 14:38:30 +00:00
Arjen Poutsma b96a7a7a8c SPR-5460: Add AtomView sample to PetClinic 2009-02-06 09:12:08 +00:00
Arjen Poutsma ce83ebf0de Added link to Atom spec in javadoc 2009-02-06 08:18:37 +00:00
Juergen Hoeller 7e4fb09369 added "Future submit(Runnable)" and "Future submit(Callable)" to AsyncTaskExecutor; SchedulingTaskExecutor interface extends AsyncTaskExecutor; added ExecutorServiceAdapter class as a standard wrapper for a Spring TaskExecutor; added ThreadPoolExecutorFactoryBean; reduced backport-concurrent support to TaskExecutor adapters 2009-02-05 22:45:35 +00:00
Juergen Hoeller 6cdc25d66a all "taskExecutor" bean properties now accept any "java.util.concurrent.Executor" 2009-02-05 21:18:10 +00:00
Juergen Hoeller ea54c6391e deprecated ConcurrentMap 2009-02-05 21:07:53 +00:00
Juergen Hoeller 92588cddc6 Java 5 code style 2009-02-05 21:04:13 +00:00
Arjen Poutsma 460977263d Added extractFullFilenameFromUrlPath to WebUtils 2009-02-05 15:45:25 +00:00
Arjen Poutsma b0180fdf32 Added MediaType 2009-02-05 15:44:16 +00:00
Arjen Poutsma 747ee86079 Made CollectionsFactory generic 2009-02-05 15:33:44 +00:00
Arjen Poutsma 5786f6c359 Made threadlocals generic 2009-02-03 11:24:10 +00:00
Ramnivas Laddad c8d6c15a05 Fixed toString(), toShortString(), and toLongString() methods for signature and join point (SPR-5437) 2009-01-27 22:58:28 +00:00
Scott Andrews 27460e323a creating eclipse project settings for org.springframework.spring-library 2009-01-26 16:03:05 +00:00
Scott Andrews dd2f1b467b adding servlet api to the eclipse classpath to clear up tooling errors from JSP files 2009-01-26 15:49:55 +00:00
Scott Andrews 178e1161d7 updating eclipse classpath for JDO 2.1 2009-01-26 15:42:13 +00:00
Scott Andrews 0a48996f14 adding missing test time dependencies 2009-01-26 15:35:17 +00:00
Juergen Hoeller e7c5a28586 polishing 2009-01-25 23:29:45 +00:00
Juergen Hoeller eef6086325 polishing 2009-01-25 23:28:01 +00:00
Juergen Hoeller e7465dcb99 generified operations interfaces; update to JDO 2.1; preparation for JPA 2.0 2009-01-25 23:20:41 +00:00
Ramnivas Laddad 612ed8c660 Added sourcepath for aspectjweaver jar 2009-01-24 17:04:29 +00:00
Arjen Poutsma 6c96c48bf5 Resurrected requestScopeTests.xml from revision 573 2009-01-24 12:16:45 +00:00
Scott Andrews 7dcb3b5841 fixing broken unit test related to SPR-5429 2009-01-23 22:32:26 +00:00
Scott Andrews 300e4d7284 SPR-5429 Update Pet Clinic to use HSQL as an embedded database
Removing support for running HSQL in stand-alone mode.  Out of the box embedded HSQL and MySQL are supported.
2009-01-23 20:52:20 +00:00
Scott Andrews 16c9391069 SPR-5429 Update Pet Clinic to use HSQL as an embedded database
Created DbcpDataSourceFactory factory bean to create and populate a dbcp based connection pool.  The factory bean is based on EmbeddedDataSourceFactory from the JavaConfig version of Pet Clinic.  The new DbcpDataSourceFactory has been tested with HSQL in embedded and stand-alone modes.
2009-01-23 20:33:17 +00:00
Scott Andrews 9335233618 javadoc polish 2009-01-23 15:18:25 +00:00
Arjen Poutsma 16843b3a07 Fixed usage of wrong TestBean package. 2009-01-23 11:57:58 +00:00
Scott Andrews 61b5428211 SPR-2733 Improvement for handling checkboxes in web forms (patch included)
Introduced default field prefix of '!', which can be overridden with WebDataBinder#setFieldDefaultPrefix.  If a field is otherwise not present, the default value is used for the field.  Field markers for the same field are ignored.
2009-01-23 00:03:33 +00:00
Scott Andrews 8e261e5833 SPR-3389 Nicer handling of Java 5 enums by the Spring MVC form taglib.
The form:options and form:radiobuttons tags will now render a set of options automatically if the bind target is an Enum and items are not otherwise specified.  The values of the enum are converted into form inputs where by default the form value is the enum's name() and the form label is the enum's toString().
2009-01-22 20:36:36 +00:00
Arjen Poutsma ad2cc34b79 SPR-2581: Provide out of the box implementation of the thread scope 2009-01-22 15:41:29 +00:00
Arjen Poutsma bf9ffe2d67 javadoc 2009-01-22 12:02:30 +00:00
Arjen Poutsma becea6115e SPR-3360: util:property-path like functionality for the p-namespace 2009-01-22 12:01:25 +00:00
Arjen Poutsma 1b6c4929ad Renamed ShortcutTests to SimplePropertyNamespaceHandlerTests 2009-01-22 11:41:14 +00:00
Scott Andrews 52d3440266 removing org.springframework.testsuite, subversive desided to commit the directory without prompting me... 2009-01-21 23:13:00 +00:00
Scott Andrews 1f770574b0 updating eclipse settings and classpaths 2009-01-21 23:02:43 +00:00
Scott Andrews 3bef38e8f8 2009-01-21 22:48:19 +00:00
Arjen Poutsma 7f7ff4ea9b Moved petclinic test configs to resource directory. 2009-01-21 22:26:48 +00:00
Arjen Poutsma fe31de529b SPR-5326: HibernateClinic in PetClinic sample should use constructor-injection instead of field injection 2009-01-21 22:13:00 +00:00
Arjen Poutsma f09db3a106 SPR-5335: manager.sh classpath for petclinic should be updated 2009-01-21 21:31:05 +00:00
Arjen Poutsma 60ce3eb12f SPR-5335: manager.sh classpath for petclinic should be updated 2009-01-21 21:04:15 +00:00
Arjen Poutsma c7d1d3ccb8 SPR-5367: PathVariable mappings are greedy over hard coded mappings 2009-01-21 17:45:42 +00:00
Arjen Poutsma 5d5e41269b Added Pattern comparitor 2009-01-21 17:06:37 +00:00
Juergen Hoeller 61c9397c01 added M2 section to changelog 2009-01-20 18:49:13 +00:00
Juergen Hoeller 49ba677b64 introduced @CookieValue annotation 2009-01-20 18:32:24 +00:00
Juergen Hoeller 9dec670be4 consistent copies of mocks 2009-01-20 18:08:14 +00:00
Juergen Hoeller 8dbbb533f3 consistent copies of mocks 2009-01-20 18:01:51 +00:00
Juergen Hoeller f0415306d5 consistent copies of mocks 2009-01-20 18:01:40 +00:00
Juergen Hoeller 76a6527c4c consistent copies of mocks 2009-01-20 18:01:26 +00:00
Ben Hale 5585526ad1 Upgraded spring-build 2009-01-20 11:06:48 +00:00
Juergen Hoeller 8af66c83ad consistent mock behavior 2009-01-19 23:35:42 +00:00
Juergen Hoeller d950b56999 revised common handler method processing for Portlet 2.0 update 2009-01-19 23:34:41 +00:00
Juergen Hoeller 464c7eedf2 updated Spring Portlet MVC to Portlet API 2.0 2009-01-19 23:32:32 +00:00
Juergen Hoeller 76888e243f polishing 2009-01-19 22:07:25 +00:00
Arjen Poutsma 5948d05ee0 Removed generated classes from repo. 2009-01-16 09:28:54 +00:00
Ben Hale 6479966ac7 Added castor and jaxb2 to the oxm build 2009-01-15 14:45:15 +00:00
Arjen Poutsma 00734954bd Added test-classes to classpath, necessary for generated xmlbeans code 2009-01-15 11:26:21 +00:00
Arjen Poutsma 6d5e07f46a Added jaxb2 and castor tasks for Ben to play with. 2009-01-15 11:12:55 +00:00
Arjen Poutsma 7ec86ebd9e Enabled XMLBeans tests 2009-01-15 10:26:00 +00:00
Ben Hale 4206b69b60 Moved to the trunk spring-build version 2009-01-15 10:18:31 +00:00
Arjen Poutsma c3fcab05f0 Enabled Jibx tests 2009-01-15 09:48:29 +00:00
Ben Hale 17fe9c9712 Updated spring-build 2009-01-14 16:45:03 +00:00
Ben Hale b1d474193d Split the compile and test-compile macros. Added a pre-compile macro. 2009-01-14 16:29:33 +00:00
Arjen Poutsma 7b73830987 Added simple test for SPR-5365 2009-01-14 11:04:28 +00:00
Arjen Poutsma 1dec645383 Polish 2009-01-14 10:03:28 +00:00
Juergen Hoeller 7cdc195331 Portlet mocks support Portlet API 2.0 2009-01-14 09:34:07 +00:00
Juergen Hoeller 46f99640ee javadoc updates for 3.0 2009-01-14 09:29:30 +00:00
Juergen Hoeller ce2c59ec84 Java 5 code style 2009-01-14 09:27:51 +00:00
Juergen Hoeller b05d800205 added "processInjectionBasedOnServletContext" variant 2009-01-14 09:23:52 +00:00
Arjen Poutsma e863f9a371 SPR-5380: MarshallingView should override AbstractView instead of AbstractUrlBasedView 2009-01-13 10:41:26 +00:00
Arjen Poutsma e966fd9605 - Removed GenericMarshaller & GenericUnmarshaller
- Made Marshaller and Unmarshaller generic
2009-01-12 16:43:52 +00:00
Arjen Poutsma 56bdfae39a Added oxm module 2009-01-09 13:34:00 +00:00
Ben Hale c04dec1b15 Updated spring-build 2009-01-09 13:33:41 +00:00
Arjen Poutsma fc06f9ba72 OXM is nearing completion 2009-01-09 12:48:19 +00:00
Arjen Poutsma f2329cf426 Aded createStaxResult 2009-01-09 12:37:41 +00:00
Arjen Poutsma 8ce1f203ff Added generated classes for Castor. 2009-01-08 11:12:28 +00:00
Arjen Poutsma ccd59ca088 Added StaxUtils, hidden StaxSource, StaxResult, and various other Stax-specific classes behind this utility class. 2009-01-07 16:20:40 +00:00
Arjen Poutsma 74f3ed3f19 Added DomContentHandler 2009-01-07 12:20:58 +00:00
Arjen Poutsma 76de5b0e10 Added DomContentHandler 2009-01-07 12:20:42 +00:00
Arjen Poutsma e03a27ef46 Added Stax Source methods to TransformerUtils 2009-01-07 12:00:39 +00:00
Arjen Poutsma 688593074a Fixed version numbers 2009-01-07 11:38:18 +00:00
Arjen Poutsma 22e78c90e0 Added StaxResult 2009-01-07 11:37:09 +00:00
Arjen Poutsma 6be49ad8c5 Added StaxEventContentHandler 2009-01-07 11:36:33 +00:00
Arjen Poutsma e0fe3f35aa Test -> Tests 2009-01-07 11:24:50 +00:00
Arjen Poutsma 7bf6d90f20 Added StaxStreamContentHandler 2009-01-07 11:24:01 +00:00
Arjen Poutsma 0637dbad5e Test -> Tests 2009-01-07 11:20:08 +00:00
Arjen Poutsma 2945253d20 Added SimpleNamespaceContext 2009-01-06 17:07:59 +00:00
Arjen Poutsma 8152b266b1 Renamed XmlReader classes to XMLReader classes 2009-01-06 16:43:49 +00:00
Arjen Poutsma 5f8d442708 Renamed XmlReader tests to XMLReader tests 2009-01-06 16:40:37 +00:00
Arjen Poutsma 86cf17e5e9 Renamed XmlReaders to XMLReaders 2009-01-06 16:32:59 +00:00
Arjen Poutsma 5dfe6775d4 Added various XML helper classes, for use with OXM 2009-01-06 16:24:42 +00:00
Arjen Poutsma 2eca3aee06 Added JaxpVersion 2009-01-06 12:33:41 +00:00
Arjen Poutsma 6ba9ad8116 Added @Override 2009-01-06 11:19:19 +00:00
Arjen Poutsma 03582973d7 Initial import of OXM module 2009-01-06 11:18:27 +00:00
Chris Beams d116c8733a polishing .beans tests 2008-12-24 22:02:08 +00:00
Chris Beams 46722fa946 removing unintentionally added file 2008-12-24 21:52:44 +00:00
Chris Beams 62db6af879 polishing .beans tests 2008-12-24 21:52:19 +00:00
Chris Beams a0bf1b4ade polishing .beans tests 2008-12-24 20:29:14 +00:00
Chris Beams 915ad0a8d9 polishing .beans tests 2008-12-24 20:17:43 +00:00
Chris Beams 751daf95a1 polishing .beans tests 2008-12-24 19:34:04 +00:00
Chris Beams 670bfd5ee2 + polishing .beans tests
+ removed unnecessary dependency on hibernate
2008-12-24 19:14:15 +00:00
Chris Beams 3d634f1eb7 polishing .beans tests 2008-12-24 18:16:53 +00:00
Chris Beams 6966099d85 polishing .aop tests 2008-12-21 00:12:12 +00:00
Chris Beams 4671fd7141 polishing .aop tests 2008-12-20 23:34:49 +00:00
Chris Beams 9211357e94 polishing .aop tests 2008-12-20 23:28:22 +00:00
Chris Beams 5dd4e5220a polishing .aop tests 2008-12-20 23:01:02 +00:00
Chris Beams 0f4ab0a987 polishing .aop tests 2008-12-20 22:30:29 +00:00
Chris Beams beea69d83b polishing .aop tests 2008-12-20 21:06:19 +00:00
Chris Beams 56e868b2d7 polishing .aop tests 2008-12-20 20:06:11 +00:00
Chris Beams 7abde41d5b polishing .aop tests 2008-12-20 19:29:15 +00:00
Chris Beams ac9f9c1348 updated eclipse team project definition from .testsuite -> .integration-tests 2008-12-20 09:40:21 +00:00
Chris Beams 07c15ce746 renamed .testsuite -> .integration-tests 2008-12-20 09:36:46 +00:00
Chris Beams a73e4fc266 removing empty dirs from .testsuite 2008-12-20 09:14:08 +00:00
Chris Beams c3a68dfdda removing empty dirs from .testsuite 2008-12-20 09:12:11 +00:00
Chris Beams 6a31155c62 eliminating all unnecessary artifacts from .testsuite 2008-12-20 09:09:31 +00:00
Chris Beams 3da373eeaf moved XmlBeanFactoryTests and attendant XML from .testsuite -> .context 2008-12-20 08:19:32 +00:00
Chris Beams d083432478 refactored .context module's .beans.factory and .context.access tests in preparation for moving .beans.factory.xml tests from .testsuite -> .context 2008-12-20 07:22:07 +00:00
Chris Beams 78c692b0cb refactored XmlBeanFactoryTests in preparation for move from .testsuite -> .context 2008-12-20 00:18:15 +00:00
Chris Beams 7a0d9c7533 moved ApplicationContext-dependent .beans.factory.xml.* tests from .testsuite -> .context 2008-12-19 22:33:26 +00:00
Chris Beams be53a80657 moved ApplicationContext-dependent .aop.* unit tests from .testsuite -> .context
in the process, identified and refactored two genuine integration tests (AopNamespaceHandlerScopeIntegrationTests, AdvisorAutoProxyCreatorIntegrationTests), which will remain in .testsuite due to broad-ranging dependencies
2008-12-19 21:58:42 +00:00
Chris Beams 2d37eb722b + moving .aop.aspectj.* unit tests from .testsuite -> .context
+ @SuppressWarnings and generic parameters to production .aop sources
2008-12-19 15:45:06 +00:00
Chris Beams 4a77699d38 refactoring .testsuite .aop.aspectj tests in preparation for migration to .context 2008-12-19 14:57:35 +00:00
Chris Beams d7a9d7c8e6 + refactoring .testsuite .aop.aspectj tests in preparation for migration to .context
+ updated all ivy.xml files to depend on AspectJ 1.6.2
2008-12-19 14:56:09 +00:00
Chris Beams 5b9da399c6 moving .aop.aspectj.* unit tests from .testsuite -> .context 2008-12-19 03:45:30 +00:00
Chris Beams b6906ecfb7 final polish on .testsuite .aop.aspectj tests prior to migration to .context 2008-12-19 03:10:43 +00:00
Chris Beams 81efa4d23c refactoring .testsuite .aop.aspectj tests in preparation for migration to .context 2008-12-19 02:59:46 +00:00
Chris Beams 6f91ffac62 refactoring .testsuite .aop.aspectj tests in preparation for migration to .context 2008-12-19 02:57:21 +00:00
Chris Beams eabec18151 refactoring .testsuite .aop.aspectj tests in preparation for migration to .context 2008-12-19 02:29:04 +00:00
Chris Beams aee972c5b1 re-adding mock.jndi.* artifacts to .orm test codebase eliminated after moving away from svn:externals 2008-12-18 22:30:35 +00:00
Chris Beams 9845f56ba0 reverting accidentally deleted (in r469) mock/web/* classes 2008-12-18 22:16:16 +00:00
Chris Beams ea68d343fa eliminated svn:externals in favor of localized copies of shared artifacts 2008-12-18 21:27:18 +00:00
Juergen Hoeller c442a5818d updated dependencies 2008-12-18 19:16:54 +00:00
Juergen Hoeller 1cc845af6d got rid of Commons Collections dependency 2008-12-18 19:14:49 +00:00
Juergen Hoeller bbe4da4f19 removed dependency on Servlet API mocks 2008-12-18 19:13:35 +00:00
Juergen Hoeller f0dbfeb791 removed dependency on Servlet API mocks 2008-12-18 18:58:26 +00:00
Chris Beams ac8f37439b removing svn:externals usage approach to common test artifacts 2008-12-18 18:44:45 +00:00
Chris Beams 685f2fbc1c + updated petclinic dependency metadata from junit 4.4->4.5; servlet 2.4->2.5
+ deprecated AssertThrows (slated for complete removal by 3.0 GA)
2008-12-18 18:32:05 +00:00
Chris Beams 986bb1995d Whitespace polishing: leading spaces->tabs; updated eclipse configuration to default to leading tabs for all bundles 2008-12-18 14:52:45 +00:00
Chris Beams 579280d7bf Whitespace polishing: leading spaces->tabs; updated eclipse configuration to default to leading tabs for all bundles 2008-12-18 14:50:25 +00:00
Chris Beams 0f521c3bfb consolidated svn:externals definitions into single, project-root location 2008-12-18 00:07:30 +00:00
Chris Beams 75738f345d updated .aop externals to pull in common.beans.core 2008-12-17 23:55:40 +00:00
Chris Beams de7ec2288e removed unused SideEffectBean imlpmentations 2008-12-17 23:52:20 +00:00
Chris Beams 08eeb52e57 introducing common.beans.* packaging and externals; experimenting with sharing SideEffectBean 2008-12-17 23:36:40 +00:00
Chris Beams 2be8114c63 cleaning up .testsuite 2008-12-17 23:20:57 +00:00
Chris Beams 92b1b73f32 moving unit tests from .testsuite -> .transaction 2008-12-17 20:16:27 +00:00
Chris Beams c5f8b4f7c6 moving unit tests from .testsuite -> .transaction 2008-12-17 20:10:34 +00:00
Chris Beams cac2c52e60 moving unit tests from .testsuite -> .transaction
fixed externals issue with .portlet that caused build failure
2008-12-17 19:46:35 +00:00
Chris Beams efcc9b6448 removing empty dirs from .testsuite 2008-12-17 18:47:48 +00:00
Chris Beams 93e30a4fc5 moving unit tests from .testsuite -> .core, .beans, .web, .web.portlet, .web.servlet 2008-12-17 18:45:41 +00:00
Chris Beams 285be534df removing empty dirs from .testsuite 2008-12-17 16:30:56 +00:00
Chris Beams 750bcf36a6 moving unit tests from .testsuite -> .test, .web.servlet 2008-12-17 16:28:56 +00:00
Chris Beams 78e1ebe1a8 adding properties file to simplify ant use in Bamboo CI build 2008-12-17 15:47:14 +00:00
Chris Beams 68444367b7 moving .test.* unit tests from .testsuite -> .test 2008-12-17 07:32:58 +00:00
Chris Beams 3e8c013df3 moving .scripting.* unit tests from .testsuite -> .context 2008-12-17 06:48:52 +00:00
Chris Beams 31f5961dce moving remoting.*, scheduling.* unit tests from .testsuite -> .context, .web 2008-12-17 06:13:28 +00:00
Chris Beams f5b1cae78c removing empty .orm packages from .testsuite 2008-12-17 05:46:13 +00:00
Chris Beams f4d8b69126 moving unit tests from .testsuite -> .orm 2008-12-17 05:33:45 +00:00
Chris Beams 10be5f08a5 moving .jndi, .mail and .mock.web unit tests from .testsuite to .context, .context.support, and .test bundles respectively 2008-12-17 02:20:01 +00:00
Chris Beams b326565ce5 removing empty jmx dirs from .testsuite; ignoring jmx.log output from .context bundle 2008-12-17 00:42:33 +00:00
Chris Beams 72854849d9 moving jmx.* unit tests from .testsuite -> .context 2008-12-17 00:39:28 +00:00
Chris Beams b4b8303375 removing empty .jms dirs from .testsuite 2008-12-17 00:20:21 +00:00
Chris Beams 5e0c5a42ad moving unit tests from .testsuite -> .jms 2008-12-17 00:19:07 +00:00
Chris Beams 15860b1607 removing empty .jdbc dirs from .testsuite 2008-12-16 23:31:35 +00:00
Chris Beams ed27e04a0d moving unit tests from .testsuite -> .jdbc 2008-12-16 23:29:28 +00:00
Chris Beams f2e9abf699 moved jca.* unit tests from .testsuite -> .transaction 2008-12-16 22:55:07 +00:00
Chris Beams 6285e61435 refactored jca.cci tests, prepped for move to .context 2008-12-16 22:28:09 +00:00
Chris Beams f11bc4712c moving instrument.classloading.* unit tests from .testsuite -> .context 2008-12-16 20:07:32 +00:00
Chris Beams 9ed180a80d prepping .intstrument.classloading unit tests for move from .testsuite -> .context 2008-12-16 20:01:48 +00:00
Chris Beams 2952609672 finished moving .ejb.* unit tests from .testsuite -> .context 2008-12-16 19:19:41 +00:00
Chris Beams 0b0c8f1506 moving .ejb.access unit tests from .testsuite -> .context 2008-12-16 18:28:19 +00:00
Chris Beams d3a46efeb2 moving unit tests from .testsuite -> .core 2008-12-16 17:04:43 +00:00
Chris Beams d72897b6fa moving unit tests from .testsuite -> .context 2008-12-16 05:35:23 +00:00
Chris Beams 74ef4cb0f3 moving unit tests from .testsuite -> .beans 2008-12-16 01:46:25 +00:00
Chris Beams 4526501559 moving unit tests from .testsuite -> .beans and .context 2008-12-16 01:08:43 +00:00
Chris Beams 4a149d00f6 adding resources to portlet/context/WEB-INF 2008-12-15 22:52:02 +00:00
Chris Beams 489427c3be moving unit tests from .testsuite -> .web.servlet 2008-12-15 22:49:08 +00:00
Chris Beams b8a8ceae91 moving unit tests from .testsuite -> .context
moved ContextSingletonBeanFactoryLocatorTests -> .context
pulled SingletonBeanFactoryLocatorTests and friends into .context via externals for use by the above
2008-12-15 18:49:11 +00:00
Chris Beams f7813b48e1 moving unit tests from .testsuite -> .beans
moving and prepping to move SingletonBeanFactoryLocatorTests and ContextSingletonBeanFactoryLocatorTests to their respective .beans and .context packages
2008-12-15 18:37:33 +00:00
Chris Beams a4c23509e3 moving unit tests from .testsuite -> .beans
refactoring/prepping several classes for upcoming move to .beans
2008-12-15 18:18:50 +00:00
Chris Beams 97e400efd6 moving unit tests from .testsuite -> .beans
RequiredAnnotationBeanPostProcessor tests
2008-12-15 17:48:31 +00:00
Chris Beams ef414420c8 moving unit tests from .testsuite -> .beans
fixed broken unit tests getting ClassNotFoundExceptions
2008-12-15 17:13:48 +00:00
Chris Beams 2ec861351c moving unit tests from .testsuite -> .beans 2008-12-15 09:25:01 +00:00
Chris Beams 52ac3cea8c moving unit tests from .testsuite -> .beans 2008-12-15 08:41:35 +00:00
Chris Beams 248a7de73f moving unit tests from .testsuite -> .beans 2008-12-15 05:20:25 +00:00
Chris Beams b44d647dad moving unit tests from .testsuite -> .beans 2008-12-15 04:10:27 +00:00
Chris Beams afa4231751 moving unit tests from .testsuite -> .beans
added <?> wildcard to Scope methods that accept ObjectFactory
2008-12-15 03:39:13 +00:00
Chris Beams 6cb71bbb71 moving unit tests from .testsuite -> .beans 2008-12-15 02:27:35 +00:00
Chris Beams 8977ad4032 moving unit tests from .testsuite -> .core 2008-12-15 01:14:57 +00:00
Chris Beams 2359942dd7 moving unit tests from .testsuite -> .context 2008-12-14 21:46:55 +00:00
Chris Beams 931728ba2f reverting CauchoRemotingTests back to 'localhosta' host name 2008-12-14 20:43:40 +00:00
Chris Beams 8b2cf634a3 moving unit tests from .testsuite -> .context 2008-12-14 20:13:56 +00:00
Chris Beams 87de85ef19 moving unit tests from .testsuite -> .context 2008-12-14 19:47:56 +00:00
Chris Beams 69d80518f3 moving unit tests from .testsuite -> .context 2008-12-14 18:40:53 +00:00
Chris Beams 95950d28de moving unit tests from .testsuite -> .context.support 2008-12-14 18:01:20 +00:00
Chris Beams 0a47beb647 moving unit tests from .testsuite -> .context.support 2008-12-14 17:35:21 +00:00
Chris Beams 7432202b6a moving unit tests from .testsuite -> .context 2008-12-14 17:03:18 +00:00
Chris Beams b4e61dd9df moving unit tests from .testsuite -> .context 2008-12-14 08:00:16 +00:00
Chris Beams 0572d9d1a4 pulling in example.scannable as external from .context -> .testsuite
eliminated duplicate artifacts in .context.annotation
2008-12-14 07:06:43 +00:00
Chris Beams 5e5d8b0196 moving example.scannable from .testsuite -> .context 2008-12-14 06:46:37 +00:00
Chris Beams e944e2fcc5 moving unit tests from .testsuite -> .context
+ created example.scannable package to house scannable components away from .context.annotation package
+ example.scannable will also lend itself to sharing via externals
2008-12-14 06:32:25 +00:00
Chris Beams 57eaf42424 moving unit tests from .testsuite -> .context 2008-12-14 03:59:10 +00:00
Chris Beams 72b306fe0a moved commonsPoolTests.xml back from .aop -> .testsuite 2008-12-14 03:41:39 +00:00
Chris Beams 64aa2620bc added missing base classes, eliminated unused *Bean classes 2008-12-14 02:50:58 +00:00
Chris Beams 83870f3fca fixed broken path to xml in CommonsPoolTargetSourceTests
eliminated duplicate tests existing in both .beans and .testsuite
2008-12-13 22:07:22 +00:00
Chris Beams 7f5e60e76a moving unit tests from .testsuite -> .aop 2008-12-13 01:46:56 +00:00
Andy Clement 84a4fe6d39 remove files 2008-12-13 01:38:21 +00:00
Andy Clement 6d03f881e9 new files 2008-12-13 01:36:48 +00:00
Chris Beams 32bea88eb7 moving unit tests from .testsuite -> .aop 2008-12-13 01:27:27 +00:00
Chris Beams e3ec177aab moving unit tests from .testsuite -> .aop 2008-12-13 01:07:30 +00:00
Chris Beams 40016fc902 moving unit tests from .testsuite -> .aop 2008-12-13 00:35:22 +00:00
Chris Beams be3ecf5fe7 moving unit tests from .testsuite -> .aop 2008-12-13 00:11:12 +00:00
Andy Clement 5ff4008423 Refactored package structure and made some getValue() methods generic 2008-12-12 23:07:08 +00:00
Chris Beams 4c88488c5a moving unit tests from .testsuite -> .aop
@Ignore'd a portion of PersistenceXmlParsingTests#testExampleComplex: it is failing, but only under clover coverage runs
2008-12-12 20:09:17 +00:00
Chris Beams 04d3f984b1 polish: leading spaces -> tabs across .aop and .testsuite bundles 2008-12-12 19:39:14 +00:00
Chris Beams b7cc5d2402 Java 5 code style 2008-12-12 19:03:33 +00:00
Chris Beams 5cb1b1d17c moving unit tests from .testsuite -> .aop 2008-12-12 18:57:46 +00:00
Chris Beams 56908e32cd polish 2008-12-12 18:22:29 +00:00
Chris Beams 3c0015c1ec moving unit tests from .testsuite -> .aop 2008-12-12 18:08:15 +00:00
Chris Beams c563f97b90 moving unit tests from .testsuite -> .aop 2008-12-12 17:30:02 +00:00
Chris Beams 1546c15187 moving unit tests from .testsuite -> .aop 2008-12-12 17:17:32 +00:00
Chris Beams 003866835e fixed breaking test that was pointing to wrong PerThisAspect 2008-12-12 04:34:47 +00:00
Chris Beams f4a7700216 moving unit tests from .testsuite -> .aop 2008-12-12 03:36:10 +00:00
Chris Beams c69bbfe058 moving unit tests from .testsuite -> .aop 2008-12-12 01:32:27 +00:00
Chris Beams 1dade36c5d added svn:externals dependency on example.aspects from org.springframework.aop 2008-12-12 01:08:48 +00:00
Chris Beams 2b7bc1ea58 moving unit tests from .testsuite -> .aop 2008-12-12 01:02:05 +00:00
Chris Beams bd33eb7715 moving unit tests from .testsuite -> .aop 2008-12-12 00:57:14 +00:00
Chris Beams 1de06a619c moving unit tests from .testsuite -> .aop 2008-12-11 23:48:24 +00:00
Chris Beams 7bba0b7a69 moving unit tests from .testsuite -> .aop 2008-12-11 23:35:15 +00:00
Chris Beams c373688c00 moving unit tests from .testsuite -> .aop 2008-12-11 23:28:31 +00:00
Chris Beams e8cacade02 moving unit tests from .testsuite -> .aop 2008-12-11 23:24:12 +00:00
Chris Beams 78f8494bec moving unit tests from .testsuite -> .aop 2008-12-11 23:17:06 +00:00
Chris Beams 2ae8ce6fe8 upgraded integration test to JUnit 4 2008-12-11 22:41:00 +00:00
Chris Beams 08f1be7f85 moving unit tests from .testsuite -> .aop 2008-12-11 22:37:31 +00:00
Chris Beams 4b2a5a2383 moving unit tests from .testsuite -> .aop 2008-12-11 22:33:33 +00:00
Chris Beams 0ae3bbb0fc moving unit tests from .testsuite -> .aop 2008-12-11 22:18:50 +00:00
Chris Beams 57b5bdea20 moving unit tests from .testsuite -> .aop 2008-12-11 22:08:06 +00:00
Chris Beams 3412f9b6f9 moving unit tests from .testsuite -> .aop 2008-12-11 21:55:53 +00:00
Chris Beams 3ca36b39e0 added an eclipse team project set, added several files to svn:ignore for .testsuite 2008-12-11 01:05:29 +00:00
Chris Beams 0e3124179b added dependency on org.eclipse.persistence 1.0.1 2008-12-10 23:48:42 +00:00
Chris Beams f389a9a7b2 added org.springframework.testsuite back into the top-level build 2008-12-09 03:13:21 +00:00
Chris Beams 1e628e6af1 fixed additional breaking tests in .testsuite
+ both .testuite and .context.support require .jasper files to test against; pulling these files into .testsuite as an svn:external from .context.support to keep it DRY
2008-12-09 01:57:13 +00:00
Chris Beams 4093a53e6a fixed or @Ignore'd broken tests 2008-12-08 21:43:29 +00:00
Chris Beams 5c1b4347e7 further updates to .classpath / ivy files for javax.el
+ made everything consistent with the .iml files
2008-12-07 02:22:45 +00:00
Chris Beams b87ab27140 fixed broken tests
+ added dependency on antlr 2.7.6, eliminating ClassNotFoundExceptions
2008-12-07 02:03:17 +00:00
Chris Beams c04c06f27e fixed broken tests
+ ACATest was changed to ACATester during the move to Spring Build, but test-servlet.xml was not updated to reflect.  This was resulting in NoSuchBeanDefinitionExceptions.
2008-12-07 01:10:58 +00:00
Chris Beams f7dcf26193 fixed incorrect version for javax.el in .classpath files (was 2.1.0, now set to 1.0.0) 2008-12-07 01:08:37 +00:00
Juergen Hoeller b449f9fe10 added build module for changelog access 2008-12-05 07:46:51 +00:00
Juergen Hoeller df029b7f19 completed changelog 2008-12-05 07:45:18 +00:00
Juergen Hoeller c4401c4058 updated changelog 2008-12-05 07:25:33 +00:00
Juergen Hoeller 0ed916495c added @RequestHeader support 2008-12-05 07:17:31 +00:00
Juergen Hoeller b3866a974a fixed header value type 2008-12-05 07:07:06 +00:00
Juergen Hoeller 70b9dd6108 closed Java 5 code style gaps 2008-12-05 07:04:19 +00:00
Christian Dupuis 62a7457599 updated .classpath files to reflect recent changes in ivy files; aspectj.weaver 1.6.2 -> 1.6.2.RELEASE 2008-11-29 04:46:36 +00:00
Juergen Hoeller 71df72d634 properly scan subpackages as well (SPR-5324) 2008-11-28 14:05:15 +00:00
Juergen Hoeller 4f40a6c313 fixed javadoc errors 2008-11-28 13:56:30 +00:00
Juergen Hoeller f8c690c542 Java 5 code style 2008-11-28 11:39:36 +00:00
Juergen Hoeller fda7100866 consistent compilation against Servlet 2.5, JSP 2.1 and JUnit 4.5 2008-11-27 21:49:10 +00:00
Juergen Hoeller c8e23290ca consistent use of model name Strings 2008-11-27 21:24:42 +00:00
Juergen Hoeller e3cc9237c4 updated mocks to Servlet 2.5 and JSP 2.1 API level 2008-11-27 21:23:23 +00:00
Juergen Hoeller 85661c6882 Java 5 code style 2008-11-27 17:35:44 +00:00
Juergen Hoeller b0790bf5e7 Java 5 code style 2008-11-27 00:27:52 +00:00
Juergen Hoeller 6bbc966a21 fixed test source configuration 2008-11-27 00:26:21 +00:00
Juergen Hoeller c38bc4aa7b updated to AspectJ 1.6.2 2008-11-27 00:25:38 +00:00
Juergen Hoeller a449472e06 2008-11-27 00:22:10 +00:00
Juergen Hoeller f744808b49 removed JOTM and XAPool support 2008-11-27 00:21:29 +00:00
Costin Leau cf1f6606f4 + marked expression package as optional for spring-context 2008-11-26 10:26:46 +00:00
Costin Leau 8ba93ae12c + fix import for org.antlr package versions 2008-11-26 09:56:50 +00:00
Costin Leau dca286d065 + migrated some manifest template changed from 2.5.x to 3.0.x 2008-11-25 22:20:53 +00:00
Ben Hale 20bdc3c2d5 Polishing 2008-11-25 14:56:07 +00:00
Ben Hale 1a2135ec17 Publication is now automatic 2008-11-25 14:11:54 +00:00
Juergen Hoeller 29657105da Java 5 code style 2008-11-25 01:29:54 +00:00
Chris Beams 1f9e63af49 + Added necessary JPA dependencies to make Petclinic JUnit tests pass
+ Removed unused imports for @RequestParam
Note: While unit tests pass in eclipse, NoClassDefFound errors are still being thrown when tests are run from the command line.
2008-11-24 22:16:21 +00:00
Scott Andrews 96ba0d8ed6 added missing compile time deps to eclipse .classpath 2008-11-24 19:58:04 +00:00
Ben Hale b70fe3f0a1 Remove the -with-dependencies build 2008-11-24 10:57:32 +00:00
Scott Andrews 14d4630570 eclipse classpath updates 2008-11-21 15:42:47 +00:00
Scott Andrews 05815d6840 applying spring:url best practices 2008-11-21 14:51:57 +00:00
Scott Andrews eb89752f2b adding eclipse/wtp project settings 2008-11-21 14:51:16 +00:00
Juergen Hoeller 597e92a1a6 Java 5 code style 2008-11-21 00:04:10 +00:00
Juergen Hoeller 9e419dacfc added script resources 2008-11-20 23:54:00 +00:00
Arjen Poutsma f56ee389e7 Petclinic is RESTful. 2008-11-20 23:43:59 +00:00
Arjen Poutsma 1929f67f02 Petclinic is RESTful. 2008-11-20 23:42:20 +00:00
Juergen Hoeller e9649b3a34 added JUnit 4.5 compatibility note 2008-11-20 22:28:00 +00:00
Juergen Hoeller 582c564fa3 removed deprecated methods 2008-11-20 22:19:24 +00:00
Juergen Hoeller 3d1a709a5e fixed buildExceptionMessage to avoid potential NPE (SPR-5275) 2008-11-20 22:18:21 +00:00
Juergen Hoeller 0038aaa697 ContextLoaderListener extends ContextLoader 2008-11-20 22:12:56 +00:00
Arjen Poutsma 693ae0c2b0 Removing my own name from the pets database. 2008-11-20 22:02:48 +00:00
Juergen Hoeller ae34a8cb1b basic JUnit 4.5 compatibility (accepting use of deprecated SPI) 2008-11-20 21:33:08 +00:00
Juergen Hoeller 22d3272117 updated for JRuby 1.1 2008-11-20 19:47:57 +00:00
Juergen Hoeller 51577b2a07 actually delegate from resolveContextualObject to resolveReference 2008-11-20 19:46:28 +00:00
Juergen Hoeller 05bebb0c05 completed value annotation support; Java 5 code style updates 2008-11-20 17:33:46 +00:00
Arjen Poutsma 998511a375 Petclinic seems to work 2008-11-20 16:28:38 +00:00
Arjen Poutsma 29c8f37ccc Petclinic seems to work 2008-11-20 15:08:30 +00:00
Arjen Poutsma a51268a31c Added petclinic db 2008-11-20 15:05:37 +00:00
Arjen Poutsma 9d3cb3a47e Added petclinic sample 2008-11-20 13:50:01 +00:00
Juergen Hoeller 68dfd9efe8 fixed javax.el version range (following 2.5.6.A) 2008-11-20 12:52:24 +00:00
Juergen Hoeller 97b1fd0fc4 fixed javax.el version range (following 2.5.6.A) 2008-11-20 12:36:59 +00:00
Juergen Hoeller 347f34c68a EL container integration; support for contextual objects; removal of deprecated Spring 2.0 functionality; Java 5 code style 2008-11-20 02:10:53 +00:00
Ben Hale 369821dd66 spring-build update 2008-11-19 17:19:15 +00:00
Arjen Poutsma efb0ab79f9 SPR-5251: URI Templates support relative @RequestMappings (on class level, with more specific mapping on method level) 2008-11-19 17:12:44 +00:00
Arjen Poutsma 27ed13f44d SPR-5251: URI Templates support relative @RequestMappings (on class level, with more specific mapping on method level) 2008-11-19 17:08:34 +00:00
Arjen Poutsma 2b2805058b Javadoc 2008-11-19 15:44:21 +00:00
Arjen Poutsma cc5d3ec389 Increased timings of performance test, because the 100 ms does not work on our CI server. 2008-11-19 15:42:16 +00:00
Ben Hale 6379c69c38 Forgot a file 2008-11-19 15:19:40 +00:00
Ben Hale 4271f6d9e1 Upgrade to spring-build. Added dm Server library file 2008-11-19 15:13:53 +00:00
Arjen Poutsma 4e65f48f72 Added test and testsuite intellij projects. 2008-11-19 14:41:38 +00:00
Arjen Poutsma bb5150361b SPR-5251: URI Templates support infix variables: A-{B}-C 2008-11-19 11:48:13 +00:00
Arjen Poutsma 90ef7649c2 SPR-5251: URI Templates support /**-style paths 2008-11-18 15:12:28 +00:00
Arjen Poutsma b33db73c93 SPR-5251: URI Templates for @InitBinder 2008-11-18 12:37:12 +00:00
Arjen Poutsma fe72e8a5f7 SPR-5251: URI Templates in @RequestMapping 2008-11-17 16:00:03 +00:00
Scott Andrews a1faaad9fa SPR-5299 TLDs must be located under META-INF
Moving spring.tld and spring-form.tld under /src/main/resources/META-INF so they can be automatically discovered by the servlet container.
2008-11-17 15:10:26 +00:00
Arjen Poutsma fe29a711f3 Updated projects and ivy.xmls 2008-11-17 15:09:17 +00:00
Arjen Poutsma b313de0d1e Added test for ServletAnnotationMappingUtils 2008-11-17 13:39:10 +00:00
Scott Andrews 7d1f2bd1da SPR-5267 Support for PUT and DELETE in spring:form tag
Any HTTP method passed to the spring-form:form tag other then GET or POST will automatically be defaulted to POST on the form tag and a hidden input field is created with the requested HTTP method.  By default, the hidden field is named '_method', the name can be overridden using the methodParam attribute on the spring-form:form tag.
2008-11-16 22:03:16 +00:00
Scott Andrews 912c1234cd SPR-5298 JSP tag for building URLs with URI templates
Created spring:url and spring:param tags that enhance the functionality of the JSTL c:url tag.  URI templates are supported in the url value attribute.  They are resolved against the params defined inside the url tag body.  Params that are unable to be applied as URI template are added to the query string.
2008-11-16 21:04:46 +00:00
Scott Andrews ecb86b46a4 syncing eclipse classpath settings 2008-11-14 01:51:48 +00:00
Arjen Poutsma 24e34c894b Fixed test 2008-11-08 10:24:07 +00:00
Arjen Poutsma c62d4cb438 Generified StringUtils, and replaced StringBuffer usage with StringBuilder 2008-11-08 10:06:48 +00:00
Arjen Poutsma ba42594112 SPR-4927: Return 405 instead of 404 when HTTP method is not supported 2008-11-08 09:37:55 +00:00
Arjen Poutsma f7a45460cc SPR-5267: Support for PUT and DELETE in spring:form tag 2008-11-08 09:31:51 +00:00
Thomas Risberg e9877fa93a SPR-5272: added sort to the categories that didn't have it 2008-11-07 20:21:08 +00:00
Arjen Poutsma 477543241f SPR-5066 2008-11-07 10:22:43 +00:00
Arjen Poutsma aeced8b1a9 Made ThreadLocals generic. 2008-11-06 12:43:00 +00:00
Arjen Poutsma 0012c1e2da SPR-5237: Default value for @RequestParam 2008-11-04 14:39:53 +00:00
Scott Andrews a647f1629d syncing eclipse settings for unit tests 2008-11-03 18:41:02 +00:00
Arjen Poutsma 0bcc8fcead Moved tests from testsuite to web.servlet 2008-11-03 12:25:46 +00:00
Arjen Poutsma 91576da3b0 2008-11-03 12:03:40 +00:00
Arjen Poutsma 3d06246195 Moved tests from testsuite to web.servlet 2008-11-03 12:03:31 +00:00
Arjen Poutsma 74733d0d1d Moved tests from testsuite to web.servlet 2008-11-03 11:51:55 +00:00
Arjen Poutsma e31ab5a09b 2008-11-03 11:51:50 +00:00
Arjen Poutsma 12f295b6f5 Moved tests from testsuite to web.servlet 2008-11-03 11:47:12 +00:00
Arjen Poutsma 4ed458d909 Moved tests from testsuite to web.servlet 2008-11-03 11:45:48 +00:00
Arjen Poutsma 427f0d64b9 Moved tests from testsuite to web.servlet 2008-11-03 11:44:37 +00:00
Arjen Poutsma 764a2441cc Moved tests from testsuite to web.servlet 2008-11-03 11:34:38 +00:00
Arjen Poutsma b08d97e2ed Moved tests from testsuite to web.servlet 2008-11-03 11:29:38 +00:00
Arjen Poutsma 85d82f2244 Moved tests from testsuite to web.servlet 2008-11-03 11:27:39 +00:00
Arjen Poutsma 327c54839b 2008-11-03 11:27:18 +00:00
Arjen Poutsma f0e0d9b494 Moved tests from testsuite to web 2008-11-03 11:14:16 +00:00
Arjen Poutsma e7f5ebf992 2008-11-03 11:14:10 +00:00
Arjen Poutsma cc057d76eb 2008-11-03 11:09:23 +00:00
Arjen Poutsma a0adee719f Moved tests from testsuite to web 2008-11-03 11:09:18 +00:00
Arjen Poutsma 827f5687e8 2008-11-03 10:53:41 +00:00
Arjen Poutsma 24b7165031 Moved tests from testsuite to web.servlet 2008-11-03 10:53:34 +00:00
Arjen Poutsma 8a4a00bd87 Moved tests from testsuite to web 2008-11-03 10:50:10 +00:00
Arjen Poutsma 6c48de5ad5 Moved tests from testsuite to web.servlet 2008-11-03 10:49:21 +00:00
Arjen Poutsma 25dab06804 Moved tests from testsuite to web 2008-11-03 10:42:27 +00:00
Arjen Poutsma 88efc06a23 Moved tests from testsuite to core 2008-11-03 10:34:10 +00:00
Arjen Poutsma 7ecdf96db5 Added Tiger tests 2008-11-03 09:56:23 +00:00
Arjen Poutsma 0a89948f53 Added Tiger tests 2008-11-03 09:46:34 +00:00
Arjen Poutsma baac76e2b1 SPR-5249: Atom and RSS View 2008-10-31 17:48:50 +00:00
Arjen Poutsma c920c938a1 made test suit compile again 2008-10-31 17:44:13 +00:00
Arjen Poutsma 89095e625c Intellij projects 2008-10-31 17:43:22 +00:00
Arjen Poutsma 6f0342388c Moved tests over from testsuite to beans 2008-10-31 17:30:55 +00:00
Arjen Poutsma 97e1cdd5fc Moved tests from testsuite to jdbc 2008-10-31 10:02:48 +00:00
Arjen Poutsma d66956b117 Changed use of AssertThrows to @Test(expected = ...) 2008-10-31 10:00:38 +00:00
Arjen Poutsma 113366fc0c Changed use of AssertThrows to @Test(expected = ...) 2008-10-31 09:57:49 +00:00
Arjen Poutsma 2fd2a0d4d2 Changed use of AssertThrows to @Test(expected = ...) 2008-10-31 09:56:27 +00:00
Ben Hale c15b580a31 Update of spring-build 2008-10-31 09:51:37 +00:00
Arjen Poutsma 39d5e191a6 Moved tests from testsuite to tx 2008-10-31 09:50:03 +00:00
Arjen Poutsma 753c7351f5 Moved tests from testsuite to context 2008-10-31 09:47:46 +00:00
Arjen Poutsma 23a7015cbd Changed use of AssertThrows to @Test(expected = ...) 2008-10-31 09:46:08 +00:00
Ben Hale f1bd19f2f3 Added max memory for javadoc vm 2008-10-31 09:39:17 +00:00
Arjen Poutsma 92b0f55028 Moved tests from testsuite to core 2008-10-31 09:35:45 +00:00
Arjen Poutsma 0392b80ad3 Changed use of AssertThrows to @Test(expected = ...) 2008-10-31 09:34:55 +00:00
Arjen Poutsma e1536fcabb Moved tests from testsuite to core 2008-10-31 09:11:09 +00:00
Arjen Poutsma 87a2905c6e Changed use of AssertThrows to @Test(expected = ...) 2008-10-31 09:09:05 +00:00
Arjen Poutsma b100e21175 Changed use of AssertThrows to @Test(expected = ...) 2008-10-31 09:05:50 +00:00
Arjen Poutsma 2cf6dc4480 Changed use of AssertThrows to @Test(expected = ...) 2008-10-31 08:57:10 +00:00
Ben Hale 19debfb080 Fixed up version 2008-10-31 08:37:11 +00:00
Arjen Poutsma 616739a2bc Added test deps 2008-10-30 23:37:52 +00:00
Scott Andrews 7e19514658 eclipse settings to support unit test 2008-10-30 22:44:02 +00:00
Arjen Poutsma e48323aa56 Moved tests from testsuite to context 2008-10-30 22:19:18 +00:00
Arjen Poutsma 9ab100ae2e Moved tests from testsuite to context 2008-10-30 22:12:41 +00:00
Arjen Poutsma 4c7245d5de Moved tests from testsuite to context support 2008-10-30 22:10:08 +00:00
Arjen Poutsma a058729c2a Moved tests from testsuite to context 2008-10-30 21:57:15 +00:00
Arjen Poutsma 5bb0e15ce9 Moved tests from testsuite to context 2008-10-30 21:56:08 +00:00
Arjen Poutsma cd17ea06af Moved tests from testsuite to context 2008-10-30 21:55:44 +00:00
Arjen Poutsma 4ad4aad271 Moved tests from testsuite to context.support 2008-10-30 21:49:52 +00:00
Ben Hale dc2ca51f4e Reorder the publishing 2008-10-30 19:36:10 +00:00
Scott Andrews 8ff43f17a9 eclipse settings to support unit test 2008-10-30 19:27:01 +00:00
Arjen Poutsma 6c4941bbc5 Moved tests from testsuite to jdbc 2008-10-30 17:35:13 +00:00
Arjen Poutsma a02ee196b5 Moved tests from testsuite to jdbc 2008-10-30 17:24:23 +00:00
Arjen Poutsma faa74a395e Added test-time dep on commons collections 2008-10-30 17:17:32 +00:00
Arjen Poutsma b090bb9bda Moved tests from testsuite to jdbc 2008-10-30 17:17:12 +00:00
Arjen Poutsma 7a58c0e76f Moved tests from testsuite to orm 2008-10-30 16:55:52 +00:00
Arjen Poutsma fdd12e9a2f Moved tests from testsuite to orm 2008-10-30 16:55:08 +00:00
Arjen Poutsma 5aae231707 Removed raw TopLink support 2008-10-30 16:52:47 +00:00
Arjen Poutsma 59d3ebebc1 Removed raw TopLink support 2008-10-30 16:51:33 +00:00
Arjen Poutsma 11a2e40d41 Removed raw TopLink support 2008-10-30 16:51:09 +00:00
Arjen Poutsma 434c744842 Moved tests from testsuite to orm 2008-10-30 16:48:56 +00:00
Arjen Poutsma 3620181a10 Moved tests from testsuite to orm 2008-10-30 16:46:52 +00:00
Arjen Poutsma b7584189f5 Moved tests from testsuite to orm 2008-10-30 16:42:34 +00:00
Ben Hale ff92c1942b Missed namespace declaration 2008-10-30 16:34:21 +00:00
Ben Hale 68db46605e Publishing changes 2008-10-30 16:31:54 +00:00
Arjen Poutsma 100a80e112 Moved tests from testsuite to context and context support 2008-10-30 16:24:14 +00:00
Arjen Poutsma a1545e3f06 SPR-4419: Shallow ETag support 2008-10-30 15:29:19 +00:00
Arjen Poutsma 4f9fc753ca Added MD5 hashing utils. 2008-10-30 15:07:49 +00:00
Arjen Poutsma 988c66c1c3 Added MD5 hashing utils. 2008-10-30 15:07:00 +00:00
Arjen Poutsma 2a4f985753 IntelliJ projects 2008-10-29 18:29:36 +00:00
Scott Andrews a01aea4189 eclipse settings to support unit test 2008-10-29 18:22:25 +00:00
Arjen Poutsma eae7267929 Moved tests from testsuite to beans 2008-10-29 18:20:29 +00:00
Arjen Poutsma e31ad80a0b Moved tests from testsuite to beans 2008-10-29 18:14:22 +00:00
Arjen Poutsma e788cef856 Moved tests from testsuite to beans 2008-10-29 18:08:07 +00:00
Arjen Poutsma dcaf024e76 Moved tests from testsuite to beans 2008-10-29 18:03:15 +00:00
Arjen Poutsma 7f90f08705 Moved tests from testsuite to beans 2008-10-29 17:59:31 +00:00
Arjen Poutsma a1b810fbdf Moved tests from testsuite to beans 2008-10-29 17:55:46 +00:00
Arjen Poutsma 49447e9bc9 Moved tests over from testsuite to beans 2008-10-29 17:51:42 +00:00
Arjen Poutsma 4efc95c825 Moved tests over from testsuite to beans 2008-10-29 17:45:51 +00:00
Arjen Poutsma 25031ce86b Moved tests to context.support 2008-10-29 17:40:43 +00:00
Arjen Poutsma bd1e259b4a Moved tests over from testsuite to beans 2008-10-29 17:32:01 +00:00
Arjen Poutsma 6b80dbb4a9 Moved tests over from testsuite to core 2008-10-29 17:10:09 +00:00
Arjen Poutsma 6849cbd5ba Moved tests over from testsuite to core 2008-10-29 17:08:09 +00:00
Arjen Poutsma 474e70db87 Moved tests over from testsuite to context.support 2008-10-29 16:41:03 +00:00
Scott Andrews f91ac5a519 eclipse settings to support unit test 2008-10-29 15:00:00 +00:00
Arjen Poutsma 58dbd04cec Moved tests over from testsuite to test 2008-10-29 13:58:15 +00:00
Arjen Poutsma 10f09e6298 Moved tests over from testsuite to core 2008-10-29 13:52:06 +00:00
Arjen Poutsma 8a5971c85d Moved tests over from testsuite to core 2008-10-29 13:16:12 +00:00
Arjen Poutsma 75e8a09462 Moved tests over from testsuite to core 2008-10-29 12:58:14 +00:00
Arjen Poutsma 9151b9caae Moved tests over from testsuite to core 2008-10-29 12:56:06 +00:00
Arjen Poutsma 77be96aed6 Moved tests over from testsuite to beans 2008-10-29 12:49:51 +00:00
Arjen Poutsma 7a49f023d1 Moved tests over from testsuite to beans 2008-10-29 12:43:13 +00:00
Arjen Poutsma c9940742fd Removed Commons Attributes from web.servlet module 2008-10-29 12:23:19 +00:00
Arjen Poutsma f8b1e44734 Removed Commons Attributes from web.servlet module 2008-10-29 12:21:47 +00:00
Arjen Poutsma 4ddebb083e Moved tests over from testsuite to core 2008-10-29 12:17:13 +00:00
Arjen Poutsma da8b1c73ab Moved tests over from testsuite to core 2008-10-29 11:54:19 +00:00
Ben Hale e2a17f5458 Classpath updates 2008-10-29 11:32:38 +00:00
Arjen Poutsma 2ec60699ee Downgraded to JSP 2.0.0 2008-10-29 11:12:12 +00:00
Arjen Poutsma 742abde947 added target ignore 2008-10-29 10:25:31 +00:00
Arjen Poutsma 8aed1512fb Added test module 2008-10-29 01:18:26 +00:00
Arjen Poutsma 2c7d3673a8 Added testsuite, as one project for now. Will move individual tests to respective modules later 2008-10-29 01:17:37 +00:00
Arjen Poutsma 6b62bd0876 Added XSDs and namespace handler files. 2008-10-29 00:44:36 +00:00
Scott Andrews b0c9435b94 adding eclipse project settings for org.springframework.instrument.classloading 2008-10-28 14:50:18 +00:00
Arjen Poutsma f39be46cb1 Added IntelliJ project 2008-10-28 14:15:25 +00:00
Arjen Poutsma 6fe74a3e5a Added IntelliJ project 2008-10-28 14:13:25 +00:00
Arjen Poutsma bc53873707 Initial import of instrument.classloading module 2008-10-28 14:06:51 +00:00
Scott Andrews 123a40f166 adding eclipse project settings for org.springframework.jms 2008-10-28 14:02:58 +00:00
Arjen Poutsma e6b7d6222a Initial import of the JMS module 2008-10-28 13:47:36 +00:00
Arjen Poutsma dc20a9478f Upgraded to commons pooling 1.4.0 2008-10-28 13:29:20 +00:00
Scott Andrews a6984e2cdc adding eclipse settings for org.springframework.aspects 2008-10-28 13:09:57 +00:00
Arjen Poutsma 268cb4a1df Added IntelliJ projects 2008-10-28 12:28:35 +00:00
Arjen Poutsma 7d62aab6cc Initial import of the aspects module 2008-10-28 11:42:01 +00:00
Arjen Poutsma 827916b8e9 Bundlor templates now refer to Spring 3.0 2008-10-28 11:20:47 +00:00
Arjen Poutsma b0f24da5ca Added @Override annotations to web-portlet module 2008-10-28 10:55:11 +00:00
Arjen Poutsma 6a2daf7bf5 Added @Override and @Deprecated annotations to web-servlet module 2008-10-28 00:39:17 +00:00
Arjen Poutsma 3a26f0d896 Added @Override and @Deprecated annotations to context-support module 2008-10-28 00:34:38 +00:00
Arjen Poutsma 631e480f7a Added @Override and @Deprecated annotations to orm module 2008-10-28 00:18:02 +00:00
Arjen Poutsma 2ebff15fa3 Added @Override and @Deprecated annotations to web module 2008-10-28 00:15:39 +00:00
Arjen Poutsma cdb36efb0d Added @Override and @Deprecated annotations to jdbc module 2008-10-28 00:01:49 +00:00
Arjen Poutsma aa60746155 Added @Override annotations to transaction module 2008-10-27 23:52:03 +00:00
Arjen Poutsma 77ad22e338 Added @Override and @Deprecated annotations to context module 2008-10-27 23:45:57 +00:00
Arjen Poutsma b4b169c937 Removed unused import 2008-10-27 23:43:25 +00:00
Arjen Poutsma 7e39725685 Changed project from agent to instrument 2008-10-27 23:39:42 +00:00
Arjen Poutsma c0db207948 Added @Override annotations to aop module 2008-10-27 23:31:39 +00:00
Arjen Poutsma c8e5aa07a5 Added @Override annotations to beans module 2008-10-27 23:30:07 +00:00
Arjen Poutsma c07477da9c Added @Override annotations to core module 2008-10-27 23:25:04 +00:00
Arjen Poutsma 34ab7832c8 Reverted to r143, before IntelliJ screwed up the imports... 2008-10-27 23:23:13 +00:00
Scott Andrews 9178e97fb4 synchronized .classpath files with ivy.xml 2008-10-27 23:13:58 +00:00
Arjen Poutsma ac0c289149 Changed order of modules 2008-10-27 22:29:01 +00:00
Arjen Poutsma 564d4feba4 Added @Override annotations to core module 2008-10-27 22:26:10 +00:00
Arjen Poutsma d549941f5e Upgraded to Quartz 1.6.2 2008-10-27 22:07:01 +00:00
Arjen Poutsma 9770262910 Added hibernate.transform version 2008-10-27 21:54:00 +00:00
Arjen Poutsma 79a5eefe04 Added other modules to build 2008-10-27 21:44:09 +00:00
Scott Andrews 87f698cd24 fixing typos 2008-10-27 16:10:52 +00:00
Arjen Poutsma 07a5693b23 Moved portlet files to web package 2008-10-27 15:51:29 +00:00
Scott Andrews 51820d82f9 adding eclipse project settings 2008-10-27 15:48:40 +00:00
Arjen Poutsma 43505a6ce7 Upgraded ivy files to correspond to those in 2.5.5 2008-10-27 13:41:44 +00:00
Arjen Poutsma 577da8f891 Moved agent to instrument 2008-10-27 13:41:19 +00:00
Arjen Poutsma 4ea298a7b0 Initial import of portlet module 2008-10-27 12:01:57 +00:00
Arjen Poutsma 995a323a6f Initial import of test module 2008-10-27 11:59:27 +00:00
Arjen Poutsma af47a8b79b Initial import of web servlet module 2008-10-27 09:13:23 +00:00
Arjen Poutsma 4df7d71c1e Initial import of context support module 2008-10-26 17:08:38 +00:00
Ben Hale da208c282a spring-build updates 2008-10-25 18:30:33 +00:00
Scott Andrews 731c33f640 adding eclipse project meta-data, .classpath file is based on dependencies listed in ivy.xml 2008-10-24 21:05:25 +00:00
Arjen Poutsma 8e85702ff4 Changed module name, using correct bundlor template 2008-10-24 10:35:54 +00:00
Arjen Poutsma f87fc289fa Changed use of getRequestParameterMap() to getRequestParameterValuesMap() 2008-10-24 10:34:02 +00:00
Juergen Hoeller af62da8c45 updated module list 2008-10-24 10:03:04 +00:00
Arjen Poutsma d2bcdc655d Removed deprecated classes 2008-10-24 09:44:06 +00:00
Arjen Poutsma 04eaa47ec1 Initial import of web module 2008-10-24 09:42:55 +00:00
Arjen Poutsma d1061e7e9f Initial import of ORM 2008-10-24 09:06:30 +00:00
Arjen Poutsma c236f9fac7 Initial import of JDBC module 2008-10-23 14:23:13 +00:00
Arjen Poutsma 8c87d84728 Removed Commons Attributes support for Transactional 2008-10-23 14:10:34 +00:00
Arjen Poutsma 846b848fd3 Initial import of tx bundle 2008-10-23 14:09:34 +00:00
Arjen Poutsma 3b6f092219 Disabled JRuby for now, needs to be made 1.1 compliant 2008-10-23 13:48:19 +00:00
Arjen Poutsma 1b26e8f9c6 Removed commons atts support for JMX, made ModelMap generic 2008-10-23 10:35:03 +00:00
Arjen Poutsma edf0d8ebbe Initial version of context module 2008-10-23 10:19:23 +00:00
Arjen Poutsma d151c40333 Initial version of context module 2008-10-23 10:17:52 +00:00
Arjen Poutsma 20bc4f0817 Added agent module 2008-10-23 10:17:23 +00:00
Arjen Poutsma c26b9cbb75 Removed deprecated classes 2008-10-23 09:22:13 +00:00
Arjen Poutsma c48f8215e6 Moved over initial version of aop bundle 2008-10-23 09:17:09 +00:00
Arjen Poutsma 5cd2b80da7 Fixed manifest templates and pomx 2008-10-23 08:38:18 +00:00
Arjen Poutsma 4973f9387a Removed deprecated code 2008-10-23 08:36:52 +00:00
Arjen Poutsma f11d3436ed Moved over initial version of beans bundle 2008-10-22 16:13:37 +00:00
Arjen Poutsma 684a4f28c2 Added tiger classes of core bundle 2008-10-22 15:48:39 +00:00
Arjen Poutsma 4bc407fef8 - Removed deprecated code
- Removed backport-util-concurrent
- Removed commons attributes support
2008-10-22 15:37:12 +00:00
Arjen Poutsma 678e5b7cdf Moved over initial version of core bundle 2008-10-22 13:55:20 +00:00
Ben Hale 378e3a70fb Upgraded spring-build 2008-10-22 09:50:29 +00:00
Arjen Poutsma 99a441fe31 Added more modules 2008-10-21 08:04:24 +00:00
Andy Clement 470e086183 map access tests added 2008-09-17 16:20:40 +00:00
Andy Clement 769e706be7 removing: initializers/processors/in operator 2008-09-17 15:23:15 +00:00
Andy Clement afdf54eff8 renamed operator IS to INSTANCEOF, may yet delete.. 2008-09-16 17:20:03 +00:00
Andy Clement 39c966f419 bean references removed, no more @(context:beanname) 2008-09-16 17:13:31 +00:00
Andy Clement 95892dc993 removed lambda functions, local function and local variable references 2008-09-16 17:00:16 +00:00
Andy Clement efee3b3434 date literal removed 2008-09-16 16:50:00 +00:00
Andy Clement 8740b702f9 Changed so that existing getters/setters are used before direct field access is attempted 2008-09-16 00:00:06 +00:00
Andy Clement 17c88107d3 Removing functionality. Removed expression list support, cannot say (foo();bar()) any more 2008-09-15 21:55:11 +00:00
Andy Clement 4d43768889 Removing functionality. Removed soundslike/distanceto/like operators 2008-09-15 21:43:38 +00:00
Andy Clement 59a4427525 Final commit before the great 'stripdown'. Used clover to determine coverage and added tests as necessary. 2008-09-15 20:14:36 +00:00
Andy Clement 23db8b58da added test and behaviour for calling a java method with incorrect number of arguments 2008-08-18 22:43:17 +00:00
Andy Clement f79e2643a3 fixed up FunctionReference a bit - so it can call varargs methods 2008-08-18 22:36:25 +00:00
Andy Clement 2f05d70067 new function invocation tests for normal and error behaviour 2008-08-18 22:36:00 +00:00
Andy Clement 2fbb7ad327 changed vis of arg conversion code so function calls can use it 2008-08-18 22:35:21 +00:00
Andy Clement ec9cb8565b fixed damage caused by code formatter 2008-08-18 22:34:33 +00:00
Andy Clement 48055c6e20 added support for Integer > Float conversion.
Moved some tests from EvaluationTests into OperatorTests.
Fleshed out OperatorTests to verify type promotions for mixed type operands.
2008-08-18 17:54:01 +00:00
Andy Clement 776553cfbb more tests relating to reals 2008-08-18 17:06:24 +00:00
Andy Clement daf922456e more discussion points 2008-08-18 00:23:52 +00:00
Andy Clement 6e2682c78e code formatter chewed on it 2008-08-18 00:23:39 +00:00
Andy Clement 844b5236de corrected TODO 2008-08-18 00:23:13 +00:00
Andy Clement e443c836fe corrected use of AccessException (no longer used in ReflectionUtils) 2008-08-18 00:22:36 +00:00
Andy Clement 7fa4d9e928 moved TODOs to readme 2008-08-18 00:22:09 +00:00
Andy Clement 7d677b23d3 moved test into ParserErrorMessageTests 2008-08-18 00:21:45 +00:00
Andy Clement bea94c2371 modified Date tests 2008-08-18 00:21:21 +00:00
Andy Clement 90309a57d9 Made GMT the default Locale... 2008-08-18 00:21:00 +00:00
Andy Clement b9aa8552e0 added new TODO that the impl isn't as complete as it could be 2008-08-18 00:20:38 +00:00
Andy Clement bb2ef1fefa started fixing the formatting 2008-08-18 00:20:16 +00:00
Andy Clement 077fc1613d starting to sort out like/matches. Matches is the java regex related one. Like is the SQL related one. But the spring .net 'like' doesn't seem to be the same as the SQL doc I found for like... 2008-08-17 01:42:06 +00:00
Andy Clement c24df36689 moved some TODOs into readme 2008-08-17 01:28:37 +00:00
Andy Clement c6db7c41a4 improved javadoc, error handling and testing of matches 2008-08-17 01:28:26 +00:00
Andy Clement bb2ade5fdd javadoc 2008-08-17 01:27:59 +00:00
Andy Clement 29fe8da1ad fixing error handling in 'is' operator 2008-08-17 01:27:45 +00:00
Andy Clement 5c0d80ece7 fixing TODOs 2008-08-17 01:27:18 +00:00
Andy Clement 5d3e568326 fixing TODOs 2008-08-17 01:26:59 +00:00
Andy Clement 88c370ad5d fixing TODOs 2008-08-17 01:26:45 +00:00
Andy Clement 80075f18ce fixing TODOs 2008-08-17 01:26:11 +00:00
Andy Clement 9e7cb0e1cf fixing TODOs 2008-08-17 01:25:57 +00:00
Andy Clement 5a68d0ee4e fixing TODOs 2008-08-17 01:25:43 +00:00
Andy Clement a23311c4ba fixing TODOs 2008-08-17 01:25:19 +00:00
Andy Clement f82561ba53 javadoc for StandardTypeLocator and moved some TODOs to the readme 2008-08-16 18:31:31 +00:00
Andy Clement 1917a50f6f remove java.awt as a default import in the StandardTypeLocator 2008-08-16 18:21:03 +00:00
Andy Clement a54e442657 fixing TODOs 2008-08-16 01:57:46 +00:00
Andy Clement d69e9ef038 moved some TODOs out into here 2008-08-16 01:57:31 +00:00
Andy Clement b26c6df1a1 fixing TODOs 2008-08-16 01:57:13 +00:00
Andy Clement 2e7b0e3767 fixing TODOs 2008-08-16 01:56:58 +00:00
Andy Clement 3d54bd5aa3 fixing TODOs 2008-08-16 01:56:43 +00:00
Andy Clement 3ebf290534 fixing TODOs 2008-08-16 01:56:29 +00:00
Andy Clement e9ddd7151e added support for long[] in stringValueOf() - plus an error reported if the type passed in is not supported 2008-08-16 01:56:16 +00:00
Andy Clement e2ffac9a7c fixed to not throw classcastexception if condition doesnt evaluate to boolean 2008-08-16 01:45:18 +00:00
Andy Clement 144325eb06 removed some unused code, improved doc 2008-08-16 01:44:42 +00:00
Andy Clement 5bb6f9c75d correcting TODO 2008-08-16 01:44:12 +00:00
Andy Clement d2ab889b00 fixed some tests that will now break because int/long can be treated as boolean. May need to change again if real numbers get the same treatment. 2008-08-16 01:43:51 +00:00
Andy Clement 8d8a82b278 new tests for ternary - checking conversion of numbers to boolean and correct error when condition result not convertable to boolean 2008-08-16 01:43:15 +00:00
Andy Clement 8730cde270 removed redundant test - there is no non-optimal reflection accessor to test now 2008-08-16 01:42:39 +00:00
Andy Clement 3987316e4c Added SuppressWarning to hide all the warnings from the poor Antlr generated code. Code formatter also chewed on the file when saved. 2008-08-16 01:41:51 +00:00
Andy Clement 2d732ba398 javadoc 2008-08-16 01:41:13 +00:00
Andy Clement 3d4158ea51 implements new interface methods. sorting out javadoc 2008-08-16 01:40:53 +00:00
Andy Clement 98c82fe995 implement new Expression methods 2008-08-16 01:40:30 +00:00
Andy Clement ef8f882036 sorting out javadoc, promoted isWritable() to this interface (for now) 2008-08-16 01:40:11 +00:00
Andy Clement 1d2e89d79c added reset() method 2008-08-16 01:39:35 +00:00
Andy Clement 9750dfc3c4 hard coded support for boxing conversions. Added support for numbers (int/long) to boolean 2008-08-16 01:39:10 +00:00
Andy Clement ef16bff7ef TODO moved out to readme.txt which contains latest interesting issues - they should become JIRAs when the dust has settled 2008-08-16 00:13:38 +00:00
Andy Clement ead98462da added support for getValue(state,desiredType) so other nodes can ask for a transform to be done on the result if necessary, rather than duplicating conversion logic all over 2008-08-16 00:12:36 +00:00
Andy Clement a5a2331d41 corrected TODO task 2008-08-16 00:11:33 +00:00
Andy Clement 0adda58016 removed fixed TODO task 2008-08-16 00:10:59 +00:00
Andy Clement 36334ec21f allow for undefined target type 2008-08-16 00:10:27 +00:00
Andy Clement 1a31d25973 Parser error message improvements: enhanced harness and used it in new parser error message tests 2008-08-15 00:26:38 +00:00
Andy Clement cf35116af7 Parser error message improvements: better explanations and removed unused code 2008-08-15 00:26:11 +00:00
Andy Clement e78b9273f8 Code formatter has chewed on it a bit 2008-08-15 00:25:46 +00:00
Andy Clement 84990ad608 Parser error message improvements: grammar tweak to disallow 0xF00G (was treated as number then property reference - even without a dot) 2008-08-15 00:25:23 +00:00
Andy Clement 7d114a1a5e Parser error message improvements: new messages 2008-08-15 00:24:22 +00:00
Andy Clement 8c85e4a9a2 will now throw exception if trying to cram a long into an int that will not fit 2008-08-14 20:28:01 +00:00
Andy Clement d83205227e tweaked grammar to handle 0X as a hex prefix and removed 'u'/'U' from int suffixes for now 2008-08-14 20:27:35 +00:00
Andy Clement 4e33a2d6e4 tweaked grammar to handle 0X as a hex prefix and removed 'u'/'U' from int suffixes for now 2008-08-14 20:26:33 +00:00
Andy Clement 2173a49855 reworked int/hex/long handling - more consistent and reliable now 2008-08-14 20:25:20 +00:00
Andy Clement a06b5aaa8d reorganizing tests - extracting EvaluationTests out into other test classes. Started work on parser error message tests. 2008-08-14 20:24:31 +00:00
Andy Clement 73d6d0095f removed unused code 2008-08-12 22:19:46 +00:00
Andy Clement e20cbef134 Avoid calling deprecated Date ctor 2008-08-12 22:18:05 +00:00
Andy Clement dfc6928957 Suppress unchecked warning in generated code 2008-08-12 22:15:01 +00:00
Andy Clement 1707667489 changed to not use deprecated toURL() 2008-08-12 22:14:10 +00:00
Andy Clement f9285d54ab temporarily commnted out code (to remove the warnings) - this code may get used for error recovery 2008-08-12 22:13:50 +00:00
Andy Clement a9f2c90f10 remove currently unnecessary dependencies 2008-08-12 22:05:06 +00:00
Andy Clement 246cfa7945 Changed project name from spring-binding to org.springframework.expression 2008-08-12 21:50:59 +00:00
Andy Clement fe11c664d2 Changed test so expected results match actual on both windows and Mac 2008-08-12 21:21:35 +00:00
Andy Clement ef59904f00 Fixed generics warnings 2008-08-12 18:31:51 +00:00
Andy Clement 40eb38917e Fixed generics warning 2008-08-12 18:31:41 +00:00
Andy Clement c15760bcd1 Fixed generics warnings 2008-08-12 18:31:31 +00:00
Andy Clement 106131ab8f Marked unused values appropriately 2008-08-12 18:28:18 +00:00
Andy Clement b12dc5ba42 Removed unused code 2008-08-12 18:27:40 +00:00
Andy Clement c09d3971a1 Corrected javadoc 2008-08-12 18:26:54 +00:00
Andy Clement 9ad3863886 Commented out currently unused code 2008-08-12 18:25:19 +00:00
Andy Clement cfdb8e01eb Fixed unnecessary casts 2008-08-12 18:23:39 +00:00
Andy Clement 49bef5a39f Fixed unnecessary casts 2008-08-12 18:23:29 +00:00
Andy Clement 2e0006f8ac Added suppression for warnings since these types are generated 2008-08-12 18:20:45 +00:00
Andy Clement 1636f3cd32 Fixed rogue import 2008-08-12 18:17:25 +00:00
Andy Clement c2f7b65751 First drop of SPEL 2008-08-12 16:36:40 +00:00
Andy Clement 6a52183414 First drop of SPEL 2008-08-12 16:27:53 +00:00
Andy Clement 65049ac8b4 First drop of SPEL 2008-08-12 16:27:20 +00:00
Andy Clement a2401ea10f First drop of SPEL 2008-08-12 16:25:32 +00:00
Andy Clement d8743000a0 First drop of SPEL 2008-08-12 16:23:50 +00:00
Andy Clement c2624ea05e First drop of SPEL 2008-08-12 16:14:43 +00:00
Andy Clement ca93824d2b Modified public interface to expression parsing 2008-08-11 18:37:11 +00:00
Ben Hale ca010140fb Initial code checkin 2008-07-11 06:34:50 +00:00
Ben Hale 549e526ab0 Added spring-build 2008-07-10 22:01:27 +00:00
Ben Hale 8119659fb1 Initial structure 2008-07-10 22:00:24 +00:00
4937 changed files with 699565 additions and 678 deletions
-57
View File
@@ -1,57 +0,0 @@
name: Build and Deploy Documentation
run-name: ${{ format('{0} ({1})', github.workflow, github.event.inputs.build-refname || 'all') }}
on:
workflow_dispatch:
inputs:
build-refname:
description: Enter git refname to build (e.g., 5.7.x).
required: false
push:
branches: docs-build
env:
GRADLE_ENTERPRISE_SECRET_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_SECRET_ACCESS_KEY }}
permissions: read-all
jobs:
build-and-deploy-docs:
name: Build and Deploy Documentation
if: github.repository_owner == 'spring-projects'
runs-on: ubuntu-latest
steps:
- name: Check Out
uses: actions/checkout@v4
with:
fetch-depth: 5
- name: Set Up Java
uses: actions/setup-java@v4
with:
distribution: 'liberica'
java-version: |
25
17
- name: Set Up Gradle
uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4.4.1
with:
cache-read-only: false
- name: Set up refname build
if: github.event.inputs.build-refname
run: |
git fetch --depth 1 https://github.com/$GITHUB_REPOSITORY ${{ github.event.inputs.build-refname }}
echo BUILD_REFNAME=${{ github.event.inputs.build-refname }} >> $GITHUB_ENV
echo BUILD_VERSION=$(git cat-file --textconv FETCH_HEAD:gradle.properties | sed -n '/^version=/ { s/^version=//;p }') >> $GITHUB_ENV
- name: Run Antora
run: ./gradlew antora
- name: Copy the cache to be included in the site
run: cp -rf build/antora/inject-collector-cache-config-extension/.cache build/site/
- name: Publish Docs
uses: spring-io/spring-doc-actions/rsync-antora-reference@v0.0.22
with:
docs-username: ${{ secrets.DOCS_USERNAME }}
docs-host: ${{ secrets.DOCS_HOST }}
docs-ssh-key: ${{ secrets.DOCS_SSH_KEY }}
docs-ssh-host-key: ${{ secrets.DOCS_SSH_HOST_KEY }}
- name: Bust Cloudflare Cache
uses: spring-io/spring-doc-actions/bust-cloudflare-antora-cache@v0.0.22
with:
context-root: spring-framework
cloudflare-zone-id: ${{ secrets.CLOUDFLARE_ZONE_ID }}
cloudflare-cache-token: ${{ secrets.CLOUDFLARE_CACHE_TOKEN }}
-56
View File
@@ -1,56 +0,0 @@
# Miscellaneous
*.java.hsp
*.sonarj
*.sw*
.DS_Store
build.sh
integration-repo
ivy-cache
argfile*
activemq-data/
classes/
# Log files
jxl.log
jmx.log
derby.log
# Gradle artifacts
.gradle
.gradletasknamecache
/build
buildSrc/build
/spring-*/build
/framework-bom/build
/framework-docs/build
/integration-tests/build
/src/asciidoc/build
spring-test/test-output/
# Maven artifacts
pom.xml
/target/
# Eclipse artifacts, including WTP generated manifests
bin
.classpath
.project
.settings
.springBeans
spring-*/src/main/java/META-INF/MANIFEST.MF
# IDEA artifacts and output dirs
*.iml
*.ipr
*.iws
.idea
out
test-output
atlassian-ide-plugin.xml
# VS Code
.vscode/
cached-antora-playbook.yml
node_modules
-3
View File
@@ -1,3 +0,0 @@
# Enable auto-env through the sdkman_auto_env config
# Add key=value pairs of SDKs to use below
java=17.0.12-librca
-140
View File
@@ -1,140 +0,0 @@
= Spring Framework Docs Build
You're currently viewing the Antora playbook branch.
The playbook branch hosts the docs build that is used to build and publish the production docs site.
The Spring Framework reference docs are built using https://antora.org[Antora].
This README covers how to build the docs in a software branch as well as how to build the production docs site locally.
== Overview
To prepare your system for building the documentation, <<prerequisites,install the prerequisites>> and then <<build-main,create your workspace and build the main branch documentation>>.
Once you've completed those steps, follow the instructions in <<build-branch,Build the 6.0.x branch documentation>> to learn how to build the documentation for a version branch you haven't previously checked out.
To build the production site documentation on your computer, follow the instructions in <<prerequisites,Prerequisites>>, <<build-main,Build the main branch documentation>>, and then <<build-production,Build the production documentation site>>.
.Branch checkout instead of worktrees
[NOTE]
====
If you prefer to set up your workspace without worktrees, complete the steps in <<prerequisites,Prerequisites>> and clone the project repository onto your computer.
Then follow the instructions in each section starting from the `sdk env || sdk env install` step once you've checked out the desired branch.
====
[#prerequisites]
== Prerequisites (everyone)
These instructions assume you already have basic tools on your system, including bash, zip, unzip, git, and curl.
In addition to these basic tools, you need https://sdkman.io/install[SDKMAN!] installed so that the correct JDK is set for each branch.
. Open your terminal and enter the following command:
+
--
$ curl -s "https://get.sdkman.io" | bash
This command downloads and installs SDKMAN!
Once installation is complete, you should see a command displayed in your terminal that will initiate SDKMAN.
--
. Copy the command displayed in your terminal and run it.
`$HOME` is the path unique to your computer (e.g., _home/my-jam/.sdkman/bin/sdkman-init.sh_).
$ source "$HOME/.sdkman/bin/sdkman-init.sh"
You'll use SDKMAN in the next sections to install and switch to the JDK required for each branch.
Now you're ready to <<build-main,create your workspace>>.
[#build-main]
== Build the main branch documentation (writers)
Your workspace will be the folder that contains the git worktrees of the project.
. In your terminal, create a directory for the project and then change into that directory.
$ mkdir spring-framework
$ cd spring-framework
. Clone the project repository and create the primary worktree for the main branch.
Then change into the new _main_ folder.
$ git clone https://github.com/spring-projects/spring-framework main
$ cd main
. Switch to the required JDK using SDKMAN by running the following command:
+
--
$ sdk env || sdk env install
SDKMAN will switch to the required JDK or install it if it isn't present.
--
. Generate the documentation with Antora using the following command:
+
--
$ ./gradlew -PbuildSrc.skipTests=true :framework-docs:antora
This command will build the documentation, including any generated attributes, for the main branch.
--
. Navigate to _$HOME/spring-framework/main/framework-docs/build/site/index.html_ to view the generated documentation.
[#build-branch]
== Build the 6.0.x branch documentation (writers)
NOTE: The instructions in this section assume you've completed the steps in the <<build-main,previous section>>.
After creating the worktree for the main branch, you can set up a worktree for any other branches you'll work on in the future.
In this section, you'll create a worktree for the 6.0.x branch in your project workspace.
. To add a worktree, you have to be in a worktree.
In your terminal, change to the _main_ folder if you aren't already in it, e.g., _$HOME/spring-framework/main_.
Set up a worktree for the 6.0.x branch and then change into the new directory by running the following commands:
$ git worktree add ../6.0.x 6.0.x --track
$ cd ../6.0.x
. Switch to the required JDK or install it.
$ sdk env || sdk env install
. Generate the documentation with the following command:
+
--
$ ./gradlew -PbuildSrc.skipTests=true :framework-docs:antora
This command will build the documentation, including any generated attributes, for the 6.0.x branch.
--
. Navigate to _$HOME/spring-framework/6.0.x/docs/build/site/index.html_ to view the generated documentation.
[#build-production]
== Build the production documentation site (docs manager)
NOTE: The instructions in this section assume you've <<build-main,prepared your workspace and created the worktree for the main branch>>.
To build the project's production site, you'll set up a worktree for the docs-build branch of the repository.
. To add a worktree, you have to be in a worktree.
In your terminal, change to the _main_ folder if you aren't already in it, e.g., _$HOME/spring-framework/main_.
Run the following command to set up the worktree for the _docs-build_ branch.
Then change into the new _docs-build_ directory.
$ git worktree add ../docs-build docs-build --track
$ cd ../docs-build
. Switch to the required JDK or install it.
$ sdk env || sdk env install
. Generate the documentation for the project's production site using the following command:
+
--
$ ./gradlew antora
This command will build all of the documentation included in the project's production site from the repository on GitHub.
To build the documentation from the current clone, using any worktrees that are available, use the following command instead:
$ ./gradlew antora --playbook local-antora-playbook.yml
--
. Navigate to _$HOME/spring-framework/docs-site/build/site/index.html_ to view the generated documentation.
-41
View File
@@ -1,41 +0,0 @@
antora:
extensions:
- require: '@springio/antora-extensions'
root_component_name: 'framework'
site:
title: Spring Framework
url: https://docs.spring.io/spring-framework/reference
robots: allow
git:
ensure_git_suffix: false
content:
sources:
- url: https://github.com/spring-projects/spring-framework
# Refname matching:
# https://docs.antora.org/antora/latest/playbook/content-refname-matching/
# branches: We include snapshots for main, 6.2.x, and 7.0.x to 9.*.x.
branches: ['main', '6.2.x', '{7..9}.+({0..9}).x']
# tags: include all releases from 6.2.0 to 9.*.*.
tags: ['v6.2.+({0..9})', 'v{7..9}.+({0..9}).+({0..9})?(-{RC,M}*)']
start_path: framework-docs
asciidoc:
extensions:
- '@asciidoctor/tabs'
- '@springio/asciidoctor-extensions'
- '@springio/asciidoctor-extensions/include-code-extension'
attributes:
page-stackoverflow-url: https://stackoverflow.com/questions/tagged/spring
page-pagination: ''
hide-uri-scheme: '@'
tabs-sync-option: '@'
include-java: 'example$docs-src/main/java/org/springframework/docs'
urls:
latest_version_segment_strategy: redirect:to
latest_version_segment: ''
redirect_facility: httpd
runtime:
log:
failure_level: warn
ui:
bundle:
url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.4.26/ui-bundle.zip
+12
View File
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module relativePaths="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
+36
View File
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="build-spring-framework" default="precommit">
<path id="bundles">
<pathelement location="../org.springframework.instrument"/>
<pathelement location="../org.springframework.instrument.classloading"/>
<pathelement location="../org.springframework.asm"/>
<pathelement location="../org.springframework.core"/>
<pathelement location="../org.springframework.expression"/>
<pathelement location="../org.springframework.beans"/>
<pathelement location="../org.springframework.aop"/>
<pathelement location="../org.springframework.context"/>
<pathelement location="../org.springframework.transaction"/>
<pathelement location="../org.springframework.oxm"/>
<pathelement location="../org.springframework.jms"/>
<pathelement location="../org.springframework.aspects"/>
<pathelement location="../org.springframework.jdbc"/>
<pathelement location="../org.springframework.web"/>
<pathelement location="../org.springframework.orm"/>
<pathelement location="../org.springframework.context.support"/>
<pathelement location="../org.springframework.web.servlet"/>
<pathelement location="../org.springframework.web.portlet"/>
<pathelement location="../org.springframework.test"/>
<pathelement location="../org.springframework.spring-library"/>
<pathelement location="../org.springframework.integration-tests"/>
</path>
<property file="${basedir}/../build.properties"/>
<import file="${basedir}/package-top-level.xml"/>
<import file="${basedir}/publish-top-level.xml"/>
<import file="${basedir}/publish-documentation.xml"/>
<import file="${basedir}/../spring-build/multi-bundle/default.xml"/>
<target name="precommit" depends="clean,clean-integration,test"/>
</project>
+130
View File
@@ -0,0 +1,130 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="generate-poms" xmlns:ivy="antlib:org.apache.ivy.ant">
<property file="${basedir}/../build.properties"/>
<import file="${basedir}/../spring-build/multi-bundle/default.xml"/>
<path id="modules-to-process">
<pathelement location="../org.springframework.instrument"/>
<pathelement location="../org.springframework.instrument.classloading"/>
<pathelement location="../org.springframework.asm"/>
<pathelement location="../org.springframework.core"/>
<pathelement location="../org.springframework.expression"/>
<pathelement location="../org.springframework.beans"/>
<pathelement location="../org.springframework.aop"/>
<pathelement location="../org.springframework.context"/>
<pathelement location="../org.springframework.transaction"/>
<pathelement location="../org.springframework.oxm"/>
<pathelement location="../org.springframework.jms"/>
<pathelement location="../org.springframework.aspects"/>
<pathelement location="../org.springframework.jdbc"/>
<pathelement location="../org.springframework.web"/>
<pathelement location="../org.springframework.orm"/>
<pathelement location="../org.springframework.context.support"/>
<pathelement location="../org.springframework.web.servlet"/>
<pathelement location="../org.springframework.web.portlet"/>
<pathelement location="../org.springframework.test"/>
</path>
<condition property="maven.extension" value=".bat" else="">
<os family="windows"/>
</condition>
<property name="mvn.exe" value="mvn${maven.extension}"/>
<target name="test">
<echo message="pom version = ${project.version}"/>
</target>
<target name="generate-pom" depends="ivy.init">
<all-bundles target="do-generate-pom" buildpathRef="modules-to-process"/>
</target>
<target name="generate-pom-test">
<all-bundles target="do-generate-pom-test" buildpathRef="modules-to-process"/>
</target>
<target name="do-generate-pom" depends="ivy.init">
<delete file="pom.xml" quiet="true"/>
<delete file="central-pom.xml" quiet="true"/>
<ivy:makepom ivyfile="ivy.xml" pomfile="pom.xml">
<mapping conf="compile" scope="compile"/>
<mapping conf="test" scope="test"/>
<mapping conf="provided" scope="provided"/>
<mapping conf="runtime" scope="runtime"/>
</ivy:makepom>
<xmlproperty file="../org.springframework.spring-library/pom.xml"/>
<replaceregexp file="pom.xml"
match="&lt;version>.*?&lt;/version>"
replace="&lt;version>@project-version@&lt;/version>" />
<exec executable="${mvn.exe}" failonerror="true">
<arg line="org.springframework.build.repository:org.springframework.build.repository.maven:create-central"/>
</exec>
<move file="pom.xml" tofile="pom-bundle.xml"/>
<move file="central-pom.xml" tofile="pom.xml"/>
<replace file="pom.xml">
<replacetoken><![CDATA[ <version>@project-version@</version>]]></replacetoken>
<replacevalue><![CDATA[ <version>@project-version@</version>
<parent>
<groupId>org.springframework</groupId>
<artifactId>spring-parent</artifactId>
<relativePath>../org.springframework.spring-parent</relativePath>
<version>@project-version@</version>
</parent>
]]></replacevalue>
</replace>
<replace file="pom.xml" token="@project-version@" value="${project.version}"/>
<replace file="pom.xml" token="latest.integration" value="${project.version}"/>
<fixcrlf srcDir="."
eol="lf"
eof="remove"
includes="pom.xml"/>
</target>
<target name="remove-unresolved-references">
<!-- TODO in spring-context these are only found in S2 bundle repo, not maven central -->
<replace file="pom.xml">
<replacetoken><![CDATA[<dependency>
<groupId>com.oracle.oc4j</groupId>
<artifactId>oracle.classloader</artifactId>
<version>10.1.3.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sun.enterprise</groupId>
<artifactId>com.sun.enterprise.loader</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
]]></replacetoken>
<replacevalue><![CDATA[]]></replacevalue>
</replace>
</target>
<target name="do-generate-pom-test">
<exec executable="${mvn.exe}" failonerror="true">
<env key="MAVEN_TERMINATE_CMD" value="on" />
<arg line="-P stage,fast install"/>
</exec>
</target>
</project>
+11
View File
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="package-bundle">
<import file="publish-maven.xml"/>
<target name="package" depends="ivy.init">
<dist-jar/>
<src-jar/>
</target>
</project>
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="package-library">
<import file="publish-maven.xml"/>
<target name="package" depends="ivy.init">
<dist-jar/>
</target>
</project>
@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="package-top-level">
<target name="package" description="Creates the release package for this project">
<delete dir="${package.output.dir}" quiet="true"/>
<mkdir dir="${package.output.dir}"/>
<delete file="${package.output.file}" quiet="true"/>
<mkdir dir="${artifacts.dir}"/>
<all-bundles target="package">
<property name="package.output.dir" value="${package.output.dir}"/>
</all-bundles>
<ant target="javadoc-api" inheritAll="false">
<property name="target.dir" value="${package.docs.dir}"/>
</ant>
<!-- Reference Document START-->
<path id="doc.projects">
<path location="${basedir}/../spring-framework-reference"/>
</path>
<all-bundles target="doc" buildpathRef="doc.projects"/>
<all-bundles target="package" buildpathRef="doc.projects">
<property name="package.output.dir" value="${package.output.dir}"/>
</all-bundles>
<!-- Reference Document END-->
<copy todir="${package.output.dir}">
<fileset dir="${basedir}/resources"/>
</copy>
<copy todir="${package.output.dir}/projects">
<fileset dir="${basedir}/..">
<exclude name="*/target/**"/>
<exclude name="integration-repo/**"/>
<exclude name="ivy-cache/**"/>
<!--exclude name="ivy-cache/repository/org.apache.velocity/org.apache.velocity.docbookframework.dist/**"/-->
<exclude name="spring-build/lib/docbook/**" />
<exclude name="**/*OLD*/**"/>
</fileset>
</copy>
<replaceregexp match="build.stamp.*\n" replace="" flags="g"
file="${package.output.dir}/projects/build.properties"/>
<replaceregexp match="release.type=.*" replace="release.type=integration" flags="g"
file="${package.output.dir}/projects/build.properties"/>
<zip destfile="${package.output.file}">
<zipfileset dir="${package.dir}">
<exclude name="${package.basename}/docs/**"/>
<exclude name="${package.basename}/projects/ivy-cache/**"/>
</zipfileset>
</zip>
<zip destfile="${artifacts.dir}/${package.basename}-with-docs.zip">
<zipfileset dir="${package.dir}">
<exclude name="${package.basename}/projects/ivy-cache/**"/>
</zipfileset>
</zip>
<!--zip destfile="${artifacts.dir}/${package.basename}-with-dependencies.zip">
<zipfileset dir="${package.dir}"/>
</zip-->
</target>
</project>
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="publish-documentation">
<!-- Main targets -->
<target name="publish-documentation" depends="publish-documentation.init">
<sshexec host="spring02.managed.contegix.com" 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}"
keyfile="${key.file}" passphrase="${passphrase}" sftp="true" verbose="true">
<fileset dir="${package.output.dir}">
<include name="changelog.txt" />
<include name="license.txt" />
<include name="readme.txt" />
</fileset>
<fileset dir="${package.docs.dir}" />
</scp>
<sshexec host="spring02.managed.contegix.com" 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>
<!-- Other targets -->
<target name="publish-documentation.init">
<fail message="The 'username' property must be set">
<condition>
<not>
<isset property="username"/>
</not>
</condition>
</fail>
<fail message="The 'key.file' property must be set">
<condition>
<not>
<isset property="key.file"/>
</not>
</condition>
</fail>
<fail message="The 'passphrase' property must be set">
<condition>
<not>
<isset property="passphrase"/>
</not>
</condition>
</fail>
</target>
</project>
+95
View File
@@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="publish-maven-central-only-pom" xmlns:maven="antlib:org.apache.maven.artifact.ant">
<description>
This build file publishes to a maven repository and two ways.
1. Publish jar, source-jar, and pom artifacts.
2. Publish only the pom artifact.
The additional complexity in the implementation is due to a bug in the maven ant tasks version 2.0.8 that
prevents deploying to a local file repository on windows.
</description>
<condition property="is.windows" value="windows">
<os family="windows"/>
</condition>
<!-- top level targets -->
<target name="publish-maven-central-only-pom-artifacts" depends="publish-central-only-pom-windows,publish-central-only-pom-unix">
</target>
<target name="publish-maven-central-code-artifacts" depends="publish-central-windows,publish-code-unix">
</target>
<target name="publish-maven-milestone-only-pom-artifacts" depends="maven.init">
<maven:deploy>
<remoteRepository url="s3://${publish.bucket}/maven/bundles/${adjusted.release.type}">
<authentication username="${accessKey}" passphrase="${secretKey}"/>
</remoteRepository>
<pom file="${local.pom.output.file}"/>
</maven:deploy>
</target>
<target name="publish-maven-milestone-code-artifacts" depends="maven.init">
<maven:deploy file="${jar.output.file}">
<remoteRepository url="s3://${publish.bucket}/maven/bundles/${adjusted.release.type}">
<authentication username="${accessKey}" passphrase="${secretKey}"/>
</remoteRepository>
<pom file="${pom.output.file}"/>
<attach file="${source-jar.output.file}" classifier="sources"/>
</maven:deploy>
</target>
<target name="install-pom" depends="maven.init">
<maven:install>
<pom file="${local.pom.output.file}"/>
</maven:install>
</target>
<!-- Supporting targets -->
<!-- POM only deployment -->
<target name="publish-central-only-pom-windows" depends="maven.init" if="is.windows">
<maven:deploy>
<!-- Due to http://jira.codehaus.org/browse/MANTTASKS-103 in 2.0.8 on windows, fixed in 2.0.9 -->
<!-- Assuming using local file, value of variable should be of the form L:\temp\maven-repo-test -->
<remoteRepository id="localDisk" url="file:${maven.central.repository}"/>
<pom file="${local.pom.output.file}"/>
</maven:deploy>
</target>
<target name="publish-central-only-pom-unix" depends="maven.init" unless="is.windows">
<maven:deploy>
<remoteRepository url="${maven.central.repository}"/>
<pom file="${local.pom.output.file}"/>
</maven:deploy>
</target>
<!-- jar, source-jar and POM deployment -->
<target name="publish-central-windows" depends="maven.init">
<maven:deploy file="${jar.output.file}">
<!-- Due to http://jira.codehaus.org/browse/MANTTASKS-103 in 2.0.8 on windows, fixed in 2.0.9 -->
<!-- Assuming using local file, value of variable should be of the form L:\temp\maven-repo-test -->
<remoteRepository id="localDisk" url="file:${maven.central.repository}"/>
<pom file="${local.pom.output.file}"/>
<attach file="${source-jar.output.file}" classifier="sources"/>
</maven:deploy>
</target>
<target name="publish-code-unix" depends="maven.init" unless="is.windows">
<maven:deploy file="${jar.output.file}">
<remoteRepository url="${maven.central.repository}"/>
<pom file="${local.pom.output.file}"/>
<attach file="${source-jar.output.file}" classifier="sources"/>
</maven:deploy>
</target>
</project>
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="publish-top-level" xmlns:aws="antlib:org.springframework.build.aws">
<target name="publish" depends="publish-package, publish-multi-bundle.publish"
description="Publish package, Ivy, and Maven artifacts"/>
<target name="publish-package" depends="aws.init">
<checksum file="${package.output.file}" algorithm="sha1"/>
<checksum file="${artifacts.dir}/${package.basename}-with-docs.zip" algorithm="sha1"/>
<!--checksum file="${artifacts.dir}/${package.basename}-with-dependencies.zip" algorithm="sha1"/-->
<aws:s3 accessKey="${accessKey}" secretKey="${secretKey}">
<upload bucketName="dist.${bucket.basename}" file="${package.output.file}"
toFile="${adjusted.release.type}/${project.key}/${package.file.name}" publicRead="true">
<metadata name="project.name" value="Spring Framework"/>
<metadata name="release.type" value="${release.type}"/>
<metadata name="bundle.version" value="${bundle.version}"/>
<metadata name="package.file.name" value="${package.file.name}"/>
</upload>
<upload bucketName="dist.${bucket.basename}" file="${package.output.file}.sha1"
toFile="${adjusted.release.type}/${project.key}/${package.file.name}.sha1" publicRead="true"/>
<upload bucketName="dist.${bucket.basename}" file="${artifacts.dir}/${package.basename}-with-docs.zip"
toFile="${adjusted.release.type}/${project.key}/${package.basename}-with-docs.zip" publicRead="true">
<metadata name="project.name" value="Spring Framework"/>
<metadata name="release.type" value="${release.type}"/>
<metadata name="bundle.version" value="${bundle.version}"/>
<metadata name="package.file.name" value="${package.basename}-with-docs.zip"/>
</upload>
<upload bucketName="dist.${bucket.basename}" file="${artifacts.dir}/${package.basename}-with-docs.zip.sha1"
toFile="${adjusted.release.type}/${project.key}/${package.basename}-with-docs.zip.sha1" publicRead="true"/>
<!--upload bucketName="dist.${bucket.basename}" file="${artifacts.dir}/${package.basename}-with-dependencies.zip"
toFile="${adjusted.release.type}/${project.key}/${package.basename}-with-dependencies.zip" publicRead="true">
<metadata name="project.name" value="Spring Framework"/>
<metadata name="release.type" value="${release.type}"/>
<metadata name="bundle.version" value="${bundle.version}"/>
<metadata name="package.file.name" value="${package.basename}-with-dependencies.zip"/>
</upload>
<upload bucketName="dist.${bucket.basename}" file="${artifacts.dir}/${package.basename}-with-dependencies.zip.sha1"
toFile="${adjusted.release.type}/${project.key}/${package.basename}-with-dependencies.zip.sha1" publicRead="true"/-->
</aws:s3>
</target>
</project>
+57
View File
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="publish-spring-framework" xmlns:maven="antlib:org.apache.maven.artifact.ant">
<property file="${basedir}/../build.properties"/>
<import file="${basedir}/../spring-build/multi-bundle/default.xml"/>
<path id="modules-with-code-artifacts">
<pathelement location="../org.springframework.instrument"/>
<pathelement location="../org.springframework.instrument.classloading"/>
<pathelement location="../org.springframework.asm"/>
<pathelement location="../org.springframework.core"/>
<pathelement location="../org.springframework.expression"/>
<pathelement location="../org.springframework.beans"/>
<pathelement location="../org.springframework.aop"/>
<pathelement location="../org.springframework.context"/>
<pathelement location="../org.springframework.transaction"/>
<pathelement location="../org.springframework.oxm"/>
<pathelement location="../org.springframework.jms"/>
<pathelement location="../org.springframework.aspects"/>
<pathelement location="../org.springframework.jdbc"/>
<pathelement location="../org.springframework.web"/>
<pathelement location="../org.springframework.orm"/>
<pathelement location="../org.springframework.context.support"/>
<pathelement location="../org.springframework.web.servlet"/>
<pathelement location="../org.springframework.web.portlet"/>
<pathelement location="../org.springframework.test"/>
</path>
<path id="modules-with-only-pom-artifacts">
<pathelement location="../org.springframework.spring-library"/>
<pathelement location="../org.springframework.spring-parent"/>
</path>
<!-- for milestones -->
<target name="publish-maven-milestone" depends="publish-maven-milestone-only-pom">
<all-bundles target="publish-maven-milestone-code-artifacts" buildpathRef="modules-with-code-artifacts"/>
</target>
<target name="publish-maven-milestone-only-pom">
<all-bundles target="publish-maven-milestone-only-pom-artifacts" buildpathRef="modules-with-only-pom-artifacts"/>
</target>
<!-- for releases -->
<target name="publish-maven-central-release" depends="publish-maven-central-only-pom-release">
<all-bundles target="publish-maven-central-code-artifacts" buildpathRef="modules-with-code-artifacts"/>
</target>
<target name="publish-maven-central-only-pom-release">
<all-bundles target="publish-maven-central-only-pom-artifacts" buildpathRef="modules-with-only-pom-artifacts"/>
</target>
</project>
+27
View File
@@ -0,0 +1,27 @@
This is where the master build that creates releases of Spring Framework resides. The build system is based on spring-build, which is linked in using an SVN external to https://src.springframework.org/svn/spring-build.
USERS
- To build all Spring Framework projects, including samples:
1. From this directory, run:
ant
Build Pre-requisites:
- javac 1.6 or > must be in your system path
- ant 1.7 or > must be in your system path
DEVELOPERS
- To build a new Spring Framework distribution for release:
1. Update the files containing the version number to reflect the new release version, if necessary.
build.properties
build-spring-framework/resources/readme.txt
spring-framework/src/spring-framework-reference.xml
2. From this directory, run:
ant jar package
The release archive will be created and placed in:
target/artifacts
@@ -0,0 +1,159 @@
SPRING FRAMEWORK CHANGELOG
==========================
http://www.springsource.org
Changes in version 3.0.0.M3 (2009-05-06)
----------------------------------------
* Spring 3.0 includes reference documentation now
* Spring 3.0 is shipping with proper Maven POMs now
* updated to JRuby 1.2 (remaining compatible with JRuby 1.1 and above)
* updated to Hessian 3.2.1 (remaining compatible with Hessian 3.1.3 and above)
* updated to FreeMarker 2.3.15 (for exposure of FreeMarkerServlet-style HTTP scopes)
* removed Axis 1.x support package, keeping basic JAX-RPC support only (next to JAX-WS)
* introduced explicit XML array element in spring-beans-3.0.xsd
* introduced new type conversion SPI and converter API in spring-core convert package
* introduced annotated @Bean factory methods and JavaConfig-style @Configuration classes
* introduced @Primary, @Lazy and @DependsOn annotations for scanned components
* custom stereotype annotations can be meta-annotated with @Service, @Controller etc as well
* @Scope and @Transactional are now supported as meta-annotations on custom annotations
* @Autowired uses field/parameter name as fallback qualifier value
* qualifier annotations can be used at method level as well (applying to all parameters)
* @Value annotation can be used at method level as well (e.g. on bean property setters)
* @Value values may use ${...} placeholders (driven by PropertyPlaceholderConfigurer)
* @Resource names may use ${...} placeholders (driven by PropertyPlaceholderConfigurer)
* fixed EL evaluation of prepared constructor arguments for repeated prototype creation
* ConstructorArgumentValues exposed indexed arguments in the order of definition
* AutowiredAnnotationBeanPostProcessor calculates cached arguments in a synchronized block
* declarative destroy-method="..." specifications get validated at bean creation time
* component-scan's "base-package" attribute supports spaces as separators as well
* CachedIntrospectionResults always caches bean classes except in case of custom BeanInfo
* GenericTypeResolver's type variable cache uses weak values (for OSGi compatibility)
* fixed CachingMapDecorator to support garbage-collected weak references (again)
* AOP ProxyFactory excludes non-public interfaces when autodetecting proxy interfaces
* added DuplicateKeyException to DAO exception hierachy
* added EmbeddedDatabase support in spring-jdbc embedded package, with initial HSQL support
* SessionAwareMessageListener supports generic declaration of concrete JMS Message type
* RmiServiceExporter and RmiRegistryFactoryBean synchronize registry lookup/creation
* added "unregisterManagedResource" method to MBeanExporter/MBeanExportOperations
* TimerTaskExecutor creates non-daemon Timer and uses bean name as default Timer name
* added TaskScheduler interface and Trigger abstraction
* added ConcurrentTaskScheduler and ThreadPoolTaskScheduler
* added CommonJ TimerManagerTaskScheduler
* added CronTrigger implementation for cron expression support
* renamed "contextProperties" attribute to "contextParameters" (matching web.xml naming)
* "contextParameters" contains Servlet/PortletConfig parameters as well
* added default "servletContext" and "servletConfig" environment beans
* added default "portletContext" and "portletConfig" environment beans
* added default web scope "application", wrapping a ServletContext/PortletContext
* JSF FacesContext and ExternalContext are resolvable dependencies by default, if available
* FacesRequestAttributes (as used by RequestContextHolder) can access global Portlet session
* revised @RequestMapping semantics for REST support purposes
* request handler methods with @ModelAttribute annotation always return a model attribute
* introduced @ExceptionHandler annotation for used in annotated web controllers
* introduced ModelAndViewResolver SPI for custom handler method return types
* FreeMarkerView can be initialized with ServletContext only (e.g. for testing)
* MockPortletSession supports destruction of session attributes on invalidation
* completed upgrade of the TestContext Framework to JUnit 4.5
* SpringJUnit4ClassRunner subclasses can now override the default ContextLoader class
* added "value" alias for @ContextConfiguration's "locations" attribute
Changes in version 3.0.0.M2 (2009-02-25)
----------------------------------------
* revised expression parser API design
* added SimpleThreadScope implementation
* refined OSGi version constraints for "javax.annotation" and "junit.framework"
* "systemProperties" bean is not considered a default match for type Properties anymore
* SimpleAliasRegistry's "getAliases" method returns transitive aliases now
* SimpleAliasRegistry detects resolved aliases that loop back to the original name
* PropertyPlaceholderConfigurer does not modify Map in case of equal String keys
* improved NoClassDefFoundError handling during constructor resolution
* inner class names in Java source style ("java.lang.Thread.State") supported as well
* pre-converted property values are preserved more eagerly for re-created beans
* prototype beans receive independent collection/array even when based on single value
* registered plain singletons will be fully matched according to their qualifiers
* @Qualifier value matching takes chained aliases of target beans into account as well
* ASM-based AnnotationMetadata fully resolves class arguments and enums into Java types
* ProceedingJoinPoint resolves parameter names using ASM-based parameter name discovery
* MethodInvocations and ProceedingJoinPoints always expose original method (not bridge)
* bridge method resolution works with Hibernate-generated CGLIB proxies as well
* generic collection type resolution respects upper bound (e.g. ? extends Number) as well
* TypeUtils detects variations of ParameterizedType/GenericArrayType assignability as well
* ReflectionUtils findMethod detects methods on "java.lang.Object" as well
* UrlResource eagerly closes HTTP connections in case of "getInputStream()" failure
* PathMatchingResourcePatternResolver avoids NPE when initialized with null ClassLoader
* all "taskExecutor" bean properties now accept any "java.util.concurrent.Executor"
* added "Future submit(Runnable)" and "Future submit(Callable)" to AsyncTaskExecutor
* SimpleAsyncTaskExecutor supports a custom "java.util.concurrent.ThreadFactory"
* SchedulingTaskExecutor interface extends AsyncTaskExecutor now
* added ThreadPoolExecutorFactoryBean (exposing the native ExecutorService interface)
* added ExecutorServiceAdapter class as a standard wrapper for a Spring TaskExecutor
* reduced backport-concurrent support to TaskExecutor adapters
* added @Async annotation and AsyncAnnotationAdvisor (namespace support coming in M3)
* EJB 3.1's @Asynchronous annotation gets detected and supported by default as well
* ApplicationListener beans get obtained on demand, supporting non-singletons as well
* ApplicationListeners will be called in the order according to the Ordered contract
* generified ApplicationListener interface, narrowing the event type to be received
* introduced SmartApplicationListener interface for supported event/source types
* generified Transaction/Hibernate/Jdo/JpaCallback with generic "doInXxx" return type
* HibernateOperations uses generic parameter/return types where possible
* JdoOperations uses generic parameter/return types where possible (following JDO 2.1)
* removed "flush" operation from JdoDialect (fully relying on JDO 2.0+ compliance now)
* added JDO 2.1 compliant StandardPersistenceManagerProxy/SpringPersistenceManagerProxy
* Spring-created EntityManagers support JPA 2.0 draft API ("unwrap", "getQueryBuilder")
* Spring initiates JPA 2.0 query timeout with remaining Spring transaction timeout
* added support for WebSphere's ResourceAdapter-managed messaging transactions
* made SpringBeanAutowiringInterceptor callback signature compatible with WebSphere
* WebSphereUowTransactionManager preserves original exception in case of rollback
* added "flush()" method to TransactionStatus and TransactionSynchronization interfaces
* test context manager automatically flushes transactions before rolling back
* DefaultLobHandler uses explicit Blob/Clob access for reading when "wrapAsLob"=true
* fixed JmsException/JmsUtils to fully avoid NPEs in case of cause messages being null
* fixed MessageListenerAdapter's "getSubscriptionName()" to work without delegate as well
* fixed HTTP invoker to support resolution of multi-level primitive array classes again
* deprecated support for JMS 1.0.2 providers (JmsTemplate102 etc)
* introduced top-level HTTP support package "org.springframework.http"
* introduced RestTemplate facility in package "org.springframework.web.client"
* introduced OXM support package (originating from Spring Web Services)
* introduced OXM-based MarshallingMessageConverter for Spring JMS
* introduced OXM-based MarshallingView for Spring MVC
* refined @PathVariable handling in MVC handler methods
* updated Spring Portlet MVC infrastructure and mocks for Portlet API 2.0
* added resource and event methods to Portlet HandlerAdapter/HandlerInterceptor
* added resolveException method for resource requests to HandlerExceptionResolver
* introduced Resource/EventAwareController subinterfaces of Portlet Controller
* introduced @Action/@Render/@Resource/@EventMapping annotations for Portlet MVC
* added @RequestHeader support for Portlet MVC (based on Portlet request properties)
* introduced @CookieValue annotation for Servlet and Portlet MVC handler methods
* @RequestMapping type-level param constraints taken into account consistently
* optional boolean parameters in MVC handler methods resolve to "false" if not present
* "url" macro in "spring.ftl" performs standard Servlet URL encoding automatically
Changes in version 3.0.0.M1 (2008-12-05)
----------------------------------------
* revised project layout and build system (module-based sources, bundle repository)
* updated entire codebase for Java 5 code style (generics, varargs, StringBuilder)
* updated to JUnit 4.5 and JRuby 1.1
* removed WebLogic 8.1 and WebSphere 5.1 support
* removed native TopLink API support (superseded by JPA)
* removed Commons Attributes support (superseded by Java 5 annotations)
* removed Jakarta JSTL support for JSP 1.2 (superseded by JSP 2.0)
* removed outdated Struts 1.x Action delegation support
* removed ContextLoaderServlet and Log4jConfigServlet
* deprecated form controller hierarchy in favor of @MVC form object handling
* deprecated JUnit 3.8 test class hierarchy in favor of test context framework
* revised TaskExecutor interface to extend "java.util.concurrent.Executor" now
* introduced Spring EL parser in org.springframework.expression package
* introduced #{...} expression support in bean definitions
* introduced @Value annotation for embedded expression support
* introduced @PathVariable annotation for MVC handler methods
* introduced ShallowEtagHeaderFilter
* introduced AbstractAtomFeedView and AbstractRssFeedView
* introduced default value support for @RequestParam
* introduced @RequestHeader annotation for MVC handler methods
* introduced "spring:url" and "spring:param" JSP tags
@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.
@@ -0,0 +1,22 @@
======================================================================
== NOTICE file corresponding to section 4 d of the Apache License, ==
== Version 2.0, for the Spring Web Flow distribution. ==
======================================================================
This product includes software developed by
the Apache Software Foundation (http://www.apache.org).
The end-user documentation included with a redistribution, if any,
must include the following acknowledgement:
"This product includes software developed by the Spring Framework
Project (http://www.springframework.org)."
Alternately, this acknowledgement may appear in the software itself,
if and wherever such third-party acknowledgements normally appear.
The names "Spring", "Spring Framework", and "Spring Web Flow" must
not be used to endorse or promote products derived from this
software without prior written permission. For written permission,
please contact rod.johnson@interface21.com or juergen.hoeller@interface21.com.
@@ -0,0 +1,29 @@
SPRING FRAMEWORK 3.0 M2 (February 2009)
---------------------------------------
http://www.springframework.org
1. INTRODUCTION
---------------
This is the second milestone of Spring 3.0 which is scheduled for final release in Q2 2009.
This release features a codebase that has been fully updated for Java 5+, introduces
Portlet 2.0 and early JPA 2.0 support, and provides even more comprehensive REST support.
2. RELEASE NOTES
----------------
This release comes without reference documentation. For the time being, please consult
the provided javadoc for details on the new features.
3. DISTRIBUTION JAR FILES
-------------------------
The Spring Framework module jar files can be found in the 'dist' directory. Note that
this release does not contain a 'spring.jar' file anymore. Furthermore, the jar file
names follow bundle repository conventions now.
4. GETTING STARTED
------------------
Check out the provided PetClinic sample application. It has been fully updated for
Spring 3.0 already.
-12
View File
@@ -1,12 +0,0 @@
plugins {
id 'base'
id 'org.antora' version '1.0.0'
}
antora {
options = [clean: true, fetch: true, stacktrace: true]
}
node {
version = '24.15.0'
}
+24
View File
@@ -0,0 +1,24 @@
version=3.0.0
build.stamp=M3
release.type=milestone
natural.name=spring-framework
project.name=Spring Framework
project.key=SPR
ivy.cache.dir=${basedir}/../ivy-cache
integration.repo.dir=${basedir}/../integration-repo
javadoc.exclude.package.names=org/springframework/samples/**
javadoc.max.memory=256M
test.vm.args=-XX:MaxPermSize=128M
# 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
+6
View File
@@ -0,0 +1,6 @@
# properties used by Bamboo build plan at http://build.springframework.org/build/admin/buildConfiguration.action?buildKey=SPR-TRUNKQUICK
# run in conjunction with ANT_OPTS='-XX:MaxPermSize=512m -Xmx1024m'
compiler.args=-enableJavadoc -warn:none
java.awt.headless=true
ci.build=true
test.vm.args=-XX:MaxPermSize=512m -Xmx1024m
+267
View File
@@ -0,0 +1,267 @@
<?xml version="1.0" encoding="UTF-8"?>
<profiles version="11">
<profile kind="CodeFormatterProfile" name="Spring" version="11">
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="120"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
<setting id="org.eclipse.jdt.core.compiler.source" value="1.5"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="120"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.5"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.5"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="tab"/>
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
</profile>
</profiles>
-2
View File
@@ -1,2 +0,0 @@
group=org.springframework
description=Spring Framework Docs Site
Binary file not shown.
-7
View File
@@ -1,7 +0,0 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
-251
View File
@@ -1,251 +0,0 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original 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
#
# https://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.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH="\\\"\\\""
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
Vendored
-94
View File
@@ -1,94 +0,0 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:execute
@rem Setup the command line
set CLASSPATH=
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
+21
View File
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="src" path="src/main/resources"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="var" path="IVY_CACHE/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-1.0.0.jar" sourcepath="/IVY_CACHE/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-sources-1.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-1.1.1.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-sources-1.1.1.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.easymock/com.springsource.org.easymock/2.3.0/com.springsource.org.easymock-2.3.0.jar" sourcepath="/IVY_CACHE/org.easymock/com.springsource.org.easymock/2.3.0/com.springsource.org.easymock-sources-2.3.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/com.jamonapi/com.springsource.com.jamonapi/2.4.0/com.springsource.com.jamonapi-2.4.0.jar" sourcepath="/IVY_CACHE/com.jamonapi/com.springsource.com.jamonapi/2.4.0/com.springsource.com.jamonapi-sources-2.4.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/net.sourceforge.cglib/com.springsource.net.sf.cglib/2.1.3/com.springsource.net.sf.cglib-2.1.3.jar" sourcepath="/IVY_CACHE/net.sourceforge.cglib/com.springsource.net.sf.cglib/2.1.3/com.springsource.net.sf.cglib-sources-2.1.3.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.log4j/com.springsource.org.apache.log4j/1.2.15/com.springsource.org.apache.log4j-1.2.15.jar" sourcepath="/IVY_CACHE/org.apache.log4j/com.springsource.org.apache.log4j/1.2.15/com.springsource.org.apache.log4j-sources-1.2.15.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.junit/com.springsource.org.junit/4.5.0/com.springsource.org.junit-4.5.0.jar" sourcepath="/IVY_CACHE/org.junit/com.springsource.org.junit/4.5.0/com.springsource.org.junit-sources-4.5.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.pool/1.3.0/com.springsource.org.apache.commons.pool-1.3.0.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.pool/1.3.0/com.springsource.org.apache.commons.pool-sources-1.3.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.aspectj/com.springsource.org.aspectj.weaver/1.6.2.RELEASE/com.springsource.org.aspectj.weaver-1.6.2.RELEASE.jar" sourcepath="IVY_CACHE/org.aspectj/com.springsource.org.aspectj.weaver/1.6.2.RELEASE/com.springsource.org.aspectj.weaver-sources-1.6.2.RELEASE.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.beans"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.core"/>
<classpathentry kind="lib" path="/org.springframework.asm/target/artifacts/org.springframework.asm.jar" sourcepath="/org.springframework.asm/target/artifacts/org.springframework.asm-sources.jar"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
+17
View File
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.springframework.aop</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
@@ -0,0 +1,268 @@
#Fri Dec 12 11:37:26 PST 2008
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_assignment=0
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
org.eclipse.jdt.core.formatter.blank_lines_before_field=0
org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
org.eclipse.jdt.core.formatter.blank_lines_before_method=1
org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
org.eclipse.jdt.core.formatter.blank_lines_before_package=0
org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
org.eclipse.jdt.core.formatter.comment.format_block_comments=true
org.eclipse.jdt.core.formatter.comment.format_header=false
org.eclipse.jdt.core.formatter.comment.format_html=true
org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
org.eclipse.jdt.core.formatter.comment.format_line_comments=true
org.eclipse.jdt.core.formatter.comment.format_source_code=true
org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
org.eclipse.jdt.core.formatter.comment.line_length=80
org.eclipse.jdt.core.formatter.compact_else_if=true
org.eclipse.jdt.core.formatter.continuation_indentation=2
org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
org.eclipse.jdt.core.formatter.indent_empty_lines=false
org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
org.eclipse.jdt.core.formatter.indentation.size=4
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
org.eclipse.jdt.core.formatter.lineSplit=80
org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
org.eclipse.jdt.core.formatter.tabulation.char=tab
org.eclipse.jdt.core.formatter.tabulation.size=4
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
@@ -0,0 +1,4 @@
#Fri Dec 12 11:37:26 PST 2008
eclipse.preferences.version=1
formatter_profile=org.eclipse.jdt.ui.default.eclipse_profile
formatter_settings_version=11
+122
View File
@@ -0,0 +1,122 @@
<?xml version="1.0" encoding="UTF-8"?>
<module relativePaths="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="inheritedJdk" />
<orderEntry type="module" module-name="beans" />
<orderEntry type="module" module-name="core" />
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$IVY_CACHE$/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-1.0.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$IVY_CACHE$/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-sources-1.0.0.jar!/" />
</SOURCES>
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$IVY_CACHE$/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-1.1.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$IVY_CACHE$/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-sources-1.1.1.jar!/" />
</SOURCES>
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$IVY_CACHE$/org.apache.commons/com.springsource.org.apache.commons.pool/1.4.0/com.springsource.org.apache.commons.pool-1.4.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$IVY_CACHE$/org.apache.commons/com.springsource.org.apache.commons.pool/1.4.0/com.springsource.org.apache.commons.pool-sources-1.4.0.jar!/" />
</SOURCES>
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$IVY_CACHE$/org.aspectj/com.springsource.org.aspectj.weaver/1.6.2.RELEASE/com.springsource.org.aspectj.weaver-1.6.2.RELEASE.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$IVY_CACHE$/org.aspectj/com.springsource.org.aspectj.weaver/1.6.2.RELEASE/com.springsource.org.aspectj.weaver-sources-1.6.2.RELEASE.jar!/" />
</SOURCES>
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$IVY_CACHE$/com.jamonapi/com.springsource.com.jamonapi/2.4.0/com.springsource.com.jamonapi-2.4.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$IVY_CACHE$/com.jamonapi/com.springsource.com.jamonapi/2.4.0/com.springsource.com.jamonapi-sources-2.4.0.jar!/" />
</SOURCES>
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$IVY_CACHE$/net.sourceforge.cglib/com.springsource.net.sf.cglib/2.1.3/com.springsource.net.sf.cglib-2.1.3.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$IVY_CACHE$/net.sourceforge.cglib/com.springsource.net.sf.cglib/2.1.3/com.springsource.net.sf.cglib-sources-2.1.3.jar!/" />
</SOURCES>
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$IVY_CACHE$/org.apache.log4j/com.springsource.org.apache.log4j/1.2.15/com.springsource.org.apache.log4j-1.2.15.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$IVY_CACHE$/org.apache.log4j/com.springsource.org.apache.log4j/1.2.15/com.springsource.org.apache.log4j-sources-1.2.15.jar!/" />
</SOURCES>
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$IVY_CACHE$/org.junit/com.springsource.org.junit/4.5.0/com.springsource.org.junit-4.5.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$IVY_CACHE$/org.junit/com.springsource.org.junit/4.5.0/com.springsource.org.junit-sources-4.5.0.jar!/" />
</SOURCES>
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$IVY_CACHE$/org.easymock/com.springsource.org.easymock/2.3.0/com.springsource.org.easymock-2.3.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$IVY_CACHE$/org.easymock/com.springsource.org.easymock/2.3.0/com.springsource.org.easymock-sources-2.3.0.jar!/" />
</SOURCES>
</library>
</orderEntry>
</component>
<component name="copyright">
<Base>
<setting name="state" value="2" />
</Base>
</component>
</module>
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="org.springframework.aop">
<property file="${basedir}/../build.properties"/>
<import file="${basedir}/../build-spring-framework/package-bundle.xml"/>
<import file="${basedir}/../spring-build/standard/default.xml"/>
</project>
+41
View File
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="http://ivyrep.jayasoft.org/ivy-doc.xsl"?>
<ivy-module
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://incubator.apache.org/ivy/schemas/ivy.xsd"
version="1.3">
<info organisation="org.springframework" module="${ant.project.name}">
<license name="Apache 2.0" url="http://www.apache.org/licenses/LICENSE-2.0"/>
</info>
<configurations>
<include file="${spring.build.dir}/common/default-ivy-configurations.xml"/>
<conf name="aspectj" extends="runtime" description="JARs needed to run with AspectJ"/>
<conf name="bytecode-proxy" extends="runtime" description="JARs needed to run with CGLIB bytecode proxies"/>
<conf name="jamon" extends="runtime" description="JARs needed to run with JamonAPI"/>
<conf name="pooling" extends="runtime" description="JARs needed to run the pooling target source"/>
</configurations>
<publications>
<artifact name="${ant.project.name}"/>
<artifact name="${ant.project.name}-sources" type="src" ext="jar"/>
</publications>
<dependencies>
<dependency org="com.jamonapi" name="com.springsource.com.jamonapi" rev="2.4.0" conf="optional, jamon->compile"/>
<dependency org="net.sourceforge.cglib" name="com.springsource.net.sf.cglib" rev="2.1.3" 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->compile"/>
<dependency org="org.apache.commons" name="com.springsource.org.apache.commons.pool" rev="1.4.0" conf="optional, pooling->compile"/>
<dependency org="org.aspectj" name="com.springsource.org.aspectj.weaver" rev="1.6.3.RELEASE" 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.3.0" conf="test->compile"/>
<dependency org="org.junit" name="com.springsource.org.junit" rev="4.5.0" conf="test->runtime"/>
<dependency org="org.springframework" name="org.springframework.asm" rev="latest.integration" conf="test->runtime"/>
</dependencies>
</ivy-module>
+89
View File
@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<packaging>jar</packaging>
<version>3.0.0.M3</version>
<parent>
<groupId>org.springframework</groupId>
<artifactId>spring-parent</artifactId>
<relativePath>../org.springframework.spring-parent</relativePath>
<version>3.0.0.M3</version>
</parent>
<dependencies>
<dependency>
<groupId>com.jamonapi</groupId>
<artifactId>jamon</artifactId>
<version>2.4</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>2.1_3</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
<version>1.4</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.2</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>2.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-asm</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,60 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop;
import org.aopalliance.aop.Advice;
/**
* Base interface holding AOP <b>advice</b> (action to take at a joinpoint)
* and a filter determining the applicability of the advice (such as
* a pointcut). <i>This interface is not for use by Spring users, but to
* allow for commonality in support for different types of advice.</i>
*
* <p>Spring AOP is based around <b>around advice</b> delivered via method
* <b>interception</b>, compliant with the AOP Alliance interception API.
* The Advisor interface allows support for different types of advice,
* such as <b>before</b> and <b>after</b> advice, which need not be
* implemented using interception.
*
* @author Rod Johnson
*/
public interface Advisor {
/**
* Return the advice part of this aspect. An advice may be an
* interceptor, a before advice, a throws advice, etc.
* @return the advice that should apply if the pointcut matches
* @see org.aopalliance.intercept.MethodInterceptor
* @see BeforeAdvice
* @see ThrowsAdvice
* @see AfterReturningAdvice
*/
Advice getAdvice();
/**
* Return whether this advice is associated with a particular instance
* (for example, creating a mixin) or shared with all instances of
* the advised class obtained from the same Spring bean factory.
* <p><b>Note that this method is not currently used by the framework.</b>
* Typical Advisor implementations always return <code>true</code>.
* Use singleton/prototype bean definitions or appropriate programmatic
* proxy creation to ensure that Advisors have the correct lifecycle model.
* @return whether this advice is associated with a particular target instance
*/
boolean isPerInstance();
}
@@ -0,0 +1,31 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop;
import org.aopalliance.aop.Advice;
/**
* Common marker interface for after advice,
* such as {@link AfterReturningAdvice} and {@link ThrowsAdvice}.
*
* @author Juergen Hoeller
* @since 2.0.3
* @see BeforeAdvice
*/
public interface AfterAdvice extends Advice {
}
@@ -0,0 +1,44 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop;
import java.lang.reflect.Method;
/**
* After returning advice is invoked only on normal method return, not if an
* exception is thrown. Such advice can see the return value, but cannot change it.
*
* @author Rod Johnson
* @see MethodBeforeAdvice
* @see ThrowsAdvice
*/
public interface AfterReturningAdvice extends AfterAdvice {
/**
* Callback after a given method successfully returned.
* @param returnValue the value returned by the method, if any
* @param method method being invoked
* @param args arguments to the method
* @param target target of the method invocation. May be <code>null</code>.
* @throws Throwable if this object wishes to abort the call.
* Any exception thrown will be returned to the caller if it's
* allowed by the method signature. Otherwise the exception
* will be wrapped as a runtime exception.
*/
void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable;
}
@@ -0,0 +1,47 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop;
import org.springframework.core.NestedRuntimeException;
/**
* Exception that gets thrown when an AOP invocation failed
* because of misconfiguration or unexpected runtime issues.
*
* @author Juergen Hoeller
* @since 2.0
*/
public class AopInvocationException extends NestedRuntimeException {
/**
* Constructor for AopInvocationException.
* @param msg the detail message
*/
public AopInvocationException(String msg) {
super(msg);
}
/**
* Constructor for AopInvocationException.
* @param msg the detail message
* @param cause the root cause
*/
public AopInvocationException(String msg, Throwable cause) {
super(msg, cause);
}
}
@@ -0,0 +1,32 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop;
import org.aopalliance.aop.Advice;
/**
* Common marker interface for before advice, such as {@link MethodBeforeAdvice}.
*
* <p>Spring supports only method before advice. Although this is unlikely to change,
* this API is designed to allow field advice in future if desired.
*
* @author Rod Johnson
* @see AfterAdvice
*/
public interface BeforeAdvice extends Advice {
}
@@ -0,0 +1,45 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop;
/**
* Filter that restricts matching of a pointcut or introduction to
* a given set of target classes.
*
* <p>Can be used as part of a {@link Pointcut} or for the entire
* targeting of an {@link IntroductionAdvisor}.
*
* @author Rod Johnson
* @see Pointcut
* @see MethodMatcher
*/
public interface ClassFilter {
/**
* Should the pointcut apply to the given interface or target class?
* @param clazz the candidate target class
* @return whether the advice should apply to the given target class
*/
boolean matches(Class<?> clazz);
/**
* Canonical instance of a ClassFilter that matches all classes.
*/
ClassFilter TRUE = TrueClassFilter.INSTANCE;
}
@@ -0,0 +1,48 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop;
import org.aopalliance.aop.Advice;
/**
* Subinterface of AOP Alliance Advice that allows additional interfaces
* to be implemented by an Advice, and available via a proxy using that
* interceptor. This is a fundamental AOP concept called <b>introduction</b>.
*
* <p>Introductions are often <b>mixins</b>, enabling the building of composite
* objects that can achieve many of the goals of multiple inheritance in Java.
*
* <p>Compared to {qlink IntroductionInfo}, this interface allows an advice to
* implement a range of interfaces that is not necessarily known in advance.
* Thus an {@link IntroductionAdvisor} can be used to specify which interfaces
* will be exposed in an advised object.
*
* @author Rod Johnson
* @since 1.1.1
* @see IntroductionInfo
* @see IntroductionAdvisor
*/
public interface DynamicIntroductionAdvice extends Advice {
/**
* Does this introduction advice implement the given interface?
* @param intf the interface to check
* @return whether the advice implements the specified interface
*/
boolean implementsInterface(Class<?> intf);
}
@@ -0,0 +1,51 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop;
/**
* Superinterface for advisors that perform one or more AOP <b>introductions</b>.
*
* <p>This interface cannot be implemented directly; subinterfaces must
* provide the advice type implementing the introduction.
*
* <p>Introduction is the implementation of additional interfaces
* (not implemented by a target) via AOP advice.
*
* @author Rod Johnson
* @since 04.04.2003
* @see IntroductionInterceptor
*/
public interface IntroductionAdvisor extends Advisor, IntroductionInfo {
/**
* Return the filter determining which target classes this introduction
* should apply to.
* <p>This represents the class part of a pointcut. Note that method
* matching doesn't make sense to introductions.
* @return the class filter
*/
ClassFilter getClassFilter();
/**
* Can the advised interfaces be implemented by the introduction advice?
* Invoked before adding an IntroductionAdvisor.
* @throws IllegalArgumentException if the advised interfaces can't be
* implemented by the introduction advice
*/
void validateInterfaces() throws IllegalArgumentException;
}
@@ -0,0 +1,44 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop;
import java.lang.reflect.Method;
/**
* A specialized type of MethodMatcher that takes into account introductions when
* matching methods. If there are no introductions on the target class, a method
* matcher may be able to optimize matching more effectively for example.
*
* @author Adrian Colyer
* @since 2.0
*/
public interface IntroductionAwareMethodMatcher extends MethodMatcher {
/**
* Perform static checking whether the given method matches. This may be invoked
* instead of the 2-arg {@link #matches(java.lang.reflect.Method, Class)} method
* if the caller supports the extended IntroductionAwareMethodMatcher interface.
* @param method the candidate method
* @param targetClass the target class (may be <code>null</code>, in which case
* the candidate class must be taken to be the method's declaring class)
* @param hasIntroductions <code>true</code> if the object on whose behalf we are
* asking is the subject on one or more introductions; <code>false</code> otherwise
* @return whether or not this method matches statically
*/
boolean matches(Method method, Class targetClass, boolean hasIntroductions);
}
@@ -0,0 +1,39 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop;
/**
* Interface supplying the information necessary to describe an introduction.
*
* <p>{@link IntroductionAdvisor IntroductionAdvisors} must implement this
* interface. If an {@link org.aopalliance.aop.Advice} implements this,
* it may be used as an introduction without an {@link IntroductionAdvisor}.
* In this case, the advice is self-describing, providing not only the
* necessary behavior, but describing the interfaces it introduces.
*
* @author Rod Johnson
* @since 1.1.1
*/
public interface IntroductionInfo {
/**
* Return the additional interfaces introduced by this Advisor or Advice.
* @return the introduced interfaces
*/
Class[] getInterfaces();
}
@@ -0,0 +1,34 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop;
import org.aopalliance.intercept.MethodInterceptor;
/**
* Subinterface of AOP Alliance MethodInterceptor that allows additional interfaces
* to be implemented by the interceptor, and available via a proxy using that
* interceptor. This is a fundamental AOP concept called <b>introduction</b>.
*
* <p>Introductions are often <b>mixins</b>, enabling the building of composite
* objects that can achieve many of the goals of multiple inheritance in Java.
*
* @author Rod Johnson
* @see DynamicIntroductionAdvice
*/
public interface IntroductionInterceptor extends MethodInterceptor, DynamicIntroductionAdvice {
}
@@ -0,0 +1,44 @@
/*
* Copyright 2002-2005 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop;
import java.lang.reflect.Method;
/**
* Advice invoked before a method is invoked. Such advices cannot
* prevent the method call proceeding, unless they throw a Throwable.
*
* @see AfterReturningAdvice
* @see ThrowsAdvice
*
* @author Rod Johnson
*/
public interface MethodBeforeAdvice extends BeforeAdvice {
/**
* Callback before a given method is invoked.
* @param method method being invoked
* @param args arguments to the method
* @param target target of the method invocation. May be <code>null</code>.
* @throws Throwable if this object wishes to abort the call.
* Any exception thrown will be returned to the caller if it's
* allowed by the method signature. Otherwise the exception
* will be wrapped as a runtime exception.
*/
void before(Method method, Object[] args, Object target) throws Throwable;
}
@@ -0,0 +1,97 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop;
import java.lang.reflect.Method;
/**
* Part of a {@link Pointcut}: Checks whether the target method is eligible for advice.
*
* <p>A MethodMatcher may be evaluated <b>statically</b> or at <b>runtime</b> (dynamically).
* Static matching involves method and (possibly) method attributes. Dynamic matching
* also makes arguments for a particular call available, and any effects of running
* previous advice applying to the joinpoint.
*
* <p>If an implementation returns <code>false</code> from its {@link #isRuntime()}
* method, evaluation can be performed statically, and the result will be the same
* for all invocations of this method, whatever their arguments. This means that
* if the {@link #isRuntime()} method returns <code>false</code>, the 3-arg
* {@link #matches(java.lang.reflect.Method, Class, Object[])} method will never be invoked.
*
* <p>If an implementation returns <code>true</code> from its 2-arg
* {@link #matches(java.lang.reflect.Method, Class)} method and its {@link #isRuntime()} method
* returns <code>true</code>, the 3-arg {@link #matches(java.lang.reflect.Method, Class, Object[])}
* method will be invoked <i>immediately before each potential execution of the related advice</i>,
* to decide whether the advice should run. All previous advice, such as earlier interceptors
* in an interceptor chain, will have run, so any state changes they have produced in
* parameters or ThreadLocal state will be available at the time of evaluation.
*
* @author Rod Johnson
* @since 11.11.2003
* @see Pointcut
* @see ClassFilter
*/
public interface MethodMatcher {
/**
* Perform static checking whether the given method matches. If this
* returns <code>false</code> or if the {@link #isRuntime()} method
* returns <code>false</code>, no runtime check (i.e. no.
* {@link #matches(java.lang.reflect.Method, Class, Object[])} call) will be made.
* @param method the candidate method
* @param targetClass the target class (may be <code>null</code>, in which case
* the candidate class must be taken to be the method's declaring class)
* @return whether or not this method matches statically
*/
boolean matches(Method method, Class<?> targetClass);
/**
* Is this MethodMatcher dynamic, that is, must a final call be made on the
* {@link #matches(java.lang.reflect.Method, Class, Object[])} method at
* runtime even if the 2-arg matches method returns <code>true</code>?
* <p>Can be invoked when an AOP proxy is created, and need not be invoked
* again before each method invocation,
* @return whether or not a runtime match via the 3-arg
* {@link #matches(java.lang.reflect.Method, Class, Object[])} method
* is required if static matching passed
*/
boolean isRuntime();
/**
* Check whether there a runtime (dynamic) match for this method,
* which must have matched statically.
* <p>This method is invoked only if the 2-arg matches method returns
* <code>true</code> for the given method and target class, and if the
* {@link #isRuntime()} method returns <code>true</code>. Invoked
* immediately before potential running of the advice, after any
* advice earlier in the advice chain has run.
* @param method the candidate method
* @param targetClass the target class (may be <code>null</code>, in which case
* the candidate class must be taken to be the method's declaring class)
* @param args arguments to the method
* @return whether there's a runtime match
* @see MethodMatcher#matches(Method, Class)
*/
boolean matches(Method method, Class<?> targetClass, Object[] args);
/**
* Canonical instance that matches all methods.
*/
MethodMatcher TRUE = TrueMethodMatcher.INSTANCE;
}
@@ -0,0 +1,53 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop;
/**
* Core Spring pointcut abstraction.
*
* <p>A pointcut is composed of a {@link ClassFilter} and a {@link MethodMatcher}.
* Both these basic terms and a Pointcut itself can be combined to build up combinations
* (e.g. through {@link org.springframework.aop.support.ComposablePointcut}).
*
* @author Rod Johnson
* @see ClassFilter
* @see MethodMatcher
* @see org.springframework.aop.support.Pointcuts
* @see org.springframework.aop.support.ClassFilters
* @see org.springframework.aop.support.MethodMatchers
*/
public interface Pointcut {
/**
* Return the ClassFilter for this pointcut.
* @return the ClassFilter (never <code>null</code>)
*/
ClassFilter getClassFilter();
/**
* Return the MethodMatcher for this pointcut.
* @return the MethodMatcher (never <code>null</code>)
*/
MethodMatcher getMethodMatcher();
/**
* Canonical Pointcut instance that always matches.
*/
Pointcut TRUE = TruePointcut.INSTANCE;
}
@@ -0,0 +1,33 @@
/*
* Copyright 2002-2005 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop;
/**
* Superinterface for all Advisors that are driven by a pointcut.
* This covers nearly all advisors except introduction advisors,
* for which method-level matching doesn't apply.
*
* @author Rod Johnson
*/
public interface PointcutAdvisor extends Advisor {
/**
* Get the Pointcut that drives this advisor.
*/
Pointcut getPointcut();
}
@@ -0,0 +1,86 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop;
import org.aopalliance.intercept.MethodInvocation;
/**
* Extension of the AOP Alliance {@link org.aopalliance.intercept.MethodInvocation}
* interface, allowing access to the proxy that the method invocation was made through.
*
* <p>Useful to be able to substitute return values with the proxy,
* if necessary, for example if the invocation target returned itself.
*
* @author Juergen Hoeller
* @author Adrian Colyer
* @since 1.1.3
* @see org.springframework.aop.framework.ReflectiveMethodInvocation
* @see org.springframework.aop.support.DelegatingIntroductionInterceptor
*/
public interface ProxyMethodInvocation extends MethodInvocation {
/**
* Return the proxy that this method invocation was made through.
* @return the original proxy object
*/
Object getProxy();
/**
* Create a clone of this object. If cloning is done before <code>proceed()</code>
* is invoked on this object, <code>proceed()</code> can be invoked once per clone
* to invoke the joinpoint (and the rest of the advice chain) more than once.
* @return an invocable clone of this invocation.
* <code>proceed()</code> can be called once per clone.
*/
MethodInvocation invocableClone();
/**
* Create a clone of this object. If cloning is done before <code>proceed()</code>
* is invoked on this object, <code>proceed()</code> can be invoked once per clone
* to invoke the joinpoint (and the rest of the advice chain) more than once.
* @param arguments the arguments that the cloned invocation is supposed to use,
* overriding the original arguments
* @return an invocable clone of this invocation.
* <code>proceed()</code> can be called once per clone.
*/
MethodInvocation invocableClone(Object[] arguments);
/**
* Set the arguments to be used on subsequent invocations in the any advice
* in this chain.
* @param arguments the argument array
*/
void setArguments(Object[] arguments);
/**
* Add the specified user attribute with the given value to this invocation.
* <p>Such attributes are not used within the AOP framework itself. They are
* just kept as part of the invocation object, for use in special interceptors.
* @param key the name of the attribute
* @param value the value of the attribute, or <code>null</code> to reset it
*/
void setUserAttribute(String key, Object value);
/**
* Return the value of the specified user attribute.
* @param key the name of the attribute
* @return the value of the attribute, or <code>null</code> if not set
* @see #setUserAttribute
*/
Object getUserAttribute(String key);
}
@@ -0,0 +1,37 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop;
/**
* Marker for AOP proxy interfaces (in particular: introduction interfaces)
* that explicitly intend to return the raw target object (which would normally
* get replaced with the proxy object when returned from a method invocation).
*
* <p>Note that this is a marker interface in the style of {@link java.io.Serializable},
* semantically applying to a declared interface rather than to the full class
* of a concrete object. In other words, this marker applies to a particular
* interface only (typically an introduction interface that does not serve
* as the primary interface of an AOP proxy), and hence does not affect
* other interfaces that a concrete AOP proxy may implement.
*
* @author Juergen Hoeller
* @since 2.0.5
* @see org.springframework.aop.scope.ScopedObject
*/
public interface RawTargetAccess {
}
@@ -0,0 +1,29 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop;
/**
* Marker interface implemented by all AOP proxies. Used to detect
* whether or not objects are Spring-generated proxies.
*
* @author Rob Harrop
* @since 2.0.1
* @see org.springframework.aop.support.AopUtils#isAopProxy(Object)
*/
public interface SpringProxy {
}
@@ -0,0 +1,39 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop;
/**
* Minimal interface for exposing the target class behind a proxy.
*
* <p>Implemented by AOP proxy objects and proxy factories
* (via {@link org.springframework.aop.framework.Advised}}
* as well as by {@link TargetSource TargetSources}.
*
* @author Juergen Hoeller
* @since 2.0.3
* @see org.springframework.aop.support.AopUtils#getTargetClass(Object)
*/
public interface TargetClassAware {
/**
* Return the target class behind the implementing object
* (typically a proxy configuration or an actual proxy).
* @return the target Class, or <code>null</code> if not known
*/
Class getTargetClass();
}
@@ -0,0 +1,70 @@
/*<
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop;
/**
* A <code>TargetSource</code> is used to obtain the current "target" of
* an AOP invocation, which will be invoked via reflection if no around
* advice chooses to end the interceptor chain itself.
*
* <p>If a <code>TargetSource</code> is "static", it will always return
* the same target, allowing optimizations in the AOP framework. Dynamic
* target sources can support pooling, hot swapping, etc.
*
* <p>Application developers don't usually need to work with
* <code>TargetSources</code> directly: this is an AOP framework interface.
*
* @author Rod Johnson
*/
public interface TargetSource extends TargetClassAware {
/**
* Return the type of targets returned by this {@link TargetSource}.
* <p>Can return <code>null</code>, although certain usages of a
* <code>TargetSource</code> might just work with a predetermined
* target class.
* @return the type of targets returned by this {@link TargetSource}
*/
Class getTargetClass();
/**
* Will all calls to {@link #getTarget()} return the same object?
* <p>In that case, there will be no need to invoke
* {@link #releaseTarget(Object)}, and the AOP framework can cache
* the return value of {@link #getTarget()}.
* @return <code>true</code> if the target is immutable
* @see #getTarget
*/
boolean isStatic();
/**
* Return a target instance. Invoked immediately before the
* AOP framework calls the "target" of an AOP method invocation.
* @return the target object, which contains the joinpoint
* @throws Exception if the target object can't be resolved
*/
Object getTarget() throws Exception;
/**
* Release the given target object obtained from the
* {@link #getTarget()} method.
* @param target object obtained from a call to {@link #getTarget()}
* @throws Exception if the object can't be released
*/
void releaseTarget(Object target) throws Exception;
}
@@ -0,0 +1,53 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop;
/**
* Tag interface for throws advice.
*
* <p>There are not any methods on this interface, as methods are invoked by
* reflection. Implementing classes must implement methods of the form:
*
* <pre class="code">void afterThrowing([Method, args, target], ThrowableSubclass);</pre>
*
* <p>Some examples of valid methods would be:
*
* <pre class="code">public void afterThrowing(Exception ex)</pre>
* <pre class="code">public void afterThrowing(RemoteException)</pre>
* <pre class="code">public void afterThrowing(Method method, Object[] args, Object target, Exception ex)</pre>
* <pre class="code">public void afterThrowing(Method method, Object[] args, Object target, ServletException ex)</pre>
*
* The first three arguments are optional, and only useful if we want further
* information about the joinpoint, as in AspectJ <b>after-throwing</b> advice.
*
* <p><b>Note:</b> If a throws-advice method throws an exception itself, it will
* override the original exception (i.e. change the exception thrown to the user).
* The overriding exception will typically be a RuntimeException; this is compatible
* with any method signature. However, if a throws-advice method throws a checked
* exception, it will have to match the declared exceptions of the target method
* and is hence to some degree coupled to specific target method signatures.
* <b>Do not throw an undeclared checked exception that is incompatible with
* the target method's signature!</b>
*
* @author Rod Johnson
* @author Juergen Hoeller
* @see AfterReturningAdvice
* @see MethodBeforeAdvice
*/
public interface ThrowsAdvice extends AfterAdvice {
}
@@ -0,0 +1,54 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop;
import java.io.Serializable;
/**
* Canonical ClassFilter instance that matches all classes.
*
* @author Rod Johnson
*/
class TrueClassFilter implements ClassFilter, Serializable {
public static final TrueClassFilter INSTANCE = new TrueClassFilter();
/**
* Enforce Singleton pattern.
*/
private TrueClassFilter() {
}
public boolean matches(Class clazz) {
return true;
}
/**
* Required to support serialization. Replaces with canonical
* instance on deserialization, protecting Singleton pattern.
* Alternative to overriding <code>equals()</code>.
*/
private Object readResolve() {
return INSTANCE;
}
@Override
public String toString() {
return "ClassFilter.TRUE";
}
}
@@ -0,0 +1,64 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop;
import java.io.Serializable;
import java.lang.reflect.Method;
/**
* Canonical MethodMatcher instance that matches all methods.
*
* @author Rod Johnson
*/
class TrueMethodMatcher implements MethodMatcher, Serializable {
public static final TrueMethodMatcher INSTANCE = new TrueMethodMatcher();
/**
* Enforce Singleton pattern.
*/
private TrueMethodMatcher() {
}
public boolean isRuntime() {
return false;
}
public boolean matches(Method method, Class targetClass) {
return true;
}
public boolean matches(Method method, Class targetClass, Object[] args) {
// Should never be invoked as isRuntime returns false.
throw new UnsupportedOperationException();
}
/**
* Required to support serialization. Replaces with canonical
* instance on deserialization, protecting Singleton pattern.
* Alternative to overriding <code>equals()</code>.
*/
private Object readResolve() {
return INSTANCE;
}
@Override
public String toString() {
return "MethodMatcher.TRUE";
}
}
@@ -0,0 +1,58 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop;
import java.io.Serializable;
/**
* Canonical Pointcut instance that always matches.
*
* @author Rod Johnson
*/
class TruePointcut implements Pointcut, Serializable {
public static final TruePointcut INSTANCE = new TruePointcut();
/**
* Enforce Singleton pattern.
*/
private TruePointcut() {
}
public ClassFilter getClassFilter() {
return ClassFilter.TRUE;
}
public MethodMatcher getMethodMatcher() {
return MethodMatcher.TRUE;
}
/**
* Required to support serialization. Replaces with canonical
* instance on deserialization, protecting Singleton pattern.
* Alternative to overriding <code>equals()</code>.
*/
private Object readResolve() {
return INSTANCE;
}
@Override
public String toString() {
return "Pointcut.TRUE";
}
}
@@ -0,0 +1,687 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInvocation;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.weaver.tools.JoinPointMatch;
import org.aspectj.weaver.tools.PointcutParameter;
import org.springframework.aop.AopInvocationException;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.aop.ProxyMethodInvocation;
import org.springframework.aop.interceptor.ExposeInvocationInterceptor;
import org.springframework.aop.support.ComposablePointcut;
import org.springframework.aop.support.MethodMatchers;
import org.springframework.aop.support.StaticMethodMatcher;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.PrioritizedParameterNameDiscoverer;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
/**
* Base class for AOP Alliance {@link org.aopalliance.aop.Advice} classes
* wrapping an AspectJ aspect or an AspectJ-annotated advice method.
*
* @author Rod Johnson
* @author Adrian Colyer
* @author Juergen Hoeller
* @author Ramnivas Laddad
* @since 2.0
*/
public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedenceInformation {
/**
* Key used in ReflectiveMethodInvocation userAtributes map for the current joinpoint.
*/
protected static final String JOIN_POINT_KEY = JoinPoint.class.getName();
/**
* Lazily instantiate joinpoint for the current invocation.
* Requires MethodInvocation to be bound with ExposeInvocationInterceptor.
* <p>Do not use if access is available to the current ReflectiveMethodInvocation
* (in an around advice).
* @return current AspectJ joinpoint, or through an exception if we're not in a
* Spring AOP invocation.
*/
public static JoinPoint currentJoinPoint() {
MethodInvocation mi = ExposeInvocationInterceptor.currentInvocation();
if (!(mi instanceof ProxyMethodInvocation)) {
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
}
ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
JoinPoint jp = (JoinPoint) pmi.getUserAttribute(JOIN_POINT_KEY);
if (jp == null) {
jp = new MethodInvocationProceedingJoinPoint(pmi);
pmi.setUserAttribute(JOIN_POINT_KEY, jp);
}
return jp;
}
protected final Method aspectJAdviceMethod;
/** The total number of arguments we have to populate on advice dispatch */
private final int adviceInvocationArgumentCount;
private final AspectJExpressionPointcut pointcut;
private final AspectInstanceFactory aspectInstanceFactory;
/**
* The name of the aspect (ref bean) in which this advice was defined (used
* when determining advice precedence so that we can determine
* whether two pieces of advice come from the same aspect).
*/
private String aspectName;
/**
* The order of declaration of this advice within the aspect.
*/
private int declarationOrder;
/**
* This will be non-null if the creator of this advice object knows the argument names
* and sets them explicitly
*/
private String[] argumentNames = null;
/** Non-null if after throwing advice binds the thrown value */
private String throwingName = null;
/** Non-null if after returning advice binds the return value */
private String returningName = null;
private Class discoveredReturningType = Object.class;
private Class discoveredThrowingType = Object.class;
/**
* Index for thisJoinPoint argument (currently only
* supported at index 0 if present at all)
*/
private int joinPointArgumentIndex = -1;
/**
* Index for thisJoinPointStaticPart argument (currently only
* supported at index 0 if present at all)
*/
private int joinPointStaticPartArgumentIndex = -1;
private Map<String, Integer> argumentBindings = null;
private boolean argumentsIntrospected = false;
// The actual type is java.lang.reflect.Type,
// but for JDK 1.4 compatibility we use Object as the static type.
private Object discoveredReturningGenericType;
// Note: Unlike return type, no such generic information is needed for the throwing type,
// since Java doesn't allow exception types to be parameterized.
/**
* Create a new AbstractAspectJAdvice for the given advice method.
* @param aspectJAdviceMethod the AspectJ-style advice method
* @param pointcut the AspectJ expression pointcut
* @param aspectInstanceFactory the factory for aspect instances
*/
public AbstractAspectJAdvice(
Method aspectJAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aspectInstanceFactory) {
Assert.notNull(aspectJAdviceMethod, "Advice method must not be null");
this.aspectJAdviceMethod = aspectJAdviceMethod;
this.adviceInvocationArgumentCount = this.aspectJAdviceMethod.getParameterTypes().length;
this.pointcut = pointcut;
this.aspectInstanceFactory = aspectInstanceFactory;
}
/**
* Return the AspectJ-style advice method.
*/
public final Method getAspectJAdviceMethod() {
return this.aspectJAdviceMethod;
}
/**
* Return the AspectJ expression pointcut.
*/
public final AspectJExpressionPointcut getPointcut() {
calculateArgumentBindings();
return this.pointcut;
}
/**
* Build a 'safe' pointcut that excludes the AspectJ advice method itself.
* @return a composable pointcut that builds on the original AspectJ expression pointcut
* @see #getPointcut()
*/
public final Pointcut buildSafePointcut() {
Pointcut pc = getPointcut();
MethodMatcher safeMethodMatcher = MethodMatchers.intersection(
new AdviceExcludingMethodMatcher(this.aspectJAdviceMethod), pc.getMethodMatcher());
return new ComposablePointcut(pc.getClassFilter(), safeMethodMatcher);
}
/**
* Return the factory for aspect instances.
*/
public final AspectInstanceFactory getAspectInstanceFactory() {
return this.aspectInstanceFactory;
}
/**
* Return the ClassLoader for aspect instances.
*/
public final ClassLoader getAspectClassLoader() {
return this.aspectInstanceFactory.getAspectClassLoader();
}
public int getOrder() {
return this.aspectInstanceFactory.getOrder();
}
public void setAspectName(String name) {
this.aspectName = name;
}
public String getAspectName() {
return this.aspectName;
}
/**
* Sets the <b>declaration order</b> of this advice within the aspect
*/
public void setDeclarationOrder(int order) {
this.declarationOrder = order;
}
public int getDeclarationOrder() {
return this.declarationOrder;
}
/**
* Set by creator of this advice object if the argument names are known.
* <p>This could be for example because they have been explicitly specified in XML,
* or in an advice annotation.
* @param argNames comma delimited list of arg names
*/
public void setArgumentNames(String argNames) {
String[] tokens = StringUtils.commaDelimitedListToStringArray(argNames);
setArgumentNamesFromStringArray(tokens);
}
public void setArgumentNamesFromStringArray(String[] args) {
this.argumentNames = new String[args.length];
for (int i = 0; i < args.length; i++) {
this.argumentNames[i] = StringUtils.trimWhitespace(args[i]);
if (!isVariableName(this.argumentNames[i])) {
throw new IllegalArgumentException(
"'argumentNames' property of AbstractAspectJAdvice contains an argument name '" +
this.argumentNames[i] + "' that is not a valid Java identifier");
}
}
if (argumentNames != null) {
if (aspectJAdviceMethod.getParameterTypes().length == argumentNames.length + 1) {
// May need to add implicit join point arg name...
Class firstArgType = aspectJAdviceMethod.getParameterTypes()[0];
if (firstArgType == JoinPoint.class ||
firstArgType == ProceedingJoinPoint.class ||
firstArgType == JoinPoint.StaticPart.class) {
String[] oldNames = argumentNames;
argumentNames = new String[oldNames.length + 1];
argumentNames[0] = "THIS_JOIN_POINT";
System.arraycopy(oldNames, 0, argumentNames, 1, oldNames.length);
}
}
}
}
public void setReturningName(String name) {
throw new UnsupportedOperationException("Only afterReturning advice can be used to bind a return value");
}
/**
* We need to hold the returning name at this level for argument binding calculations,
* this method allows the afterReturning advice subclass to set the name.
*/
protected void setReturningNameNoCheck(String name) {
// name could be a variable or a type...
if (isVariableName(name)) {
this.returningName = name;
}
else {
// assume a type
try {
this.discoveredReturningType = ClassUtils.forName(name, getAspectClassLoader());
}
catch (Throwable ex) {
throw new IllegalArgumentException("Returning name '" + name +
"' is neither a valid argument name nor the fully-qualified name of a Java type on the classpath. " +
"Root cause: " + ex);
}
}
}
protected Class getDiscoveredReturningType() {
return this.discoveredReturningType;
}
protected Object getDiscoveredReturningGenericType() {
return this.discoveredReturningGenericType;
}
public void setThrowingName(String name) {
throw new UnsupportedOperationException("Only afterThrowing advice can be used to bind a thrown exception");
}
/**
* We need to hold the throwing name at this level for argument binding calculations,
* this method allows the afterThrowing advice subclass to set the name.
*/
protected void setThrowingNameNoCheck(String name) {
// name could be a variable or a type...
if (isVariableName(name)) {
this.throwingName = name;
}
else {
// assume a type
try {
this.discoveredThrowingType = ClassUtils.forName(name, getAspectClassLoader());
}
catch (Throwable ex) {
throw new IllegalArgumentException("Throwing name '" + name +
"' is neither a valid argument name nor the fully-qualified name of a Java type on the classpath. " +
"Root cause: " + ex);
}
}
}
protected Class getDiscoveredThrowingType() {
return this.discoveredThrowingType;
}
private boolean isVariableName(String name) {
char[] chars = name.toCharArray();
if (!Character.isJavaIdentifierStart(chars[0])) {
return false;
}
for (int i = 1; i < chars.length; i++) {
if (!Character.isJavaIdentifierPart(chars[i])) {
return false;
}
}
return true;
}
/**
* Do as much work as we can as part of the set-up so that argument binding
* on subsequent advice invocations can be as fast as possible.
* <p>If the first argument is of type JoinPoint or ProceedingJoinPoint then we
* pass a JoinPoint in that position (ProceedingJoinPoint for around advice).
* <p>If the first argument is of type <code>JoinPoint.StaticPart</code>
* then we pass a <code>JoinPoint.StaticPart</code> in that position.
* <p>Remaining arguments have to be bound by pointcut evaluation at
* a given join point. We will get back a map from argument name to
* value. We need to calculate which advice parameter needs to be bound
* to which argument name. There are multiple strategies for determining
* this binding, which are arranged in a ChainOfResponsibility.
*/
public synchronized final void calculateArgumentBindings() {
// The simple case... nothing to bind.
if (this.argumentsIntrospected || this.adviceInvocationArgumentCount == 0) {
return;
}
int numUnboundArgs = this.adviceInvocationArgumentCount;
Class[] parameterTypes = this.aspectJAdviceMethod.getParameterTypes();
if (maybeBindJoinPoint(parameterTypes[0]) || maybeBindProceedingJoinPoint(parameterTypes[0])) {
numUnboundArgs--;
}
else if (maybeBindJoinPointStaticPart(parameterTypes[0])) {
numUnboundArgs--;
}
if (numUnboundArgs > 0) {
// need to bind arguments by name as returned from the pointcut match
bindArgumentsByName(numUnboundArgs);
}
this.argumentsIntrospected = true;
}
private boolean maybeBindJoinPoint(Class candidateParameterType) {
if (candidateParameterType.equals(JoinPoint.class)) {
this.joinPointArgumentIndex = 0;
return true;
}
else {
return false;
}
}
private boolean maybeBindProceedingJoinPoint(Class candidateParameterType) {
if (candidateParameterType.equals(ProceedingJoinPoint.class)) {
if (!supportsProceedingJoinPoint()) {
throw new IllegalArgumentException("ProceedingJoinPoint is only supported for around advice");
}
this.joinPointArgumentIndex = 0;
return true;
}
else {
return false;
}
}
protected boolean supportsProceedingJoinPoint() {
return false;
}
private boolean maybeBindJoinPointStaticPart(Class candidateParameterType) {
if (candidateParameterType.equals(JoinPoint.StaticPart.class)) {
this.joinPointStaticPartArgumentIndex = 0;
return true;
}
else {
return false;
}
}
private void bindArgumentsByName(int numArgumentsExpectingToBind) {
if (this.argumentNames == null) {
this.argumentNames = createParameterNameDiscoverer().getParameterNames(this.aspectJAdviceMethod);
}
if (this.argumentNames != null) {
// We have been able to determine the arg names.
bindExplicitArguments(numArgumentsExpectingToBind);
}
else {
throw new IllegalStateException("Advice method [" + this.aspectJAdviceMethod.getName() + "] " +
"requires " + numArgumentsExpectingToBind + " arguments to be bound by name, but " +
"the argument names were not specified and could not be discovered.");
}
}
/**
* Create a ParameterNameDiscoverer to be used for argument binding.
* <p>The default implementation creates a {@link PrioritizedParameterNameDiscoverer}
* containing a {@link LocalVariableTableParameterNameDiscoverer} and an
* {@link AspectJAdviceParameterNameDiscoverer}.
*/
protected ParameterNameDiscoverer createParameterNameDiscoverer() {
// We need to discover them, or if that fails, guess,
// and if we can't guess with 100% accuracy, fail.
PrioritizedParameterNameDiscoverer discoverer = new PrioritizedParameterNameDiscoverer();
discoverer.addDiscoverer(new LocalVariableTableParameterNameDiscoverer());
AspectJAdviceParameterNameDiscoverer adviceParameterNameDiscoverer =
new AspectJAdviceParameterNameDiscoverer(this.pointcut.getExpression());
adviceParameterNameDiscoverer.setReturningName(this.returningName);
adviceParameterNameDiscoverer.setThrowingName(this.throwingName);
// Last in chain, so if we're called and we fail, that's bad...
adviceParameterNameDiscoverer.setRaiseExceptions(true);
discoverer.addDiscoverer(adviceParameterNameDiscoverer);
return discoverer;
}
private void bindExplicitArguments(int numArgumentsLeftToBind) {
this.argumentBindings = new HashMap<String, Integer>();
int numExpectedArgumentNames = this.aspectJAdviceMethod.getParameterTypes().length;
if (this.argumentNames.length != numExpectedArgumentNames) {
throw new IllegalStateException("Expecting to find " + numExpectedArgumentNames
+ " arguments to bind by name in advice, but actually found " +
this.argumentNames.length + " arguments.");
}
// So we match in number...
int argumentIndexOffset = this.adviceInvocationArgumentCount - numArgumentsLeftToBind;
for (int i = argumentIndexOffset; i < this.argumentNames.length; i++) {
this.argumentBindings.put(this.argumentNames[i], i);
}
// Check that returning and throwing were in the argument names list if
// specified, and find the discovered argument types.
if (this.returningName != null) {
if (!this.argumentBindings.containsKey(this.returningName)) {
throw new IllegalStateException("Returning argument name '"
+ this.returningName + "' was not bound in advice arguments");
}
else {
Integer index = this.argumentBindings.get(this.returningName);
this.discoveredReturningType = this.aspectJAdviceMethod.getParameterTypes()[index];
this.discoveredReturningGenericType = this.aspectJAdviceMethod.getGenericParameterTypes()[index];
}
}
if (this.throwingName != null) {
if (!this.argumentBindings.containsKey(this.throwingName)) {
throw new IllegalStateException("Throwing argument name '"
+ this.throwingName + "' was not bound in advice arguments");
}
else {
Integer index = this.argumentBindings.get(this.throwingName);
this.discoveredThrowingType = this.aspectJAdviceMethod.getParameterTypes()[index];
}
}
// configure the pointcut expression accordingly.
configurePointcutParameters(argumentIndexOffset);
}
/**
* All parameters from argumentIndexOffset onwards are candidates for
* pointcut parameters - but returning and throwing vars are handled differently
* and must be removed from the list if present.
*/
private void configurePointcutParameters(int argumentIndexOffset) {
int numParametersToRemove = argumentIndexOffset;
if (this.returningName != null) {
numParametersToRemove++;
}
if (this.throwingName != null) {
numParametersToRemove++;
}
String[] pointcutParameterNames = new String[this.argumentNames.length - numParametersToRemove];
Class[] pointcutParameterTypes = new Class[pointcutParameterNames.length];
Class[] methodParameterTypes = this.aspectJAdviceMethod.getParameterTypes();
int index = 0;
for (int i = 0; i < this.argumentNames.length; i++) {
if (i < argumentIndexOffset) {
continue;
}
if (this.argumentNames[i].equals(this.returningName) ||
this.argumentNames[i].equals(this.throwingName)) {
continue;
}
pointcutParameterNames[index] = this.argumentNames[i];
pointcutParameterTypes[index] = methodParameterTypes[i];
index++;
}
this.pointcut.setParameterNames(pointcutParameterNames);
this.pointcut.setParameterTypes(pointcutParameterTypes);
}
/**
* Take the arguments at the method execution join point and output a set of arguments
* to the advice method
* @param jp the current JoinPoint
* @param jpMatch the join point match that matched this execution join point
* @param returnValue the return value from the method execution (may be null)
* @param ex the exception thrown by the method execution (may be null)
* @return the empty array if there are no arguments
*/
protected Object[] argBinding(JoinPoint jp, JoinPointMatch jpMatch, Object returnValue, Throwable ex) {
calculateArgumentBindings();
// AMC start
Object[] adviceInvocationArgs = new Object[this.adviceInvocationArgumentCount];
int numBound = 0;
if (this.joinPointArgumentIndex != -1) {
adviceInvocationArgs[this.joinPointArgumentIndex] = jp;
numBound++;
}
else if (this.joinPointStaticPartArgumentIndex != -1) {
adviceInvocationArgs[this.joinPointStaticPartArgumentIndex] = jp.getStaticPart();
numBound++;
}
if (!CollectionUtils.isEmpty(this.argumentBindings)) {
// binding from pointcut match
if (jpMatch != null) {
PointcutParameter[] parameterBindings = jpMatch.getParameterBindings();
for (PointcutParameter parameter : parameterBindings) {
String name = parameter.getName();
Integer index = this.argumentBindings.get(name);
adviceInvocationArgs[index] = parameter.getBinding();
numBound++;
}
}
// binding from returning clause
if (this.returningName != null) {
Integer index = this.argumentBindings.get(this.returningName);
adviceInvocationArgs[index] = returnValue;
numBound++;
}
// binding from thrown exception
if (this.throwingName != null) {
Integer index = this.argumentBindings.get(this.throwingName);
adviceInvocationArgs[index] = ex;
numBound++;
}
}
if (numBound != this.adviceInvocationArgumentCount) {
throw new IllegalStateException("Required to bind " + this.adviceInvocationArgumentCount
+ " arguments, but only bound " + numBound + " (JoinPointMatch " +
(jpMatch == null ? "was NOT" : "WAS") +
" bound in invocation)");
}
return adviceInvocationArgs;
}
/**
* Invoke the advice method.
* @param jpMatch the JoinPointMatch that matched this execution join point
* @param returnValue the return value from the method execution (may be null)
* @param ex the exception thrown by the method execution (may be null)
* @return the invocation result
* @throws Throwable in case of invocation failure
*/
protected Object invokeAdviceMethod(JoinPointMatch jpMatch, Object returnValue, Throwable ex) throws Throwable {
return invokeAdviceMethodWithGivenArgs(argBinding(getJoinPoint(), jpMatch, returnValue, ex));
}
// As above, but in this case we are given the join point.
protected Object invokeAdviceMethod(JoinPoint jp, JoinPointMatch jpMatch, Object returnValue, Throwable t)
throws Throwable {
return invokeAdviceMethodWithGivenArgs(argBinding(jp, jpMatch, returnValue, t));
}
protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
Object[] actualArgs = args;
if (this.aspectJAdviceMethod.getParameterTypes().length == 0) {
actualArgs = null;
}
try {
ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
// TODO AopUtils.invokeJoinpointUsingReflection
return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);
}
catch (IllegalArgumentException ex) {
throw new AopInvocationException("Mismatch on arguments to advice method [" +
this.aspectJAdviceMethod + "]; pointcut expression [" +
this.pointcut.getPointcutExpression() + "]", ex);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
/**
* Overridden in around advice to return proceeding join point.
*/
protected JoinPoint getJoinPoint() {
return currentJoinPoint();
}
/**
* Get the current join point match at the join point we are being dispatched on.
*/
protected JoinPointMatch getJoinPointMatch() {
MethodInvocation mi = ExposeInvocationInterceptor.currentInvocation();
if (!(mi instanceof ProxyMethodInvocation)) {
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
}
return getJoinPointMatch((ProxyMethodInvocation) mi);
}
// Note: We can't use JoinPointMatch.getClass().getName() as the key, since
// Spring AOP does all the matching at a join point, and then all the invocations.
// Under this scenario, if we just use JoinPointMatch as the key, then
// 'last man wins' which is not what we want at all.
// Using the expression is guaranteed to be safe, since 2 identical expressions
// are guaranteed to bind in exactly the same way.
protected JoinPointMatch getJoinPointMatch(ProxyMethodInvocation pmi) {
return (JoinPointMatch) pmi.getUserAttribute(this.pointcut.getExpression());
}
@Override
public String toString() {
return getClass().getName() + ": advice method [" + this.aspectJAdviceMethod + "]; " +
"aspect name '" + this.aspectName + "'";
}
/**
* MethodMatcher that excludes the specified advice method.
* @see AbstractAspectJAdvice#buildSafePointcut()
*/
private static class AdviceExcludingMethodMatcher extends StaticMethodMatcher {
private final Method adviceMethod;
public AdviceExcludingMethodMatcher(Method adviceMethod) {
this.adviceMethod = adviceMethod;
}
public boolean matches(Method method, Class targetClass) {
return !this.adviceMethod.equals(method);
}
}
}
@@ -0,0 +1,47 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj;
import org.springframework.core.Ordered;
/**
* Interface implemented to provide an instance of an AspectJ aspect.
* Decouples from Spring's bean factory.
*
* <p>Extends the {@link org.springframework.core.Ordered} interface
* to express an order value for the underlying aspect in a chain.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 2.0
* @see org.springframework.beans.factory.BeanFactory#getBean
*/
public interface AspectInstanceFactory extends Ordered {
/**
* Create an instance of this factory's aspect.
* @return the aspect instance (never <code>null</code>)
*/
Object getAspectInstance();
/**
* Expose the aspect class loader that this factory uses.
* @return the aspect class loader (never <code>null</code>)
*/
ClassLoader getAspectClassLoader();
}
@@ -0,0 +1,804 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.weaver.tools.PointcutParser;
import org.aspectj.weaver.tools.PointcutPrimitive;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.util.StringUtils;
/**
* {@link ParameterNameDiscoverer} implementation that tries to deduce parameter names
* for an advice method from the pointcut expression, returning, and throwing clauses.
* If an unambiguous interpretation is not available, it returns <code>null</code>.
*
* <p>This class interprets arguments in the following way:
* <ol>
* <li>If the first parameter of the method is of type {@link JoinPoint}
* or {@link ProceedingJoinPoint}, it is assumed to be for passing
* <code>thisJoinPoint</code> to the advice, and the parameter name will
* be assigned the value <code>"thisJoinPoint"</code>.</li>
* <li>If the first parameter of the method is of type
* <code>JoinPoint.StaticPart</code>, it is assumed to be for passing
* <code>"thisJoinPointStaticPart"</code> to the advice, and the parameter name
* will be assigned the value <code>"thisJoinPointStaticPart"</code>.</li>
* <li>If a {@link #setThrowingName(String) throwingName} has been set, and
* there are no unbound arguments of type <code>Throwable+</code>, then an
* {@link IllegalArgumentException} is raised. If there is more than one
* unbound argument of type <code>Throwable+</code>, then an
* {@link AmbiguousBindingException} is raised. If there is exactly one
* unbound argument of type <code>Throwable+</code>, then the corresponding
* parameter name is assigned the value &lt;throwingName&gt;.</li>
* <li>If there remain unbound arguments, then the pointcut expression is
* examined. Let <code>a</code> be the number of annotation-based pointcut
* expressions (&#64;annotation, &#64;this, &#64;target, &#64;args,
* &#64;within, &#64;withincode) that are used in binding form. Usage in
* binding form has itself to be deduced: if the expression inside the
* pointcut is a single string literal that meets Java variable name
* conventions it is assumed to be a variable name. If <code>a</code> is
* zero we proceed to the next stage. If <code>a</code> &gt; 1 then an
* <code>AmbiguousBindingException</code> is raised. If <code>a</code> == 1,
* and there are no unbound arguments of type <code>Annotation+</code>,
* then an <code>IllegalArgumentException</code> is raised. if there is
* exactly one such argument, then the corresponding parameter name is
* assigned the value from the pointcut expression.</li>
* <li>If a returningName has been set, and there are no unbound arguments
* then an <code>IllegalArgumentException</code> is raised. If there is
* more than one unbound argument then an
* <code>AmbiguousBindingException</code> is raised. If there is exactly
* one unbound argument then the corresponding parameter name is assigned
* the value &lt;returningName&gt;.</li>
* <li>If there remain unbound arguments, then the pointcut expression is
* examined once more for <code>this</code>, <code>target</code>, and
* <code>args</code> pointcut expressions used in the binding form (binding
* forms are deduced as described for the annotation based pointcuts). If
* there remains more than one unbound argument of a primitive type (which
* can only be bound in <code>args</code>) then an
* <code>AmbiguousBindingException</code> is raised. If there is exactly
* one argument of a primitive type, then if exactly one <code>args</code>
* bound variable was found, we assign the corresponding parameter name
* the variable name. If there were no <code>args</code> bound variables
* found an <code>IllegalStateException</code> is raised. If there are
* multiple <code>args</code> bound variables, an
* <code>AmbiguousBindingException</code> is raised. At this point, if
* there remains more than one unbound argument we raise an
* <code>AmbiguousBindingException</code>. If there are no unbound arguments
* remaining, we are done. If there is exactly one unbound argument
* remaining, and only one candidate variable name unbound from
* <code>this</code>, <code>target</code>, or <code>args</code>, it is
* assigned as the corresponding parameter name. If there are multiple
* possibilities, an <code>AmbiguousBindingException</code> is raised.</li>
* </ol>
*
* <p>The behavior on raising an <code>IllegalArgumentException</code> or
* <code>AmbiguousBindingException</code> is configurable to allow this discoverer
* to be used as part of a chain-of-responsibility. By default the condition will
* be logged and the <code>getParameterNames(..)</code> method will simply return
* <code>null</code>. If the {@link #setRaiseExceptions(boolean) raiseExceptions}
* property is set to <code>true</code>, the conditions will be thrown as
* <code>IllegalArgumentException</code> and <code>AmbiguousBindingException</code>,
* respectively.
*
* <p>Was that perfectly clear? ;)
*
* <p>Short version: If an unambiguous binding can be deduced, then it is.
* If the advice requirements cannot possibly be satisfied, then <code>null</code>
* is returned. By setting the {@link #setRaiseExceptions(boolean) raiseExceptions}
* property to <code>true</code>, descriptive exceptions will be thrown instead of
* returning <code>null</code> in the case that the parameter names cannot be discovered.
*
* @author Adrian Colyer
* @since 2.0
*/
public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscoverer {
private static final String THIS_JOIN_POINT = "thisJoinPoint";
private static final String THIS_JOIN_POINT_STATIC_PART = "thisJoinPointStaticPart";
// Steps in the binding algorithm...
private static final int STEP_JOIN_POINT_BINDING = 1;
private static final int STEP_THROWING_BINDING = 2;
private static final int STEP_ANNOTATION_BINDING = 3;
private static final int STEP_RETURNING_BINDING = 4;
private static final int STEP_PRIMITIVE_ARGS_BINDING = 5;
private static final int STEP_THIS_TARGET_ARGS_BINDING = 6;
private static final int STEP_REFERENCE_PCUT_BINDING = 7;
private static final int STEP_FINISHED = 8;
private static final Set<String> singleValuedAnnotationPcds = new HashSet<String>();
private static final Set<String> nonReferencePointcutTokens = new HashSet<String>();
static {
singleValuedAnnotationPcds.add("@this");
singleValuedAnnotationPcds.add("@target");
singleValuedAnnotationPcds.add("@within");
singleValuedAnnotationPcds.add("@withincode");
singleValuedAnnotationPcds.add("@annotation");
Set pointcutPrimitives = PointcutParser.getAllSupportedPointcutPrimitives();
for (Iterator iterator = pointcutPrimitives.iterator(); iterator.hasNext();) {
PointcutPrimitive primitive = (PointcutPrimitive) iterator.next();
nonReferencePointcutTokens.add(primitive.getName());
}
nonReferencePointcutTokens.add("&&");
nonReferencePointcutTokens.add("!");
nonReferencePointcutTokens.add("||");
nonReferencePointcutTokens.add("and");
nonReferencePointcutTokens.add("or");
nonReferencePointcutTokens.add("not");
}
private boolean raiseExceptions;
/**
* If the advice is afterReturning, and binds the return value, this is the parameter name used.
*/
private String returningName;
/**
* If the advice is afterThrowing, and binds the thrown value, this is the parameter name used.
*/
private String throwingName;
/**
* The pointcut expression associated with the advice, as a simple String.
*/
private String pointcutExpression;
private Class[] argumentTypes;
private String[] parameterNameBindings;
private int numberOfRemainingUnboundArguments;
/**
* Create a new discoverer that attempts to discover parameter names
* from the given pointcut expression.
*/
public AspectJAdviceParameterNameDiscoverer(String pointcutExpression) {
this.pointcutExpression = pointcutExpression;
}
/**
* Indicate whether {@link IllegalArgumentException} and {@link AmbiguousBindingException}
* must be thrown as appropriate in the case of failing to deduce advice parameter names.
* @param raiseExceptions <code>true</code> if exceptions are to be thrown
*/
public void setRaiseExceptions(boolean raiseExceptions) {
this.raiseExceptions = raiseExceptions;
}
/**
* If <code>afterReturning</code> advice binds the return value, the
* returning variable name must be specified.
* @param returningName the name of the returning variable
*/
public void setReturningName(String returningName) {
this.returningName = returningName;
}
/**
* If <code>afterThrowing</code> advice binds the thrown value, the
* throwing variable name must be specified.
* @param throwingName the name of the throwing variable
*/
public void setThrowingName(String throwingName) {
this.throwingName = throwingName;
}
/**
* Deduce the parameter names for an advice method.
* <p>See the {@link AspectJAdviceParameterNameDiscoverer class level javadoc}
* for this class for details of the algorithm used.
* @param method the target {@link Method}
* @return the parameter names
*/
public String[] getParameterNames(Method method) {
this.argumentTypes = method.getParameterTypes();
this.numberOfRemainingUnboundArguments = this.argumentTypes.length;
this.parameterNameBindings = new String[this.numberOfRemainingUnboundArguments];
int minimumNumberUnboundArgs = 0;
if (this.returningName != null) {
minimumNumberUnboundArgs++;
}
if (this.throwingName != null) {
minimumNumberUnboundArgs++;
}
if (this.numberOfRemainingUnboundArguments < minimumNumberUnboundArgs) {
throw new IllegalStateException(
"Not enough arguments in method to satisfy binding of returning and throwing variables");
}
try {
int algorithmicStep = STEP_JOIN_POINT_BINDING;
while ((this.numberOfRemainingUnboundArguments > 0) && algorithmicStep < STEP_FINISHED) {
switch (algorithmicStep++) {
case STEP_JOIN_POINT_BINDING:
if (!maybeBindThisJoinPoint()) {
maybeBindThisJoinPointStaticPart();
}
break;
case STEP_THROWING_BINDING:
maybeBindThrowingVariable();
break;
case STEP_ANNOTATION_BINDING:
maybeBindAnnotationsFromPointcutExpression();
break;
case STEP_RETURNING_BINDING:
maybeBindReturningVariable();
break;
case STEP_PRIMITIVE_ARGS_BINDING:
maybeBindPrimitiveArgsFromPointcutExpression();
break;
case STEP_THIS_TARGET_ARGS_BINDING:
maybeBindThisOrTargetOrArgsFromPointcutExpression();
break;
case STEP_REFERENCE_PCUT_BINDING:
maybeBindReferencePointcutParameter();
break;
default:
throw new IllegalStateException("Unknown algorithmic step: " + (algorithmicStep - 1));
}
}
}
catch (AmbiguousBindingException ambigEx) {
if (this.raiseExceptions) {
throw ambigEx;
}
else {
return null;
}
}
catch (IllegalArgumentException ex) {
if (this.raiseExceptions) {
throw ex;
}
else {
return null;
}
}
if (this.numberOfRemainingUnboundArguments == 0) {
return this.parameterNameBindings;
}
else {
if (this.raiseExceptions) {
throw new IllegalStateException("Failed to bind all argument names: " +
this.numberOfRemainingUnboundArguments + " argument(s) could not be bound");
}
else {
// convention for failing is to return null, allowing participation in a chain of responsibility
return null;
}
}
}
/**
* An advice method can never be a constructor in Spring.
* @return <code>null</code>
* @throws UnsupportedOperationException if
* {@link #setRaiseExceptions(boolean) raiseExceptions} has been set to <code>true</code>
*/
public String[] getParameterNames(Constructor ctor) {
if (this.raiseExceptions) {
throw new UnsupportedOperationException("An advice method can never be a constructor");
}
else {
// we return null rather than throw an exception so that we behave well
// in a chain-of-responsibility.
return null;
}
}
private void bindParameterName(int index, String name) {
this.parameterNameBindings[index] = name;
this.numberOfRemainingUnboundArguments--;
}
/**
* If the first parameter is of type JoinPoint or ProceedingJoinPoint,bind "thisJoinPoint" as
* parameter name and return true, else return false.
*/
private boolean maybeBindThisJoinPoint() {
if ((this.argumentTypes[0] == JoinPoint.class) || (this.argumentTypes[0] == ProceedingJoinPoint.class)) {
bindParameterName(0, THIS_JOIN_POINT);
return true;
}
else {
return false;
}
}
private void maybeBindThisJoinPointStaticPart() {
if (this.argumentTypes[0] == JoinPoint.StaticPart.class) {
bindParameterName(0, THIS_JOIN_POINT_STATIC_PART);
}
}
/**
* If a throwing name was specified and there is exactly one choice remaining
* (argument that is a subtype of Throwable) then bind it.
*/
private void maybeBindThrowingVariable() {
if (this.throwingName == null) {
return;
}
// So there is binding work to do...
int throwableIndex = -1;
for (int i = 0; i < this.argumentTypes.length; i++) {
if (isUnbound(i) && isSubtypeOf(Throwable.class, i)) {
if (throwableIndex == -1) {
throwableIndex = i;
}
else {
// Second candidate we've found - ambiguous binding
throw new AmbiguousBindingException("Binding of throwing parameter '" +
this.throwingName + "' is ambiguous: could be bound to argument " +
throwableIndex + " or argument " + i);
}
}
}
if (throwableIndex == -1) {
throw new IllegalStateException("Binding of throwing parameter '" + this.throwingName
+ "' could not be completed as no available arguments are a subtype of Throwable");
}
else {
bindParameterName(throwableIndex, this.throwingName);
}
}
/**
* If a returning variable was specified and there is only one choice remaining, bind it.
*/
private void maybeBindReturningVariable() {
if (this.numberOfRemainingUnboundArguments == 0) {
throw new IllegalStateException(
"Algorithm assumes that there must be at least one unbound parameter on entry to this method");
}
if (this.returningName != null) {
if (this.numberOfRemainingUnboundArguments > 1) {
throw new AmbiguousBindingException("Binding of returning parameter '" + this.returningName +
"' is ambiguous, there are " + this.numberOfRemainingUnboundArguments + " candidates.");
}
// We're all set... find the unbound parameter, and bind it.
for (int i = 0; i < this.parameterNameBindings.length; i++) {
if (this.parameterNameBindings[i] == null) {
bindParameterName(i, this.returningName);
break;
}
}
}
}
/**
* Parse the string pointcut expression looking for:
* &#64;this, &#64;target, &#64;args, &#64;within, &#64;withincode, &#64;annotation.
* If we find one of these pointcut expressions, try and extract a candidate variable
* name (or variable names, in the case of args).
* <p>Some more support from AspectJ in doing this exercise would be nice... :)
*/
private void maybeBindAnnotationsFromPointcutExpression() {
List<String> varNames = new ArrayList<String>();
String[] tokens = StringUtils.tokenizeToStringArray(this.pointcutExpression, " ");
for (int i = 0; i < tokens.length; i++) {
String toMatch = tokens[i];
int firstParenIndex = toMatch.indexOf("(");
if (firstParenIndex != -1) {
toMatch = toMatch.substring(0, firstParenIndex);
}
if (singleValuedAnnotationPcds.contains(toMatch)) {
PointcutBody body = getPointcutBody(tokens, i);
i += body.numTokensConsumed;
String varName = maybeExtractVariableName(body.text);
if (varName != null) {
varNames.add(varName);
}
}
else if (tokens[i].startsWith("@args(") || tokens[i].equals("@args")) {
PointcutBody body = getPointcutBody(tokens, i);
i += body.numTokensConsumed;
maybeExtractVariableNamesFromArgs(body.text, varNames);
}
}
bindAnnotationsFromVarNames(varNames);
}
/**
* Match the given list of extracted variable names to argument slots.
*/
private void bindAnnotationsFromVarNames(List<String> varNames) {
if (!varNames.isEmpty()) {
// we have work to do...
int numAnnotationSlots = countNumberOfUnboundAnnotationArguments();
if (numAnnotationSlots > 1) {
throw new AmbiguousBindingException("Found " + varNames.size() +
" potential annotation variable(s), and " +
numAnnotationSlots + " potential argument slots");
}
else if (numAnnotationSlots == 1) {
if (varNames.size() == 1) {
// it's a match
findAndBind(Annotation.class, varNames.get(0));
}
else {
// multiple candidate vars, but only one slot
throw new IllegalArgumentException("Found " + varNames.size() +
" candidate annotation binding variables" +
" but only one potential argument binding slot");
}
}
else {
// no slots so presume those candidate vars were actually type names
}
}
}
/*
* If the token starts meets Java identifier conventions, it's in.
*/
private String maybeExtractVariableName(String candidateToken) {
if (candidateToken == null || candidateToken.equals("")) {
return null;
}
if (Character.isJavaIdentifierStart(candidateToken.charAt(0)) &&
Character.isLowerCase(candidateToken.charAt(0))) {
char[] tokenChars = candidateToken.toCharArray();
for (char tokenChar : tokenChars) {
if (!Character.isJavaIdentifierPart(tokenChar)) {
return null;
}
}
return candidateToken;
}
else {
return null;
}
}
/**
* Given an args pointcut body (could be <code>args</code> or <code>at_args</code>),
* add any candidate variable names to the given list.
*/
private void maybeExtractVariableNamesFromArgs(String argsSpec, List<String> varNames) {
if (argsSpec == null) {
return;
}
String[] tokens = StringUtils.tokenizeToStringArray(argsSpec, ",");
for (int i = 0; i < tokens.length; i++) {
tokens[i] = StringUtils.trimWhitespace(tokens[i]);
String varName = maybeExtractVariableName(tokens[i]);
if (varName != null) {
varNames.add(varName);
}
}
}
/**
* Parse the string pointcut expression looking for this(), target() and args() expressions.
* If we find one, try and extract a candidate variable name and bind it.
*/
private void maybeBindThisOrTargetOrArgsFromPointcutExpression() {
if (this.numberOfRemainingUnboundArguments > 1) {
throw new AmbiguousBindingException("Still " + this.numberOfRemainingUnboundArguments
+ " unbound args at this(),target(),args() binding stage, with no way to determine between them");
}
List<String> varNames = new ArrayList<String>();
String[] tokens = StringUtils.tokenizeToStringArray(this.pointcutExpression, " ");
for (int i = 0; i < tokens.length; i++) {
if (tokens[i].equals("this") ||
tokens[i].startsWith("this(") ||
tokens[i].equals("target") ||
tokens[i].startsWith("target(")) {
PointcutBody body = getPointcutBody(tokens, i);
i += body.numTokensConsumed;
String varName = maybeExtractVariableName(body.text);
if (varName != null) {
varNames.add(varName);
}
}
else if (tokens[i].equals("args") || tokens[i].startsWith("args(")) {
PointcutBody body = getPointcutBody(tokens, i);
i += body.numTokensConsumed;
List<String> candidateVarNames = new ArrayList<String>();
maybeExtractVariableNamesFromArgs(body.text, candidateVarNames);
// we may have found some var names that were bound in previous primitive args binding step,
// filter them out...
for (String varName : candidateVarNames) {
if (!alreadyBound(varName)) {
varNames.add(varName);
}
}
}
}
if (varNames.size() > 1) {
throw new AmbiguousBindingException("Found " + varNames.size() +
" candidate this(), target() or args() variables but only one unbound argument slot");
}
else if (varNames.size() == 1) {
for (int j = 0; j < this.parameterNameBindings.length; j++) {
if (isUnbound(j)) {
bindParameterName(j, varNames.get(0));
break;
}
}
}
// else varNames.size must be 0 and we have nothing to bind.
}
private void maybeBindReferencePointcutParameter() {
if (this.numberOfRemainingUnboundArguments > 1) {
throw new AmbiguousBindingException("Still " + this.numberOfRemainingUnboundArguments
+ " unbound args at reference pointcut binding stage, with no way to determine between them");
}
List<String> varNames = new ArrayList<String>();
String[] tokens = StringUtils.tokenizeToStringArray(this.pointcutExpression, " ");
for (int i = 0; i < tokens.length; i++) {
String toMatch = tokens[i];
if (toMatch.startsWith("!")) {
toMatch = toMatch.substring(1);
}
int firstParenIndex = toMatch.indexOf("(");
if (firstParenIndex != -1) {
toMatch = toMatch.substring(0, firstParenIndex);
}
else {
if (tokens.length < i + 2) {
// no "(" and nothing following
continue;
}
else {
String nextToken = tokens[i + 1];
if (nextToken.charAt(0) != '(') {
// next token is not "(" either, can't be a pc...
continue;
}
}
}
// eat the body
PointcutBody body = getPointcutBody(tokens, i);
i += body.numTokensConsumed;
if (!nonReferencePointcutTokens.contains(toMatch)) {
// then it could be a reference pointcut
String varName = maybeExtractVariableName(body.text);
if (varName != null) {
varNames.add(varName);
}
}
}
if (varNames.size() > 1) {
throw new AmbiguousBindingException("Found " + varNames.size() +
" candidate reference pointcut variables but only one unbound argument slot");
}
else if (varNames.size() == 1) {
for (int j = 0; j < this.parameterNameBindings.length; j++) {
if (isUnbound(j)) {
bindParameterName(j, varNames.get(0));
break;
}
}
}
// else varNames.size must be 0 and we have nothing to bind.
}
/*
* We've found the start of a binding pointcut at the given index into the
* token array. Now we need to extract the pointcut body and return it.
*/
private PointcutBody getPointcutBody(String[] tokens, int startIndex) {
int numTokensConsumed = 0;
String currentToken = tokens[startIndex];
int bodyStart = currentToken.indexOf('(');
if (currentToken.charAt(currentToken.length() - 1) == ')') {
// It's an all in one... get the text between the first (and the last)
return new PointcutBody(0, currentToken.substring(bodyStart + 1, currentToken.length() - 1));
}
else {
StringBuilder sb = new StringBuilder();
if (bodyStart >= 0 && bodyStart != (currentToken.length() - 1)) {
sb.append(currentToken.substring(bodyStart + 1));
sb.append(" ");
}
numTokensConsumed++;
int currentIndex = startIndex + numTokensConsumed;
while (currentIndex < tokens.length) {
if (tokens[currentIndex].equals("(")) {
currentIndex++;
continue;
}
if (tokens[currentIndex].endsWith(")")) {
sb.append(tokens[currentIndex].substring(0, tokens[currentIndex].length() - 1));
return new PointcutBody(numTokensConsumed, sb.toString().trim());
}
String toAppend = tokens[currentIndex];
if (toAppend.startsWith("(")) {
toAppend = toAppend.substring(1);
}
sb.append(toAppend);
sb.append(" ");
currentIndex++;
numTokensConsumed++;
}
}
// We looked and failed...
return new PointcutBody(numTokensConsumed, null);
}
/**
* Match up args against unbound arguments of primitive types
*/
private void maybeBindPrimitiveArgsFromPointcutExpression() {
int numUnboundPrimitives = countNumberOfUnboundPrimitiveArguments();
if (numUnboundPrimitives > 1) {
throw new AmbiguousBindingException("Found '" + numUnboundPrimitives +
"' unbound primitive arguments with no way to distinguish between them.");
}
if (numUnboundPrimitives == 1) {
// Look for arg variable and bind it if we find exactly one...
List<String> varNames = new ArrayList<String>();
String[] tokens = StringUtils.tokenizeToStringArray(this.pointcutExpression, " ");
for (int i = 0; i < tokens.length; i++) {
if (tokens[i].equals("args") || tokens[i].startsWith("args(")) {
PointcutBody body = getPointcutBody(tokens, i);
i += body.numTokensConsumed;
maybeExtractVariableNamesFromArgs(body.text, varNames);
}
}
if (varNames.size() > 1) {
throw new AmbiguousBindingException("Found " + varNames.size() +
" candidate variable names but only one candidate binding slot when matching primitive args");
}
else if (varNames.size() == 1) {
// 1 primitive arg, and one candidate...
for (int i = 0; i < this.argumentTypes.length; i++) {
if (isUnbound(i) && this.argumentTypes[i].isPrimitive()) {
bindParameterName(i, (String) varNames.get(0));
break;
}
}
}
}
}
/*
* Return true if the parameter name binding for the given parameter
* index has not yet been assigned.
*/
private boolean isUnbound(int i) {
return this.parameterNameBindings[i] == null;
}
private boolean alreadyBound(String varName) {
for (int i = 0; i < this.parameterNameBindings.length; i++) {
if (!isUnbound(i) && varName.equals(this.parameterNameBindings[i])) {
return true;
}
}
return false;
}
/*
* Return <code>true</code> if the given argument type is a subclass
* of the given supertype.
*/
private boolean isSubtypeOf(Class supertype, int argumentNumber) {
return supertype.isAssignableFrom(this.argumentTypes[argumentNumber]);
}
private int countNumberOfUnboundAnnotationArguments() {
int count = 0;
for (int i = 0; i < this.argumentTypes.length; i++) {
if (isUnbound(i) && isSubtypeOf(Annotation.class, i)) {
count++;
}
}
return count;
}
private int countNumberOfUnboundPrimitiveArguments() {
int count = 0;
for (int i = 0; i < this.argumentTypes.length; i++) {
if (isUnbound(i) && this.argumentTypes[i].isPrimitive()) {
count++;
}
}
return count;
}
/*
* Find the argument index with the given type, and bind the given
* <code>varName</code> in that position.
*/
private void findAndBind(Class argumentType, String varName) {
for (int i = 0; i < this.argumentTypes.length; i++) {
if (isUnbound(i) && isSubtypeOf(argumentType, i)) {
bindParameterName(i, varName);
return;
}
}
throw new IllegalStateException("Expected to find an unbound argument of type '" +
argumentType.getName() + "'");
}
/**
* Simple struct to hold the extracted text from a pointcut body, together
* with the number of tokens consumed in extracting it.
*/
private static class PointcutBody {
private int numTokensConsumed;
private String text;
public PointcutBody(int tokens, String text) {
this.numTokensConsumed = tokens;
this.text = text;
}
}
/**
* Thrown in response to an ambiguous binding being detected when
* trying to resolve a method's parameter names.
*/
public static class AmbiguousBindingException extends RuntimeException {
/**
* Construct a new AmbiguousBindingException with the specified message.
* @param msg the detail message
*/
public AmbiguousBindingException(String msg) {
super(msg);
}
}
}
@@ -0,0 +1,57 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj;
import java.lang.reflect.Method;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.AfterAdvice;
/**
* Spring AOP advice wrapping an AspectJ after advice method.
*
* @author Rod Johnson
* @since 2.0
*/
public class AspectJAfterAdvice extends AbstractAspectJAdvice implements MethodInterceptor, AfterAdvice {
public AspectJAfterAdvice(
Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
super(aspectJBeforeAdviceMethod, pointcut, aif);
}
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
finally {
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
public boolean isBeforeAdvice() {
return false;
}
public boolean isAfterAdvice() {
return true;
}
}
@@ -0,0 +1,89 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import org.springframework.aop.AfterAdvice;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.util.ClassUtils;
import org.springframework.util.TypeUtils;
/**
* Spring AOP advice wrapping an AspectJ after-returning advice method.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Ramnivas Laddad
* @since 2.0
*/
public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice implements AfterReturningAdvice, AfterAdvice {
public AspectJAfterReturningAdvice(
Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
super(aspectJBeforeAdviceMethod, pointcut, aif);
}
public boolean isBeforeAdvice() {
return false;
}
public boolean isAfterAdvice() {
return true;
}
@Override
public void setReturningName(String name) {
setReturningNameNoCheck(name);
}
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
if (shouldInvokeOnReturnValueOf(method, returnValue)) {
invokeAdviceMethod(getJoinPointMatch(), returnValue, null);
}
}
/**
* Following AspectJ semantics, if a returning clause was specified, then the
* advice is only invoked if the returned value is an instance of the given
* returning type and generic type parameters, if any, match the assignment
* rules. If the returning type is Object, the advice is *always* invoked.
* @param returnValue the return value of the target method
* @return whether to invoke the advice method for the given return value
*/
private boolean shouldInvokeOnReturnValueOf(Method method, Object returnValue) {
Class type = getDiscoveredReturningType();
Object genericType = getDiscoveredReturningGenericType();
// If we aren't dealing with a raw type, check if generic parameters are assignable.
return (ClassUtils.isAssignableValue(type, returnValue) &&
(genericType == null || genericType == type || GenericTypeMatcher.isAssignable(genericType, method)));
}
/**
* Inner class to avoid a static JDK 1.5 dependency for generic type matching.
*/
private static class GenericTypeMatcher {
public static boolean isAssignable(Object genericType, Method method) {
return TypeUtils.isAssignable((Type) genericType, method.getGenericReturnType());
}
}
}
@@ -0,0 +1,74 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj;
import java.lang.reflect.Method;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.AfterAdvice;
/**
* Spring AOP advice wrapping an AspectJ after-throwing advice method.
*
* @author Rod Johnson
* @since 2.0
*/
public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice implements MethodInterceptor, AfterAdvice {
public AspectJAfterThrowingAdvice(
Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
super(aspectJBeforeAdviceMethod, pointcut, aif);
}
public boolean isBeforeAdvice() {
return false;
}
public boolean isAfterAdvice() {
return true;
}
@Override
public void setThrowingName(String name) {
setThrowingNameNoCheck(name);
}
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
catch (Throwable t) {
if (shouldInvokeOnThrowing(t)) {
invokeAdviceMethod(getJoinPointMatch(), null, t);
}
throw t;
}
}
/**
* In AspectJ semantics, after throwing advice that specifies a throwing clause
* is only invoked if the thrown exception is a subtype of the given throwing type.
*/
private boolean shouldInvokeOnThrowing(Throwable t) {
Class throwingType = getDiscoveredThrowingType();
return throwingType.isAssignableFrom(t.getClass());
}
}
@@ -0,0 +1,72 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj;
import org.aopalliance.aop.Advice;
import org.springframework.aop.Advisor;
import org.springframework.aop.AfterAdvice;
import org.springframework.aop.BeforeAdvice;
/**
* Utility methods for dealing with AspectJ advisors.
*
* @author Adrian Colyer
* @author Juergen Hoeller
* @since 2.0
*/
public abstract class AspectJAopUtils {
/**
* Return <code>true</code> if the advisor is a form of before advice.
*/
public static boolean isBeforeAdvice(Advisor anAdvisor) {
AspectJPrecedenceInformation precedenceInfo = getAspectJPrecedenceInformationFor(anAdvisor);
if (precedenceInfo != null) {
return precedenceInfo.isBeforeAdvice();
}
return (anAdvisor.getAdvice() instanceof BeforeAdvice);
}
/**
* Return <code>true</code> if the advisor is a form of after advice.
*/
public static boolean isAfterAdvice(Advisor anAdvisor) {
AspectJPrecedenceInformation precedenceInfo = getAspectJPrecedenceInformationFor(anAdvisor);
if (precedenceInfo != null) {
return precedenceInfo.isAfterAdvice();
}
return (anAdvisor.getAdvice() instanceof AfterAdvice);
}
/**
* Return the AspectJPrecedenceInformation provided by this advisor or its advice.
* If neither the advisor nor the advice have precedence information, this method
* will return <code>null</code>.
*/
public static AspectJPrecedenceInformation getAspectJPrecedenceInformationFor(Advisor anAdvisor) {
if (anAdvisor instanceof AspectJPrecedenceInformation) {
return (AspectJPrecedenceInformation) anAdvisor;
}
Advice advice = anAdvisor.getAdvice();
if (advice instanceof AspectJPrecedenceInformation) {
return (AspectJPrecedenceInformation) advice;
}
return null;
}
}
@@ -0,0 +1,79 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj;
import java.lang.reflect.Method;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.weaver.tools.JoinPointMatch;
import org.springframework.aop.ProxyMethodInvocation;
/**
* Spring AOP around advice (MethodInterceptor) that wraps
* an AspectJ advice method. Exposes ProceedingJoinPoint.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 2.0
*/
public class AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor {
public AspectJAroundAdvice(
Method aspectJAroundAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
super(aspectJAroundAdviceMethod, pointcut, aif);
}
public boolean isBeforeAdvice() {
return false;
}
public boolean isAfterAdvice() {
return false;
}
@Override
protected boolean supportsProceedingJoinPoint() {
return true;
}
public Object invoke(MethodInvocation mi) throws Throwable {
if (!(mi instanceof ProxyMethodInvocation)) {
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
}
ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
JoinPointMatch jpm = getJoinPointMatch(pmi);
return invokeAdviceMethod(pjp, jpm, null, null);
}
/**
* Return the ProceedingJoinPoint for the current invocation,
* instantiating it lazily if it hasn't been bound to the thread already.
* @param rmi the current Spring AOP ReflectiveMethodInvocation,
* which we'll use for attribute binding
* @return the ProceedingJoinPoint to make available to advice methods
*/
protected ProceedingJoinPoint lazyGetProceedingJoinPoint(ProxyMethodInvocation rmi) {
return new MethodInvocationProceedingJoinPoint(rmi);
}
}
@@ -0,0 +1,531 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.patterns.NamePattern;
import org.aspectj.weaver.reflect.ReflectionWorld;
import org.aspectj.weaver.reflect.ShadowMatchImpl;
import org.aspectj.weaver.tools.ContextBasedMatcher;
import org.aspectj.weaver.tools.FuzzyBoolean;
import org.aspectj.weaver.tools.JoinPointMatch;
import org.aspectj.weaver.tools.MatchingContext;
import org.aspectj.weaver.tools.PointcutDesignatorHandler;
import org.aspectj.weaver.tools.PointcutExpression;
import org.aspectj.weaver.tools.PointcutParameter;
import org.aspectj.weaver.tools.PointcutParser;
import org.aspectj.weaver.tools.PointcutPrimitive;
import org.aspectj.weaver.tools.ShadowMatch;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.IntroductionAwareMethodMatcher;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.ProxyMethodInvocation;
import org.springframework.aop.framework.autoproxy.ProxyCreationContext;
import org.springframework.aop.interceptor.ExposeInvocationInterceptor;
import org.springframework.aop.support.AbstractExpressionPointcut;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
/**
* Spring {@link org.springframework.aop.Pointcut} implementation
* that uses the AspectJ weaver to evaluate a pointcut expression.
*
* <p>The pointcut expression value is an AspectJ expression. This can
* reference other pointcuts and use composition and other operations.
*
* <p>Naturally, as this is to be processed by Spring AOP's proxy-based model,
* only method execution pointcuts are supported.
*
* @author Rob Harrop
* @author Adrian Colyer
* @author Rod Johnson
* @author Juergen Hoeller
* @author Ramnivas Laddad
* @since 2.0
*/
public class AspectJExpressionPointcut extends AbstractExpressionPointcut
implements ClassFilter, IntroductionAwareMethodMatcher, BeanFactoryAware {
private static final Set<PointcutPrimitive> DEFAULT_SUPPORTED_PRIMITIVES = new HashSet<PointcutPrimitive>();
static {
DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.EXECUTION);
DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.ARGS);
DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.REFERENCE);
DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.THIS);
DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.TARGET);
DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.WITHIN);
DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_ANNOTATION);
DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_WITHIN);
DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_ARGS);
DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_TARGET);
}
private static final Log logger = LogFactory.getLog(AspectJExpressionPointcut.class);
private final Map<Method, ShadowMatch> shadowMatchCache = new ConcurrentHashMap<Method, ShadowMatch>(32);
private PointcutParser pointcutParser;
private Class pointcutDeclarationScope;
private String[] pointcutParameterNames = new String[0];
private Class[] pointcutParameterTypes = new Class[0];
private BeanFactory beanFactory;
private PointcutExpression pointcutExpression;
/**
* Create a new default AspectJExpressionPointcut.
*/
public AspectJExpressionPointcut() {
this(DEFAULT_SUPPORTED_PRIMITIVES);
}
/**
* Create a new AspectJExpressionPointcut with the given supported primitives.
* @param supportedPrimitives Set of {@link org.aspectj.weaver.tools.PointcutPrimitive}
* instances
*/
public AspectJExpressionPointcut(Set supportedPrimitives) {
this.pointcutParser =
PointcutParser.getPointcutParserSupportingSpecifiedPrimitivesAndUsingContextClassloaderForResolution(
supportedPrimitives);
this.pointcutParser.registerPointcutDesignatorHandler(new BeanNamePointcutDesignatorHandler());
}
/**
* Create a new AspectJExpressionPointcut with the given settings.
* @param declarationScope the declaration scope for the pointcut
* @param paramNames the parameter names for the pointcut
* @param paramTypes the parameter types for the pointcut
*/
public AspectJExpressionPointcut(Class declarationScope, String[] paramNames, Class[] paramTypes) {
this(DEFAULT_SUPPORTED_PRIMITIVES);
this.pointcutDeclarationScope = declarationScope;
if (paramNames.length != paramTypes.length) {
throw new IllegalStateException(
"Number of pointcut parameter names must match number of pointcut parameter types");
}
this.pointcutParameterNames = paramNames;
this.pointcutParameterTypes = paramTypes;
}
/**
* Set the declaration scope for the pointcut.
*/
public void setPointcutDeclarationScope(Class pointcutDeclarationScope) {
this.pointcutDeclarationScope = pointcutDeclarationScope;
}
/**
* Set the parameter names for the pointcut.
*/
public void setParameterNames(String[] names) {
this.pointcutParameterNames = names;
}
/**
* Set the parameter types for the pointcut.
*/
public void setParameterTypes(Class[] types) {
this.pointcutParameterTypes = types;
}
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
public ClassFilter getClassFilter() {
checkReadyToMatch();
return this;
}
public MethodMatcher getMethodMatcher() {
checkReadyToMatch();
return this;
}
/**
* Check whether this pointcut is ready to match,
* lazily building the underlying AspectJ pointcut expression.
*/
private void checkReadyToMatch() {
if (getExpression() == null) {
throw new IllegalStateException("Must set property 'expression' before attempting to match");
}
if (this.pointcutExpression == null) {
this.pointcutExpression = buildPointcutExpression();
}
}
/**
* Build the underlying AspectJ pointcut expression.
*/
private PointcutExpression buildPointcutExpression() {
PointcutParameter[] pointcutParameters = new PointcutParameter[this.pointcutParameterNames.length];
for (int i = 0; i < pointcutParameters.length; i++) {
pointcutParameters[i] = this.pointcutParser.createPointcutParameter(
this.pointcutParameterNames[i], this.pointcutParameterTypes[i]);
}
return this.pointcutParser.parsePointcutExpression(
replaceBooleanOperators(getExpression()), this.pointcutDeclarationScope, pointcutParameters);
}
/**
* If a pointcut expression has been specified in XML, the user cannot
* write <code>and</code> as "&&" (though &amp;&amp; will work).
* We also allow <code>and</code> between two pointcut sub-expressions.
* <p>This method converts back to <code>&&</code> for the AspectJ pointcut parser.
*/
private String replaceBooleanOperators(String pcExpr) {
pcExpr = StringUtils.replace(pcExpr," and "," && ");
pcExpr = StringUtils.replace(pcExpr, " or ", " || ");
pcExpr = StringUtils.replace(pcExpr, " not ", " ! ");
return pcExpr;
}
/**
* Return the underlying AspectJ pointcut expression.
*/
public PointcutExpression getPointcutExpression() {
checkReadyToMatch();
return this.pointcutExpression;
}
public boolean matches(Class targetClass) {
checkReadyToMatch();
try {
return this.pointcutExpression.couldMatchJoinPointsInType(targetClass);
}
catch (BCException ex) {
logger.debug("PointcutExpression matching rejected target class", ex);
return false;
}
}
public boolean matches(Method method, Class targetClass, boolean beanHasIntroductions) {
checkReadyToMatch();
Method targetMethod = AopUtils.getMostSpecificMethod(method, targetClass);
ShadowMatch shadowMatch = getShadowMatch(targetMethod, method);
// Special handling for this, target, @this, @target, @annotation
// in Spring - we can optimize since we know we have exactly this class,
// and there will never be matching subclass at runtime.
if (shadowMatch.alwaysMatches()) {
return true;
}
else if (shadowMatch.neverMatches()) {
return false;
}
else {
// the maybe case
return (beanHasIntroductions || matchesIgnoringSubtypes(shadowMatch) || matchesTarget(shadowMatch, targetClass));
}
}
public boolean matches(Method method, Class targetClass) {
return matches(method, targetClass, false);
}
public boolean isRuntime() {
checkReadyToMatch();
return this.pointcutExpression.mayNeedDynamicTest();
}
public boolean matches(Method method, Class targetClass, Object[] args) {
checkReadyToMatch();
ShadowMatch shadowMatch = getShadowMatch(AopUtils.getMostSpecificMethod(method, targetClass), method);
ShadowMatch originalShadowMatch = getShadowMatch(method, method);
// Bind Spring AOP proxy to AspectJ "this" and Spring AOP target to AspectJ target,
// consistent with return of MethodInvocationProceedingJoinPoint
ProxyMethodInvocation pmi = null;
Object targetObject = null;
Object thisObject = null;
try {
MethodInvocation mi = ExposeInvocationInterceptor.currentInvocation();
targetObject = mi.getThis();
if (!(mi instanceof ProxyMethodInvocation)) {
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
}
pmi = (ProxyMethodInvocation) mi;
thisObject = pmi.getProxy();
}
catch (IllegalStateException ex) {
// No current invocation...
// TODO: Should we really proceed here?
logger.debug("Couldn't access current invocation - matching with limited context: " + ex);
}
JoinPointMatch joinPointMatch = shadowMatch.matchesJoinPoint(thisObject, targetObject, args);
/*
* Do a final check to see if any this(TYPE) kind of residue match. For
* this purpose, we use the original method's (proxy method's) shadow to
* ensure that 'this' is correctly checked against. Without this check,
* we get incorrect match on this(TYPE) where TYPE matches the target
* type but not 'this' (as would be the case of JDK dynamic proxies).
* <p>See SPR-2979 for the original bug.
*/
if (pmi != null) { // there is a current invocation
RuntimeTestWalker originalMethodResidueTest = new RuntimeTestWalker(originalShadowMatch);
if (!originalMethodResidueTest.testThisInstanceOfResidue(thisObject.getClass())) {
return false;
}
}
if (joinPointMatch.matches() && pmi != null) {
bindParameters(pmi, joinPointMatch);
}
return joinPointMatch.matches();
}
protected String getCurrentProxiedBeanName() {
return ProxyCreationContext.getCurrentProxiedBeanName();
}
/**
* A match test returned maybe - if there are any subtype sensitive variables
* involved in the test (this, target, at_this, at_target, at_annotation) then
* we say this is not a match as in Spring there will never be a different
* runtime subtype.
*/
private boolean matchesIgnoringSubtypes(ShadowMatch shadowMatch) {
return !(new RuntimeTestWalker(shadowMatch).testsSubtypeSensitiveVars());
}
private boolean matchesTarget(ShadowMatch shadowMatch, Class targetClass) {
return new RuntimeTestWalker(shadowMatch).testTargetInstanceOfResidue(targetClass);
}
private void bindParameters(ProxyMethodInvocation invocation, JoinPointMatch jpm) {
// Note: Can't use JoinPointMatch.getClass().getName() as the key, since
// Spring AOP does all the matching at a join point, and then all the invocations
// under this scenario, if we just use JoinPointMatch as the key, then
// 'last man wins' which is not what we want at all.
// Using the expression is guaranteed to be safe, since 2 identical expressions
// are guaranteed to bind in exactly the same way.
invocation.setUserAttribute(getExpression(), jpm);
}
private ShadowMatch getShadowMatch(Method targetMethod, Method originalMethod) {
// Avoid lock contention for known Methods through concurrent access...
ShadowMatch shadowMatch = this.shadowMatchCache.get(targetMethod);
if (shadowMatch == null) {
synchronized (this.shadowMatchCache) {
// Not found - now check again with full lock...
shadowMatch = this.shadowMatchCache.get(targetMethod);
if (shadowMatch == null) {
try {
shadowMatch = this.pointcutExpression.matchesMethodExecution(targetMethod);
}
catch (ReflectionWorld.ReflectionWorldException ex) {
// Failed to introspect target method, probably because it has been loaded
// in a special ClassLoader. Let's try the original method instead...
if (targetMethod == originalMethod) {
shadowMatch = new ShadowMatchImpl(org.aspectj.util.FuzzyBoolean.NO, null, null, null);
}
else {
try {
shadowMatch = this.pointcutExpression.matchesMethodExecution(originalMethod);
}
catch (ReflectionWorld.ReflectionWorldException ex2) {
// Could neither introspect the target class nor the proxy class ->
// let's simply consider this method as non-matching.
shadowMatch = new ShadowMatchImpl(org.aspectj.util.FuzzyBoolean.NO, null, null, null);
}
}
}
this.shadowMatchCache.put(targetMethod, shadowMatch);
}
}
}
return shadowMatch;
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof AspectJExpressionPointcut)) {
return false;
}
AspectJExpressionPointcut otherPc = (AspectJExpressionPointcut) other;
return ObjectUtils.nullSafeEquals(this.getExpression(), otherPc.getExpression()) &&
ObjectUtils.nullSafeEquals(this.pointcutDeclarationScope, otherPc.pointcutDeclarationScope) &&
ObjectUtils.nullSafeEquals(this.pointcutParameterNames, otherPc.pointcutParameterNames) &&
ObjectUtils.nullSafeEquals(this.pointcutParameterTypes, otherPc.pointcutParameterTypes);
}
@Override
public int hashCode() {
int hashCode = ObjectUtils.nullSafeHashCode(this.getExpression());
hashCode = 31 * hashCode + ObjectUtils.nullSafeHashCode(this.pointcutDeclarationScope);
hashCode = 31 * hashCode + ObjectUtils.nullSafeHashCode(this.pointcutParameterNames);
hashCode = 31 * hashCode + ObjectUtils.nullSafeHashCode(this.pointcutParameterTypes);
return hashCode;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("AspectJExpressionPointcut: ");
if (this.pointcutParameterNames != null && this.pointcutParameterTypes != null) {
sb.append("(");
for (int i = 0; i < this.pointcutParameterTypes.length; i++) {
sb.append(this.pointcutParameterTypes[i].getName());
sb.append(" ");
sb.append(this.pointcutParameterNames[i]);
if ((i+1) < this.pointcutParameterTypes.length) {
sb.append(", ");
}
}
sb.append(")");
}
sb.append(" ");
if (getExpression() != null) {
sb.append(getExpression());
}
else {
sb.append("<pointcut expression not set>");
}
return sb.toString();
}
/**
* Handler for the Spring-specific <code>bean()</code> pointcut designator
* extension to AspectJ.
* <p>This handler must be added to each pointcut object that needs to
* handle the <code>bean()</code> PCD. Matching context is obtained
* automatically by examining a thread local variable and therefore a matching
* context need not be set on the pointcut.
*/
private class BeanNamePointcutDesignatorHandler implements PointcutDesignatorHandler {
private static final String BEAN_DESIGNATOR_NAME = "bean";
public String getDesignatorName() {
return BEAN_DESIGNATOR_NAME;
}
public ContextBasedMatcher parse(String expression) {
return new BeanNameContextMatcher(expression);
}
}
/**
* Matcher class for the BeanNamePointcutDesignatorHandler.
*
* <p>Dynamic match tests for this matcher always return true,
* since the matching decision is made at the proxy creation time.
* For static match tests, this matcher abstains to allow the overall
* pointcut to match even when negation is used with the bean() poitncut.
*/
private class BeanNameContextMatcher implements ContextBasedMatcher {
private final NamePattern expressionPattern;
public BeanNameContextMatcher(String expression) {
this.expressionPattern = new NamePattern(expression);
}
public boolean couldMatchJoinPointsInType(Class someClass) {
return (contextMatch(someClass) == FuzzyBoolean.YES);
}
public boolean couldMatchJoinPointsInType(Class someClass, MatchingContext context) {
return (contextMatch(someClass) == FuzzyBoolean.YES);
}
public boolean matchesDynamically(MatchingContext context) {
return true;
}
public FuzzyBoolean matchesStatically(MatchingContext context) {
return contextMatch(null);
}
public boolean mayNeedDynamicTest() {
return false;
}
private FuzzyBoolean contextMatch(Class targetType) {
String advisedBeanName = getCurrentProxiedBeanName();
if (advisedBeanName == null) { // no proxy creation in progress
// abstain; can't return YES, since that will make pointcut with negation fail
return FuzzyBoolean.MAYBE;
}
if (BeanFactoryUtils.isGeneratedBeanName(advisedBeanName)) {
return FuzzyBoolean.NO;
}
if (targetType != null) {
boolean isFactory = FactoryBean.class.isAssignableFrom(targetType);
return FuzzyBoolean.fromBoolean(
matchesBeanName(isFactory ? BeanFactory.FACTORY_BEAN_PREFIX + advisedBeanName : advisedBeanName));
}
else {
return FuzzyBoolean.fromBoolean(matchesBeanName(advisedBeanName) ||
matchesBeanName(BeanFactory.FACTORY_BEAN_PREFIX + advisedBeanName));
}
}
private boolean matchesBeanName(String advisedBeanName) {
if (this.expressionPattern.matches(advisedBeanName)) {
return true;
}
if (beanFactory != null) {
String[] aliases = beanFactory.getAliases(advisedBeanName);
for (String alias : aliases) {
if (this.expressionPattern.matches(alias)) {
return true;
}
}
}
return false;
}
}
}
@@ -0,0 +1,61 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.AbstractGenericPointcutAdvisor;
/**
* Spring AOP Advisor that can be used for any AspectJ pointcut expression.
*
* @author Rob Harrop
* @since 2.0
*/
public class AspectJExpressionPointcutAdvisor extends AbstractGenericPointcutAdvisor {
private final AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
public Pointcut getPointcut() {
return this.pointcut;
}
public void setExpression(String expression) {
this.pointcut.setExpression(expression);
}
public void setLocation(String location) {
this.pointcut.setLocation(location);
}
public void setParameterTypes(Class[] types) {
this.pointcut.setParameterTypes(types);
}
public void setParameterNames(String[] names) {
this.pointcut.setParameterNames(names);
}
public String getLocation() {
return this.pointcut.getLocation();
}
public String getExpression() {
return this.pointcut.getExpression();
}
}
@@ -0,0 +1,50 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
/**
* Spring AOP advice that wraps an AspectJ before method.
*
* @author Rod Johnson
* @author Adrian Colyer
* @since 2.0
*/
public class AspectJMethodBeforeAdvice extends AbstractAspectJAdvice implements MethodBeforeAdvice {
public AspectJMethodBeforeAdvice(
Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
super(aspectJBeforeAdviceMethod, pointcut, aif);
}
public void before(Method method, Object[] args, Object target) throws Throwable {
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
public boolean isBeforeAdvice() {
return true;
}
public boolean isAfterAdvice() {
return false;
}
}
@@ -0,0 +1,98 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj;
import org.aopalliance.aop.Advice;
import org.springframework.aop.Pointcut;
import org.springframework.aop.PointcutAdvisor;
import org.springframework.core.Ordered;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* AspectJPointcutAdvisor that adapts an {@link AbstractAspectJAdvice}
* to the {@link org.springframework.aop.PointcutAdvisor} interface.
*
* @author Adrian Colyer
* @author Juergen Hoeller
* @since 2.0
*/
public class AspectJPointcutAdvisor implements PointcutAdvisor, Ordered {
private final AbstractAspectJAdvice advice;
private final Pointcut pointcut;
private Integer order;
/**
* Create a new AspectJPointcutAdvisor for the given advice
* @param advice the AbstractAspectJAdvice to wrap
*/
public AspectJPointcutAdvisor(AbstractAspectJAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
this.pointcut = advice.buildSafePointcut();
}
public void setOrder(int order) {
this.order = order;
}
public boolean isPerInstance() {
return true;
}
public Advice getAdvice() {
return this.advice;
}
public Pointcut getPointcut() {
return this.pointcut;
}
public int getOrder() {
if (this.order != null) {
return this.order;
}
else {
return this.advice.getOrder();
}
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof AspectJPointcutAdvisor)) {
return false;
}
AspectJPointcutAdvisor otherAdvisor = (AspectJPointcutAdvisor) other;
return (ObjectUtils.nullSafeEquals(this.advice, otherAdvisor.advice));
}
@Override
public int hashCode() {
return AspectJPointcutAdvisor.class.hashCode();
}
}
@@ -0,0 +1,58 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj;
import org.springframework.core.Ordered;
/**
* Interface to be implemented by types that can supply the information
* needed to sort advice/advisors by AspectJ's precedence rules.
*
* @author Adrian Colyer
* @since 2.0
* @see org.springframework.aop.aspectj.autoproxy.AspectJPrecedenceComparator
*/
public interface AspectJPrecedenceInformation extends Ordered {
// Implementation note:
// We need the level of indirection this interface provides as otherwise the
// AspectJPrecedenceComparator must ask an Advisor for its Advice in all cases
// in order to sort advisors. This causes problems with the
// InstantiationModelAwarePointcutAdvisor which needs to delay creating
// its advice for aspects with non-singleton instantiation models.
/**
* The name of the aspect (bean) in which the advice was declared.
*/
String getAspectName();
/**
* The declaration order of the advice member within the aspect.
*/
int getDeclarationOrder();
/**
* Return whether this is a before advice.
*/
boolean isBeforeAdvice();
/**
* Return whether this is an after advice.
*/
boolean isAfterAdvice();
}
@@ -0,0 +1,72 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj;
import java.util.List;
import org.springframework.aop.Advisor;
import org.springframework.aop.PointcutAdvisor;
import org.springframework.aop.interceptor.ExposeInvocationInterceptor;
/**
* Utility methods for working with AspectJ proxies.
*
* @author Rod Johnson
* @author Ramnivas Laddad
* @since 2.0
*/
public abstract class AspectJProxyUtils {
/**
* Add special advisors if necessary to work with a proxy chain that contains AspectJ advisors.
* This will expose the current Spring AOP invocation (necessary for some AspectJ pointcut matching)
* and make available the current AspectJ JoinPoint. The call will have no effect if there are no
* AspectJ advisors in the advisor chain.
* @param advisors Advisors available
* @return <code>true</code> if any special {@link Advisor Advisors} were added, otherwise <code>false</code>.
*/
public static boolean makeAdvisorChainAspectJCapableIfNecessary(List<Advisor> advisors) {
// Don't add advisors to an empty list; may indicate that proxying is just not required
if (!advisors.isEmpty()) {
boolean foundAspectJAdvice = false;
for (Advisor advisor : advisors) {
// Be careful not to get the Advice without a guard, as
// this might eagerly instantiate a non-singleton AspectJ aspect
if (isAspectJAdvice(advisor)) {
foundAspectJAdvice = true;
}
}
if (foundAspectJAdvice && !advisors.contains(ExposeInvocationInterceptor.ADVISOR)) {
advisors.add(0, ExposeInvocationInterceptor.ADVISOR);
return true;
}
}
return false;
}
/**
* Determine whether the given Advisor contains an AspectJ advice.
* @param advisor the Advisor to check
*/
private static boolean isAspectJAdvice(Advisor advisor) {
return (advisor instanceof InstantiationModelAwarePointcutAdvisor ||
advisor.getAdvice() instanceof AbstractAspectJAdvice ||
(advisor instanceof PointcutAdvisor &&
((PointcutAdvisor) advisor).getPointcut() instanceof AspectJExpressionPointcut));
}
}
@@ -0,0 +1,109 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.bridge.AbortException;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.IMessage.Kind;
import org.aspectj.bridge.IMessageHandler;
/**
* Implementation of AspectJ's {@link IMessageHandler} interface that
* routes AspectJ weaving messages through the same logging system as the
* regular Spring messages.
*
* <p>Pass the option...
*
* <p><code class="code">-XmessageHandlerClass:org.springframework.aop.aspectj.AspectJWeaverMessageHandler</code>
*
* <p>to the weaver; for example, specifying the following in a
* "<code>META-INF/aop.xml</code> file:
*
* <p><code class="code">&lt;weaver options="..."/&gt;</code>
*
* @author Adrian Colyer
* @author Juergen Hoeller
* @since 2.0
*/
public class AspectJWeaverMessageHandler implements IMessageHandler {
private static final String AJ_ID = "[AspectJ] ";
private static final Log LOGGER = LogFactory.getLog("AspectJ Weaver");
public boolean handleMessage(IMessage message) throws AbortException {
Kind messageKind = message.getKind();
if (LOGGER.isDebugEnabled() || LOGGER.isTraceEnabled()) {
if (messageKind == IMessage.DEBUG) {
LOGGER.debug(makeMessageFor(message));
return true;
}
}
if (LOGGER.isInfoEnabled()) {
if ((messageKind == IMessage.INFO) || (messageKind == IMessage.WEAVEINFO)) {
LOGGER.info(makeMessageFor(message));
return true;
}
}
if (LOGGER.isWarnEnabled()) {
if (messageKind == IMessage.WARNING) {
LOGGER.warn(makeMessageFor(message));
return true;
}
}
if (LOGGER.isErrorEnabled()) {
if (messageKind == IMessage.ERROR) {
LOGGER.error(makeMessageFor(message));
return true;
}
}
if (LOGGER.isFatalEnabled()) {
if (messageKind == IMessage.ABORT) {
LOGGER.fatal(makeMessageFor(message));
return true;
}
}
return false;
}
private String makeMessageFor(IMessage aMessage) {
return AJ_ID + aMessage.getMessage();
}
public boolean isIgnoring(Kind messageKind) {
// We want to see everything, and allow configuration of log levels dynamically.
return false;
}
public void dontIgnore(Kind messageKind) {
// We weren't ignoring anything anyway...
}
public void ignore(Kind kind) {
// We weren't ignoring anything anyway...
}
}
@@ -0,0 +1,110 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj;
import org.aopalliance.aop.Advice;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.IntroductionAdvisor;
import org.springframework.aop.support.ClassFilters;
import org.springframework.aop.support.DelegatePerTargetObjectIntroductionInterceptor;
import org.springframework.aop.support.DelegatingIntroductionInterceptor;
/**
* Introduction advisor delegating to the given object.
* Implements AspectJ annotation-style behavior for the DeclareParents annotation.
*
* @author Rod Johnson
* @author Ramnivas Laddad
* @since 2.0
*/
public class DeclareParentsAdvisor implements IntroductionAdvisor {
private final Class introducedInterface;
private final ClassFilter typePatternClassFilter;
private final Advice advice;
/**
* Create a new advisor for this DeclareParents field.
* @param interfaceType static field defining the introduction
* @param typePattern type pattern the introduction is restricted to
* @param defaultImpl the default implementation class
*/
public DeclareParentsAdvisor(Class interfaceType, String typePattern, Class defaultImpl) {
this(interfaceType, typePattern, defaultImpl,
new DelegatePerTargetObjectIntroductionInterceptor(defaultImpl, interfaceType));
}
/**
* Create a new advisor for this DeclareParents field.
* @param interfaceType static field defining the introduction
* @param typePattern type pattern the introduction is restricted to
* @param delegateRef the delegate implementation object
*/
public DeclareParentsAdvisor(Class interfaceType, String typePattern, Object delegateRef) {
this(interfaceType, typePattern, delegateRef.getClass(),
new DelegatingIntroductionInterceptor(delegateRef));
}
/**
* Private constructor to share common code between impl-based delegate and reference-based delegate
* (cannot use method such as init() to share common code, due the the use of final fields)
* @param interfaceType static field defining the introduction
* @param typePattern type pattern the introduction is restricted to
* @param implementationClass implementation class
* @param advice delegation advice
*/
private DeclareParentsAdvisor(Class interfaceType, String typePattern, Class implementationClass, Advice advice) {
this.introducedInterface = interfaceType;
ClassFilter typePatternFilter = new TypePatternClassFilter(typePattern);
// Excludes methods implemented.
ClassFilter exclusion = new ClassFilter() {
public boolean matches(Class clazz) {
return !(introducedInterface.isAssignableFrom(clazz));
}
};
this.typePatternClassFilter = ClassFilters.intersection(typePatternFilter, exclusion);
this.advice = advice;
}
public ClassFilter getClassFilter() {
return this.typePatternClassFilter;
}
public void validateInterfaces() throws IllegalArgumentException {
// Do nothing
}
public boolean isPerInstance() {
return true;
}
public Advice getAdvice() {
return this.advice;
}
public Class[] getInterfaces() {
return new Class[] {this.introducedInterface};
}
}
@@ -0,0 +1,42 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj;
import org.springframework.aop.PointcutAdvisor;
/**
* Interface to be implemented by Spring AOP Advisors wrapping AspectJ
* aspects that may have a lazy initialization strategy. For example,
* a perThis instantiation model would mean lazy initialization of the advice.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 2.0
*/
public interface InstantiationModelAwarePointcutAdvisor extends PointcutAdvisor {
/**
* Return whether this advisor is lazily initializing its underlying advice.
*/
boolean isLazy();
/**
* Return whether this advisor has already instantiated its advice.
*/
boolean isAdviceInstantiated();
}
@@ -0,0 +1,285 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;
import org.aspectj.lang.reflect.SourceLocation;
import org.aspectj.runtime.internal.AroundClosure;
import org.springframework.aop.ProxyMethodInvocation;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.util.Assert;
/**
* Implementation of AspectJ ProceedingJoinPoint interface
* wrapping an AOP Alliance MethodInvocation.
*
* <p><b>Note</b>: the <code>getThis()</code> method returns the current Spring AOP proxy.
* The <code>getTarget()</code> method returns the current Spring AOP target (which may be
* <code>null</code> if there is no target), and is a plain POJO without any advice.
* <b>If you want to call the object and have the advice take effect, use
* <code>getThis()</code>.</b> A common example is casting the object to an
* introduced interface in the implementation of an introduction.
*
* <p>Of course there is no such distinction between target and proxy in AspectJ.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Adrian Colyer
* @author Ramnivas Laddad
* @since 2.0
*/
public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint, JoinPoint.StaticPart {
private final ProxyMethodInvocation methodInvocation;
private Object[] defensiveCopyOfArgs;
/** Lazily initialized signature object */
private Signature signature;
/** Lazily initialized source location object */
private SourceLocation sourceLocation;
/**
* Create a new MethodInvocationProceedingJoinPoint, wrapping the given
* Spring ProxyMethodInvocation object.
* @param methodInvocation the Spring ProxyMethodInvocation object
*/
public MethodInvocationProceedingJoinPoint(ProxyMethodInvocation methodInvocation) {
Assert.notNull(methodInvocation, "MethodInvocation must not be null");
this.methodInvocation = methodInvocation;
}
public void set$AroundClosure(AroundClosure aroundClosure) {
throw new UnsupportedOperationException();
}
public Object proceed() throws Throwable {
return this.methodInvocation.invocableClone().proceed();
}
public Object proceed(Object[] arguments) throws Throwable {
Assert.notNull(arguments, "Argument array passed to proceed cannot be null");
if (arguments.length != this.methodInvocation.getArguments().length) {
throw new IllegalArgumentException("Expecting " +
this.methodInvocation.getArguments().length + " arguments to proceed, " +
"but was passed " + arguments.length + " arguments");
}
this.methodInvocation.setArguments(arguments);
return this.methodInvocation.invocableClone(arguments).proceed();
}
/**
* Returns the Spring AOP proxy. Cannot be <code>null</code>.
*/
public Object getThis() {
return this.methodInvocation.getProxy();
}
/**
* Returns the Spring AOP target. May be <code>null</code> if there is no target.
*/
public Object getTarget() {
return this.methodInvocation.getThis();
}
public Object[] getArgs() {
if (this.defensiveCopyOfArgs == null) {
Object[] argsSource = this.methodInvocation.getArguments();
this.defensiveCopyOfArgs = new Object[argsSource.length];
System.arraycopy(argsSource, 0, this.defensiveCopyOfArgs, 0, argsSource.length);
}
return this.defensiveCopyOfArgs;
}
public Signature getSignature() {
if (this.signature == null) {
this.signature = new MethodSignatureImpl();
}
return signature;
}
public SourceLocation getSourceLocation() {
if (this.sourceLocation == null) {
this.sourceLocation = new SourceLocationImpl();
}
return this.sourceLocation;
}
public String getKind() {
return ProceedingJoinPoint.METHOD_EXECUTION;
}
public JoinPoint.StaticPart getStaticPart() {
return this;
}
public String toShortString() {
return "execution(" + getSignature().toShortString() + ")";
}
public String toLongString() {
return "execution(" + getSignature().toLongString() + ")";
}
public String toString() {
return "execution(" + getSignature().toString() + ")";
}
/**
* Lazily initialized MethodSignature.
*/
private class MethodSignatureImpl implements MethodSignature {
private volatile String[] parameterNames;
public String getName() {
return methodInvocation.getMethod().getName();
}
public int getModifiers() {
return methodInvocation.getMethod().getModifiers();
}
public Class getDeclaringType() {
return methodInvocation.getMethod().getDeclaringClass();
}
public String getDeclaringTypeName() {
return methodInvocation.getMethod().getDeclaringClass().getName();
}
public Class getReturnType() {
return methodInvocation.getMethod().getReturnType();
}
public Method getMethod() {
return methodInvocation.getMethod();
}
public Class[] getParameterTypes() {
return methodInvocation.getMethod().getParameterTypes();
}
public String[] getParameterNames() {
if (this.parameterNames == null) {
this.parameterNames = (new LocalVariableTableParameterNameDiscoverer()).getParameterNames(getMethod());
}
return this.parameterNames;
}
public Class[] getExceptionTypes() {
return methodInvocation.getMethod().getExceptionTypes();
}
public String toShortString() {
return toString(false, false, false, false);
}
public String toLongString() {
return toString(true, true, true, true);
}
public String toString() {
return toString(false, true, false, true);
}
private String toString(boolean includeModifier, boolean includeReturnTypeAndArgs,
boolean useLongReturnAndArgumentTypeName, boolean useLongTypeName) {
StringBuilder sb = new StringBuilder();
if (includeModifier) {
sb.append(Modifier.toString(getModifiers()));
sb.append(" ");
}
if (includeReturnTypeAndArgs) {
appendType(sb, getReturnType(), useLongReturnAndArgumentTypeName);
sb.append(" ");
}
appendType(sb, getDeclaringType(), useLongTypeName);
sb.append(".");
sb.append(getMethod().getName());
sb.append("(");
Class[] parametersTypes = getParameterTypes();
appendTypes(sb, parametersTypes, includeReturnTypeAndArgs, useLongReturnAndArgumentTypeName);
sb.append(")");
return sb.toString();
}
private void appendTypes(StringBuilder sb, Class<?>[] types,
boolean includeArgs, boolean useLongReturnAndArgumentTypeName) {
if (includeArgs) {
for (int size = types.length, i = 0; i < size; i++) {
appendType(sb, types[i], useLongReturnAndArgumentTypeName);
if (i < size - 1) {
sb.append(",");
}
}
}
else {
if (types.length != 0) {
sb.append("..");
}
}
}
private void appendType(StringBuilder sb, Class<?> type, boolean useLongTypeName) {
if (type.isArray()) {
appendType(sb, type.getComponentType(), useLongTypeName);
sb.append("[]");
}
else {
sb.append(useLongTypeName ? type.getName() : type.getSimpleName());
}
}
}
/**
* Lazily initialized SourceLocation.
*/
private class SourceLocationImpl implements SourceLocation {
public Class getWithinType() {
if (methodInvocation.getThis() == null) {
throw new UnsupportedOperationException("No source location joinpoint available: target is null");
}
return methodInvocation.getThis().getClass();
}
public String getFileName() {
throw new UnsupportedOperationException();
}
public int getLine() {
throw new UnsupportedOperationException();
}
public int getColumn() {
throw new UnsupportedOperationException();
}
}
}
@@ -0,0 +1,258 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj;
import java.lang.reflect.Field;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.ast.And;
import org.aspectj.weaver.ast.Call;
import org.aspectj.weaver.ast.FieldGetCall;
import org.aspectj.weaver.ast.HasAnnotation;
import org.aspectj.weaver.ast.ITestVisitor;
import org.aspectj.weaver.ast.Instanceof;
import org.aspectj.weaver.ast.Literal;
import org.aspectj.weaver.ast.Not;
import org.aspectj.weaver.ast.Or;
import org.aspectj.weaver.ast.Test;
import org.aspectj.weaver.internal.tools.MatchingContextBasedTest;
import org.aspectj.weaver.reflect.ReflectionVar;
import org.aspectj.weaver.reflect.ShadowMatchImpl;
import org.aspectj.weaver.tools.ShadowMatch;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
/**
* This class encapsulates some AspectJ internal knowledge that should be
* pushed back into the AspectJ project in a future release.
*
* <p>It relies on implementation specific knowledge in AspectJ to break
* encapsulation and do something AspectJ was not designed to do: query
* the types of runtime tests that will be performed. The code here should
* migrate to <code>ShadowMatch.getVariablesInvolvedInRuntimeTest()</code>
* or some similar operation.
*
* <p>See <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=151593"/>.
*
* @author Adrian Colyer
* @author Ramnivas Laddad
* @since 2.0
*/
class RuntimeTestWalker {
private final Test runtimeTest;
public RuntimeTestWalker(ShadowMatch shadowMatch) {
ShadowMatchImpl shadowMatchImplementation = (ShadowMatchImpl) shadowMatch;
try {
Field testField = shadowMatchImplementation.getClass().getDeclaredField("residualTest");
ReflectionUtils.makeAccessible(testField);
this.runtimeTest = (Test) testField.get(shadowMatch);
}
catch (NoSuchFieldException noSuchFieldEx) {
throw new IllegalStateException("The version of aspectjtools.jar / aspectjweaver.jar " +
"on the classpath is incompatible with this version of Spring: Expected field " +
"'runtimeTest' is not present on ShadowMatchImpl class.");
}
catch (IllegalAccessException illegalAccessEx) {
// Famous last words... but I don't see how this can happen given the
// makeAccessible call above
throw new IllegalStateException("Unable to access ShadowMatchImpl.runtimeTest field.");
}
}
/**
* If the test uses any of the this, target, at_this, at_target, and at_annotation vars,
* then it tests subtype sensitive vars.
*/
public boolean testsSubtypeSensitiveVars() {
return new SubtypeSensitiveVarTypeTestVisitor().testsSubtypeSensitiveVars(this.runtimeTest);
}
public boolean testThisInstanceOfResidue(Class thisClass) {
return new ThisInstanceOfResidueTestVisitor(thisClass).thisInstanceOfMatches(this.runtimeTest);
}
public boolean testTargetInstanceOfResidue(Class targetClass) {
return new TargetInstanceOfResidueTestVisitor(targetClass).targetInstanceOfMatches(this.runtimeTest);
}
private static class TestVisitorAdapter implements ITestVisitor {
protected static final int THIS_VAR = 0;
protected static final int TARGET_VAR = 1;
protected static final int AT_THIS_VAR = 3;
protected static final int AT_TARGET_VAR = 4;
protected static final int AT_ANNOTATION_VAR = 8;
public void visit(And e) {
e.getLeft().accept(this);
e.getRight().accept(this);
}
public void visit(Or e) {
e.getLeft().accept(this);
e.getRight().accept(this);
}
public void visit(Not e) {
e.getBody().accept(this);
}
public void visit(Instanceof i) {
}
public void visit(Literal literal) {
}
public void visit(Call call) {
}
public void visit(FieldGetCall fieldGetCall) {
}
public void visit(HasAnnotation hasAnnotation) {
}
public void visit(MatchingContextBasedTest matchingContextTest) {
}
protected int getVarType(ReflectionVar v) {
try {
Field varTypeField = ReflectionVar.class.getDeclaredField("varType");
ReflectionUtils.makeAccessible(varTypeField);
Integer varTypeValue = (Integer) varTypeField.get(v);
return varTypeValue.intValue();
}
catch (NoSuchFieldException noSuchFieldEx) {
throw new IllegalStateException("the version of aspectjtools.jar / aspectjweaver.jar " +
"on the classpath is incompatible with this version of Spring:- expected field " +
"'varType' is not present on ReflectionVar class");
}
catch (IllegalAccessException illegalAccessEx) {
// Famous last words... but I don't see how this can happen given the
// makeAccessible call above
throw new IllegalStateException("Unable to access ReflectionVar.varType field.");
}
}
}
private static abstract class InstanceOfResidueTestVisitor extends TestVisitorAdapter {
private Class matchClass;
private boolean matches;
private int matchVarType;
public InstanceOfResidueTestVisitor(Class matchClass, boolean defaultMatches, int matchVarType) {
this.matchClass = matchClass;
this.matches = defaultMatches;
this.matchVarType = matchVarType;
}
public boolean instanceOfMatches(Test test) {
test.accept(this);
return matches;
}
@Override
public void visit(Instanceof i) {
ResolvedType type = (ResolvedType) i.getType();
int varType = getVarType((ReflectionVar) i.getVar());
if (varType != this.matchVarType) {
return;
}
try {
Class typeClass = ClassUtils.forName(type.getName(), this.matchClass.getClassLoader());
// Don't use ReflectionType.isAssignableFrom() as it won't be aware of (Spring) mixins
this.matches = typeClass.isAssignableFrom(this.matchClass);
}
catch (ClassNotFoundException ex) {
this.matches = false;
}
}
}
/**
* Check if residue of target(TYPE) kind. See SPR-3783 for more details.
*/
private static class TargetInstanceOfResidueTestVisitor extends InstanceOfResidueTestVisitor {
public TargetInstanceOfResidueTestVisitor(Class targetClass) {
super(targetClass, false, TARGET_VAR);
}
public boolean targetInstanceOfMatches(Test test) {
return instanceOfMatches(test);
}
}
/**
* Check if residue of this(TYPE) kind. See SPR-2979 for more details.
*/
private static class ThisInstanceOfResidueTestVisitor extends InstanceOfResidueTestVisitor {
public ThisInstanceOfResidueTestVisitor(Class thisClass) {
super(thisClass, true, THIS_VAR);
}
// TODO: Optimization: Process only if this() specifies a type and not an identifier.
public boolean thisInstanceOfMatches(Test test) {
return instanceOfMatches(test);
}
}
private static class SubtypeSensitiveVarTypeTestVisitor extends TestVisitorAdapter {
private final Object thisObj = new Object();
private final Object targetObj = new Object();
private final Object[] argsObjs = new Object[0];
private boolean testsSubtypeSensitiveVars = false;
public boolean testsSubtypeSensitiveVars(Test aTest) {
aTest.accept(this);
return this.testsSubtypeSensitiveVars;
}
@Override
public void visit(Instanceof i) {
ReflectionVar v = (ReflectionVar) i.getVar();
Object varUnderTest = v.getBindingAtJoinPoint(thisObj,targetObj,argsObjs);
if ((varUnderTest == thisObj) || (varUnderTest == targetObj)) {
this.testsSubtypeSensitiveVars = true;
}
}
@Override
public void visit(HasAnnotation hasAnn) {
// If you thought things were bad before, now we sink to new levels of horror...
ReflectionVar v = (ReflectionVar) hasAnn.getVar();
int varType = getVarType(v);
if ((varType == AT_THIS_VAR) || (varType == AT_TARGET_VAR) || (varType == AT_ANNOTATION_VAR)) {
this.testsSubtypeSensitiveVars = true;
}
}
}
}
@@ -0,0 +1,91 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj;
import org.springframework.aop.framework.AopConfigException;
import org.springframework.core.Ordered;
import org.springframework.util.Assert;
/**
* Implementation of {@link AspectInstanceFactory} that creates a new instance
* of the specified aspect class for every {@link #getAspectInstance()} call.
*
* @author Juergen Hoeller
* @since 2.0.4
*/
public class SimpleAspectInstanceFactory implements AspectInstanceFactory {
private final Class aspectClass;
/**
* Create a new SimpleAspectInstanceFactory for the given aspect class.
* @param aspectClass the aspect class
*/
public SimpleAspectInstanceFactory(Class aspectClass) {
Assert.notNull(aspectClass, "Aspect class must not be null");
this.aspectClass = aspectClass;
}
/**
* Return the specified aspect class (never <code>null</code>).
*/
public final Class getAspectClass() {
return this.aspectClass;
}
public final Object getAspectInstance() {
try {
return this.aspectClass.newInstance();
}
catch (InstantiationException ex) {
throw new AopConfigException("Unable to instantiate aspect class [" + this.aspectClass.getName() + "]", ex);
}
catch (IllegalAccessException ex) {
throw new AopConfigException("Cannot access element class [" + this.aspectClass.getName() + "]", ex);
}
}
public ClassLoader getAspectClassLoader() {
return this.aspectClass.getClassLoader();
}
/**
* Determine the order for this factory's aspect instance,
* either an instance-specific order expressed through implementing
* the {@link org.springframework.core.Ordered} interface,
* or a fallback order.
* @see org.springframework.core.Ordered
* @see #getOrderForAspectClass
*/
public int getOrder() {
return getOrderForAspectClass(this.aspectClass);
}
/**
* Determine a fallback order for the case that the aspect instance
* does not express an instance-specific order through implementing
* the {@link org.springframework.core.Ordered} interface.
* <p>The default implementation simply returns <code>Ordered.LOWEST_PRECEDENCE</code>.
* @param aspectClass the aspect class
*/
protected int getOrderForAspectClass(Class<?> aspectClass) {
return Ordered.LOWEST_PRECEDENCE;
}
}
@@ -0,0 +1,81 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj;
import org.springframework.core.Ordered;
import org.springframework.util.Assert;
/**
* Implementation of {@link AspectInstanceFactory} that is backed by a
* specified singleton object, returning the same instance for every
* {@link #getAspectInstance()} call.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 2.0
* @see SimpleAspectInstanceFactory
*/
public class SingletonAspectInstanceFactory implements AspectInstanceFactory {
private final Object aspectInstance;
/**
* Create a new SingletonAspectInstanceFactory for the given aspect instance.
* @param aspectInstance the singleton aspect instance
*/
public SingletonAspectInstanceFactory(Object aspectInstance) {
Assert.notNull(aspectInstance, "Aspect instance must not be null");
this.aspectInstance = aspectInstance;
}
public final Object getAspectInstance() {
return this.aspectInstance;
}
public ClassLoader getAspectClassLoader() {
return this.aspectInstance.getClass().getClassLoader();
}
/**
* Determine the order for this factory's aspect instance,
* either an instance-specific order expressed through implementing
* the {@link org.springframework.core.Ordered} interface,
* or a fallback order.
* @see org.springframework.core.Ordered
* @see #getOrderForAspectClass
*/
public int getOrder() {
if (this.aspectInstance instanceof Ordered) {
return ((Ordered) this.aspectInstance).getOrder();
}
return getOrderForAspectClass(this.aspectInstance.getClass());
}
/**
* Determine a fallback order for the case that the aspect instance
* does not express an instance-specific order through implementing
* the {@link org.springframework.core.Ordered} interface.
* <p>The default implementation simply returns <code>Ordered.LOWEST_PRECEDENCE</code>.
* @param aspectClass the aspect class
*/
protected int getOrderForAspectClass(Class<?> aspectClass) {
return Ordered.LOWEST_PRECEDENCE;
}
}
@@ -0,0 +1,115 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj;
import org.aspectj.weaver.tools.PointcutParser;
import org.aspectj.weaver.tools.TypePatternMatcher;
import org.springframework.aop.ClassFilter;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Spring AOP {@link ClassFilter} implementation using AspectJ type matching.
*
* @author Rod Johnson
* @since 2.0
*/
public class TypePatternClassFilter implements ClassFilter {
private String typePattern;
private TypePatternMatcher aspectJTypePatternMatcher;
/**
* Creates a new instance of the {@link TypePatternClassFilter} class.
* <p>This is the JavaBean constructor; be sure to set the
* {@link #setTypePattern(String) typePattern} property, else a
* no doubt fatal {@link IllegalStateException} will be thrown
* when the {@link #matches(Class)} method is first invoked.
*/
public TypePatternClassFilter() {
}
/**
* Create a fully configured {@link TypePatternClassFilter} using the
* given type pattern.
* @param typePattern the type pattern that AspectJ weaver should parse
* @throws IllegalArgumentException if the supplied <code>typePattern</code> is <code>null</code>
* or is recognized as invalid
*/
public TypePatternClassFilter(String typePattern) {
setTypePattern(typePattern);
}
/**
* Set the AspectJ type pattern to match.
* <p>Examples include:
* <code class="code">
* org.springframework.beans.*
* </code>
* This will match any class or interface in the given package.
* <code class="code">
* org.springframework.beans.ITestBean+
* </code>
* This will match the <code>ITestBean</code> interface and any class
* that implements it.
* <p>These conventions are established by AspectJ, not Spring AOP.
* @param typePattern the type pattern that AspectJ weaver should parse
* @throws IllegalArgumentException if the supplied <code>typePattern</code> is <code>null</code>
* or is recognized as invalid
*/
public void setTypePattern(String typePattern) {
Assert.notNull(typePattern);
this.typePattern = typePattern;
this.aspectJTypePatternMatcher =
PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution().
parseTypePattern(replaceBooleanOperators(typePattern));
}
public String getTypePattern() {
return typePattern;
}
/**
* Should the pointcut apply to the given interface or target class?
* @param clazz candidate target class
* @return whether the advice should apply to this candidate target class
* @throws IllegalStateException if no {@link #setTypePattern(String)} has been set
*/
public boolean matches(Class clazz) {
if (this.aspectJTypePatternMatcher == null) {
throw new IllegalStateException("No 'typePattern' has been set via ctor/setter.");
}
return this.aspectJTypePatternMatcher.matches(clazz);
}
/**
* If a type pattern has been specified in XML, the user cannot
* write <code>and</code> as "&&" (though &amp;&amp; will work).
* We also allow <code>and</code> between two sub-expressions.
* <p>This method converts back to <code>&&</code> for the AspectJ pointcut parser.
*/
private String replaceBooleanOperators(String pcExpr) {
pcExpr = StringUtils.replace(pcExpr," and "," && ");
pcExpr = StringUtils.replace(pcExpr, " or ", " || ");
pcExpr = StringUtils.replace(pcExpr, " not ", " ! ");
return pcExpr;
}
}
@@ -0,0 +1,335 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj.annotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.AjType;
import org.aspectj.lang.reflect.AjTypeSystem;
import org.aspectj.lang.reflect.PerClauseKind;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.framework.AopConfigException;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.PrioritizedParameterNameDiscoverer;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.StringUtils;
/**
* Abstract base class for factories that can create Spring AOP Advisors
* given AspectJ classes from classes honoring the AspectJ 5 annotation syntax.
*
* <p>This class handles annotation parsing and validation functionality.
* It does not actually generate Spring AOP Advisors, which is deferred to subclasses.
*
* @author Rod Johnson
* @author Adrian Colyer
* @author Juergen Hoeller
* @since 2.0
*/
public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFactory {
protected static final ParameterNameDiscoverer ASPECTJ_ANNOTATION_PARAMETER_NAME_DISCOVERER =
new AspectJAnnotationParameterNameDiscoverer();
private static final String AJC_MAGIC = "ajc$";
/**
* Find and return the first AspectJ annotation on the given method
* (there <i>should</i> only be one anyway...)
*/
@SuppressWarnings("unchecked")
protected static AspectJAnnotation findAspectJAnnotationOnMethod(Method method) {
Class<? extends Annotation>[] classesToLookFor = new Class[] {
Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class};
for (Class<? extends Annotation> c : classesToLookFor) {
AspectJAnnotation foundAnnotation = findAnnotation(method, c);
if (foundAnnotation != null) {
return foundAnnotation;
}
}
return null;
}
private static <A extends Annotation> AspectJAnnotation<A> findAnnotation(Method method, Class<A> toLookFor) {
A result = AnnotationUtils.findAnnotation(method, toLookFor);
if (result != null) {
return new AspectJAnnotation<A>(result);
}
else {
return null;
}
}
/** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass());
protected final ParameterNameDiscoverer parameterNameDiscoverer;
protected AbstractAspectJAdvisorFactory() {
PrioritizedParameterNameDiscoverer prioritizedParameterNameDiscoverer = new PrioritizedParameterNameDiscoverer();
prioritizedParameterNameDiscoverer.addDiscoverer(ASPECTJ_ANNOTATION_PARAMETER_NAME_DISCOVERER);
this.parameterNameDiscoverer = prioritizedParameterNameDiscoverer;
}
/**
* We consider something to be an AspectJ aspect suitable for use by the Spring AOP system
* if it has the @Aspect annotation, and was not compiled by ajc. The reason for this latter test
* is that aspects written in the code-style (AspectJ language) also have the annotation present
* when compiled by ajc with the -1.5 flag, yet they cannot be consumed by Spring AOP.
*/
public boolean isAspect(Class<?> clazz) {
return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));
}
private boolean hasAspectAnnotation(Class<?> clazz) {
return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);
}
/**
* We need to detect this as "code-style" AspectJ aspects should not be
* interpreted by Spring AOP.
*/
private boolean compiledByAjc(Class<?> clazz) {
// The AJTypeSystem goes to great lengths to provide a uniform appearance between code-style and
// annotation-style aspects. Therefore there is no 'clean' way to tell them apart. Here we rely on
// an implementation detail of the AspectJ compiler.
for (Field field : clazz.getDeclaredFields()) {
if (field.getName().startsWith(AJC_MAGIC)) {
return true;
}
}
return false;
}
public void validate(Class<?> aspectClass) throws AopConfigException {
// If the parent has the annotation and isn't abstract it's an error
if (aspectClass.getSuperclass().getAnnotation(Aspect.class) != null &&
!Modifier.isAbstract(aspectClass.getSuperclass().getModifiers())) {
throw new AopConfigException("[" + aspectClass.getName() + "] cannot extend concrete aspect [" +
aspectClass.getSuperclass().getName() + "]");
}
AjType<?> ajType = AjTypeSystem.getAjType(aspectClass);
if (!ajType.isAspect()) {
throw new NotAnAtAspectException(aspectClass);
}
if (ajType.getPerClause().getKind() == PerClauseKind.PERCFLOW) {
throw new AopConfigException(aspectClass.getName() + " uses percflow instantiation model: " +
"This is not supported in Spring AOP.");
}
if (ajType.getPerClause().getKind() == PerClauseKind.PERCFLOWBELOW) {
throw new AopConfigException(aspectClass.getName() + " uses percflowbelow instantiation model: " +
"This is not supported in Spring AOP.");
}
}
/**
* The pointcut and advice annotations both have an "argNames" member which contains a
* comma-separated list of the argument names. We use this (if non-empty) to build the
* formal parameters for the pointcut.
*/
protected AspectJExpressionPointcut createPointcutExpression(
Method annotatedMethod, Class declarationScope, String[] pointcutParameterNames) {
Class<?> [] pointcutParameterTypes = new Class<?>[0];
if (pointcutParameterNames != null) {
pointcutParameterTypes = extractPointcutParameterTypes(pointcutParameterNames,annotatedMethod);
}
AspectJExpressionPointcut ajexp =
new AspectJExpressionPointcut(declarationScope,pointcutParameterNames,pointcutParameterTypes);
ajexp.setLocation(annotatedMethod.toString());
return ajexp;
}
/**
* Create the pointcut parameters needed by aspectj based on the given argument names
* and the argument types that are available from the adviceMethod. Needs to take into
* account (ignore) any JoinPoint based arguments as these are not pointcut context but
* rather part of the advice execution context (thisJoinPoint, thisJoinPointStaticPart)
*/
private Class<?>[] extractPointcutParameterTypes(String[] argNames, Method adviceMethod) {
Class<?>[] ret = new Class<?>[argNames.length];
Class<?>[] paramTypes = adviceMethod.getParameterTypes();
if (argNames.length > paramTypes.length) {
throw new IllegalStateException("Expecting at least " + argNames.length +
" arguments in the advice declaration, but only found " + paramTypes.length);
}
// Make the simplifying assumption for now that all of the JoinPoint based arguments
// come first in the advice declaration.
int typeOffset = paramTypes.length - argNames.length;
for (int i = 0; i < ret.length; i++) {
ret[i] = paramTypes[i + typeOffset];
}
return ret;
}
protected enum AspectJAnnotationType {
AtPointcut,
AtBefore,
AtAfter,
AtAfterReturning,
AtAfterThrowing,
AtAround
}
/**
* Class modelling an AspectJ annotation, exposing its type enumeration and
* pointcut String.
*/
protected static class AspectJAnnotation<A extends Annotation> {
private static Map<Class,AspectJAnnotationType> annotationTypes = new HashMap<Class,AspectJAnnotationType>();
private static final String[] EXPRESSION_PROPERTIES = new String[]{"value", "pointcut"};
static {
annotationTypes.put(Pointcut.class,AspectJAnnotationType.AtPointcut);
annotationTypes.put(After.class,AspectJAnnotationType.AtAfter);
annotationTypes.put(AfterReturning.class,AspectJAnnotationType.AtAfterReturning);
annotationTypes.put(AfterThrowing.class,AspectJAnnotationType.AtAfterThrowing);
annotationTypes.put(Around.class,AspectJAnnotationType.AtAround);
annotationTypes.put(Before.class,AspectJAnnotationType.AtBefore);
}
private final A annotation;
private AspectJAnnotationType annotationType;
private final String expression;
private final String argNames;
public AspectJAnnotation(A aspectjAnnotation) {
this.annotation = aspectjAnnotation;
for (Class type : annotationTypes.keySet()) {
if (type.isInstance(this.annotation)) {
this.annotationType = annotationTypes.get(type);
break;
}
}
if (this.annotationType == null) {
throw new IllegalStateException("Unknown annotation type: " + this.annotation.toString());
}
// We know these methods exist with the same name on each object,
// but need to invoke them reflectively as there isn't a common interface.
try {
this.expression = resolveExpression();
this.argNames = (String)
this.annotation.getClass().getMethod("argNames", (Class[]) null).invoke(this.annotation);
}
catch (Exception ex) {
throw new IllegalArgumentException(aspectjAnnotation + " cannot be an AspectJ annotation", ex);
}
}
private String resolveExpression() throws Exception {
String expression = null;
for (String methodName : EXPRESSION_PROPERTIES) {
Method method;
try {
method = this.annotation.getClass().getDeclaredMethod(methodName);
}
catch (NoSuchMethodException ex) {
method = null;
}
if (method != null) {
String candidate = (String) method.invoke(this.annotation);
if (StringUtils.hasText(candidate)) {
expression = candidate;
}
}
}
return expression;
}
public AspectJAnnotationType getAnnotationType() {
return this.annotationType;
}
public A getAnnotation() {
return this.annotation;
}
public String getPointcutExpression() {
return this.expression;
}
public String getArgNames() {
return this.argNames;
}
@Override
public String toString() {
return this.annotation.toString();
}
}
/**
* ParameterNameDiscoverer implementation that analyzes the arg names
* specified at the AspectJ annotation level.
*/
private static class AspectJAnnotationParameterNameDiscoverer implements ParameterNameDiscoverer {
public String[] getParameterNames(Method method) {
if (method.getParameterTypes().length == 0) {
return new String[0];
}
AspectJAnnotation annotation = findAspectJAnnotationOnMethod(method);
if (annotation == null) {
return null;
}
StringTokenizer strTok = new StringTokenizer(annotation.getArgNames(), ",");
if (strTok.countTokens() > 0) {
String[] names = new String[strTok.countTokens()];
for (int i = 0; i < names.length; i++) {
names[i] = strTok.nextToken();
}
return names;
}
else {
return null;
}
}
public String[] getParameterNames(Constructor ctor) {
throw new UnsupportedOperationException("Spring AOP cannot handle constructor advice");
}
}
}
@@ -0,0 +1,141 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj.annotation;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.util.Assert;
/**
* {@link AspectJAwareAdvisorAutoProxyCreator} subclass that processes all AspectJ
* annotation aspects in the current application context, as well as Spring Advisors.
*
* <p>Any AspectJ annotated classes will automatically be recognized, and their
* advice applied if Spring AOP's proxy-based model is capable of applying it.
* This covers method execution joinpoints.
*
* <p>If the &lt;aop:include&gt; element is used, only @AspectJ beans with names matched by
* an include pattern will be considered as defining aspects to use for Spring auto-proxying.
*
* <p>Processing of Spring Advisors follows the rules established in
* {@link org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator}.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 2.0
* @see org.springframework.aop.aspectj.annotation.AspectJAdvisorFactory
*/
public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {
private List<Pattern> includePatterns;
private AspectJAdvisorFactory aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory();
private BeanFactoryAspectJAdvisorsBuilder aspectJAdvisorsBuilder;
/**
* Set a list of regex patterns, matching eligible @AspectJ bean names.
* <p>Default is to consider all @AspectJ beans as eligible.
*/
public void setIncludePatterns(List<String> patterns) {
this.includePatterns = new ArrayList<Pattern>(patterns.size());
for (String patternText : patterns) {
this.includePatterns.add(Pattern.compile(patternText));
}
}
public void setAspectJAdvisorFactory(AspectJAdvisorFactory aspectJAdvisorFactory) {
Assert.notNull(this.aspectJAdvisorFactory, "AspectJAdvisorFactory must not be null");
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
}
@Override
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
this.aspectJAdvisorsBuilder =
new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}
@Override
protected List<Advisor> findCandidateAdvisors() {
// Add all the Spring advisors found according to superclass rules.
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
return advisors;
}
@Override
protected boolean isInfrastructureClass(Class beanClass) {
// Previously we setProxyTargetClass(true) in the constructor, but that has too
// broad an impact. Instead we now override isInfrastructureClass to avoid proxying
// aspects. I'm not entirely happy with that as there is no good reason not
// to advise aspects, except that it causes advice invocation to go through a
// proxy, and if the aspect implements e.g the Ordered interface it will be
// proxied by that interface and fail at runtime as the advice method is not
// defined on the interface. We could potentially relax the restriction about
// not advising aspects in the future.
return (super.isInfrastructureClass(beanClass) || this.aspectJAdvisorFactory.isAspect(beanClass));
}
/**
* Check whether the given aspect bean is eligible for auto-proxying.
* <p>If no &lt;aop:include&gt; elements were used then "includePatterns" will be
* <code>null</code> and all beans are included. If "includePatterns" is non-null,
* then one of the patterns must match.
*/
protected boolean isEligibleAspectBean(String beanName) {
if (this.includePatterns == null) {
return true;
}
else {
for (Pattern pattern : this.includePatterns) {
if (pattern.matcher(beanName).matches()) {
return true;
}
}
return false;
}
}
/**
* Subclass of BeanFactoryAspectJAdvisorsBuilderAdapter that delegates to
* surrounding AnnotationAwareAspectJAutoProxyCreator facilities.
*/
private class BeanFactoryAspectJAdvisorsBuilderAdapter extends BeanFactoryAspectJAdvisorsBuilder {
public BeanFactoryAspectJAdvisorsBuilderAdapter(
ListableBeanFactory beanFactory, AspectJAdvisorFactory advisorFactory) {
super(beanFactory, advisorFactory);
}
@Override
protected boolean isEligibleBean(String beanName) {
return AnnotationAwareAspectJAutoProxyCreator.this.isEligibleAspectBean(beanName);
}
}
}
@@ -0,0 +1,104 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj.annotation;
import java.lang.reflect.Method;
import java.util.List;
import org.aopalliance.aop.Advice;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.framework.AopConfigException;
/**
* Interface for factories that can create Spring AOP Advisors from classes
* annotated with AspectJ annotation syntax.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 2.0
* @see AspectMetadata
* @see org.aspectj.lang.reflect.AjTypeSystem
*/
public interface AspectJAdvisorFactory {
/**
* Determine whether or not the given class is an aspect, as reported
* by AspectJ's {@link org.aspectj.lang.reflect.AjTypeSystem}.
* <p>Will simply return <code>false</code> if the supposed aspect is
* invalid (such as an extension of a concrete aspect class).
* Will return true for some aspects that Spring AOP cannot process,
* such as those with unsupported instantiation models.
* Use the {@link #validate} method to handle these cases if necessary.
* @param clazz the supposed annotation-style AspectJ class
* @return whether or not this class is recognized by AspectJ as an aspect class
*/
boolean isAspect(Class<?> clazz);
/**
* Is the given class a valid AspectJ aspect class?
* @param aspectClass the supposed AspectJ annotation-style class to validate
* @throws AopConfigException if the class is an invalid aspect
* (which can never be legal)
* @throws NotAnAtAspectException if the class is not an aspect at all
* (which may or may not be legal, depending on the context)
*/
void validate(Class<?> aspectClass) throws AopConfigException;
/**
* Build Spring AOP Advisors for all annotated At-AspectJ methods
* on the specified aspect instance.
* @param aif the aspect instance factory (not the aspect instance itself
* in order to avoid eager instantiation)
* @return a list of advisors for this class
*/
List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aif);
/**
* Build a Spring AOP Advisor for the given AspectJ advice method.
* @param candidateAdviceMethod the candidate advice method
* @param aif the aspect instance factory
* @param declarationOrderInAspect the declaration order within the aspect
* @param aspectName the name of the aspect
* @return <code>null</code> if the method is not an AspectJ advice method
* or if it is a pointcut that will be used by other advice but will not
* create a Spring advice in its own right
*/
Advisor getAdvisor(Method candidateAdviceMethod,
MetadataAwareAspectInstanceFactory aif, int declarationOrderInAspect, String aspectName);
/**
* Build a Spring AOP Advice for the given AspectJ advice method.
* @param candidateAdviceMethod the candidate advice method
* @param pointcut the corresponding AspectJ expression pointcut
* @param aif the aspect instance factory
* @param declarationOrderInAspect the declaration order within the aspect
* @param aspectName the name of the aspect
* @return <code>null</code> if the method is not an AspectJ advice method
* or if it is a pointcut that will be used by other advice but will not
* create a Spring advice in its own right
* @see org.springframework.aop.aspectj.AspectJAroundAdvice
* @see org.springframework.aop.aspectj.AspectJMethodBeforeAdvice
* @see org.springframework.aop.aspectj.AspectJAfterAdvice
* @see org.springframework.aop.aspectj.AspectJAfterReturningAdvice
* @see org.springframework.aop.aspectj.AspectJAfterThrowingAdvice
*/
Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut pointcut,
MetadataAwareAspectInstanceFactory aif, int declarationOrderInAspect, String aspectName);
}
@@ -0,0 +1,210 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj.annotation;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.aspectj.lang.reflect.PerClauseKind;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJProxyUtils;
import org.springframework.aop.framework.AopConfigException;
import org.springframework.aop.framework.ProxyCreatorSupport;
import org.springframework.aop.support.AopUtils;
import org.springframework.core.OrderComparator;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
* AspectJ-based proxy factory, allowing for programmatic building
* of proxies which include AspectJ aspects (code style as well
* Java 5 annotation style).
*
* @author Rob Harrop
* @author Juergen Hoeller
* @author Ramnivas Laddad
* @since 2.0
* @see #addAspect(Object)
* @see #addAspect(Class)
* @see #getProxy()
* @see #getProxy(ClassLoader)
* @see org.springframework.aop.framework.ProxyFactory
*/
public class AspectJProxyFactory extends ProxyCreatorSupport {
/** Cache for singleton aspect instances */
private static final Map<Class, Object> aspectCache = new HashMap<Class, Object>();
private final AspectJAdvisorFactory aspectFactory = new ReflectiveAspectJAdvisorFactory();
/**
* Create a new AspectJProxyFactory.
*/
public AspectJProxyFactory() {
}
/**
* Create a new AspectJProxyFactory.
* <p>Will proxy all interfaces that the given target implements.
* @param target the target object to be proxied
*/
public AspectJProxyFactory(Object target) {
Assert.notNull(target, "Target object must not be null");
setInterfaces(ClassUtils.getAllInterfaces(target));
setTarget(target);
}
/**
* Create a new <code>AspectJProxyFactory</code>.
* No target, only interfaces. Must add interceptors.
*/
public AspectJProxyFactory(Class[] interfaces) {
setInterfaces(interfaces);
}
/**
* Add the supplied aspect instance to the chain. The type of the aspect instance
* supplied must be a singleton aspect. True singleton lifecycle is not honoured when
* using this method - the caller is responsible for managing the lifecycle of any
* aspects added in this way.
* @param aspectInstance the AspectJ aspect instance
*/
public void addAspect(Object aspectInstance) {
Class aspectClass = aspectInstance.getClass();
String aspectName = aspectClass.getName();
AspectMetadata am = createAspectMetadata(aspectClass, aspectName);
if (am.getAjType().getPerClause().getKind() != PerClauseKind.SINGLETON) {
throw new IllegalArgumentException(
"Aspect class [" + aspectClass.getName() + "] does not define a singleton aspect");
}
addAdvisorsFromAspectInstanceFactory(
new SingletonMetadataAwareAspectInstanceFactory(aspectInstance, aspectName));
}
/**
* Add an aspect of the supplied type to the end of the advice chain.
* @param aspectClass the AspectJ aspect class
*/
public void addAspect(Class aspectClass) {
String aspectName = aspectClass.getName();
AspectMetadata am = createAspectMetadata(aspectClass, aspectName);
MetadataAwareAspectInstanceFactory instanceFactory = createAspectInstanceFactory(am, aspectClass, aspectName);
addAdvisorsFromAspectInstanceFactory(instanceFactory);
}
/**
* Add all {@link Advisor Advisors} from the supplied {@link MetadataAwareAspectInstanceFactory}
* to the current chain. Exposes any special purpose {@link Advisor Advisors} if needed.
* @see #makeAdvisorChainAspectJCapableIfNecessary()
*/
private void addAdvisorsFromAspectInstanceFactory(MetadataAwareAspectInstanceFactory instanceFactory) {
List<Advisor> advisors = this.aspectFactory.getAdvisors(instanceFactory);
advisors = AopUtils.findAdvisorsThatCanApply(advisors, getTargetClass());
AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(advisors);
OrderComparator.sort(advisors);
addAdvisors(advisors);
}
/**
* Create an {@link AspectMetadata} instance for the supplied aspect type.
*/
private AspectMetadata createAspectMetadata(Class aspectClass, String aspectName) {
AspectMetadata am = new AspectMetadata(aspectClass, aspectName);
if (!am.getAjType().isAspect()) {
throw new IllegalArgumentException("Class [" + aspectClass.getName() + "] is not a valid aspect type");
}
return am;
}
/**
* Create a {@link MetadataAwareAspectInstanceFactory} for the supplied aspect type. If the aspect type
* has no per clause, then a {@link SingletonMetadataAwareAspectInstanceFactory} is returned, otherwise
* a {@link PrototypeAspectInstanceFactory} is returned.
*/
private MetadataAwareAspectInstanceFactory createAspectInstanceFactory(
AspectMetadata am, Class aspectClass, String aspectName) {
MetadataAwareAspectInstanceFactory instanceFactory = null;
if (am.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
// Create a shared aspect instance.
Object instance = getSingletonAspectInstance(aspectClass);
instanceFactory = new SingletonMetadataAwareAspectInstanceFactory(instance, aspectName);
}
else {
// Create a factory for independent aspect instances.
instanceFactory = new SimpleMetadataAwareAspectInstanceFactory(aspectClass, aspectName);
}
return instanceFactory;
}
/**
* Get the singleton aspect instance for the supplied aspect type. An instance
* is created if one cannot be found in the instance cache.
*/
private Object getSingletonAspectInstance(Class aspectClass) {
synchronized (aspectCache) {
Object instance = aspectCache.get(aspectClass);
if (instance != null) {
return instance;
}
try {
instance = aspectClass.newInstance();
aspectCache.put(aspectClass, instance);
return instance;
}
catch (InstantiationException ex) {
throw new AopConfigException("Unable to instantiate aspect class [" + aspectClass.getName() + "]", ex);
}
catch (IllegalAccessException ex) {
throw new AopConfigException("Cannot access aspect class [" + aspectClass.getName() + "]", ex);
}
}
}
/**
* Create a new proxy according to the settings in this factory.
* <p>Can be called repeatedly. Effect will vary if we've added
* or removed interfaces. Can add and remove interceptors.
* <p>Uses a default class loader: Usually, the thread context class loader
* (if necessary for proxy creation).
* @return the new proxy
*/
@SuppressWarnings("unchecked")
public <T> T getProxy() {
return (T) createAopProxy().getProxy();
}
/**
* Create a new proxy according to the settings in this factory.
* <p>Can be called repeatedly. Effect will vary if we've added
* or removed interfaces. Can add and remove interceptors.
* <p>Uses the given class loader (if necessary for proxy creation).
* @param classLoader the class loader to create the proxy with
* @return the new proxy
*/
@SuppressWarnings("unchecked")
public <T> T getProxy(ClassLoader classLoader) {
return (T) createAopProxy().getProxy(classLoader);
}
}
@@ -0,0 +1,176 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj.annotation;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.AjType;
import org.aspectj.lang.reflect.AjTypeSystem;
import org.aspectj.lang.reflect.PerClauseKind;
import org.springframework.aop.Pointcut;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.aspectj.TypePatternClassFilter;
import org.springframework.aop.framework.AopConfigException;
import org.springframework.aop.support.ComposablePointcut;
/**
* Metadata for an AspectJ aspect class, with an additional Spring AOP pointcut
* for the per clause.
*
* <p>Uses AspectJ 5 AJType reflection API, so is only supported on Java 5.
* Enables us to work with different AspectJ instantiation models such as
* "singleton", "pertarget" and "perthis".
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 2.0
* @see org.springframework.aop.aspectj.AspectJExpressionPointcut
*/
public class AspectMetadata {
/**
* AspectJ reflection information (AspectJ 5 / Java 5 specific).
*/
private final AjType ajType;
/**
* Spring AOP pointcut corresponding to the per clause of the
* aspect. Will be the Pointcut.TRUE canonical instance in the
* case of a singleton, otherwise an AspectJExpressionPointcut.
*/
private final Pointcut perClausePointcut;
/**
* The name of this aspect as defined to Spring (the bean name) -
* allows us to determine if two pieces of advice come from the
* same aspect and hence their relative precedence.
*/
private String aspectName;
/**
* Create a new AspectMetadata instance for the given aspect class.
* @param aspectClass the aspect class
* @param aspectName the name of the aspect
*/
public AspectMetadata(Class<?> aspectClass, String aspectName) {
this.aspectName = aspectName;
Class<?> currClass = aspectClass;
AjType ajType = null;
while (!currClass.equals(Object.class)) {
AjType ajTypeToCheck = AjTypeSystem.getAjType(currClass);
if (ajTypeToCheck.isAspect()) {
ajType = ajTypeToCheck;
break;
}
currClass = currClass.getSuperclass();
}
if (ajType == null) {
throw new IllegalArgumentException("Class '" + aspectClass.getName() + "' is not an @AspectJ aspect");
}
this.ajType = ajType;
if (this.ajType.getDeclarePrecedence().length > 0) {
throw new IllegalArgumentException("DeclarePrecendence not presently supported in Spring AOP");
}
switch (this.ajType.getPerClause().getKind()) {
case SINGLETON :
this.perClausePointcut = Pointcut.TRUE;
return;
case PERTARGET : case PERTHIS :
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
ajexp.setLocation("@Aspect annotation on " + aspectClass.getName());
ajexp.setExpression(findPerClause(aspectClass));
this.perClausePointcut = ajexp;
return;
case PERTYPEWITHIN :
// Works with a type pattern
this.perClausePointcut = new ComposablePointcut(new TypePatternClassFilter(findPerClause(aspectClass)));
return;
default :
throw new AopConfigException(
"PerClause " + ajType.getPerClause().getKind() + " not supported by Spring AOP for " + aspectClass);
}
}
/**
* Extract contents from String of form <code>pertarget(contents)</code>.
*/
private String findPerClause(Class<?> aspectClass) {
// TODO when AspectJ provides this, we can remove this hack. Hence we don't
// bother to make it elegant. Or efficient. Or robust :-)
String str = aspectClass.getAnnotation(Aspect.class).value();
str = str.substring(str.indexOf("(") + 1);
str = str.substring(0, str.length() - 1);
return str;
}
/**
* Return AspectJ reflection information.
*/
public AjType getAjType() {
return this.ajType;
}
/**
* Return the aspect class.
*/
public Class getAspectClass() {
return this.ajType.getJavaClass();
}
/**
* Return the aspect class.
*/
public String getAspectName() {
return this.aspectName;
}
/**
* Return a Spring pointcut expression for a singleton aspect.
* (e.g. <code>Pointcut.TRUE</code> if it's a singleton).
*/
public Pointcut getPerClausePointcut() {
return this.perClausePointcut;
}
/**
* Return whether the aspect is defined as "perthis" or "pertarget".
*/
public boolean isPerThisOrPerTarget() {
PerClauseKind kind = getAjType().getPerClause().getKind();
return (kind == PerClauseKind.PERTARGET || kind == PerClauseKind.PERTHIS);
}
/**
* Return whether the aspect is defined as "pertypewithin".
*/
public boolean isPerTypeWithin() {
PerClauseKind kind = getAjType().getPerClause().getKind();
return (kind == PerClauseKind.PERTYPEWITHIN);
}
/**
* Return whether the aspect needs to be lazily instantiated.
*/
public boolean isLazilyInstantiated() {
return (isPerThisOrPerTarget() || isPerTypeWithin());
}
}
@@ -0,0 +1,122 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj.annotation;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.util.ClassUtils;
/**
* {@link org.springframework.aop.aspectj.AspectInstanceFactory} implementation
* backed by a Spring {@link org.springframework.beans.factory.BeanFactory}.
*
* <p>Note that this may instantiate multiple times if using a prototype,
* which probably won't give the semantics you expect.
* Use a {@link LazySingletonAspectInstanceFactoryDecorator}
* to wrap this to ensure only one new aspect comes back.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 2.0
* @see org.springframework.beans.factory.BeanFactory
* @see LazySingletonAspectInstanceFactoryDecorator
*/
public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInstanceFactory {
private final BeanFactory beanFactory;
private final String name;
private final AspectMetadata aspectMetadata;
/**
* Create a BeanFactoryAspectInstanceFactory. AspectJ will be called to
* introspect to create AJType metadata using the type returned for the
* given bean name from the BeanFactory.
* @param beanFactory BeanFactory to obtain instance(s) from
* @param name name of the bean
*/
public BeanFactoryAspectInstanceFactory(BeanFactory beanFactory, String name) {
this(beanFactory, name, beanFactory.getType(name));
}
/**
* Create a BeanFactoryAspectInstanceFactory, providing a type that AspectJ should
* introspect to create AJType metadata. Use if the BeanFactory may consider the type
* to be a subclass (as when using CGLIB), and the information should relate to a superclass.
* @param beanFactory BeanFactory to obtain instance(s) from
* @param name the name of the bean
* @param type the type that should be introspected by AspectJ
*/
public BeanFactoryAspectInstanceFactory(BeanFactory beanFactory, String name, Class type) {
this.beanFactory = beanFactory;
this.name = name;
this.aspectMetadata = new AspectMetadata(type, name);
}
public Object getAspectInstance() {
return this.beanFactory.getBean(this.name);
}
public ClassLoader getAspectClassLoader() {
if (this.beanFactory instanceof ConfigurableBeanFactory) {
return ((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader();
}
else {
return ClassUtils.getDefaultClassLoader();
}
}
public AspectMetadata getAspectMetadata() {
return this.aspectMetadata;
}
/**
* Determine the order for this factory's target aspect, either
* an instance-specific order expressed through implementing the
* {@link org.springframework.core.Ordered} interface (only
* checked for singleton beans), or an order expressed through the
* {@link org.springframework.core.annotation.Order} annotation
* at the class level.
* @see org.springframework.core.Ordered
* @see org.springframework.core.annotation.Order
*/
public int getOrder() {
Class<?> type = this.beanFactory.getType(this.name);
if (type != null) {
if (Ordered.class.isAssignableFrom(type) && this.beanFactory.isSingleton(this.name)) {
return ((Ordered) this.beanFactory.getBean(this.name)).getOrder();
}
Order order = type.getAnnotation(Order.class);
if (order != null) {
return order.value();
}
}
return Ordered.LOWEST_PRECEDENCE;
}
@Override
public String toString() {
return getClass().getSimpleName() + ": bean name '" + this.name + "'";
}
}
@@ -0,0 +1,162 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj.annotation;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.aspectj.lang.reflect.PerClauseKind;
import org.springframework.aop.Advisor;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.util.Assert;
/**
* Helper for retrieving @AspectJ beans from a BeanFactory and building
* Spring Advisors based on them, for use with auto-proxying.
*
* @author Juergen Hoeller
* @since 2.0.2
* @see AnnotationAwareAspectJAutoProxyCreator
*/
public class BeanFactoryAspectJAdvisorsBuilder {
private final ListableBeanFactory beanFactory;
private final AspectJAdvisorFactory advisorFactory;
private List<String> aspectBeanNames;
private final Map<String, List<Advisor>> advisorsCache = new HashMap<String, List<Advisor>>();
private final Map<String, MetadataAwareAspectInstanceFactory> aspectFactoryCache =
new HashMap<String, MetadataAwareAspectInstanceFactory>();
/**
* Create a new BeanFactoryAspectJAdvisorsBuilder for the given BeanFactory.
* @param beanFactory the ListableBeanFactory to scan
*/
public BeanFactoryAspectJAdvisorsBuilder(ListableBeanFactory beanFactory) {
this(beanFactory, new ReflectiveAspectJAdvisorFactory());
}
/**
* Create a new BeanFactoryAspectJAdvisorsBuilder for the given BeanFactory.
* @param beanFactory the ListableBeanFactory to scan
* @param advisorFactory the AspectJAdvisorFactory to build each Advisor with
*/
public BeanFactoryAspectJAdvisorsBuilder(ListableBeanFactory beanFactory, AspectJAdvisorFactory advisorFactory) {
Assert.notNull(beanFactory, "ListableBeanFactory must not be null");
Assert.notNull(advisorFactory, "AspectJAdvisorFactory must not be null");
this.beanFactory = beanFactory;
this.advisorFactory = advisorFactory;
}
/**
* Look for AspectJ-annotated aspect beans in the current bean factory,
* and return to a list of Spring AOP Advisors representing them.
* <p>Creates a Spring Advisor for each AspectJ advice method.
* @return the list of {@link org.springframework.aop.Advisor} beans
* @see #isEligibleBean
*/
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = null;
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new LinkedList<Advisor>();
aspectNames = new LinkedList<String>();
String[] beanNames =
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
// We must be careful not to instantiate beans eagerly as in this
// case they would be cached by the Spring container but would not
// have been weaved
Class beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
}
else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
}
else {
// Per target or per this.
if (this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("Bean with name '" + beanName +
"' is a singleton, but aspect instantiation model is not singleton");
}
MetadataAwareAspectInstanceFactory factory =
new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
if (aspectNames.isEmpty()) {
return Collections.EMPTY_LIST;
}
List<Advisor> advisors = new LinkedList<Advisor>();
for (String aspectName : aspectNames) {
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
}
else {
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
/**
* Return whether the aspect bean with the given name is eligible.
* @param beanName the name of the aspect bean
* @return whether the bean is eligible
*/
protected boolean isEligibleBean(String beanName) {
return true;
}
}
@@ -0,0 +1,263 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj.annotation;
import java.lang.reflect.Method;
import org.aopalliance.aop.Advice;
import org.aspectj.lang.reflect.PerClauseKind;
import org.springframework.aop.Pointcut;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.aspectj.AspectJPrecedenceInformation;
import org.springframework.aop.aspectj.InstantiationModelAwarePointcutAdvisor;
import org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactory.AspectJAnnotation;
import org.springframework.aop.support.DynamicMethodMatcherPointcut;
import org.springframework.aop.support.Pointcuts;
/**
* Internal implementation of AspectJPointcutAdvisor.
* Note that there will be one instance of this advisor for each target method.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 2.0
*/
class InstantiationModelAwarePointcutAdvisorImpl
implements InstantiationModelAwarePointcutAdvisor, AspectJPrecedenceInformation {
private final AspectJExpressionPointcut declaredPointcut;
private Pointcut pointcut;
private final MetadataAwareAspectInstanceFactory aspectInstanceFactory;
private final Method method;
private final boolean lazy;
private final AspectJAdvisorFactory atAspectJAdvisorFactory;
private Advice instantiatedAdvice;
private int declarationOrder;
private String aspectName;
private Boolean isBeforeAdvice = null;
private Boolean isAfterAdvice = null;
public InstantiationModelAwarePointcutAdvisorImpl(
AspectJAdvisorFactory af,
AspectJExpressionPointcut ajexp,
MetadataAwareAspectInstanceFactory aif,
Method method,
int declarationOrderInAspect,
String aspectName) {
this.declaredPointcut = ajexp;
this.method = method;
this.atAspectJAdvisorFactory = af;
this.aspectInstanceFactory = aif;
this.declarationOrder = declarationOrderInAspect;
this.aspectName = aspectName;
if (aif.getAspectMetadata().isLazilyInstantiated()) {
// Static part of the pointcut is a lazy type.
Pointcut preInstantiationPointcut =
Pointcuts.union(aif.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
// Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
// If it's not a dynamic pointcut, it may be optimized out
// by the Spring AOP infrastructure after the first evaluation.
this.pointcut = new PerTargetInstantiationModelPointcut(this.declaredPointcut, preInstantiationPointcut, aif);
this.lazy = true;
}
else {
// A singleton aspect.
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
this.pointcut = declaredPointcut;
this.lazy = false;
}
}
/**
* The pointcut for Spring AOP to use. Actual behaviour of the pointcut will change
* depending on the state of the advice.
*/
public Pointcut getPointcut() {
return this.pointcut;
}
/**
* This is only of interest for Spring AOP: AspectJ instantiation semantics
* are much richer. In AspectJ terminology, all a return of <code>true</code>
* means here is that the aspect is not a SINGLETON.
*/
public boolean isPerInstance() {
return (getAspectMetadata().getAjType().getPerClause().getKind() != PerClauseKind.SINGLETON);
}
/**
* Return the AspectJ AspectMetadata for this advisor.
*/
public AspectMetadata getAspectMetadata() {
return this.aspectInstanceFactory.getAspectMetadata();
}
/**
* Lazily instantiate advice if necessary.
*/
public synchronized Advice getAdvice() {
if (this.instantiatedAdvice == null) {
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
}
return this.instantiatedAdvice;
}
public boolean isLazy() {
return this.lazy;
}
public synchronized boolean isAdviceInstantiated() {
return (this.instantiatedAdvice != null);
}
private Advice instantiateAdvice(AspectJExpressionPointcut pcut) {
return this.atAspectJAdvisorFactory.getAdvice(
this.method, pcut, this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
}
public MetadataAwareAspectInstanceFactory getAspectInstanceFactory() {
return this.aspectInstanceFactory;
}
public AspectJExpressionPointcut getDeclaredPointcut() {
return this.declaredPointcut;
}
public int getOrder() {
return this.aspectInstanceFactory.getOrder();
}
public String getAspectName() {
return this.aspectName;
}
public int getDeclarationOrder() {
return this.declarationOrder;
}
public boolean isBeforeAdvice() {
if (this.isBeforeAdvice == null) {
determineAdviceType();
}
return this.isBeforeAdvice;
}
public boolean isAfterAdvice() {
if (this.isAfterAdvice == null) {
determineAdviceType();
}
return this.isAfterAdvice;
}
/**
* Duplicates some logic from getAdvice, but importantly does not force
* creation of the advice.
*/
private void determineAdviceType() {
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(this.method);
if (aspectJAnnotation == null) {
this.isBeforeAdvice = false;
this.isAfterAdvice = false;
}
else {
switch (aspectJAnnotation.getAnnotationType()) {
case AtAfter:
case AtAfterReturning:
case AtAfterThrowing:
this.isAfterAdvice = true;
this.isBeforeAdvice = false;
break;
case AtAround:
case AtPointcut:
this.isAfterAdvice = false;
this.isBeforeAdvice = false;
break;
case AtBefore:
this.isAfterAdvice = false;
this.isBeforeAdvice = true;
}
}
}
@Override
public String toString() {
return "InstantiationModelAwarePointcutAdvisor: expression [" + getDeclaredPointcut().getExpression() +
"]; advice method [" + this.method + "]; perClauseKind=" +
this.aspectInstanceFactory.getAspectMetadata().getAjType().getPerClause().getKind();
}
/**
* Pointcut implementation that changes its behaviour when the advice is instantiated.
* Note that this is a <i>dynamic</i> pointcut. Otherwise it might
* be optimized out if it does not at first match statically.
*/
private class PerTargetInstantiationModelPointcut extends DynamicMethodMatcherPointcut {
private final AspectJExpressionPointcut declaredPointcut;
private final Pointcut preInstantiationPointcut;
private LazySingletonAspectInstanceFactoryDecorator aspectInstanceFactory;
private PerTargetInstantiationModelPointcut(AspectJExpressionPointcut declaredPointcut,
Pointcut preInstantiationPointcut, MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
this.declaredPointcut = declaredPointcut;
this.preInstantiationPointcut = preInstantiationPointcut;
if (aspectInstanceFactory instanceof LazySingletonAspectInstanceFactoryDecorator) {
this.aspectInstanceFactory = (LazySingletonAspectInstanceFactoryDecorator) aspectInstanceFactory;
}
}
@Override
public boolean matches(Method method, Class targetClass) {
// We're either instantiated and matching on declared pointcut, or uninstantiated matching on either pointcut
return (isAspectMaterialized() && this.declaredPointcut.matches(method, targetClass)) ||
this.preInstantiationPointcut.getMethodMatcher().matches(method, targetClass);
}
public boolean matches(Method method, Class targetClass, Object[] args) {
// This can match only on declared pointcut.
return (isAspectMaterialized() && this.declaredPointcut.matches(method, targetClass));
}
private boolean isAspectMaterialized() {
return (this.aspectInstanceFactory == null || this.aspectInstanceFactory.isMaterialized());
}
}
}
@@ -0,0 +1,78 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj.annotation;
import org.springframework.util.Assert;
/**
* Decorator to cause a {@link MetadataAwareAspectInstanceFactory} to instantiate only once.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 2.0
*/
public class LazySingletonAspectInstanceFactoryDecorator implements MetadataAwareAspectInstanceFactory {
private final MetadataAwareAspectInstanceFactory maaif;
private volatile Object materialized;
/**
* Create a new lazily initializing decorator for the given AspectInstanceFactory.
* @param maaif the MetadataAwareAspectInstanceFactory to decorate
*/
public LazySingletonAspectInstanceFactoryDecorator(MetadataAwareAspectInstanceFactory maaif) {
Assert.notNull(maaif, "AspectInstanceFactory must not be null");
this.maaif = maaif;
}
public synchronized Object getAspectInstance() {
if (this.materialized == null) {
synchronized (this) {
if (this.materialized == null) {
this.materialized = this.maaif.getAspectInstance();
}
}
}
return this.materialized;
}
public boolean isMaterialized() {
return (this.materialized != null);
}
public ClassLoader getAspectClassLoader() {
return this.maaif.getAspectClassLoader();
}
public AspectMetadata getAspectMetadata() {
return this.maaif.getAspectMetadata();
}
public int getOrder() {
return this.maaif.getOrder();
}
@Override
public String toString() {
return "LazySingletonAspectInstanceFactoryDecorator: decorating " + this.maaif;
}
}
@@ -0,0 +1,42 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj.annotation;
import org.springframework.aop.aspectj.AspectInstanceFactory;
/**
* Subinterface of {@link org.springframework.aop.aspectj.AspectInstanceFactory}
* that returns {@link AspectMetadata} associated with AspectJ-annotated classes.
*
* <p>Ideally, AspectInstanceFactory would include this method itself, but because
* AspectMetadata uses Java-5-only {@link org.aspectj.lang.reflect.AjType},
* we need to split out this subinterface.
*
* @author Rod Johnson
* @since 2.0
* @see AspectMetadata
* @see org.aspectj.lang.reflect.AjType
*/
public interface MetadataAwareAspectInstanceFactory extends AspectInstanceFactory {
/**
* Return the AspectJ AspectMetadata for this factory's aspect.
* @return the aspect metadata
*/
AspectMetadata getAspectMetadata();
}
@@ -0,0 +1,50 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj.annotation;
import org.springframework.aop.framework.AopConfigException;
/**
* Extension of AopConfigException thrown when trying to perform
* an advisor generation operation on a class that is not an
* AspectJ annotation-style aspect.
*
* @author Rod Johnson
* @since 2.0
*/
public class NotAnAtAspectException extends AopConfigException {
private Class<?> nonAspectClass;
/**
* Create a new NotAnAtAspectException for the given class.
* @param nonAspectClass the offending class
*/
public NotAnAtAspectException(Class<?> nonAspectClass) {
super(nonAspectClass.getName() + " is not an @AspectJ aspect");
this.nonAspectClass = nonAspectClass;
}
/**
* Returns the offending class.
*/
public Class<?> getNonAspectClass() {
return this.nonAspectClass;
}
}
@@ -0,0 +1,52 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj.annotation;
import org.springframework.beans.factory.BeanFactory;
/**
* AspectInstanceFactory backed by a BeanFactory-provided prototype,
* enforcing prototype semantics.
*
* <p>Note that this may instantiate multiple times, which probably won't give the
* semantics you expect. Use a {@link LazySingletonAspectInstanceFactoryDecorator}
* to wrap this to ensure only one new aspect comes back.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 2.0
* @see org.springframework.beans.factory.BeanFactory
* @see LazySingletonAspectInstanceFactoryDecorator
*/
public class PrototypeAspectInstanceFactory extends BeanFactoryAspectInstanceFactory {
/**
* Create a PrototypeAspectInstanceFactory. AspectJ will be called to
* introspect to create AJType metadata using the type returned for the
* given bean name from the BeanFactory.
* @param beanFactory the BeanFactory to obtain instance(s) from
* @param name the name of the bean
*/
public PrototypeAspectInstanceFactory(BeanFactory beanFactory, String name) {
super(beanFactory, name);
if (!beanFactory.isPrototype(name)) {
throw new IllegalArgumentException(
"Cannot use PrototypeAspectInstanceFactory with bean named '" + name + "': not a prototype");
}
}
}
@@ -0,0 +1,239 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj.annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.LinkedList;
import java.util.List;
import org.aopalliance.aop.Advice;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.DeclareParents;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.aop.Advisor;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.aspectj.AbstractAspectJAdvice;
import org.springframework.aop.aspectj.AspectJAfterAdvice;
import org.springframework.aop.aspectj.AspectJAfterReturningAdvice;
import org.springframework.aop.aspectj.AspectJAfterThrowingAdvice;
import org.springframework.aop.aspectj.AspectJAroundAdvice;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.aspectj.AspectJMethodBeforeAdvice;
import org.springframework.aop.aspectj.DeclareParentsAdvisor;
import org.springframework.aop.framework.AopConfigException;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
/**
* Factory that can create Spring AOP Advisors given AspectJ classes from
* classes honoring the AspectJ 5 annotation syntax, using reflection to
* invoke the corresponding advice methods.
*
* @author Rod Johnson
* @author Adrian Colyer
* @author Juergen Hoeller
* @author Ramnivas Laddad
* @since 2.0
*/
public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory {
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory maaif) {
final Class<?> aspectClass = maaif.getAspectMetadata().getAspectClass();
final String aspectName = maaif.getAspectMetadata().getAspectName();
validate(aspectClass);
// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
// so that it will only instantiate once.
final MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(maaif);
final List<Advisor> advisors = new LinkedList<Advisor>();
ReflectionUtils.doWithMethods(aspectClass, new ReflectionUtils.MethodCallback() {
public void doWith(Method method) throws IllegalArgumentException {
// Exclude pointcuts
if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
}
});
// If it's a per target aspect, emit the dummy instantiating aspect.
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
// Find introduction fields.
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
/**
* Build a {@link org.springframework.aop.aspectj.DeclareParentsAdvisor}
* for the given introduction field.
* <p>Resulting Advisors will need to be evaluated for targets.
* @param introductionField the field to introspect
* @return <code>null</code> if not an Advisor
*/
private Advisor getDeclareParentsAdvisor(Field introductionField) {
DeclareParents declareParents = (DeclareParents) introductionField.getAnnotation(DeclareParents.class);
if (declareParents == null) {
// Not an introduction field
return null;
}
if (DeclareParents.class.equals(declareParents.defaultImpl())) {
// This is what comes back if it wasn't set. This seems bizarre...
// TODO this restriction possibly should be relaxed
throw new IllegalStateException("defaultImpl must be set on DeclareParents");
}
return new DeclareParentsAdvisor(
introductionField.getType(), declareParents.value(), declareParents.defaultImpl());
}
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aif,
int declarationOrderInAspect, String aspectName) {
validate(aif.getAspectMetadata().getAspectClass());
AspectJExpressionPointcut ajexp =
getPointcut(candidateAdviceMethod, aif.getAspectMetadata().getAspectClass());
if (ajexp == null) {
return null;
}
return new InstantiationModelAwarePointcutAdvisorImpl(
this, ajexp, aif, candidateAdviceMethod, declarationOrderInAspect, aspectName);
}
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
AspectJExpressionPointcut ajexp =
new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class[0]);
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
return ajexp;
}
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut ajexp,
MetadataAwareAspectInstanceFactory aif, int declarationOrderInAspect, String aspectName) {
Class<?> candidateAspectClass = aif.getAspectMetadata().getAspectClass();
validate(candidateAspectClass);
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
// If we get here, we know we have an AspectJ method.
// Check that it's an AspectJ-annotated class
if (!isAspect(candidateAspectClass)) {
throw new AopConfigException("Advice must be declared inside an aspect type: " +
"Offending method '" + candidateAdviceMethod + "' in class [" +
candidateAspectClass.getName() + "]");
}
if (logger.isDebugEnabled()) {
logger.debug("Found AspectJ method: " + candidateAdviceMethod);
}
AbstractAspectJAdvice springAdvice;
switch (aspectJAnnotation.getAnnotationType()) {
case AtBefore:
springAdvice = new AspectJMethodBeforeAdvice(candidateAdviceMethod, ajexp, aif);
break;
case AtAfter:
springAdvice = new AspectJAfterAdvice(candidateAdviceMethod, ajexp, aif);
break;
case AtAfterReturning:
springAdvice = new AspectJAfterReturningAdvice(candidateAdviceMethod, ajexp, aif);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing:
springAdvice = new AspectJAfterThrowingAdvice(candidateAdviceMethod, ajexp, aif);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
case AtAround:
springAdvice = new AspectJAroundAdvice(candidateAdviceMethod, ajexp, aif);
break;
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method " + candidateAdviceMethod);
}
// Now to configure the advice...
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrderInAspect);
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings();
return springAdvice;
}
/**
* Synthetic advisor that instantiates the aspect.
* Triggered by per-clause pointcut on non-singleton aspect.
* The advice has no effect.
*/
protected static class SyntheticInstantiationAdvisor extends DefaultPointcutAdvisor {
public SyntheticInstantiationAdvisor(final MetadataAwareAspectInstanceFactory aif) {
super(aif.getAspectMetadata().getPerClausePointcut(), new MethodBeforeAdvice() {
public void before(Method method, Object[] args, Object target) {
// Simply instantiate the aspect
aif.getAspectInstance();
}
});
}
}
}
@@ -0,0 +1,68 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj.annotation;
import org.springframework.aop.aspectj.SimpleAspectInstanceFactory;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
/**
* Implementation of {@link MetadataAwareAspectInstanceFactory} that
* creates a new instance of the specified aspect class for every
* {@link #getAspectInstance()} call.
*
* @author Juergen Hoeller
* @since 2.0.4
*/
public class SimpleMetadataAwareAspectInstanceFactory extends SimpleAspectInstanceFactory
implements MetadataAwareAspectInstanceFactory {
private final AspectMetadata metadata;
/**
* Create a new SimpleMetadataAwareAspectInstanceFactory for the given aspect class.
* @param aspectClass the aspect class
* @param aspectName the aspect name
*/
public SimpleMetadataAwareAspectInstanceFactory(Class aspectClass, String aspectName) {
super(aspectClass);
this.metadata = new AspectMetadata(aspectClass, aspectName);
}
public final AspectMetadata getAspectMetadata() {
return this.metadata;
}
/**
* Determine a fallback order for the case that the aspect instance
* does not express an instance-specific order through implementing
* the {@link org.springframework.core.Ordered} interface.
* <p>The default implementation simply returns <code>Ordered.LOWEST_PRECEDENCE</code>.
* @param aspectClass the aspect class
*/
@Override
protected int getOrderForAspectClass(Class<?> aspectClass) {
Order order = aspectClass.getAnnotation(Order.class);
if (order != null) {
return order.value();
}
return Ordered.LOWEST_PRECEDENCE;
}
}
@@ -0,0 +1,69 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj.annotation;
import org.springframework.aop.aspectj.SingletonAspectInstanceFactory;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
/**
* Implementation of {@link MetadataAwareAspectInstanceFactory} that is backed
* by a specified singleton object, returning the same instance for every
* {@link #getAspectInstance()} call.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 2.0
* @see SimpleMetadataAwareAspectInstanceFactory
*/
public class SingletonMetadataAwareAspectInstanceFactory extends SingletonAspectInstanceFactory
implements MetadataAwareAspectInstanceFactory {
private final AspectMetadata metadata;
/**
* Create a new SingletonMetadataAwareAspectInstanceFactory for the given aspect.
* @param aspectInstance the singleton aspect instance
* @param aspectName the name of the aspect
*/
public SingletonMetadataAwareAspectInstanceFactory(Object aspectInstance, String aspectName) {
super(aspectInstance);
this.metadata = new AspectMetadata(aspectInstance.getClass(), aspectName);
}
public final AspectMetadata getAspectMetadata() {
return this.metadata;
}
/**
* Check whether the aspect class carries an
* {@link org.springframework.core.annotation.Order} annotation,
* falling back to <code>Ordered.LOWEST_PRECEDENCE</code>.
* @see org.springframework.core.annotation.Order
*/
@Override
protected int getOrderForAspectClass(Class<?> aspectClass) {
Order order = aspectClass.getAnnotation(Order.class);
if (order != null) {
return order.value();
}
return Ordered.LOWEST_PRECEDENCE;
}
}
@@ -0,0 +1,9 @@
<html>
<body>
Classes enabling AspectJ 5 @Annotated classes to be used in Spring AOP.
<p>Normally to be used through an AspectJAutoProxyCreator rather than directly.
</body>
</html>
@@ -0,0 +1,165 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.aop.aspectj.autoproxy;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import org.aopalliance.aop.Advice;
import org.aspectj.util.PartialOrder;
import org.aspectj.util.PartialOrder.PartialComparable;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AbstractAspectJAdvice;
import org.springframework.aop.aspectj.AspectJPointcutAdvisor;
import org.springframework.aop.aspectj.AspectJProxyUtils;
import org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator;
import org.springframework.aop.interceptor.ExposeInvocationInterceptor;
import org.springframework.core.Ordered;
import org.springframework.util.ClassUtils;
/**
* {@link org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator}
* subclass that exposes AspectJ's invocation context and understands AspectJ's rules
* for advice precedence when multiple pieces of advice come from the same aspect.
*
* @author Adrian Colyer
* @author Juergen Hoeller
* @author Ramnivas Laddad
* @since 2.0
*/
public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {
private static final Comparator DEFAULT_PRECEDENCE_COMPARATOR = new AspectJPrecedenceComparator();
/**
* Sort the rest by AspectJ precedence. If two pieces of advice have
* come from the same aspect they will have the same order.
* Advice from the same aspect is then further ordered according to the
* following rules:
* <ul>
* <li>if either of the pair is after advice, then the advice declared
* last gets highest precedence (runs last)</li>
* <li>otherwise the advice declared first gets highest precedence (runs first)</li>
* </ul>
* <p><b>Important:</b> Advisors are sorted in precedence order, from highest
* precedence to lowest. "On the way in" to a join point, the highest precedence
* advisor should run first. "On the way out" of a join point, the highest precedence
* advisor should run last.
*/
@Override
@SuppressWarnings("unchecked")
protected List<Advisor> sortAdvisors(List<Advisor> advisors) {
// build list for sorting
List<PartiallyComparableAdvisorHolder> partiallyComparableAdvisors =
new LinkedList<PartiallyComparableAdvisorHolder>();
for (Advisor element : advisors) {
partiallyComparableAdvisors.add(
new PartiallyComparableAdvisorHolder(element, DEFAULT_PRECEDENCE_COMPARATOR));
}
// sort it
List<PartiallyComparableAdvisorHolder> sorted =
(List<PartiallyComparableAdvisorHolder>) PartialOrder.sort(partiallyComparableAdvisors);
if (sorted == null) {
// TODO: work harder to give a better error message here.
throw new IllegalArgumentException("Advice precedence circularity error");
}
// extract results again
List<Advisor> result = new LinkedList<Advisor>();
for (PartiallyComparableAdvisorHolder pcAdvisor : sorted) {
result.add(pcAdvisor.getAdvisor());
}
return result;
}
/**
* Adds an {@link ExposeInvocationInterceptor} to the beginning of the advice chain.
* These additional advices are needed when using AspectJ expression pointcuts
* and when using AspectJ-style advice.
*/
@Override
protected void extendAdvisors(List<Advisor> candidateAdvisors) {
AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);
}
@Override
protected boolean shouldSkip(Class beanClass, String beanName) {
// TODO: Consider optimization by caching the list of the aspect names
List<Advisor> candidateAdvisors = findCandidateAdvisors();
for (Advisor advisor : candidateAdvisors) {
if (advisor instanceof AspectJPointcutAdvisor) {
if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) {
return true;
}
}
}
return super.shouldSkip(beanClass, beanName);
}
/**
* Implements AspectJ PartialComparable interface for defining partial orderings.
*/
private static class PartiallyComparableAdvisorHolder implements PartialComparable {
private final Advisor advisor;
private final Comparator<Advisor> comparator;
public PartiallyComparableAdvisorHolder(Advisor advisor, Comparator<Advisor> comparator) {
this.advisor = advisor;
this.comparator = comparator;
}
public int compareTo(Object obj) {
Advisor otherAdvisor = ((PartiallyComparableAdvisorHolder) obj).advisor;
return this.comparator.compare(this.advisor, otherAdvisor);
}
public int fallbackCompareTo(Object obj) {
return 0;
}
public Advisor getAdvisor() {
return this.advisor;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
Advice advice = this.advisor.getAdvice();
sb.append(ClassUtils.getShortName(advice.getClass()));
sb.append(": ");
if (this.advisor instanceof Ordered) {
sb.append("order ").append(((Ordered) this.advisor).getOrder()).append(", ");
}
if (advice instanceof AbstractAspectJAdvice) {
AbstractAspectJAdvice ajAdvice = (AbstractAspectJAdvice) advice;
sb.append(ajAdvice.getAspectName());
sb.append(", declaration order ");
sb.append(ajAdvice.getDeclarationOrder());
}
return sb.toString();
}
}
}

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