mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Compare commits
1370 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 40015e3de3 | |||
| 5e448af903 | |||
| 1f3ce640c9 | |||
| cca44f411e | |||
| 9b0412f35f | |||
| 7eee3b9926 | |||
| b5a279d2c8 | |||
| 0862a29066 | |||
| 8d83f6966e | |||
| ce5117c9ed | |||
| 836e3c9253 | |||
| 2006eecb18 | |||
| 91287828f7 | |||
| efd2fc7688 | |||
| 74b5487a28 | |||
| 2882ae29b2 | |||
| 4a7b96c4ca | |||
| 7398e0ea97 | |||
| beaad20795 | |||
| 1bd84db56e | |||
| 6316a45927 | |||
| e298c202af | |||
| 288408e89f | |||
| 53a244d408 | |||
| 8213d0cb50 | |||
| b9868a498e | |||
| df7bdfa7c6 | |||
| f8402e9f82 | |||
| 7eeb654eec | |||
| b558c62953 | |||
| d64dd1943f | |||
| bffa50e31a | |||
| 143cb50986 | |||
| b3ccc438af | |||
| 94513c1a28 | |||
| c9607fdaf2 | |||
| 7c108c1e77 | |||
| 77372d7cdb | |||
| 173f307ec9 | |||
| 2c987b0ffb | |||
| 46a4ac9628 | |||
| c2997f4dd9 | |||
| 0150000d8b | |||
| cad5eb836c | |||
| c82dab6497 | |||
| e6f4e16219 | |||
| d0032f43c7 | |||
| 8a43dd172c | |||
| 11aaefffbf | |||
| c6b36cc207 | |||
| 5856db6f72 | |||
| 3c5e02a54a | |||
| db0c921313 | |||
| 641bc35a50 | |||
| c166803d41 | |||
| 12e1784a99 | |||
| bfabd58106 | |||
| 540845e613 | |||
| 8e7982397c | |||
| 84890ebc0d | |||
| a9f28575b1 | |||
| a730bf47df | |||
| b5ec65cef6 | |||
| 965c12b0f8 | |||
| 7187029ef6 | |||
| 6363bb4b5b | |||
| 58ea5a702d | |||
| 97b988ade8 | |||
| 227234288f | |||
| 05a7b65d43 | |||
| cee6cb859d | |||
| 19c6a4e209 | |||
| b9089a8f9d | |||
| 7a20ed7d70 | |||
| 99588950d2 | |||
| a2129a132f | |||
| 0f1c10bc1c | |||
| 585745de32 | |||
| 65077d262c | |||
| da36c2b8b8 | |||
| 8f01770f29 | |||
| c51b9a7be2 | |||
| 3ffc0a2da2 | |||
| acac25b2eb | |||
| cb0c0c503f | |||
| 215ccc2e10 | |||
| d95cbe23ee | |||
| ac1ffff9db | |||
| c0257aba9b | |||
| 79aa661dd6 | |||
| 18540debf6 | |||
| 7605707c18 | |||
| d48c3b5d4f | |||
| b122cf87df | |||
| 183523d045 | |||
| a4f62bb863 | |||
| 80def4b695 | |||
| 42e18e6c4e | |||
| d8767774c9 | |||
| f67e726be7 | |||
| 41b9a461df | |||
| 037497cb4f | |||
| 3ecb6b1a03 | |||
| 6b92f66ebd | |||
| 070a723ef2 | |||
| d4be29e661 | |||
| 3a3f15f144 | |||
| 3edf8566ed | |||
| a2f00f205a | |||
| 340a8b28f9 | |||
| 83c5753ae1 | |||
| 67bb044a6f | |||
| 9ddfb375cb | |||
| 6fc6a9e80c | |||
| f18fa08aa0 | |||
| aa4ecdb79e | |||
| 8041f6abdd | |||
| 210c77ddb0 | |||
| 24cb345b6c | |||
| 0fdd7550b8 | |||
| f1fb0e5330 | |||
| d4c2f63160 | |||
| b167f3f7a6 | |||
| 63fe7bdd34 | |||
| 270db64243 | |||
| 15fd972417 | |||
| 10d9860457 | |||
| 01eab03dca | |||
| eb50eec85b | |||
| 4faa5af3f8 | |||
| 218e64cc80 | |||
| b82edcca04 | |||
| d8a4949faf | |||
| 22739bebf3 | |||
| fece2c1125 | |||
| 8b55b34d79 | |||
| d1e998bedd | |||
| 2ddb14ae5b | |||
| ae74fbdd4b | |||
| 28769e906f | |||
| 47c21bf73b | |||
| 59fda2dbab | |||
| 43f8eca91b | |||
| 6cb6bd751e | |||
| 58d68cef98 | |||
| 5f3f30fdb4 | |||
| 7a6b2cfe1f | |||
| a8ab9af002 | |||
| ca19b14f13 | |||
| 175f6d4bc5 | |||
| 0206845341 | |||
| a37a9e8a38 | |||
| 577755d580 | |||
| 610812949f | |||
| 82ec515e59 | |||
| d418eed56f | |||
| 244c96151e | |||
| 92298469bf | |||
| bfd54f4f35 | |||
| c5e53ee432 | |||
| 8c9b64c948 | |||
| 171f1ee097 | |||
| be21358db7 | |||
| 5da5fc6499 | |||
| c7aaa85ef6 | |||
| a25e4d794e | |||
| 3c067e5db6 | |||
| 0f924820e8 | |||
| 1f1577e33e | |||
| e1dbb66798 | |||
| 1933b648c3 | |||
| 5cb06f5da2 | |||
| ffa4ed093f | |||
| 4c73a29f99 | |||
| 0195b0da3c | |||
| 27a10c74d1 | |||
| 7893b3ebf6 | |||
| 21d6883139 | |||
| a6569a2930 | |||
| d9d7fb6f9a | |||
| 4108927b28 | |||
| ac5b1bcfab | |||
| c5c1d70aa3 | |||
| 043ec2c8b2 | |||
| 1f296403da | |||
| 35da7bdb44 | |||
| ab21dbad08 | |||
| c32c0d5674 | |||
| e506ccf4e1 | |||
| 0ef971b82b | |||
| b062de1133 | |||
| 3740380a7a | |||
| cb434793d5 | |||
| 9114f80b68 | |||
| ae3cfff380 | |||
| c046419acd | |||
| bd22bed10a | |||
| a0fead1880 | |||
| f7cd9865f4 | |||
| ebe8052d55 | |||
| 6b3c299a50 | |||
| 722778c74a | |||
| 1cd77e2a15 | |||
| 5be9473136 | |||
| 7553b76f15 | |||
| d78eda8aeb | |||
| 061063257a | |||
| 4e43ba544b | |||
| ccded10d86 | |||
| 2433feab09 | |||
| be04aca037 | |||
| 153680a5e6 | |||
| a15d023b45 | |||
| 63b8ae085a | |||
| 1c6e131746 | |||
| 00984781af | |||
| e1fb19f4e1 | |||
| 21cca695e5 | |||
| ba2bac17de | |||
| 5918e2fa9c | |||
| 6d94c92d97 | |||
| 3f0462510e | |||
| 40fa8afce4 | |||
| aac2de9221 | |||
| cbab6fa59f | |||
| b7b2a25953 | |||
| d9b54a524d | |||
| 9008e08171 | |||
| eb0990b37e | |||
| 1fc6de0403 | |||
| b467f2c858 | |||
| e211c09065 | |||
| f88f69e700 | |||
| eda6268d9d | |||
| 668207d59d | |||
| 803b336354 | |||
| 4c154d3cab | |||
| 7ad191c912 | |||
| 70cb81b4b5 | |||
| 6e516b7281 | |||
| aab05c4da9 | |||
| 562747ef41 | |||
| c1d2c36f32 | |||
| e8b9c6d5ff | |||
| b2b195e2cf | |||
| 2c559aa8c8 | |||
| bf90a2ddb6 | |||
| a3f155220b | |||
| 6d4faa6c52 | |||
| d8ecc76d4c | |||
| 05bcc4028d | |||
| 334a294e2a | |||
| 99f7142e3f | |||
| aa54518e2e | |||
| c2dab9c200 | |||
| 609f91e1b4 | |||
| 87e7258c9a | |||
| 134e79c0fd | |||
| 08fb61316d | |||
| 4b89069cab | |||
| 5f2d88f74a | |||
| 53692a79e2 | |||
| b07a7be262 | |||
| 7a42ff16ac | |||
| f848e5081d | |||
| 91a53a36ec | |||
| 1247d2085b | |||
| 90636f66a8 | |||
| c33df5977a | |||
| 6f69b7b752 | |||
| 912d349366 | |||
| 284f98f12a | |||
| 907febd86e | |||
| af7203b839 | |||
| a251d6a6cc | |||
| 449337a544 | |||
| f92f295055 | |||
| 6a4bc3e39f | |||
| 88e0dcfa06 | |||
| bd05b046d0 | |||
| 7e5215b5d4 | |||
| ba946c08dd | |||
| 3eda5144ae | |||
| e68f2f0a5f | |||
| 45d9b0cb2d | |||
| 66b4499973 | |||
| e035477e6a | |||
| 479b4c1b84 | |||
| 05a3f3ad8d | |||
| b67da6c3f8 | |||
| 0485f15998 | |||
| b60a7a2e07 | |||
| e6425ee41f | |||
| 0a17e41755 | |||
| 055c343ce0 | |||
| 3f68ccadd9 | |||
| 4e3227441b | |||
| e56cfb8173 | |||
| 66a5bb7c22 | |||
| 82bcef037d | |||
| 5ddf8245dd | |||
| 3e5aca86d5 | |||
| d7e0776148 | |||
| 416004b1bc | |||
| 2182287d3e | |||
| e3298061d2 | |||
| 9aafa1c6b2 | |||
| b72cca5403 | |||
| d0f13b5beb | |||
| 4504ab8bc2 | |||
| 7730e76c06 | |||
| dbfa049e1e | |||
| 9f05f28727 | |||
| a9da123259 | |||
| 001d676dec | |||
| 061b2c91a0 | |||
| 9ab2c6628b | |||
| 2f980d95ff | |||
| 9857ba077b | |||
| 9a088b8128 | |||
| e4792aaf33 | |||
| b58e19b04c | |||
| 48869a86cc | |||
| a032ce12cb | |||
| ecb351c475 | |||
| b51f067f74 | |||
| 9b3fbc2333 | |||
| ee04046ed7 | |||
| 3cf22a0255 | |||
| 0aec5efb56 | |||
| 5c3cf5f672 | |||
| d1afb29074 | |||
| b2b1ff60dd | |||
| 255d1ad434 | |||
| 5b0448c609 | |||
| 1841b14b21 | |||
| 19fcbeafb4 | |||
| ace7b072f1 | |||
| fd159246ed | |||
| 2516bc0faf | |||
| 3963ff6e3b | |||
| a5b30fd074 | |||
| 35971f9f90 | |||
| 49a2970def | |||
| 665a997f66 | |||
| 5109501d16 | |||
| e27f4b1577 | |||
| f8690cf791 | |||
| f6c07b371f | |||
| 29b12adbaa | |||
| a79c015297 | |||
| 01b65cd201 | |||
| 61fcef1471 | |||
| 34ebad5fff | |||
| 9bd0bd9c3a | |||
| 99733aef2a | |||
| 8a23ce917a | |||
| 6e303d25c4 | |||
| ac1d2d93d6 | |||
| b90260f8d2 | |||
| 258a47435d | |||
| 1503a139e2 | |||
| 3d2dd447af | |||
| abf523698c | |||
| e3400f77c9 | |||
| 9008cf907a | |||
| 720f7ecf48 | |||
| 87caa13363 | |||
| cecee4d02b | |||
| f45bb92917 | |||
| 73ec840279 | |||
| 771db05608 | |||
| e250ff0fb4 | |||
| b4cd58394a | |||
| bda3d81bc9 | |||
| 2b4e714c68 | |||
| 82730830d1 | |||
| f5b0edbebd | |||
| 48874801a3 | |||
| 58b07f586d | |||
| 7cddb1c50e | |||
| a8133a9917 | |||
| bf4b9f5ffb | |||
| 0625990020 | |||
| e116a29795 | |||
| d97f899bee | |||
| 5ce4cada53 | |||
| b87b23087d | |||
| bab902e85b | |||
| 5e64f228b6 | |||
| edad222e6a | |||
| 91172f4f43 | |||
| 3a9fc70f91 | |||
| 30b0e5e250 | |||
| 55f2fe7dd5 | |||
| d109879b6c | |||
| 4af36454ba | |||
| 753cda3d81 | |||
| b054ca4a48 | |||
| 9ef47b82a5 | |||
| 103297cf59 | |||
| 6adf8d18df | |||
| 8e77701358 | |||
| c1246d506c | |||
| af0fac9099 | |||
| 367048c5d1 | |||
| 061af2f25f | |||
| faad0f4bb1 | |||
| c3a639f07d | |||
| bd4f4d0d30 | |||
| 3e0003a1a0 | |||
| 60a69bd653 | |||
| 72da237474 | |||
| d3cb310962 | |||
| d4f73c1d3d | |||
| 3c0ce48cbd | |||
| 8e5c033446 | |||
| f04febaf2d | |||
| b261d336b1 | |||
| 8519a2d705 | |||
| f90125f984 | |||
| 18af8a00f9 | |||
| b7b7c067c6 | |||
| 60fa490b50 | |||
| 605ac0e230 | |||
| 7304c09021 | |||
| 9bcfc5480d | |||
| 022e74ea3d | |||
| 4d5a9c41e0 | |||
| 11886f2149 | |||
| 1dce03af78 | |||
| 3afe8aee18 | |||
| e26fc66523 | |||
| c24ffc9175 | |||
| 228c0b18cb | |||
| b456bc107b | |||
| f25a04c69c | |||
| f8425a5f7b | |||
| dcad6c341b | |||
| 66abad2540 | |||
| e0e1cb3c24 | |||
| df5e9b1211 | |||
| 263fabb0fc | |||
| d1d5e2d52a | |||
| 96b9cf6ca9 | |||
| 3918518779 | |||
| 7e9e8401f7 | |||
| cb72fe1be2 | |||
| f5ced9be38 | |||
| 88560fd910 | |||
| 6de707d8e0 | |||
| 0c1424acb6 | |||
| 0d405fd124 | |||
| 45ed0ba43c | |||
| cd271fca43 | |||
| 3f31a1cf75 | |||
| 4d56b89619 | |||
| f9017ea05d | |||
| ce6194c7c3 | |||
| 8bd0633697 | |||
| db7531be60 | |||
| 94292cad1c | |||
| 8d5662ec7a | |||
| c059f53823 | |||
| 3160ddf0e8 | |||
| ccdd1a9efd | |||
| d956da2fa1 | |||
| 9e4140e549 | |||
| 942c656970 | |||
| 7faf4a6713 | |||
| 41d6f8e9ed | |||
| 0d7ce3eac5 | |||
| e6b708376d | |||
| 8f8fc97b79 | |||
| 27b04036a9 | |||
| 7f91153bba | |||
| 5d6937bab1 | |||
| ef3b70d40a | |||
| ab13e9b5ec | |||
| 5a1bd20864 | |||
| e11a40f809 | |||
| 868d3a4451 | |||
| 569cb91573 | |||
| 32167790b0 | |||
| 20ea69e06b | |||
| b2204ec94e | |||
| de06de11fe | |||
| 07e9f1775b | |||
| d49c067770 | |||
| 89fadb987c | |||
| 037c277351 | |||
| 5e5a8a09cf | |||
| 91560774a0 | |||
| b31c34ed7d | |||
| 7b189d1124 | |||
| bd88bbab4a | |||
| 420f8237c0 | |||
| 897aab9f59 | |||
| a383633630 | |||
| 4a0c2f8879 | |||
| 0e59fc4a15 | |||
| 96b1dc9db4 | |||
| 902938e95f | |||
| 379bc5a8a6 | |||
| cbb90236dc | |||
| 53ed9b282b | |||
| 3d3f8f3219 | |||
| 28a765f32b | |||
| 65655b949f | |||
| c8984d2e30 | |||
| 11330baf77 | |||
| 433b4eff8f | |||
| 2f4453a99c | |||
| 65885d1dfd | |||
| 723f94fd0e | |||
| 2a140addfd | |||
| eb3a3a6de2 | |||
| e12fbd3e2b | |||
| 928f5423af | |||
| 65622bd546 | |||
| 882289b06e | |||
| 12cffc68c8 | |||
| c58f46f056 | |||
| 632c0e7c5e | |||
| 392accd910 | |||
| 8446fd1b26 | |||
| 5f9b2db90b | |||
| 4cef52a86f | |||
| de866a0ff6 | |||
| d684e49462 | |||
| fe1e7f0d6c | |||
| 857faec1f3 | |||
| 5b420e20c7 | |||
| 78c906caaa | |||
| 2ef3a86c4f | |||
| 53cdb9dfeb | |||
| cc238207f9 | |||
| 5330dc48aa | |||
| 4764fa53f0 | |||
| f72c431e8a | |||
| 0dc29cb2d3 | |||
| 5801af9ef5 | |||
| d0393ea109 | |||
| 75c5405d6f | |||
| 3a5af35d37 | |||
| dea5918d66 | |||
| 2136b04b65 | |||
| b4af04ba9d | |||
| f0777d130f | |||
| 1532119787 | |||
| 6c6004a93b | |||
| b90fa49ebc | |||
| bca067abb2 | |||
| 0c6b38b0b5 | |||
| 8800bab8a6 | |||
| ed3cb4217d | |||
| 66aca1e8b3 | |||
| d7f72fbbd4 | |||
| 2676771255 | |||
| 3cf303cabd | |||
| a6d9c90841 | |||
| 0390c2b9fe | |||
| f9736ec3f6 | |||
| 6fe5871e91 | |||
| ecf2d8c5de | |||
| 469e30b507 | |||
| 8a3c56b6d5 | |||
| 680bfbe718 | |||
| d600e35157 | |||
| 101d8381ef | |||
| ae56f3a361 | |||
| de326e5e95 | |||
| 2c2df7f555 | |||
| 2ad2022058 | |||
| 57a503b274 | |||
| 0b8140b50d | |||
| a8ed98255f | |||
| 738d84f75c | |||
| 7f24edc3d5 | |||
| ff4f749adb | |||
| 578e80c1cf | |||
| d9a664a588 | |||
| e9ecf5d716 | |||
| 27be8434f1 | |||
| 3f885d0302 | |||
| 9f9a27a1d8 | |||
| d22a6f9da9 | |||
| 8ccd74b6c8 | |||
| ceb668ac6c | |||
| 68055ba4c9 | |||
| ad5c7aeb31 | |||
| 59d2d35f4a | |||
| 103c1aa82f | |||
| a1e4f4f406 | |||
| fa7472c057 | |||
| bd1b559d47 | |||
| 15df7b11d0 | |||
| 4955a73047 | |||
| 11bb7264a2 | |||
| 853eab8b4c | |||
| 15fe75b1a1 | |||
| dad714710f | |||
| 365737b515 | |||
| 026523d24b | |||
| 2b0655b459 | |||
| f53621a86f | |||
| 42cdfbcd89 | |||
| 9919cc976b | |||
| a45d33a158 | |||
| c0aac20081 | |||
| b0afa0c472 | |||
| 17a1362ed8 | |||
| dd8c18188f | |||
| 159f98728e | |||
| c1f18582e7 | |||
| f8a05da1c9 | |||
| a910ce68ff | |||
| aa216672ae | |||
| 4ddcd35d13 | |||
| 02cc37cc16 | |||
| 03415960ff | |||
| c2707150b1 | |||
| 8ce4037af2 | |||
| 101a5cd8ff | |||
| 8df0403e99 | |||
| 07920fc3df | |||
| 87e327773e | |||
| b28310b051 | |||
| 20d3085dc8 | |||
| 218ee6d24c | |||
| 3f06a92b6b | |||
| 5057c4a69c | |||
| 4cab4a7545 | |||
| 3dbe38e418 | |||
| c5f83686d2 | |||
| 77074c6c87 | |||
| 1e34e2725a | |||
| 7790dedff2 | |||
| 399b388ea5 | |||
| 5af6d917e9 | |||
| ea9eb853fa | |||
| 05360c095c | |||
| 1ed05eceb9 | |||
| 69c4cdf975 | |||
| 3f6cc3f552 | |||
| e21a1c5a61 | |||
| 86906d1b4d | |||
| 6e13cc9eaa | |||
| b25462ddf9 | |||
| e60389283d | |||
| 066b4d542b | |||
| 594596f361 | |||
| bf03d0d56f | |||
| 33252495cf | |||
| a71514222a | |||
| 8464ac90c7 | |||
| ebbf63f4e0 | |||
| e6018afe8b | |||
| b9aeba23ef | |||
| d98da7d240 | |||
| e7c99b2b62 | |||
| 64d6a42dfd | |||
| bf1a95c771 | |||
| f6b56a591c | |||
| 2a19148eed | |||
| 7048f32666 | |||
| b3b5b356d2 | |||
| 7355dff967 | |||
| eb7f8309e2 | |||
| 67ba18f956 | |||
| 12ce250c6c | |||
| e6b0a1d4d7 | |||
| 385298b808 | |||
| 03120b70d0 | |||
| 4d2a398cbc | |||
| 353781021d | |||
| 688dd1a018 | |||
| d34d8764b0 | |||
| 28da6e0d98 | |||
| 4ee6735376 | |||
| ff6abbd369 | |||
| ecda2aee4a | |||
| e2a9bc9c66 | |||
| b5b60cafb7 | |||
| 270fab4fd0 | |||
| f7f0d18e41 | |||
| 386b7507c6 | |||
| 8a1a23af83 | |||
| 580dc8e72a | |||
| 66d2c6698b | |||
| 7f90e3bcf7 | |||
| bc1abe6070 | |||
| 6aa0e62597 | |||
| 52179d8bfb | |||
| ee686188b7 | |||
| 4a98fcb3f7 | |||
| 29ab58c4d8 | |||
| f6d05eaad4 | |||
| 5105793228 | |||
| 689e7b7af2 | |||
| 636e2f0f4c | |||
| 461b488eee | |||
| 6b93f41f3a | |||
| 092241a632 | |||
| 20f4e9023b | |||
| c24bafd644 | |||
| 21b4526063 | |||
| b2ff0b1df0 | |||
| 87d0da2d4c | |||
| ad78b5cdb5 | |||
| de84703c02 | |||
| b67b5ec408 | |||
| 65e88449aa | |||
| 20de98362a | |||
| ea7ff5241d | |||
| ae877e92c7 | |||
| 16305530f2 | |||
| 282de41f06 | |||
| 16eb915c95 | |||
| 0eabef0720 | |||
| 2c9753ad25 | |||
| 81e81ce77c | |||
| 9cecaa769e | |||
| 8c8eca7e05 | |||
| fba8bcc7dc | |||
| fa719ad4c5 | |||
| 63dc53a5ea | |||
| bc7679f9fc | |||
| a6d5d7c8e2 | |||
| 122e4346bb | |||
| c18137d40a | |||
| a827ab88b1 | |||
| 351e72b6e2 | |||
| cbed1c1b4b | |||
| 124837e2c3 | |||
| 753a54096f | |||
| d50881d82b | |||
| f836601e0f | |||
| fbda55f141 | |||
| 10c358718e | |||
| 6f2062fb3a | |||
| f42d4241b4 | |||
| 3576bc4585 | |||
| 47389a0edd | |||
| ab139dffd0 | |||
| a5f3d00977 | |||
| 53b6e1c1b0 | |||
| 65b0a8fcb2 | |||
| 461c200ce6 | |||
| a614430899 | |||
| bc2440ea16 | |||
| 6fb49f1de7 | |||
| 6118d67321 | |||
| cbca6e1acb | |||
| 2c2cf32b8a | |||
| 89755542da | |||
| 051b5f4f4f | |||
| b370969690 | |||
| a1f6eabbce | |||
| 247c46e6ea | |||
| 915ca47cad | |||
| 0d8a020684 | |||
| 1e388a894e | |||
| 4e7752c9ba | |||
| c13e5f9f5b | |||
| 706a09c49e | |||
| c38c09bc35 | |||
| 77bb68b967 | |||
| 212daa1995 | |||
| f7ac7a395c | |||
| 465e84eda4 | |||
| ec577f8e24 | |||
| 26470cc23a | |||
| 296aa96d71 | |||
| a2c3274b8e | |||
| 5e19f2959e | |||
| 5dc59aaa7b | |||
| c9289a4dcf | |||
| 19b4618fb5 | |||
| 4c0744ee54 | |||
| b07d02f1bf | |||
| 69cbadf7e9 | |||
| 0543036ec9 | |||
| 2ff2f0205d | |||
| e22431188b | |||
| b8c0e153e3 | |||
| ff09482653 | |||
| d932c043da | |||
| 0cb7e4dcb3 | |||
| 2e5f1c22f6 | |||
| cf93e7c69e | |||
| 9da980d325 | |||
| 7da13e7ad1 | |||
| a0e40a5610 | |||
| ac5c75690a | |||
| 795a5e02cd | |||
| bb75662a7e | |||
| 23cb161fb3 | |||
| eb1c039a6e | |||
| 4c39f90466 | |||
| d4de1ac346 | |||
| 4880d1d461 | |||
| 5a8aa53232 | |||
| 85b8befbd1 | |||
| 4c4f19ec94 | |||
| 145dcfd0c2 | |||
| 991c982e5b | |||
| 1d6f374970 | |||
| eee72c52da | |||
| b0e3081636 | |||
| 886eb665bf | |||
| 70ee2ee7b1 | |||
| f3f535623f | |||
| 63076d0865 | |||
| fc0a6ce40c | |||
| 88773ae7f1 | |||
| 81b10be1d0 | |||
| 50c5593740 | |||
| af4b22e5b9 | |||
| 6e55c8cd2f | |||
| def90d1016 | |||
| f30b0a86f7 | |||
| 95ad7168bf | |||
| ccb312a974 | |||
| f588ab05fa | |||
| 2dd1134303 | |||
| 0efb9d8023 | |||
| 21fd150894 | |||
| ac9a625ccc | |||
| c31213e5cb | |||
| f82cc6458b | |||
| 8d7df01d73 | |||
| 5303ab68aa | |||
| c91ff130d5 | |||
| 54d0346084 | |||
| 4f926c82bf | |||
| b07b146965 | |||
| cfbc5224e3 | |||
| a0c41a0e03 | |||
| 8fe5151f84 | |||
| 77f8b070cd | |||
| 4f4f3fab7d | |||
| 0444ab236a | |||
| 9ede9fe697 | |||
| 3e98b26b77 | |||
| 0aee6e9f5b | |||
| eddc5b8898 | |||
| 57993d871e | |||
| 3c8a47bd06 | |||
| 7f8c91a52d | |||
| 62f9f477f5 | |||
| 894875ce8d | |||
| 9d1c3fa9ac | |||
| d207c2294d | |||
| e653a9cd03 | |||
| 5675046cb7 | |||
| 20a8039642 | |||
| 4bda92fd8a | |||
| 97adfdd398 | |||
| a5b5df450e | |||
| 80b8fb8b83 | |||
| ef227c5d01 | |||
| 9e5b129ba5 | |||
| 12b30843c5 | |||
| 09f02bc620 | |||
| 3d2611484a | |||
| 6af91773ee | |||
| 9e71af86f8 | |||
| 60ff93e5ac | |||
| f25d2a9416 | |||
| fd4b9cf6a3 | |||
| 1a351db6e0 | |||
| 5b537e9604 | |||
| 6c69f47acf | |||
| 44ef114981 | |||
| 67b342d923 | |||
| 5063c6dd00 | |||
| 8d0bb00188 | |||
| fe59d4a787 | |||
| e65610555e | |||
| 68b4c7df6e | |||
| 103ac0359d | |||
| fff4c77dbe | |||
| b960bd579d | |||
| 5f7f37f1c1 | |||
| 572abbcff9 | |||
| e74b33242b | |||
| b54a099f49 | |||
| c39b529c93 | |||
| 54acebd086 | |||
| 36940c5fc8 | |||
| 6aa05994ae | |||
| d3560706df | |||
| 64f0200675 | |||
| 64fc4c23ea | |||
| 4ae1709313 | |||
| 19cdd558d3 | |||
| 58f63f6142 | |||
| 60ac239091 | |||
| c0f4d9c893 | |||
| ccc7d0f53f | |||
| 87eb3f970e | |||
| db2d323d96 | |||
| 0598eafb84 | |||
| b5e826976c | |||
| 5e1065838b | |||
| a6af91f7b2 | |||
| e8a4ddd3e0 | |||
| 18bd4a8337 | |||
| 97059f4e18 | |||
| 83231997c0 | |||
| 870507cc36 | |||
| 9adb01a4a6 | |||
| b3b4c7aaad | |||
| cdee538129 | |||
| d9112d071b | |||
| f4631b1cb6 | |||
| d075b82372 | |||
| 62eb6cb473 | |||
| 9c35130fdc | |||
| b825e398ae | |||
| 6390e897b8 | |||
| 117b138233 | |||
| 0f65a0f239 | |||
| e1a0625a15 | |||
| 315c16de5f | |||
| 5f781e6266 | |||
| 09998b2434 | |||
| daa45dd424 | |||
| c927e7dc7c | |||
| f23b55dc13 | |||
| 16aa399040 | |||
| 3db5a299bb | |||
| cef44f6d53 | |||
| caaa45c9ef | |||
| 6389097ac1 | |||
| c9975504c6 | |||
| 06cd013b31 | |||
| 99c5a70ce3 | |||
| d87a947ef2 | |||
| 69cb15f27f | |||
| ef024db318 | |||
| bef30a838c | |||
| bfd61d6303 | |||
| 61958b6b3b | |||
| 03e9e4568f | |||
| 63f574e741 | |||
| b670b19429 | |||
| aafe8ef9be | |||
| f0bb45ae28 | |||
| 3322368106 | |||
| 7aec01bbac | |||
| a9386f5c79 | |||
| c5c38c6664 | |||
| 6c0d934b92 | |||
| 81649d5c3b | |||
| b25dc7cc55 | |||
| 3833444778 | |||
| d7b79dc9a9 | |||
| 4778c4b750 | |||
| 0590184557 | |||
| 5279a07673 | |||
| 59360f4f65 | |||
| 5f166f6799 | |||
| 56e119e822 | |||
| 7832381dd2 | |||
| 0f7f749ada | |||
| 82178b8d93 | |||
| 0fd4a45070 | |||
| ac93b81a78 | |||
| 2047b9b6b3 | |||
| 4f0876de39 | |||
| fab29dfee7 | |||
| 0224cbc3de | |||
| 44626054ce | |||
| 4d09809f17 | |||
| ce6f14bd8b | |||
| d96a6914a8 | |||
| 4d897e7ab5 | |||
| 41ecbc6814 | |||
| 6e21c17253 | |||
| 0135a9451a | |||
| 0c6b99e489 | |||
| a44ec9f4f7 | |||
| 5ca1f11ce2 | |||
| 66f708392e | |||
| 4343714c6d | |||
| 644f3065b6 | |||
| 45f79530db | |||
| 4c35697c79 | |||
| e3cdabfaac | |||
| abdc35c893 | |||
| 56d2c9daf5 | |||
| 208c2d9c8b | |||
| 1dbb64580c | |||
| 5f5e7c3262 | |||
| db71811c5a | |||
| df54c8613d | |||
| 2d525901ff | |||
| dcf0244566 | |||
| 83c018a0b4 | |||
| b53ccb3807 | |||
| 8ab9da4461 | |||
| a897e3f01f | |||
| 59b8a139d7 | |||
| 9c44f9252d | |||
| 6070a498fe | |||
| 6b2b5c4c23 | |||
| 2d6ea2f4fe | |||
| fbd797e50b | |||
| 110b032ad9 | |||
| 5fdee47841 | |||
| ee2b1cde82 | |||
| 39f81760f8 | |||
| b32c4cfb8a | |||
| f2fdf9fa6b | |||
| 1cda8cb6fa | |||
| d13f0c8052 | |||
| 0a4a09a09d | |||
| 1bbe93e535 | |||
| b1e2a2ec3c | |||
| 71d7b22d5e | |||
| 1152d51c6f | |||
| ead5df4546 | |||
| 2f840b1097 | |||
| 0968e9fbd0 | |||
| bc37c50972 | |||
| 0c2a710787 | |||
| f614150421 | |||
| 2afb58e74e | |||
| 693a83ba88 | |||
| 1305d6ac11 | |||
| 265b82013d | |||
| 8c791b529b | |||
| 0f75210408 | |||
| dd93a40e7a | |||
| 6fcca3cd93 | |||
| 3339356a55 | |||
| b7f143ae58 | |||
| bcfef8a4e1 | |||
| 975dcd7bbf | |||
| 0a6f2348b8 | |||
| 1b6f3f1f22 | |||
| 081d81e5b0 | |||
| 5abd3b99b9 | |||
| a70bb40b3d | |||
| 8bf2e2459e | |||
| 45448463b8 | |||
| 1896efd048 | |||
| 6ffb750171 | |||
| d9ed1e953e | |||
| 9e642e75b2 | |||
| a6769d60c0 | |||
| 7a792f6c23 | |||
| 95c695eb2f | |||
| 7097a9e965 | |||
| c31f245dc9 | |||
| 88ff3c9a23 | |||
| f82563fb6f | |||
| 4c05eaeb16 | |||
| 1cd0a9750d | |||
| 0cb9271b95 | |||
| 8d5fc2bf91 | |||
| f7952fccc8 | |||
| 23b0f82173 | |||
| 0cc0a9bc2b | |||
| 998aa14981 | |||
| b077d5ba97 | |||
| e4d8651aa9 | |||
| e195c39d3c | |||
| 7cbd9e1d93 | |||
| 1ff99f2569 | |||
| 2e032889ef | |||
| fd3a39dc98 | |||
| 38cf127c8b | |||
| 0ba8375546 | |||
| 5c41e2c6e1 | |||
| 410dd0aa9f | |||
| 1284086ffa | |||
| 543515e36c | |||
| bb3c8e5c87 | |||
| a70f525d4e | |||
| 4ca54fb415 | |||
| 2ef40d2422 | |||
| b9a3d3f392 | |||
| 38f5c7a1d5 | |||
| b56328aa9e | |||
| 4a90266f8e | |||
| 8af7f27942 | |||
| 8bda9cd2bf | |||
| a939c4ea4e | |||
| c270d347cf | |||
| 2ba1dd47b0 | |||
| 431fd5bb22 | |||
| 819f4be08e | |||
| 4ab4fa7042 | |||
| 265084cb6c | |||
| a7a03356f4 | |||
| 4931e8b229 | |||
| b594192425 | |||
| e5d4ffc166 | |||
| f7b0a2c0a2 | |||
| 9ca6003533 | |||
| e328083d11 | |||
| d1b3f57320 | |||
| 75d0f9b95c | |||
| 0fb4af6b59 | |||
| d2f28ccf41 | |||
| bddb38d787 | |||
| f3274624b3 | |||
| 4160fc85f2 | |||
| f6228b91e5 | |||
| f208988563 | |||
| fd1bfeefe4 | |||
| 198911e0d2 | |||
| 776f0490f9 | |||
| 2ec39f5000 | |||
| dc99df2972 | |||
| 7fb19d658b | |||
| 2fef141a00 | |||
| f37d7082a2 | |||
| 39325958bc | |||
| d6f4f4c7b4 | |||
| 943c46b07d | |||
| 8ff801648d | |||
| 5c7c56a6b3 | |||
| b64945988b | |||
| bb93f5967f | |||
| 1c33206042 | |||
| 2153b2fbd5 | |||
| 5f9f69958e | |||
| 0057481a0a | |||
| f52986ea15 | |||
| 1b0c6b848d | |||
| 2764024351 | |||
| 83a7cb9177 | |||
| 086aeb0aac | |||
| b5b1962530 | |||
| 5b87793521 | |||
| 18b5cd101e | |||
| 86475593bb | |||
| 26b3443299 | |||
| 6622c71935 | |||
| c2e1f113f5 | |||
| 77a70f256c | |||
| 56dcd9296a | |||
| cb4bc58dbd | |||
| b963906bd1 | |||
| d016a1cc2f | |||
| c8d65f078b | |||
| d7a8d499be | |||
| 2f539cded9 | |||
| 6635a5d96d | |||
| cb9619f62b | |||
| 59d9f73f46 | |||
| 3cfac84bff | |||
| 1b8a67d5d7 | |||
| dc6c1dc727 | |||
| db6e807421 | |||
| d7a1630381 | |||
| 929665d284 | |||
| 9d2f7934de | |||
| 35354ad520 | |||
| 42c7be4590 | |||
| a0c4d2c13c | |||
| 5f9b444319 | |||
| b497f6ccad | |||
| 63996cbb06 | |||
| 7c6c1c3ad8 | |||
| 14b69148f9 | |||
| b673087a87 | |||
| 541cf2de80 | |||
| 753d0b0c91 | |||
| 027bd24260 | |||
| 4f4732df45 | |||
| 8d4b9c0810 | |||
| 5ce16e01eb | |||
| 143ce57e76 | |||
| e1d5c7310a | |||
| 859f422cbf | |||
| 77f07da49d | |||
| 96de14ef2e | |||
| dd1bbde891 | |||
| 04e08d6952 | |||
| 4c76b48fd6 | |||
| dc1b500430 | |||
| 1e1964a060 | |||
| 2ce5090d00 | |||
| 8334a03e03 | |||
| bc6b707a22 | |||
| 010e72c35a | |||
| ad29a2376d | |||
| 3ffc2ba48d | |||
| 31144591b0 | |||
| 8b0a4921d9 | |||
| 74022861c5 | |||
| 481dd31006 | |||
| 736c7212db | |||
| 93b17042a2 | |||
| e65ba99e23 | |||
| 95ddeff17d | |||
| 085aecd51f | |||
| c4d8f6b3eb | |||
| 5fdc29f152 | |||
| 1d005e12af | |||
| 61f23710eb | |||
| 27e0642543 | |||
| 09a55c8ede | |||
| 231c8337d2 | |||
| 93abbd0ef7 | |||
| 8678652f3e | |||
| 976f920db2 | |||
| f36e8252c8 | |||
| f72769a621 | |||
| abf6a7ee18 | |||
| 33a7bbb485 | |||
| e01c2eafa1 | |||
| f4763a801f | |||
| 11d2921767 | |||
| 0ea5b5ef0b | |||
| ad3fa505f3 | |||
| 1202f67cc8 | |||
| 12892eef98 | |||
| 0d413c7e36 | |||
| 604a9f077d | |||
| fae06dc156 | |||
| 5013664ec5 | |||
| ebd15e3287 | |||
| 0400ccc11f | |||
| d1dfa873b7 | |||
| 95fb766d10 | |||
| e161c93f8d | |||
| 388edd7aaa | |||
| 0a36596468 | |||
| 73a75220a8 | |||
| ac3a1d9132 | |||
| fcfe94139c | |||
| b16e502c16 | |||
| 0b577dd558 | |||
| 4093935275 | |||
| 277d153604 | |||
| cb9e877e4a | |||
| 132bb8a672 | |||
| 126f83959b | |||
| 69124f9392 | |||
| 5165465821 | |||
| d67e655c17 | |||
| fdfbf2a01b | |||
| b7b52fffea | |||
| 7a1c4d23b4 | |||
| b7e37ddb07 | |||
| 1a06b6a0ab | |||
| 81d7f5bc5a | |||
| 666700f7f3 | |||
| cc32399878 | |||
| 541aae12ef | |||
| 73b54f4efe | |||
| c8d6360855 | |||
| d4a21f1db8 | |||
| 0be6473316 | |||
| fbfa67e8a6 | |||
| f6a2e58d95 | |||
| a64f0f1ebe | |||
| 1ac7b95c1d | |||
| dc24944cd9 | |||
| b444220564 | |||
| 57f0a7d94b | |||
| 5e1c00ceb2 | |||
| e664779f3e | |||
| 01ce468ff2 | |||
| dc0613f487 | |||
| 18c63f70c4 | |||
| f751acea12 | |||
| 7e5106d1ac | |||
| a1916ca765 | |||
| d6197b743d | |||
| d54cf0ca37 | |||
| ac490114ae | |||
| 973fb6ce40 | |||
| 9400fb3e78 | |||
| cc0bd730eb | |||
| bc06ffb6b8 | |||
| 5e68cc5a58 | |||
| 34d4e3cbe0 | |||
| fbee526a40 | |||
| 218051464d | |||
| 1cf0c12674 | |||
| 8546e64b03 | |||
| 8259d45583 | |||
| de1d548725 | |||
| 6c89946d42 | |||
| e10161182b | |||
| 89975c8b79 | |||
| 5d2d2bcf39 | |||
| bb97ca32c4 | |||
| 9a2f9ccde4 | |||
| fce0361052 | |||
| da2ddca34c | |||
| 021663b12f | |||
| 1f5568fa81 | |||
| ef50082cad | |||
| be60908d6d | |||
| 35517b62a0 | |||
| 2e9683aa7c | |||
| 12e8f31b38 | |||
| 064b6db666 | |||
| 48e1ed0a24 | |||
| c3044e122c | |||
| 9d354192ef | |||
| e3462aeef3 | |||
| 94eeb99333 | |||
| 7309b11849 | |||
| 44fcc572a7 | |||
| 602118f1a3 | |||
| a6b6ba88dc | |||
| 196000d765 | |||
| 937de9f032 | |||
| 3562858736 | |||
| 5fbd87d939 | |||
| 12a237a459 | |||
| 502c0e9055 | |||
| 38d6b55363 | |||
| c6f3613411 | |||
| 6653f25e81 | |||
| 5a158fb76f | |||
| d9aab1079c | |||
| 692b1ef636 | |||
| 4024b67926 | |||
| 2cb6e21161 | |||
| f49a8d2e3e | |||
| af674bfac4 | |||
| 5716360936 | |||
| b896457586 | |||
| 3b9605bc57 | |||
| 4375b9c89a | |||
| 4efa91d2f0 | |||
| a9d4a58294 | |||
| 46cd083976 | |||
| a300aa19b6 | |||
| 34a75c1ae6 | |||
| ab5e4a4ff3 | |||
| 856fefeaad | |||
| b41e3956bc | |||
| ee5330801d | |||
| a741410421 | |||
| eb0b4f0cbd | |||
| f2477c4bf5 | |||
| da5432fbf5 | |||
| 7b561c76fe | |||
| 6c66406f7f | |||
| 08f9f8b8fb | |||
| 3bfbcd7276 | |||
| d85dc01e28 | |||
| 211e36c249 | |||
| 7ac0e2ba02 | |||
| 66939ded0f | |||
| 17887d24a1 | |||
| 7519162e65 | |||
| 3f65721ba8 | |||
| 222ae33666 | |||
| 35472300ae | |||
| 35d4d7bbac | |||
| efb2647978 | |||
| 534f8a4705 | |||
| aac9107f6b | |||
| 4877a0412c | |||
| 95ad3c923a | |||
| 5008f7fdec | |||
| ef02feed55 | |||
| a0b71d867f |
+12
@@ -0,0 +1,12 @@
|
||||
.springBeans
|
||||
.DS_Store
|
||||
target
|
||||
integration-repo
|
||||
ivy-cache
|
||||
jmx.log
|
||||
jxl.log
|
||||
jmx.log
|
||||
org.springframework.jdbc/derby.log
|
||||
org.springframework.spring-parent/.classpath
|
||||
org.springframework.spring-parent/.project
|
||||
org.springframework.test/test-output/
|
||||
@@ -1,10 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="build-spring-framework" default="precommit">
|
||||
|
||||
<path id="bundles">
|
||||
<path id="unit.test.bundles">
|
||||
<pathelement location="../org.springframework.instrument"/>
|
||||
<pathelement location="../org.springframework.instrument.tomcat"/>
|
||||
<pathelement location="../org.springframework.asm"/>
|
||||
<pathelement location="../org.springframework.core"/>
|
||||
<pathelement location="../org.springframework.expression"/>
|
||||
<pathelement location="../org.springframework.beans"/>
|
||||
@@ -13,17 +12,23 @@
|
||||
<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.aspects"/>
|
||||
<pathelement location="../org.springframework.web.servlet"/>
|
||||
<pathelement location="../org.springframework.web.portlet"/>
|
||||
<pathelement location="../org.springframework.test"/>
|
||||
<pathelement location="../org.springframework.web.struts"/>
|
||||
<pathelement location="../org.springframework.spring-library"/>
|
||||
</path>
|
||||
|
||||
<path id="bundles">
|
||||
<pathelement location="../org.springframework.spring-parent"/>
|
||||
<pathelement location="../org.springframework.asm"/>
|
||||
<path refid="unit.test.bundles" />
|
||||
<pathelement location="../org.springframework.integration-tests"/>
|
||||
<pathelement location="../org.springframework.spring-library"/>
|
||||
</path>
|
||||
|
||||
<property file="${basedir}/../build.properties"/>
|
||||
@@ -32,7 +37,7 @@
|
||||
<import file="${basedir}/publish-documentation.xml"/>
|
||||
<import file="${basedir}/../spring-build/multi-bundle/default.xml"/>
|
||||
|
||||
<target name="precommit" depends="clean,clean-integration,test"/>
|
||||
<target name="precommit" depends="clean, clean-integration, test"/>
|
||||
|
||||
<presetdef name="javadoc.links">
|
||||
<javadoc>
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
<?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.tomcat"/>
|
||||
<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.web.struts"/>
|
||||
</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="<version>.*?</version>"
|
||||
replace="<version>@project-version@</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>
|
||||
@@ -1,8 +1,6 @@
|
||||
<?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/>
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
<?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>
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
<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>
|
||||
@@ -56,19 +55,19 @@
|
||||
<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>
|
||||
<zipfileset dir="${package.dir}"/>
|
||||
</zip>
|
||||
|
||||
<!--zip destfile="${artifacts.dir}/${package.basename}-with-dependencies.zip">
|
||||
<zipfileset dir="${package.dir}"/>
|
||||
</zip-->
|
||||
<zip destfile="${artifacts.dir}/${package.basename}-dependencies.zip">
|
||||
<zipfileset dir="${basedir}/../ivy-cache/repository">
|
||||
<exclude name="org.apache.velocity/org.apache.velocity.docbookframework.dist/**"/>
|
||||
</zipfileset>
|
||||
</zip>
|
||||
|
||||
</target>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
<?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">
|
||||
|
||||
<!--
|
||||
|
||||
This POM cannot be used to build Spring; it is a work in progress and should only be used as
|
||||
part of a Maven repository upload bundle using artifacts created by the spring build system.
|
||||
|
||||
-->
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>3.0.0.BUILD-SNAPSHOT</version>
|
||||
<name>Spring Framework</name>
|
||||
<description>Spring is a layered Java/J2EE application platform, based on code published in Expert
|
||||
One-on-One J2EE Design and Development by Rod Johnson (Wrox, 2002). </description>
|
||||
<url>http://www.springframework.org</url>
|
||||
<issueManagement>
|
||||
<system>JIRA</system>
|
||||
<url>http://jira.springframework.org/browse/SPR</url>
|
||||
</issueManagement>
|
||||
<ciManagement>
|
||||
<system>Bamboo</system>
|
||||
<url>https://build.springframework.org/browse/SPR</url>
|
||||
</ciManagement>
|
||||
<inceptionYear>2003</inceptionYear>
|
||||
<organization>
|
||||
<name>SpringSource</name>
|
||||
<url>http://www.springsource.com</url>
|
||||
</organization>
|
||||
<licenses>
|
||||
<license>
|
||||
<name>The Apache Software License, Version 2.0</name>
|
||||
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
</licenses>
|
||||
<scm>
|
||||
<url>https://fisheye.springframework.org/browse/spring-framework</url>
|
||||
<connection>scm:svn:https://src.springframework.org/svn/spring-framework/trunk</connection>
|
||||
<developerConnection>scm:svn:https://src.springframework.org/svn/spring-framework/trunk</developerConnection>
|
||||
</scm>
|
||||
<mailingLists>
|
||||
<mailingList>
|
||||
<name> Spring Forum
|
||||
</name>
|
||||
<post>http://forum.springframework.org</post>
|
||||
<archive>http://forum.springframework.org</archive>
|
||||
</mailingList>
|
||||
</mailingLists>
|
||||
|
||||
<modules>
|
||||
<module>../org.springframework.spring-parent</module>
|
||||
<module>../org.springframework.instrument</module>
|
||||
<module>../org.springframework.instrument.tomcat</module>
|
||||
<module>../org.springframework.asm</module>
|
||||
<module>../org.springframework.core</module>
|
||||
<module>../org.springframework.expression</module>
|
||||
<module>../org.springframework.beans</module>
|
||||
<module>../org.springframework.aop</module>
|
||||
<module>../org.springframework.context</module>
|
||||
<module>../org.springframework.transaction</module>
|
||||
<module>../org.springframework.oxm</module>
|
||||
<module>../org.springframework.jms</module>
|
||||
<module>../org.springframework.aspects</module>
|
||||
<module>../org.springframework.jdbc</module>
|
||||
<module>../org.springframework.web</module>
|
||||
<module>../org.springframework.orm</module>
|
||||
<module>../org.springframework.context.support</module>
|
||||
<module>../org.springframework.web.servlet</module>
|
||||
<module>../org.springframework.web.portlet</module>
|
||||
<module>../org.springframework.test</module>
|
||||
<module>../org.springframework.web.struts</module>
|
||||
</modules>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>staging</id>
|
||||
<distributionManagement>
|
||||
<site>
|
||||
<id>staging</id>
|
||||
<url>file:///${user.dir}/target/staging</url>
|
||||
</site>
|
||||
<repository>
|
||||
<id>staging</id>
|
||||
<url>file:///${user.dir}/target/staging</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>staging</id>
|
||||
<url>file:///${user.dir}/target/staging</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -3,10 +3,10 @@
|
||||
|
||||
<!-- Main targets -->
|
||||
<target name="publish-documentation" depends="publish-documentation.init">
|
||||
<sshexec host="spring02.managed.contegix.com" username="${username}" keyfile="${key.file}" passphrase="${passphrase}"
|
||||
<sshexec host="static.springsource.org" username="${username}" keyfile="${key.file}" passphrase="${passphrase}"
|
||||
command="mkdir /opt/www/domains/springframework.org/www/htdocs/spring/docs/${bundle.version}"/>
|
||||
|
||||
<scp remoteToDir="${username}@spring02.managed.contegix.com:/opt/www/domains/springframework.org/www/htdocs/spring/docs/${bundle.version}"
|
||||
<scp remoteToDir="${username}@static.springsource.org:/opt/www/domains/springframework.org/www/htdocs/spring/docs/${bundle.version}"
|
||||
keyfile="${key.file}" passphrase="${passphrase}" sftp="true" verbose="true">
|
||||
<fileset dir="${package.output.dir}">
|
||||
<include name="changelog.txt" />
|
||||
@@ -16,7 +16,7 @@
|
||||
<fileset dir="${package.docs.dir}" />
|
||||
</scp>
|
||||
|
||||
<sshexec host="spring02.managed.contegix.com" username="${username}" keyfile="${key.file}" passphrase="${passphrase}"
|
||||
<sshexec host="static.springsource.org" username="${username}" keyfile="${key.file}" passphrase="${passphrase}"
|
||||
command="rm /opt/www/domains/springframework.org/www/htdocs/spring/docs/3.0.x ; ln -s /opt/www/domains/springframework.org/www/htdocs/spring/docs/${bundle.version} /opt/www/domains/springframework.org/www/htdocs/spring/docs/3.0.x"/>
|
||||
</target>
|
||||
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
<?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>
|
||||
@@ -7,7 +7,7 @@
|
||||
<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"/-->
|
||||
<checksum file="${artifacts.dir}/${package.basename}-dependencies.zip" algorithm="sha1"/>
|
||||
|
||||
<aws:s3 accessKey="${accessKey}" secretKey="${secretKey}">
|
||||
<upload bucketName="dist.${bucket.basename}" file="${package.output.file}"
|
||||
@@ -30,15 +30,15 @@
|
||||
<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">
|
||||
<upload bucketName="dist.${bucket.basename}" file="${artifacts.dir}/${package.basename}-dependencies.zip"
|
||||
toFile="${adjusted.release.type}/${project.key}/${package.basename}-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"/>
|
||||
<metadata name="package.file.name" value="${package.basename}-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"/-->
|
||||
<upload bucketName="dist.${bucket.basename}" file="${artifacts.dir}/${package.basename}-dependencies.zip.sha1"
|
||||
toFile="${adjusted.release.type}/${project.key}/${package.basename}-dependencies.zip.sha1" publicRead="true"/>
|
||||
</aws:s3>
|
||||
</target>
|
||||
</project>
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
<?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.tomcat"/>
|
||||
<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.web.struts"/>
|
||||
</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>
|
||||
@@ -3,6 +3,408 @@ SPRING FRAMEWORK CHANGELOG
|
||||
http://www.springsource.org
|
||||
|
||||
|
||||
Changes in version 3.0.7 (2011-12-22)
|
||||
-------------------------------------
|
||||
|
||||
* fixed GenericTypeResolver to consistently return null if not resolvable
|
||||
* added proper "contentLength()" implementation to ByteArrayResource
|
||||
* refined Resource "exists()" check for HTTP URLs to always return false for 404 status
|
||||
* LocaleEditor and StringToLocaleConverter do not restrict variant part through validation
|
||||
* LinkedCaseInsensitiveMap overrides putAll method as well (for IBM JDK 1.6 compatibility)
|
||||
* ConversionService prevents Converter from trying to convert to a subtype of its actual target type
|
||||
* ConversionService is able to work with "Collections.emptyList()" as target type (again)
|
||||
* CollectionCollection/MapToMapConverter preserve original Collection/Map if no converted elements
|
||||
* fixed nested element conversion with a DataBinder + ConversionService + PropertyEditor
|
||||
* restored DataBinder's ability to bind to an auto-growing List with unknown element type
|
||||
* optimized DefaultListableBeanFactory's PropertyDescriptor caching for concurrent access
|
||||
* context:property-placeholder's "file-encoding" attribute value is being applied correctly
|
||||
* SpringValidatorAdapter accepts non-indexed set paths (for Hibernate Validator compatibility)
|
||||
* fixed AbstractAsyncExecutionAspect's setExecutor method to correctly wrap in a TaskExecutorAdapter
|
||||
* @Transactional qualifiers match against transaction manager definitions in parent contexts as well
|
||||
* TransactionSynchronizationManager eagerly cleans up void ResourceHolders on any access
|
||||
* updated H2 error codes in sql-error-codes.xml
|
||||
* fixed NamedParameterJdbcTemplate to use correct maximum type for queryForInt/Long
|
||||
* SimpleJdbcTestUtils executeSqlScript properly closes its LineNumberReader after use
|
||||
* Hibernate synchronization properly unbinds Session even in case of afterCompletion exception
|
||||
* JDO PersistenceManager synchronization performs close attempt after completion (if necessary)
|
||||
* JPA EntityManagerFactoryUtils silently ignores IllegalArgumentExceptions from setHint calls
|
||||
* added "forwarder" property to ConnectorServerFactoryBean, accepting an MBeanServerForwarder
|
||||
* JmsInvokerClientInterceptor/FactoryBean always uses createConnection/createSession when on JMS 1.1
|
||||
* RmiClientInterceptor detects nested SocketException as connect failure as well
|
||||
* Servlet/PortletContextResource's getFile prefers "file:" URL resolution over calling getRealPath
|
||||
* Portlet session mutex uses global session attribute to be shared among all portlets in the session
|
||||
* fixed ServletServerHttpRequest to reconstruct from "request.getParameterMap()" for form POST only
|
||||
* fixed @RequestMapping header matching to correctly process negated header conditions
|
||||
* added "getObjectMapper()" accessor to MappingJacksonHttpMessageConverter
|
||||
* ResourceHttpRequestHandler sends content without content-type header if no media type found
|
||||
* AbstractCachingViewResolver allows for caching unresolved view names ("cacheUnresolved"=true)
|
||||
* fixed "formMultiSelect"/"formCheckboxes" FreeMarker macros to compare against actual field value
|
||||
|
||||
|
||||
Changes in version 3.0.6 (2011-08-18)
|
||||
-------------------------------------
|
||||
|
||||
* fixed aspects bundle to declare dependencies for @Async aspect as well
|
||||
* ProxyCreationContext uses "ThreadLocal.remove()" over "ThreadLocal.set(null)" as well
|
||||
* DefaultListableBeanFactory is only deserializable through a SerializedBeanFactoryReference
|
||||
* DefaultListableBeanFactory's getBean(name, type) attempts type conversion if necessary
|
||||
* DefaultListableBeanFactory allows for init methods to register further bean definitions (again)
|
||||
* XmlBeanDefinitionReader accepts description subelement within map entry as well (as per the XSD)
|
||||
* ConfigurationClassPostProcessor supports use of same processor instance with several factories
|
||||
* fixed potential InjectionMetadata NPE when using SpringBeanAutowiringInterceptor
|
||||
* SpringBeanAutowiringSupport is able to process @Value annotations on any given target instance
|
||||
* overridden @PersistenceContext annotations on subclass methods are being processed correctly
|
||||
* BeanDefinitionVisitor now actually visits factory method names
|
||||
* restored support for String-to-ContextResource conversion
|
||||
* restored original GenericConversionService behavior with respect to empty collections/maps
|
||||
* restored original FormattingConversionService behavior with respect to the use of subtypes
|
||||
* added "formatters" property to FormattingConversionServiceFactoryBean
|
||||
* collection/array conversion returns original collection if possible (instead of first element)
|
||||
* fixed collection element resolution when using a ConversionService with a DataBinder
|
||||
* DataBinder uses a default limit of 256 for array/collection auto-growing
|
||||
* added "autoGrowNestedPaths" property to ConfigurableWebBindingInitializer
|
||||
* Servlet/PortletRequestDataBinder perform unwrapping for MultipartRequest as well
|
||||
* fixed AbstractBindingResult to avoid NPE in "hashCode()" if target is null
|
||||
* fixed several HttpHeaders issues (charset handling, quoting/unquoting)
|
||||
* SimpleClientHttpRequest uses fixed-length streaming mode (always sets content-length header)
|
||||
* added "connectTimeout" and "readTimeout" properties to Simple/CommonsClientHttpRequestFactory
|
||||
* explicit status code in RedirectView respected in HTTP 1.0 compatibility mode
|
||||
* FormHttpMessageConverter correctly processes POST requests
|
||||
* ResourceHttpRequestHandler does not set Content-Length header for 304 response
|
||||
* ResourceHttpRequestHandler detects invalid directory traversal in given path
|
||||
* LocaleChangeInterceptor validates locale values in order to prevent XSS vulnerability
|
||||
* HtmlUtils properly escapes single quotes as well
|
||||
* added support for web.xml context-param "springJspExpressionSupport" (explicit "true"/"false")
|
||||
* ContextLoader and FrameworkServlet support "contextId" parameter for custom serialization id
|
||||
* RemoteExporter uses an opaque proxy for 'serviceInterface' (no AOP interfaces exposed)
|
||||
* added "acceptProxyClasses" flag to RemoteInvocationSerializingExporter
|
||||
* refined WebLogic RMI descriptor to only mark 'getTargetInterfaceName' method as idempotent
|
||||
* EhCacheManagerFactoryBean properly closes "ehcache.xml" input stream, if any
|
||||
* revised JMS CachedConnectionFactory to avoid unnecessary rollback calls on Session return
|
||||
* fixed JMS CachedConnectionFactory to fully synchronize its Session list
|
||||
* fixed NamedParameterJdbcTemplate's handling of arrays as query parameters
|
||||
* fixed JPA 2.0 timeout hints to correctly specify milliseconds
|
||||
* updated Quartz package to support Quartz 1.8 as well (note: not supporting Quartz 2.0 yet)
|
||||
* fixed @Rule execution order in SpringJUnit4ClassRunner to match standard JUnit 4 behavior
|
||||
|
||||
|
||||
Changes in version 3.0.5 (2010-10-20)
|
||||
-------------------------------------
|
||||
|
||||
* support for Hibernate 3.6 final
|
||||
* added core serializer abstraction with default implementations using Java Serialization
|
||||
* consistent use of JDK 1.5's "ThreadLocal.remove()" over "ThreadLocal.set(null)"
|
||||
* fixed JodaTimeContextHolder to use a non-inheritable ThreadLocal and expose a reset method
|
||||
* revised "ClassUtils.isAssignable" semantics to cover primitives vs wrappers in both directions
|
||||
* optimized AnnotationUtils findAnnotation performance for repeated search on same interfaces
|
||||
* ConversionService protects itself against infinite recursion in ObjectToCollectionConverter
|
||||
* fixed TypeDescriptor to correctly resolve nested collections and their element types
|
||||
* BeanWrapper does not attempt to populate Map values on access (just auto-grows Map itself)
|
||||
* fixed Autowired/CommonAnnotationBeanPostProcessor to prevent race condition in skipping check
|
||||
* fixed @Value injection to correctly cache temporary null results for non-singleton beans
|
||||
* ApplicationContext registers context-specific ClassArrayEditor for its bean ClassLoader
|
||||
* refined ApplicationContext singleton processing to not fail for manually registered null instances
|
||||
* fixed ApplicationContext event processing for repeated invocations to non-singleton listener beans
|
||||
* optimized @Bean error messages for static factory methods as well as for argument type mismatches
|
||||
* modified expression parsing to pass full TypeDescriptor context through to ConversionService calls
|
||||
* adapted expression parser's Constructor/MethodResolver to accept TypeDescriptors instead of raw types
|
||||
* SpEL supports projection on any kind of Collection (not just on Lists and arrays)
|
||||
* SpEL MapAccessor consistently rejects "target.key" style access to Maps if no such key is found
|
||||
* SpEL method invocations prefer method with fewest parameters (e.g. no-arg over vararg)
|
||||
* AspectJExpressionPointcut uses bean ClassLoader for initializing the AspectJ pointcut parser
|
||||
* added AnnotationAsyncExecutionAspect as AspectJ-based variant of @Async processing
|
||||
* added mode="proxy"/"aspectj" and proxy-target-class options to task:annotation-driven
|
||||
* JDBC bundle uses local ClassLoader as bean ClassLoader for "sql-error-codes.xml" parsing
|
||||
* EmbeddedDatabaseFactory shuts down database when failing to populate it in "initDatabase()"
|
||||
* embedded database support now also works with Derby >= 10.6
|
||||
* "jdbc:embedded-database" uses id as database name to allow multiple ones in parallel
|
||||
* ResourceDatabasePopulator throws descriptive ScriptStatementFailedException with resource details
|
||||
* added configurable Connection/Statement/ResultSet target types to Jdbc4NativeJdbcExtractor
|
||||
* added OracleJdbc4NativeJdbcExtractor with pre-configured Oracle JDBC API types
|
||||
* DefaultLobHandler's "wrapAsLob" mode works with PostgreSQL's "getAsciiStream()" requirement
|
||||
* ResultSetWrappingSqlRowSet (as used by JdbcTemplate's "queryForRowSet") supports column labels now
|
||||
* LocalSessionFactoryBean's "entityCacheStrategies" works with region names on Hibernate 3.6 as well
|
||||
* fixed DefaultMessageListenerContainer's no-message-received commit to work without Session caching
|
||||
* DefaultMessageListenerContainer's skips no-message-received commit on Tibco (avoiding a deadlock)
|
||||
* JaxWsPortClientInterceptor does not fall back to annotation-specified name as portName anymore
|
||||
* UriTemplate is serializable now
|
||||
* fixed AnnotationMethodHandlerAdapter's caching to avoid concurrency issues in RequestMappingInfo
|
||||
* fixed @MVC processing of parameter-level annotations to work with interface-based proxies again
|
||||
* revised @RequestParam processing to support CSV-to-array/collection binding with ConversionService
|
||||
* fixed EvalTag's EvaluationContext caching to properly handle JSP tag caching across requests
|
||||
* AbstractJasperReportsView only sets locale model attributes if not present already
|
||||
* DispatcherPortlet throws custom NoHandlerFoundException instead of misleading UnavailableException
|
||||
* DispatcherPortlet copies all action parameters to render parameters in case of an action exception
|
||||
* DispatcherPortlet's default resource serving explicitly prevents access to WEB-INF and META-INF
|
||||
* Portlet @ExceptionHandler methods allow for writing the response directly (like in the Servlet case)
|
||||
* MockHttpServletRequest/HttpSession/etc returns independent Enumeration from "getAttributeNames()"
|
||||
|
||||
|
||||
Changes in version 3.0.4 (2010-08-19)
|
||||
-------------------------------------
|
||||
|
||||
* support for Hibernate Core 3.6, Hibernate Validator 4.1, EclipseLink 2.1, EHCache 2.2
|
||||
* OSGi manifest version range accepts EHCache 2.x as well
|
||||
* added "contentLength()" method to Resource abstraction
|
||||
* URL-based Resource variants introspect "last-modified" and "content-length" response headers
|
||||
* refined "exists()" check for UrlResource (HEAD request) and ClassPathResource (URL resolution)
|
||||
* ConversionService is able to deal with empty collections and nested collections (fixed regression)
|
||||
* ConversionService properly handles nested Resource arrays in Map values (fixed regression)
|
||||
* ConversionService does not accidentally use copy constructor for same type
|
||||
* fixed double ConversionFailedException nesting for ObjectToObjectConverter invocations
|
||||
* BeanWrapper preserves annotation information for individual array/list/map elements
|
||||
* Spring's constructor resolution consistently finds non-public multi-arg constructors
|
||||
* revised constructor argument caching, avoiding a race condition for converted argument values
|
||||
* SpEL passes full collection type context (generics, annotations) to ConversionService
|
||||
* SpEL 'select last' operator now works consistently with maps
|
||||
* BeanWrapper/DataBinder's "autoGrowNestedPaths" works for Maps as well
|
||||
* fixed concurrency issue in TypedStringValue, showing for nested typed Maps in prototype beans
|
||||
* fixed WeakReferenceMonitor to never stop its monitoring thread if an entry has been registered
|
||||
* fixed CronTrigger to correctly parse month parts expressed as numbers (1-12 instead of 0-11)
|
||||
* TaskExecutorFactoryBean (as used by task:executor) exposes full ThreadPoolTaskExecutor type
|
||||
* JmsResourceHolder does not ignore IllegalStateException from locally synchronized transaction
|
||||
* fixed JMS CachingConnectionFactory to correctly cache a producer without fixed destination as well
|
||||
* DefaultMessageListenerContainer triggers Session commit even if no message has been received
|
||||
* DefaultMessageListenerContainer supports client id setting even for non-shared Connections
|
||||
* Spring's MessageEndpointFactory classes are now JCA 1.6 compliant as well
|
||||
* AbstractJaxWsServiceExporter supports "bindingType" bean property, overriding @BindingType
|
||||
* AbstractJaxWsServiceExporter supports "webServiceFeatures" bean property on JAX-WS 2.2
|
||||
* JaxWsPortProxyFactoryBean takes "wsdlDocumentUrl", "namespaceUri" etc defaults from @WebService
|
||||
* Jaxb2Marshaller's "marshallerProperties" Map accepts any value type
|
||||
* SpringTemplateLoader for FreeMarker supports last-modified timestamp through Resource abstraction
|
||||
* HibernateJpaDialect correctly closes borrowed connections even for nested JDBC executions
|
||||
* DefaultJdoDialect supports JDO 3.0 query timeout facility (as supported by DataNucleus 2.1)
|
||||
* transaction names based on method id from most specific method (target class instead of interface)
|
||||
* added "validationMessageSource" to LocalValidatorFactoryBean, for Spring-based validation messages
|
||||
* Spring field error arguments include actually declared annotation attributes in alphabetical order
|
||||
* JSR-303 Pattern message resolvable through Spring MessageSource (despite special characters)
|
||||
* DispatcherServlet applies default view name translation to error views as well
|
||||
* mvc:annotation-driven reliably detects JSR-303 and JAXB2 in an OSGi environment as well
|
||||
* revised @MVC handler method resolution with respect to handler methods on generic interfaces
|
||||
* @MVC handler methods reliably resolve MultipartRequest arguments with HiddenHttpMethodFilter
|
||||
* WebDataBinder and @MVC request params detect and introspect MultipartFile arrays as well
|
||||
* fixed @PathVariable regression in combination with ConversionService usage on DataBinder
|
||||
* @CookieValue returns decoded cookie value in a Servlet environment (analogous to @RequestParam)
|
||||
* MVC HandlerExceptionResolvers prevent caching for exception views if preventResponseCaching=true
|
||||
* @ExceptionHandler works for inherited method and CGLIB proxies on Portlet controllers as well
|
||||
* Portlet @MVC's implicit render model will be updated at the end of the event phase
|
||||
* Portlet AbstractController consistently uses session mutex if "synchronizeOnSession" is active
|
||||
* PortletWrappingController supports Portlet 2.0 resource and event requests as well
|
||||
* fixed JSP EvalTag to render null result as empty String instead of "null" String
|
||||
* JSP EvalTag resolves "@myBeanName" references in expressions against the WebApplicationContext
|
||||
* added support for static resource serving: ResourceHttpRequestHandler, mvc:resources
|
||||
* revised DispatcherServlet's last-modified handling to properly work with scoped controllers
|
||||
* MockMultipartHttpServletRequest pre-defines method "POST" and content type "multipart/form-data"
|
||||
|
||||
|
||||
Changes in version 3.0.3 (2010-06-15)
|
||||
-------------------------------------
|
||||
|
||||
* Spring autodetects JodaTime 1.3 or higher (as required), ignoring older JodaTime versions
|
||||
* clarified that Spring's Jackson support requires Jackson 1.3 or higher
|
||||
* JPA 2.0 support tested and supported with Hibernate 3.5.2 and OpenJPA 2.0.0 GA as well
|
||||
* revised VFS support for Spring's component scanning to work on JBoss AS 6.0.0 M3 as well
|
||||
* fixed URIEditor's URI construction to consider fragment as well
|
||||
* added default InputSourceEditor for SAX InputSource construction with a URL String as system id
|
||||
* CachedIntrospectionResults only caches GenericTypeAwarePropertyDescriptors if fully safe
|
||||
* revised BeanWrapper's exception wrapping to consistently handle ConversionExceptions
|
||||
* DefaultListableBeanFactory checks for alias circle on registerAlias (avoiding endless loop)
|
||||
* ConversionService is able to apply Converters to interface-based array elements
|
||||
* ConversionService fully supports conversion from String to MediaType now (through 'valueOf')
|
||||
* revised exception handling in ObjectToObjectConverter, avoiding InvocationTargetExceptions
|
||||
* a context ConversionService is able to override an ApplicationContext's resource editors
|
||||
* refined LifecycleProcessor exception handling, properly wrapping a start exception from a bean
|
||||
* revised DefaultLifecycleProcessor's handling of circular dependencies to avoid stack overflow
|
||||
* fixed constructor argument caching for prototypes with multiple constructor matches
|
||||
* specific detection of CGLIB subclasses in order to properly handle CGLIB interfaces
|
||||
* registerDependentBean resolves to the canonical bean name in order to handle alias references
|
||||
* fixed registerResolvableDependency mechanism to correctly handle non-serializable factory objects
|
||||
* added "expose-proxy" attribute to aop namespace (enforcing AopContext proxy exposure with CGLIB)
|
||||
* revised AbstractInterceptorDrivenBeanDefinitionDecorator for further alignment with auto-proxying
|
||||
* BeanDefinitionVisitor/PropertyPlaceholderConfigurer finds and resolves values in arrays as well
|
||||
* property placeholders can deal with nested expressions which happen to use the same suffix
|
||||
* SpEL's Elvis operator is able to deal with #{${myProp}?:defaultValue} case if myProp is empty
|
||||
* introduced EmbeddedValueResolverAware callback interface for convenient placeholder resolution
|
||||
* @Transactional qualifier value matches against @Qualifier annotations on @Bean methods as well
|
||||
* setTransactionIsolation on JDBC Connection only called when actually necessary (for PostgreSQL)
|
||||
* added limit for parsed SQL cache to NamedParameterJdbcTemplate (default is 256; configurable)
|
||||
* CachingConnectionFactory detects destination equality for WebSphere MQ as well (using toString)
|
||||
* DefaultPersistenceUnitManager's getPersistenceUnitInfo method has 2.5 compatible signature again
|
||||
* DefaultMessageListenerContainer reacts to maxConcurrentConsumers reduction for long-lived tasks
|
||||
* added "idleConsumerLimit" bean property to DefaultMessageListenerContainer (default is 1)
|
||||
* AsyncAnnotationBeanPostProcessor consistently adds @Async processing as first Advisor in the chain
|
||||
* ScheduledTaskRegistrar (as used for @Scheduled processing) properly shuts down its default executor
|
||||
* CronTrigger defensively protects itself against accidental re-fires if a task runs too early
|
||||
* MailSendException includes all messages as failed messages in case of a connect failure
|
||||
* added support for JAX-WS 2.1 WebServiceFeatures to JaxWsPortClientInterceptor/PortProxyFactoryBean
|
||||
* added XmlAwareFormHttpMessageConverter, taking over the 3.0.2-introduced XML multipart support
|
||||
* ServletContextResourcePatternResolver handles "/WEB-INF/lib/*.jar!/**/context.xml" style patterns
|
||||
* fixed MVC mapping regression for servlet url-pattern "/" case on servers other than WebSphere
|
||||
* MVC mappings properly apply even to welcome file entries that forward to a DispatcherServlet
|
||||
* fixed @ExceptionHandler resolution in case of multiple matches at different inheritance levels
|
||||
* revised Portlet SessionStatus.setComplete() to avoid re-exposure of attributes in render phase
|
||||
* shortened Portlet MVC's implicit model render parameter name to "implicitModel"
|
||||
* added convenient "checkRefresh" bean property to TilesConfigurer
|
||||
* TilesConfigurer's "definitionsFactoryClass" property applies common Tiles DefinitionsFactory setup
|
||||
* JSP FormTag calculates proper default form action even when using a rewrite filter on WebSphere
|
||||
* JSP HiddenInputTag allows for using common HTML attributes (equivalent to LabelTag)
|
||||
* fixed JSP ErrorsTag to avoid invalid "*.errors" id, using form object name as id prefix instead
|
||||
* fixed JSP SelectTag's support for rendering enum constants
|
||||
* JSP Radiobutton/CheckboxesTag utilizes PropertyEditor/ConversionService for label rendering
|
||||
* MockHttpServletResponse supports multiple includes
|
||||
|
||||
|
||||
Changes in version 3.0.2 (2010-04-02)
|
||||
-------------------------------------
|
||||
|
||||
* fixed cross-module version ranges in OSGi manifests
|
||||
* fixed contents of org.springframework.web.struts jar
|
||||
* upgraded to Hibernate Validator 4.0.2 and Jackson 1.4.2
|
||||
* compatibility with Hibernate 3.5 final (native and also as a JPA 2.0 provider)
|
||||
* compatibility with OpenJPA 2.0 (support for JPA 2.0 persistence.xml versioning)
|
||||
* compatibility with Hessian 4.0 (in terms of exception propagation)
|
||||
* compatibility with JasperReports 3.x (in terms of resource management)
|
||||
* restored full compatibility with Servlet 2.4 containers on all VMs
|
||||
* PropertyEditor lookup fallback works on Google App Engine as well
|
||||
* fixed TypeDescriptor/MethodParameter toString for all cases in debug log messages
|
||||
* widened AbstractFactoryBean's "getObjectType" signature to return any Class as well
|
||||
* BeanPostProcessors are allowed to return a null bean value in the middle of the chain
|
||||
* autowire="byType" ignores parameter name when choosing a primary bean, as defined
|
||||
* ObjectFactoryCreatingFactoryBean creates a serializable ObjectFactory reference
|
||||
* added ProviderCreatingFactoryBean, exposing a serializable JSR-330 Provider reference
|
||||
* "conversionService" bean will be ignored if it is not of type ConversionService
|
||||
* revised AbstractInterceptorDrivenBeanDefinitionDecorator for alignment with auto-proxying
|
||||
* SimpleJdbcCall's "returningResultSet" accepts any plain RowMapper now
|
||||
* added public "validateDatabaseSchema" method to Hibernate LocalSessionFactoryBean
|
||||
* HibernateJpaDialect borrows JDBC Connection on demand (supporting aggressive release)
|
||||
* JCA listener containers delegate to wrapped Transaction handle (for Geronimo compatibility)
|
||||
* @Transactional qualifiers work in unit tests as well (TransactionalTestExecutionListener)
|
||||
* @Value processing works in test instances (using the test context framework) as well now
|
||||
* @DirtiesContext is now inherited for class-level usage
|
||||
* NativeWebRequest detects native MultipartRequest when decorated by HiddenHttpMethodFilter
|
||||
* WebRequestInterceptor exposes HttpServletResponse through NativeWebRequest (after downcast)
|
||||
* WebContentInterceptor does not restrict HTTP methods by default anymore
|
||||
* WebApplicationObjectSupport's initServletContext will be called only once in any scenario
|
||||
* DispatcherPortlet passes handler instance into HandlerExceptionResolver for action exception
|
||||
* DispatcherPortlet applies preHandleRender callbacks in case of action exception as well
|
||||
* UrlPathHelper cuts off trailing servlet-path slashes for root mappings (on WebSphere)
|
||||
* introduced support for HttpEntity and ResponseEntity wrappers, adding context to body values
|
||||
* fixed DataBinder's conversion error handling for direct field access with ConversionService
|
||||
* @InitBinder methods support all applicable Spring 3.0 parameter annotations as well
|
||||
* fixed @RequestParam(required=false) regression for @InitBinder methods
|
||||
* @ExceptionHandler methods consistently receive original exception
|
||||
* fixed indexed property binding regression in form tag library
|
||||
* fixed @Configurable issue with null bean name
|
||||
|
||||
|
||||
Changes in version 3.0.1 (2010-02-18)
|
||||
-------------------------------------
|
||||
|
||||
* upgraded to AspectJ 1.6.8
|
||||
* full support for JPA 2.0 persistence schema and PersistenceUnitInfo SPI
|
||||
* support for JPA PersistenceContext/Unit injection on Google App Engine
|
||||
* support for Hibernate 3.5 (as native Hibernate API and as JPA 2.0 provider)
|
||||
* support for Tiles 2.2.1 (preserving compatibility with Tiles 2.1.2 and above)
|
||||
* consistent treatment of unresolvable placeholders for Resource and Resource array properties
|
||||
* ConversionFailedException exDLBFposes offending value through public "getValue()" method
|
||||
* fixed BeanFactory's "getBeansWithAnnotation" to ignore beans with non-determinable type
|
||||
* widened FactoryBean's "getObjectType" signature to return any Class (Class<?>)
|
||||
* do not ever consider Object as a candidate type for autowiring by type (autowire="byType")
|
||||
* BeanDefinitionReader and ClassPath/FileSystemXmlApplicationContext use varargs where possible
|
||||
* introduced BeanDefinitionRegistryPostProcessor extension to BeanFactoryPostProcessor
|
||||
* @Configuration classes support definition of BeanFactoryPostProcessor beans
|
||||
* component-scan's scoped-proxy attribute applies to scope-annotated singleton beans as well
|
||||
* generic ApplicationListener event type gets detected through AOP proxy as well
|
||||
* ApplicationListeners will only be executed once per event (even for scripted objects)
|
||||
* ApplicationListeners will get detected lazily as well (e.g. on @Bean's concrete result)
|
||||
* inner bean ApplicationListeners will be invoked through their proxy (if any)
|
||||
* fixed SimpleApplicationEventMulticaster's retriever caching to allow for proper removal
|
||||
* context-specific "conversionService" bean may refer to annotation-configured converter beans
|
||||
* refined DefaultLifecycleProcessor's start/stop logging and stop exception handling
|
||||
* DefaultLifecycleProcessor allows for overriding specific hooks in subclasses
|
||||
* BeanNameAutoProxyCreator detects alias matches for specified bean names
|
||||
* proxies with AspectJ pointcuts are fully serializable within a BeanFactory now
|
||||
* SharedEntityManagerCreator's EntityManager proxies are fully serializable now
|
||||
* Query call chaining works with shared EntityManager proxy outside of transaction as well
|
||||
* TransactionInterceptor is able to serialize "transactionManagerBeanName" as well
|
||||
* non-matching @Transactional qualifier value will lead to IllegalStateException
|
||||
* fixed WebSphereUowTransactionManager regression: correctly roll back in case of exception
|
||||
* JndiObjectFactoryBean explicitly only chooses public interfaces as default proxy interfaces
|
||||
* added vararg variants of query methods to JdbcTemplate (as known from SimpleJdbcTemplate)
|
||||
* MBeanClientInterceptor/MBeanProxyFactoryBean understands CompositeData/TabularData arrays
|
||||
* added "workManagerMBeanName" property to JBossWorkManagerTaskExecutor
|
||||
* task:executor's id value is now used as thread name prefix of ThreadPoolTaskExecutor
|
||||
* fixed @Scheduled processing to kick in once only even in an ApplicationContext hierarchy
|
||||
* fixed MediaType's Comparable behavior to do a full comparison, aligned with equals behavior
|
||||
* added "sortBySpecificity" method to MediaType, for typical use with accept header matching
|
||||
* MimeMessageHelper encodes from, to, cc, bcc String addresses with given encoding as well
|
||||
* changed HttpStatus.REQUEST_TOO_LONG constant to REQUEST_ENTITY_TOO_LARGE
|
||||
* relaxed generic Class declaration in HttpMessageConverter's canRead/canWrite/read signatures
|
||||
* fixed "mvc:view-controller" to work in a fully isolated fashion on Spring Dynamic Modules
|
||||
* DefaultRequestToViewNameTranslator strips trailing slashes as well (can also be turned off)
|
||||
* @RequestParam/RequestHeader/CookieValue's defaultValue allows for declaring empty String
|
||||
* @SessionAttributes works when used on an annotated controller interface with AOP proxying
|
||||
* WebRequest is a resolvable dependency in Servlet/Portlet web application contexts
|
||||
* revised JSP-based views to never fail when trying to set Servlet API forward attributes
|
||||
* lenient evaluation of boolean 'true' attribute expressions in JSP form tag library
|
||||
* added new spring:eval tag for evaluating SpEL expressions from JSP pages
|
||||
* SpringBeanAutowiringSupport works in extra ClassLoaders as well (e.g. WebLogic JAX-WS)
|
||||
|
||||
|
||||
Changes in version 3.0.0.GA (2009-12-16)
|
||||
----------------------------------------
|
||||
|
||||
* component scanning autodetects the new EE 6 "javax.annotation.ManagedBean" stereotype
|
||||
* updated JPA 2.0 support to the final spec (tested compatibility with EclipseLink 2.0 GA)
|
||||
* full support for GlassFish V3 GA (includes component scanning and load-time weaving)
|
||||
* upgraded to JRuby 1.4 (while remaining compatible with JRuby 1.1 and above)
|
||||
* bean property names are matched leniently ("title" and "Title"; "ISBN" and "iSBN")
|
||||
* bean properties of type enum array/collection can be populated with comma-separated String
|
||||
* removed getBeansWithAnnotation(Class,boolean,boolean) method from ListableBeanFactory
|
||||
* PropertyPlaceholderConfigurer is compatible with Spring 2.5 extensions (again)
|
||||
* SmartLifecycle beans will get auto-started on demand even if marked as lazy-init
|
||||
* MBeanExporter detects FactoryBean-exported resources independent from declaration order
|
||||
* refactored SpelExpressionParser to accept SpelParserConfiguration object with boolean flags
|
||||
* revised TypeDescriptor's valueOf and forObject factory methods with some level of caching
|
||||
* revised GenericConverter's "getConvertibleTypes" signature to return Set of ConvertiblePair
|
||||
* GenericConversionService prefers matches against inherited interfaces over superclasses
|
||||
* renamed ConverterRegistry's addGenericConverter(GenericConverter) method to addConverter
|
||||
* no default converters for Object-to-Map and Map-To-Object anymore
|
||||
* default converter for String-to-Properties parsing only applies for actual Properties objects
|
||||
* default ObjectToStringConverter only stringifies objects that indicate proper toString behavior
|
||||
* added "converters" property to FormattingConversionServiceFactoryBean as well
|
||||
* full support for formatters and formatting annotations on array/collection elements
|
||||
* no default number formatter (relying on plain java.lang.Number parsing and rendering)
|
||||
* no default formatters for Date/Calendar (requiring explicit use of @DateTimeFormat)
|
||||
* BeanValidationPostProcessor runs in before-initialization phase (before init methods) by default
|
||||
* removed MultipartRequest mixin interface again (avoiding a package dependency cycle)
|
||||
* revised RestTemplate method signatures to accept Object values instead of just Strings
|
||||
* revised path variable extraction to properly deal with dots in variable values (again)
|
||||
* reintroduced createBinder template method in Servlet/Portlet AnnotationMethodHandlerAdapter
|
||||
|
||||
|
||||
Changes in version 3.0.0.RC3 (2009-12-01)
|
||||
-----------------------------------------
|
||||
|
||||
* prepared for Grails and ROO requirements
|
||||
* restored compatibility with Apache CXF
|
||||
* fixed bean definition import via "classpath*:" URLs
|
||||
* added chaining-capable "add" method to MutablePropertyValues
|
||||
* constructor arguments can be overridden by name in child bean definitions
|
||||
* BeanDefinitions return isSingleton()=true by default again, with scope name empty
|
||||
* init/destroy methods get processed in the order of declaration at each hierarchy level
|
||||
* fixed lookup of LifecycleProcessor bean in a Spring Dynamic Modules environment
|
||||
* refined lifecycle processing through introduction of startup/shutdown phases
|
||||
* fixed transaction synchronization setup with TransactionAwareDataSourceProxy involved
|
||||
* added support for Hibernate 3.3 RegionFactory cache SPI to LocalSessionFactoryBean
|
||||
* JSR-303 SpringValidatorAdapter uses field name as first argument (analogous to bind errors)
|
||||
* replaced DefaultConversionService with ConversionServiceFactory(Bean)
|
||||
* revised FormatterRegistry interface and FormattingConversionServiceFactoryBean setup
|
||||
* mvc:annotation-driven exposes default Validator and ConversionService as top-level beans
|
||||
* mvc:annotation-driven registers applicable HttpMessageConverters by default, if available
|
||||
* added interceptors support to mvc namespace, for path-based interceptor mappings
|
||||
|
||||
|
||||
Changes in version 3.0.0.RC2 (2009-11-13)
|
||||
-----------------------------------------
|
||||
|
||||
|
||||
@@ -1,25 +1,27 @@
|
||||
SPRING FRAMEWORK 3.0 M4 (August 2009)
|
||||
-------------------------------------
|
||||
http://www.springframework.org
|
||||
SPRING FRAMEWORK 3.0.7 (December 2011)
|
||||
--------------------------------------
|
||||
http://www.springsource.org
|
||||
|
||||
1. INTRODUCTION
|
||||
|
||||
This is the fourth milestone of Spring 3.0 which is scheduled for final release in Q3 2009.
|
||||
It is nearly feature complete, with only very specific areas still being worked on for RC1.
|
||||
Spring Framework 3.0 is the next generation of Spring: fully Java 5 based,
|
||||
EL enabled, REST enabled, and with support for JSR-330 (Dependency
|
||||
Injection) and JSR-303 (Bean Validation).
|
||||
|
||||
2. RELEASE NOTES
|
||||
|
||||
This release comes with complete reference documentation already. Consult the provided
|
||||
javadoc for technical details of specific packages and classes.
|
||||
This release comes with complete reference documentation. For further
|
||||
details, consult the provided javadoc for specific packages and classes.
|
||||
|
||||
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, in contrast to previous Spring
|
||||
generations. Furthermore, the jar file names follow bundle repository conventions now.
|
||||
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, in contrast to previous Spring generations. Furthermore, the jar
|
||||
file names now follow bundle repository conventions.
|
||||
|
||||
4. GETTING STARTED
|
||||
|
||||
A Getting Started guide is to be provided in time for Spring 3.0 GA. For the time being,
|
||||
please consult the blog examples at http://blog.springsource.com as well as the sections
|
||||
of interest in the reference documentation.
|
||||
Please consult the blog examples at http://blog.springsource.com as well
|
||||
as sections of interest in the reference documentation. Sample
|
||||
applications and related material are provided as separate downloads.
|
||||
|
||||
+30
-23
@@ -1,23 +1,30 @@
|
||||
version=3.0.0
|
||||
release.type=integration
|
||||
natural.name=spring-framework
|
||||
project.name=Spring Framework
|
||||
project.key=SPR
|
||||
ivy.cache.dir=${basedir}/../ivy-cache
|
||||
integration.repo.dir=${basedir}/../integration-repo
|
||||
javadoc.exclude.package.names=org/springframework/samples/**
|
||||
javadoc.max.memory=256M
|
||||
test.vm.args=-Xmx1024M -XX:MaxPermSize=512M -XX:+HeapDumpOnOutOfMemoryError
|
||||
compiler.args=-enableJavadoc -warn:none
|
||||
|
||||
# For when releasing
|
||||
#release.type=release
|
||||
#build.stamp=RELEASE
|
||||
|
||||
# For when releasing milestones
|
||||
#release.type=milestone
|
||||
#build.stamp=M1
|
||||
|
||||
# For development in trunk
|
||||
#release.type=integration
|
||||
#build.stamp=BUILD-SNAPSHOT
|
||||
version=3.0.7
|
||||
# osgi ranges
|
||||
spring.osgi.range.nq=${version:[=.=.=, =.=.+1)}
|
||||
spring.osgi.range="${spring.osgi.range.nq}"
|
||||
aj.osgi.range="[1.5.4, 2.0.0)"
|
||||
|
||||
#
|
||||
#release.type=integration
|
||||
natural.name=spring-framework
|
||||
project.name=Spring Framework
|
||||
project.key=SPR
|
||||
ivy.cache.dir=${basedir}/../ivy-cache
|
||||
integration.repo.dir=${basedir}/../integration-repo
|
||||
license.dir=${basedir}/../build-spring-framework/resources
|
||||
javadoc.exclude.package.names=org/springframework/samples/**
|
||||
javadoc.max.memory=256M
|
||||
test.vm.args=-Xmx1024M -XX:MaxPermSize=512M -XX:+HeapDumpOnOutOfMemoryError
|
||||
compiler.args=-enableJavadoc -warn:none
|
||||
|
||||
# For when releasing
|
||||
release.type=release
|
||||
build.stamp=RELEASE
|
||||
|
||||
# For when releasing milestones
|
||||
#release.type=milestone
|
||||
#build.stamp=M1
|
||||
|
||||
# For development in trunk
|
||||
#release.type=integration
|
||||
#build.stamp=BUILD-SNAPSHOT
|
||||
|
||||
+5
-2
@@ -1,2 +1,5 @@
|
||||
org.testng.version=5.10.0
|
||||
org.junit.version=4.7.0
|
||||
#common dependency versions
|
||||
aspectj.version=1.6.8.RELEASE
|
||||
slf4j.version=1.5.3
|
||||
junit.version=4.7.0
|
||||
testng.version=5.10.0
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src/main/java"/>
|
||||
<classpathentry kind="src" path="src/main/resources"/>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/resources"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-1.0.0.jar" sourcepath="/IVY_CACHE/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-sources-1.0.0.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-1.1.1.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-sources-1.1.1.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/org.easymock/com.springsource.org.easymock/2.5.1/com.springsource.org.easymock-2.5.1.jar" sourcepath="/IVY_CACHE/org.easymock/com.springsource.org.easymock/2.5.1/com.springsource.org.easymock-sources-2.5.1.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/com.jamonapi/com.springsource.com.jamonapi/2.4.0/com.springsource.com.jamonapi-2.4.0.jar" sourcepath="/IVY_CACHE/com.jamonapi/com.springsource.com.jamonapi/2.4.0/com.springsource.com.jamonapi-sources-2.4.0.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/net.sourceforge.cglib/com.springsource.net.sf.cglib/2.2.0/com.springsource.net.sf.cglib-2.2.0.jar" sourcepath="/IVY_CACHE/net.sourceforge.cglib/com.springsource.net.sf.cglib/2.1.3/com.springsource.net.sf.cglib-sources-2.1.3.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/org.apache.log4j/com.springsource.org.apache.log4j/1.2.15/com.springsource.org.apache.log4j-1.2.15.jar" sourcepath="/IVY_CACHE/org.apache.log4j/com.springsource.org.apache.log4j/1.2.15/com.springsource.org.apache.log4j-sources-1.2.15.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-4.7.0.jar" sourcepath="/IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-sources-4.7.0.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.pool/1.3.0/com.springsource.org.apache.commons.pool-1.3.0.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.pool/1.3.0/com.springsource.org.apache.commons.pool-sources-1.3.0.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/org.aspectj/com.springsource.org.aspectj.weaver/1.6.5.RELEASE/com.springsource.org.aspectj.weaver-1.6.5.RELEASE.jar" sourcepath="IVY_CACHE/org.aspectj/com.springsource.org.aspectj.weaver/1.6.5.RELEASE/com.springsource.org.aspectj.weaver-sources-1.6.5.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>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src/main/java"/>
|
||||
<classpathentry kind="src" path="src/main/resources"/>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/resources"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-1.0.0.jar" sourcepath="/IVY_CACHE/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-sources-1.0.0.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-1.1.1.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-sources-1.1.1.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/org.easymock/com.springsource.org.easymock/2.5.1/com.springsource.org.easymock-2.5.1.jar" sourcepath="/IVY_CACHE/org.easymock/com.springsource.org.easymock/2.5.1/com.springsource.org.easymock-sources-2.5.1.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/com.jamonapi/com.springsource.com.jamonapi/2.4.0/com.springsource.com.jamonapi-2.4.0.jar" sourcepath="/IVY_CACHE/com.jamonapi/com.springsource.com.jamonapi/2.4.0/com.springsource.com.jamonapi-sources-2.4.0.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/net.sourceforge.cglib/com.springsource.net.sf.cglib/2.2.0/com.springsource.net.sf.cglib-2.2.0.jar" sourcepath="/IVY_CACHE/net.sourceforge.cglib/com.springsource.net.sf.cglib/2.1.3/com.springsource.net.sf.cglib-sources-2.1.3.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/org.apache.log4j/com.springsource.org.apache.log4j/1.2.15/com.springsource.org.apache.log4j-1.2.15.jar" sourcepath="/IVY_CACHE/org.apache.log4j/com.springsource.org.apache.log4j/1.2.15/com.springsource.org.apache.log4j-sources-1.2.15.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-4.7.0.jar" sourcepath="/IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-sources-4.7.0.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.pool/1.3.0/com.springsource.org.apache.commons.pool-1.3.0.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.pool/1.3.0/com.springsource.org.apache.commons.pool-sources-1.3.0.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/org.aspectj/com.springsource.org.aspectj.weaver/1.6.8.RELEASE/com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar" sourcepath="IVY_CACHE/org.aspectj/com.springsource.org.aspectj.weaver/1.6.8.RELEASE/com.springsource.org.aspectj.weaver-sources-1.6.8.RELEASE.jar"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.beans"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.core"/>
|
||||
<classpathentry kind="lib" path="/org.springframework.asm/target/artifacts/org.springframework.asm.jar" sourcepath="/org.springframework.asm/target/artifacts/org.springframework.asm-sources.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE"/>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="org.springframework.aop">
|
||||
<property file="${basedir}/../build.properties"/>
|
||||
<property file="${basedir}/../build.versions"/>
|
||||
<import file="${basedir}/../build-spring-framework/package-bundle.xml"/>
|
||||
<import file="${basedir}/../spring-build/standard/default.xml"/>
|
||||
</project>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
<configurations>
|
||||
<include file="${spring.build.dir}/common/default-ivy-configurations.xml"/>
|
||||
<conf name="commons-logging" extends="runtime" description="JARs needed to run with Commons Logging"/>
|
||||
<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"/>
|
||||
@@ -20,21 +21,23 @@
|
||||
<publications>
|
||||
<artifact name="${ant.project.name}"/>
|
||||
<artifact name="${ant.project.name}-sources" type="src" ext="jar"/>
|
||||
<artifact name="license" type="license" ext="txt"/>
|
||||
<artifact name="notice" type="notice" ext="txt"/>
|
||||
</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.2.0" conf="optional, bytecode-proxy->compile"/>
|
||||
<dependency org="org.aopalliance" name="com.springsource.org.aopalliance" rev="1.0.0" conf="compile->compile"/>
|
||||
<dependency org="org.apache.commons" name="com.springsource.org.apache.commons.logging" rev="1.1.1" conf="compile->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.5.RELEASE" conf="optional, aspectj->compile"/>
|
||||
<dependency org="org.apache.commons" name="com.springsource.org.apache.commons.logging" rev="1.1.1" conf="compile, commons-logging->compile"/>
|
||||
<dependency org="org.apache.commons" name="com.springsource.org.apache.commons.pool" rev="1.5.3" conf="optional, pooling->compile"/>
|
||||
<dependency org="org.aspectj" name="com.springsource.org.aspectj.weaver" rev="${aspectj.version}" conf="optional, aspectj->compile"/>
|
||||
<dependency org="org.springframework" name="org.springframework.beans" rev="latest.integration" conf="compile->compile"/>
|
||||
<dependency org="org.springframework" name="org.springframework.core" rev="latest.integration" conf="compile->compile"/>
|
||||
<!-- test dependencies -->
|
||||
<dependency org="org.apache.log4j" name="com.springsource.org.apache.log4j" rev="1.2.15" conf="test->runtime"/>
|
||||
<dependency org="org.easymock" name="com.springsource.org.easymock" rev="2.5.1" conf="test->compile"/>
|
||||
<dependency org="org.junit" name="com.springsource.org.junit" rev="4.7.0" conf="test->runtime"/>
|
||||
<dependency org="org.junit" name="com.springsource.org.junit" rev="${junit.version}" conf="test->runtime"/>
|
||||
<dependency org="org.springframework" name="org.springframework.asm" rev="latest.integration" conf="test->runtime"/>
|
||||
</dependencies>
|
||||
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>3.0.0.BUILD-SNAPSHOT</version>
|
||||
<version>3.0.7.RELEASE</version>
|
||||
<parent>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-parent</artifactId>
|
||||
<relativePath>../org.springframework.spring-parent</relativePath>
|
||||
<version>3.0.0.BUILD-SNAPSHOT</version>
|
||||
<version>3.0.7.RELEASE</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
@@ -35,7 +35,7 @@
|
||||
<dependency>
|
||||
<groupId>commons-pool</groupId>
|
||||
<artifactId>commons-pool</artifactId>
|
||||
<version>1.4</version>
|
||||
<version>1.5.3</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
@@ -34,6 +34,6 @@ public interface TargetClassAware {
|
||||
* (typically a proxy configuration or an actual proxy).
|
||||
* @return the target Class, or <code>null</code> if not known
|
||||
*/
|
||||
Class getTargetClass();
|
||||
Class<?> getTargetClass();
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*<
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -39,7 +39,7 @@ public interface TargetSource extends TargetClassAware {
|
||||
* target class.
|
||||
* @return the type of targets returned by this {@link TargetSource}
|
||||
*/
|
||||
Class getTargetClass();
|
||||
Class<?> getTargetClass();
|
||||
|
||||
/**
|
||||
* Will all calls to {@link #getTarget()} return the same object?
|
||||
|
||||
+4
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,7 @@ package org.springframework.aop.aspectj;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -139,9 +140,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
|
||||
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;
|
||||
private Type 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.
|
||||
|
||||
@@ -295,7 +294,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
||||
return this.discoveredReturningType;
|
||||
}
|
||||
|
||||
protected Object getDiscoveredReturningGenericType() {
|
||||
protected Type getDiscoveredReturningGenericType() {
|
||||
return this.discoveredReturningGenericType;
|
||||
}
|
||||
|
||||
|
||||
+4
-14
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -69,21 +69,11 @@ public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice implement
|
||||
*/
|
||||
private boolean shouldInvokeOnReturnValueOf(Method method, Object returnValue) {
|
||||
Class type = getDiscoveredReturningType();
|
||||
Object genericType = getDiscoveredReturningGenericType();
|
||||
Type 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());
|
||||
}
|
||||
(genericType == null || genericType == type ||
|
||||
TypeUtils.isAssignable(genericType, method.getGenericReturnType())));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+50
-35
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
@@ -52,6 +54,7 @@ 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.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -75,28 +78,24 @@ import org.springframework.util.StringUtils;
|
||||
public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
implements ClassFilter, IntroductionAwareMethodMatcher, BeanFactoryAware {
|
||||
|
||||
private static final Set<PointcutPrimitive> DEFAULT_SUPPORTED_PRIMITIVES = new HashSet<PointcutPrimitive>();
|
||||
private static final Set<PointcutPrimitive> 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);
|
||||
SUPPORTED_PRIMITIVES.add(PointcutPrimitive.EXECUTION);
|
||||
SUPPORTED_PRIMITIVES.add(PointcutPrimitive.ARGS);
|
||||
SUPPORTED_PRIMITIVES.add(PointcutPrimitive.REFERENCE);
|
||||
SUPPORTED_PRIMITIVES.add(PointcutPrimitive.THIS);
|
||||
SUPPORTED_PRIMITIVES.add(PointcutPrimitive.TARGET);
|
||||
SUPPORTED_PRIMITIVES.add(PointcutPrimitive.WITHIN);
|
||||
SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_ANNOTATION);
|
||||
SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_WITHIN);
|
||||
SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_ARGS);
|
||||
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];
|
||||
@@ -105,26 +104,15 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
private PointcutExpression pointcutExpression;
|
||||
private transient PointcutExpression pointcutExpression;
|
||||
|
||||
private transient Map<Method, ShadowMatch> shadowMatchCache = new ConcurrentHashMap<Method, ShadowMatch>(32);
|
||||
|
||||
|
||||
/**
|
||||
* 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());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,7 +122,6 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
* @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(
|
||||
@@ -199,15 +186,30 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
* Build the underlying AspectJ pointcut expression.
|
||||
*/
|
||||
private PointcutExpression buildPointcutExpression() {
|
||||
PointcutParser parser = initializePointcutParser();
|
||||
PointcutParameter[] pointcutParameters = new PointcutParameter[this.pointcutParameterNames.length];
|
||||
for (int i = 0; i < pointcutParameters.length; i++) {
|
||||
pointcutParameters[i] = this.pointcutParser.createPointcutParameter(
|
||||
pointcutParameters[i] = parser.createPointcutParameter(
|
||||
this.pointcutParameterNames[i], this.pointcutParameterTypes[i]);
|
||||
}
|
||||
return this.pointcutParser.parsePointcutExpression(
|
||||
return parser.parsePointcutExpression(
|
||||
replaceBooleanOperators(getExpression()), this.pointcutDeclarationScope, pointcutParameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the underlying AspectJ pointcut parser.
|
||||
*/
|
||||
private PointcutParser initializePointcutParser() {
|
||||
ClassLoader cl = (this.beanFactory instanceof ConfigurableBeanFactory ?
|
||||
((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader() :
|
||||
Thread.currentThread().getContextClassLoader());
|
||||
PointcutParser parser =
|
||||
PointcutParser.getPointcutParserSupportingSpecifiedPrimitivesAndUsingSpecifiedClassLoaderForResolution(
|
||||
SUPPORTED_PRIMITIVES, cl);
|
||||
parser.registerPointcutDesignatorHandler(new BeanNamePointcutDesignatorHandler());
|
||||
return parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a pointcut expression has been specified in XML, the user cannot
|
||||
* write <code>and</code> as "&&" (though && will work).
|
||||
@@ -221,6 +223,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the underlying AspectJ pointcut expression.
|
||||
*/
|
||||
@@ -229,7 +232,6 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
return this.pointcutExpression;
|
||||
}
|
||||
|
||||
|
||||
public boolean matches(Class targetClass) {
|
||||
checkReadyToMatch();
|
||||
try {
|
||||
@@ -458,7 +460,6 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -528,4 +529,18 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Serialization support
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
||||
// Rely on default serialization, just initialize state after deserialization.
|
||||
ois.defaultReadObject();
|
||||
|
||||
// Initialize transient fields.
|
||||
// pointcutExpression will be initialized lazily by checkReadyToMatch()
|
||||
this.shadowMatchCache = new ConcurrentHashMap<Method, ShadowMatch>(32);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+10
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -73,7 +73,7 @@ class RuntimeTestWalker {
|
||||
catch (IllegalAccessException illegalAccessEx) {
|
||||
// Famous last words... but I don't see how this can happen given the
|
||||
// makeAccessible call above
|
||||
throw new IllegalStateException("Unable to access ShadowMatchImpl.runtimeTest field.");
|
||||
throw new IllegalStateException("Unable to access ShadowMatchImpl.residualTest field");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,15 +83,18 @@ class RuntimeTestWalker {
|
||||
* then it tests subtype sensitive vars.
|
||||
*/
|
||||
public boolean testsSubtypeSensitiveVars() {
|
||||
return new SubtypeSensitiveVarTypeTestVisitor().testsSubtypeSensitiveVars(this.runtimeTest);
|
||||
return (this.runtimeTest != null &&
|
||||
new SubtypeSensitiveVarTypeTestVisitor().testsSubtypeSensitiveVars(this.runtimeTest));
|
||||
}
|
||||
|
||||
public boolean testThisInstanceOfResidue(Class thisClass) {
|
||||
return new ThisInstanceOfResidueTestVisitor(thisClass).thisInstanceOfMatches(this.runtimeTest);
|
||||
return (this.runtimeTest != null &&
|
||||
new ThisInstanceOfResidueTestVisitor(thisClass).thisInstanceOfMatches(this.runtimeTest));
|
||||
}
|
||||
|
||||
public boolean testTargetInstanceOfResidue(Class targetClass) {
|
||||
return new TargetInstanceOfResidueTestVisitor(targetClass).targetInstanceOfMatches(this.runtimeTest);
|
||||
return (this.runtimeTest != null &&
|
||||
new TargetInstanceOfResidueTestVisitor(targetClass).targetInstanceOfMatches(this.runtimeTest));
|
||||
}
|
||||
|
||||
|
||||
@@ -139,8 +142,7 @@ class RuntimeTestWalker {
|
||||
try {
|
||||
Field varTypeField = ReflectionVar.class.getDeclaredField("varType");
|
||||
ReflectionUtils.makeAccessible(varTypeField);
|
||||
Integer varTypeValue = (Integer) varTypeField.get(v);
|
||||
return varTypeValue.intValue();
|
||||
return (Integer) varTypeField.get(v);
|
||||
}
|
||||
catch (NoSuchFieldException noSuchFieldEx) {
|
||||
throw new IllegalStateException("the version of aspectjtools.jar / aspectjweaver.jar " +
|
||||
@@ -150,7 +152,7 @@ class RuntimeTestWalker {
|
||||
catch (IllegalAccessException illegalAccessEx) {
|
||||
// Famous last words... but I don't see how this can happen given the
|
||||
// makeAccessible call above
|
||||
throw new IllegalStateException("Unable to access ReflectionVar.varType field.");
|
||||
throw new IllegalStateException("Unable to access ReflectionVar.varType field");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+31
-28
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -215,9 +215,10 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
*/
|
||||
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"};
|
||||
|
||||
private static final String[] EXPRESSION_PROPERTIES = new String[]{"value", "pointcut"};
|
||||
private static Map<Class, AspectJAnnotationType> annotationTypes =
|
||||
new HashMap<Class, AspectJAnnotationType>();
|
||||
|
||||
static {
|
||||
annotationTypes.put(Pointcut.class,AspectJAnnotationType.AtPointcut);
|
||||
@@ -229,46 +230,48 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
private final AspectJAnnotationType annotationType;
|
||||
|
||||
private final String pointcutExpression;
|
||||
|
||||
private final String argumentNames;
|
||||
|
||||
public AspectJAnnotation(A annotation) {
|
||||
this.annotation = annotation;
|
||||
this.annotationType = determineAnnotationType(annotation);
|
||||
// We know these methods exist with the same name on each object,
|
||||
// but need to invoke them reflectively as there isn't a common interface.
|
||||
try {
|
||||
this.expression = resolveExpression();
|
||||
this.argNames = (String)
|
||||
this.annotation.getClass().getMethod("argNames", (Class[]) null).invoke(this.annotation);
|
||||
this.pointcutExpression = resolveExpression(annotation);
|
||||
this.argumentNames = (String) annotation.getClass().getMethod("argNames").invoke(annotation);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalArgumentException(aspectjAnnotation + " cannot be an AspectJ annotation", ex);
|
||||
throw new IllegalArgumentException(annotation + " cannot be an AspectJ annotation", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private String resolveExpression() throws Exception {
|
||||
private AspectJAnnotationType determineAnnotationType(A annotation) {
|
||||
for (Class type : annotationTypes.keySet()) {
|
||||
if (type.isInstance(annotation)) {
|
||||
return annotationTypes.get(type);
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("Unknown annotation type: " + annotation.toString());
|
||||
}
|
||||
|
||||
private String resolveExpression(A annotation) throws Exception {
|
||||
String expression = null;
|
||||
for (String methodName : EXPRESSION_PROPERTIES) {
|
||||
Method method;
|
||||
try {
|
||||
method = this.annotation.getClass().getDeclaredMethod(methodName);
|
||||
method = annotation.getClass().getDeclaredMethod(methodName);
|
||||
}
|
||||
catch (NoSuchMethodException ex) {
|
||||
method = null;
|
||||
}
|
||||
if (method != null) {
|
||||
String candidate = (String) method.invoke(this.annotation);
|
||||
String candidate = (String) method.invoke(annotation);
|
||||
if (StringUtils.hasText(candidate)) {
|
||||
expression = candidate;
|
||||
}
|
||||
@@ -286,11 +289,11 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
}
|
||||
|
||||
public String getPointcutExpression() {
|
||||
return this.expression;
|
||||
return this.pointcutExpression;
|
||||
}
|
||||
|
||||
public String getArgNames() {
|
||||
return this.argNames;
|
||||
public String getArgumentNames() {
|
||||
return this.argumentNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -314,7 +317,7 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
|
||||
if (annotation == null) {
|
||||
return null;
|
||||
}
|
||||
StringTokenizer strTok = new StringTokenizer(annotation.getArgNames(), ",");
|
||||
StringTokenizer strTok = new StringTokenizer(annotation.getArgumentNames(), ",");
|
||||
if (strTok.countTokens() > 0) {
|
||||
String[] names = new String[strTok.countTokens()];
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
|
||||
+5
-10
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -58,18 +58,13 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
||||
|
||||
private String aspectName;
|
||||
|
||||
private Boolean isBeforeAdvice = null;
|
||||
private Boolean isBeforeAdvice;
|
||||
|
||||
private Boolean isAfterAdvice = null;
|
||||
private Boolean isAfterAdvice;
|
||||
|
||||
|
||||
public InstantiationModelAwarePointcutAdvisorImpl(
|
||||
AspectJAdvisorFactory af,
|
||||
AspectJExpressionPointcut ajexp,
|
||||
MetadataAwareAspectInstanceFactory aif,
|
||||
Method method,
|
||||
int declarationOrderInAspect,
|
||||
String aspectName) {
|
||||
public InstantiationModelAwarePointcutAdvisorImpl(AspectJAdvisorFactory af, AspectJExpressionPointcut ajexp,
|
||||
MetadataAwareAspectInstanceFactory aif, Method method, int declarationOrderInAspect, String aspectName) {
|
||||
|
||||
this.declaredPointcut = ajexp;
|
||||
this.method = method;
|
||||
|
||||
+38
-32
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,9 +21,9 @@ import java.util.List;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactoryBean;
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.ManagedList;
|
||||
@@ -34,22 +34,25 @@ import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Base implementation for {@link org.springframework.beans.factory.xml.BeanDefinitionDecorator BeanDefinitionDecorators} wishing
|
||||
* to add an {@link org.aopalliance.intercept.MethodInterceptor interceptor} to the resulting
|
||||
* bean.
|
||||
* Base implementation for
|
||||
* {@link org.springframework.beans.factory.xml.BeanDefinitionDecorator BeanDefinitionDecorators}
|
||||
* wishing to add an {@link org.aopalliance.intercept.MethodInterceptor interceptor}
|
||||
* to the resulting bean.
|
||||
*
|
||||
* <p>This base class controls the creation of the {@link ProxyFactoryBean} bean definition
|
||||
* and wraps the original as an inner-bean definition for the <code>target</code> property of
|
||||
* {@link ProxyFactoryBean}.
|
||||
* and wraps the original as an inner-bean definition for the <code>target</code> property
|
||||
* of {@link ProxyFactoryBean}.
|
||||
*
|
||||
* <p>Chaining is correctly handled, ensuring that only one {@link ProxyFactoryBean} definition
|
||||
* is created. If a previous {@link org.springframework.beans.factory.xml.BeanDefinitionDecorator} already created the {@link org.springframework.aop.framework.ProxyFactoryBean}
|
||||
* then the interceptor is simply added to the existing definition.
|
||||
* is created. If a previous {@link org.springframework.beans.factory.xml.BeanDefinitionDecorator}
|
||||
* already created the {@link org.springframework.aop.framework.ProxyFactoryBean} then the
|
||||
* interceptor is simply added to the existing definition.
|
||||
*
|
||||
* <p>Subclasses have only to create the <code>BeanDefinition</code> to the interceptor they
|
||||
* wish to add.
|
||||
* <p>Subclasses have only to create the <code>BeanDefinition</code> to the interceptor that
|
||||
* they wish to add.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0
|
||||
* @see org.aopalliance.intercept.MethodInterceptor
|
||||
*/
|
||||
@@ -60,51 +63,54 @@ public abstract class AbstractInterceptorDrivenBeanDefinitionDecorator implement
|
||||
|
||||
// get the root bean name - will be the name of the generated proxy factory bean
|
||||
String existingBeanName = definitionHolder.getBeanName();
|
||||
BeanDefinition existingDefinition = definitionHolder.getBeanDefinition();
|
||||
BeanDefinition targetDefinition = definitionHolder.getBeanDefinition();
|
||||
BeanDefinitionHolder targetHolder = new BeanDefinitionHolder(targetDefinition, existingBeanName + ".TARGET");
|
||||
|
||||
// delegate to subclass for interceptor def
|
||||
// delegate to subclass for interceptor definition
|
||||
BeanDefinition interceptorDefinition = createInterceptorDefinition(node);
|
||||
|
||||
// generate name and register the interceptor
|
||||
String interceptorName = existingBeanName + "." + getInterceptorNameSuffix(interceptorDefinition);
|
||||
BeanDefinitionReaderUtils.registerBeanDefinition(new BeanDefinitionHolder(interceptorDefinition, interceptorName), registry);
|
||||
BeanDefinitionReaderUtils.registerBeanDefinition(
|
||||
new BeanDefinitionHolder(interceptorDefinition, interceptorName), registry);
|
||||
|
||||
BeanDefinitionHolder result = definitionHolder;
|
||||
|
||||
if (!isProxyFactoryBeanDefinition(existingDefinition)) {
|
||||
|
||||
// create the proxy definitionHolder
|
||||
if (!isProxyFactoryBeanDefinition(targetDefinition)) {
|
||||
// create the proxy definition
|
||||
RootBeanDefinition proxyDefinition = new RootBeanDefinition();
|
||||
// create proxy factory bean definitionHolder
|
||||
// create proxy factory bean definition
|
||||
proxyDefinition.setBeanClass(ProxyFactoryBean.class);
|
||||
|
||||
// set up property values
|
||||
MutablePropertyValues mpvs = new MutablePropertyValues();
|
||||
proxyDefinition.setPropertyValues(mpvs);
|
||||
|
||||
proxyDefinition.setScope(targetDefinition.getScope());
|
||||
proxyDefinition.setLazyInit(targetDefinition.isLazyInit());
|
||||
// set the target
|
||||
mpvs.addPropertyValue("target", existingDefinition);
|
||||
|
||||
proxyDefinition.setDecoratedDefinition(targetHolder);
|
||||
proxyDefinition.getPropertyValues().add("target", targetHolder);
|
||||
// create the interceptor names list
|
||||
ManagedList interceptorList = new ManagedList();
|
||||
mpvs.addPropertyValue("interceptorNames", interceptorList);
|
||||
|
||||
proxyDefinition.getPropertyValues().add("interceptorNames", new ManagedList<String>());
|
||||
// copy autowire settings from original bean definition.
|
||||
proxyDefinition.setAutowireCandidate(targetDefinition.isAutowireCandidate());
|
||||
proxyDefinition.setPrimary(targetDefinition.isPrimary());
|
||||
if (targetDefinition instanceof AbstractBeanDefinition) {
|
||||
proxyDefinition.copyQualifiersFrom((AbstractBeanDefinition) targetDefinition);
|
||||
}
|
||||
// wrap it in a BeanDefinitionHolder with bean name
|
||||
result = new BeanDefinitionHolder(proxyDefinition, existingBeanName);
|
||||
}
|
||||
|
||||
addInterceptorNameToList(interceptorName, result.getBeanDefinition());
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void addInterceptorNameToList(String interceptorName, BeanDefinition beanDefinition) {
|
||||
List list = (List) beanDefinition.getPropertyValues().getPropertyValue("interceptorNames").getValue();
|
||||
List<String> list = (List<String>)
|
||||
beanDefinition.getPropertyValues().getPropertyValue("interceptorNames").getValue();
|
||||
list.add(interceptorName);
|
||||
}
|
||||
|
||||
private boolean isProxyFactoryBeanDefinition(BeanDefinition existingDefinition) {
|
||||
return existingDefinition.getBeanClassName().equals(ProxyFactoryBean.class.getName());
|
||||
return ProxyFactoryBean.class.getName().equals(existingDefinition.getBeanClassName());
|
||||
}
|
||||
|
||||
protected String getInterceptorNameSuffix(BeanDefinition interceptorDefinition) {
|
||||
|
||||
+10
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -93,7 +93,14 @@ public abstract class AopConfigUtils {
|
||||
public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {
|
||||
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
|
||||
BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
|
||||
definition.getPropertyValues().addPropertyValue("proxyTargetClass", Boolean.TRUE);
|
||||
definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {
|
||||
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
|
||||
BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
|
||||
definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +120,7 @@ public abstract class AopConfigUtils {
|
||||
}
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
|
||||
beanDefinition.setSource(source);
|
||||
beanDefinition.getPropertyValues().addPropertyValue("order", Ordered.HIGHEST_PRECEDENCE);
|
||||
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
|
||||
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
|
||||
return beanDefinition;
|
||||
|
||||
+10
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -46,6 +46,11 @@ public abstract class AopNamespaceUtils {
|
||||
*/
|
||||
public static final String PROXY_TARGET_CLASS_ATTRIBUTE = "proxy-target-class";
|
||||
|
||||
/**
|
||||
* The <code>expose-proxy</code> attribute as found on AOP-related XML tags.
|
||||
*/
|
||||
private static final String EXPOSE_PROXY_ATTRIBUTE = "expose-proxy";
|
||||
|
||||
|
||||
public static void registerAutoProxyCreatorIfNecessary(
|
||||
ParserContext parserContext, Element sourceElement) {
|
||||
@@ -102,6 +107,10 @@ public abstract class AopNamespaceUtils {
|
||||
if (proxyTargetClass) {
|
||||
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
|
||||
}
|
||||
boolean exposeProxy = Boolean.valueOf(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
|
||||
if (exposeProxy) {
|
||||
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser {
|
||||
}
|
||||
if (!includePatterns.isEmpty()) {
|
||||
includePatterns.setSource(parserContext.extractSource(element));
|
||||
beanDef.getPropertyValues().addPropertyValue("includePatterns", includePatterns);
|
||||
beanDef.getPropertyValues().add("includePatterns", includePatterns);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+25
-28
@@ -102,20 +102,17 @@ class ConfigBeanDefinitionParser implements BeanDefinitionParser {
|
||||
|
||||
configureAutoProxyCreator(parserContext, element);
|
||||
|
||||
NodeList childNodes = element.getChildNodes();
|
||||
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||
Node node = childNodes.item(i);
|
||||
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||
String localName = parserContext.getDelegate().getLocalName(node);
|
||||
if (POINTCUT.equals(localName)) {
|
||||
parsePointcut((Element) node, parserContext);
|
||||
}
|
||||
else if (ADVISOR.equals(localName)) {
|
||||
parseAdvisor((Element) node, parserContext);
|
||||
}
|
||||
else if (ASPECT.equals(localName)) {
|
||||
parseAspect((Element) node, parserContext);
|
||||
}
|
||||
List<Element> childElts = DomUtils.getChildElements(element);
|
||||
for (Element elt: childElts) {
|
||||
String localName = parserContext.getDelegate().getLocalName(elt);
|
||||
if (POINTCUT.equals(localName)) {
|
||||
parsePointcut(elt, parserContext);
|
||||
}
|
||||
else if (ADVISOR.equals(localName)) {
|
||||
parseAdvisor(elt, parserContext);
|
||||
}
|
||||
else if (ASPECT.equals(localName)) {
|
||||
parseAspect(elt, parserContext);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,12 +151,12 @@ class ConfigBeanDefinitionParser implements BeanDefinitionParser {
|
||||
|
||||
Object pointcut = parsePointcutProperty(advisorElement, parserContext);
|
||||
if (pointcut instanceof BeanDefinition) {
|
||||
advisorDef.getPropertyValues().addPropertyValue(POINTCUT, pointcut);
|
||||
advisorDef.getPropertyValues().add(POINTCUT, pointcut);
|
||||
parserContext.registerComponent(
|
||||
new AdvisorComponentDefinition(advisorBeanName, advisorDef, (BeanDefinition) pointcut));
|
||||
}
|
||||
else if (pointcut instanceof String) {
|
||||
advisorDef.getPropertyValues().addPropertyValue(POINTCUT, new RuntimeBeanReference((String) pointcut));
|
||||
advisorDef.getPropertyValues().add(POINTCUT, new RuntimeBeanReference((String) pointcut));
|
||||
parserContext.registerComponent(
|
||||
new AdvisorComponentDefinition(advisorBeanName, advisorDef));
|
||||
}
|
||||
@@ -183,12 +180,12 @@ class ConfigBeanDefinitionParser implements BeanDefinitionParser {
|
||||
"'advice-ref' attribute contains empty value.", advisorElement, this.parseState.snapshot());
|
||||
}
|
||||
else {
|
||||
advisorDefinition.getPropertyValues().addPropertyValue(
|
||||
advisorDefinition.getPropertyValues().add(
|
||||
ADVICE_BEAN_NAME, new RuntimeBeanNameReference(adviceRef));
|
||||
}
|
||||
|
||||
if (advisorElement.hasAttribute(ORDER_PROPERTY)) {
|
||||
advisorDefinition.getPropertyValues().addPropertyValue(
|
||||
advisorDefinition.getPropertyValues().add(
|
||||
ORDER_PROPERTY, advisorElement.getAttribute(ORDER_PROPERTY));
|
||||
}
|
||||
|
||||
@@ -321,14 +318,14 @@ class ConfigBeanDefinitionParser implements BeanDefinitionParser {
|
||||
|
||||
// create the method factory bean
|
||||
RootBeanDefinition methodDefinition = new RootBeanDefinition(MethodLocatingFactoryBean.class);
|
||||
methodDefinition.getPropertyValues().addPropertyValue("targetBeanName", aspectName);
|
||||
methodDefinition.getPropertyValues().addPropertyValue("methodName", adviceElement.getAttribute("method"));
|
||||
methodDefinition.getPropertyValues().add("targetBeanName", aspectName);
|
||||
methodDefinition.getPropertyValues().add("methodName", adviceElement.getAttribute("method"));
|
||||
methodDefinition.setSynthetic(true);
|
||||
|
||||
// create instance factory definition
|
||||
RootBeanDefinition aspectFactoryDef =
|
||||
new RootBeanDefinition(SimpleBeanFactoryAwareAspectInstanceFactory.class);
|
||||
aspectFactoryDef.getPropertyValues().addPropertyValue("aspectBeanName", aspectName);
|
||||
aspectFactoryDef.getPropertyValues().add("aspectBeanName", aspectName);
|
||||
aspectFactoryDef.setSynthetic(true);
|
||||
|
||||
// register the pointcut
|
||||
@@ -341,7 +338,7 @@ class ConfigBeanDefinitionParser implements BeanDefinitionParser {
|
||||
advisorDefinition.setSource(parserContext.extractSource(adviceElement));
|
||||
advisorDefinition.getConstructorArgumentValues().addGenericArgumentValue(adviceDef);
|
||||
if (aspectElement.hasAttribute(ORDER_PROPERTY)) {
|
||||
advisorDefinition.getPropertyValues().addPropertyValue(
|
||||
advisorDefinition.getPropertyValues().add(
|
||||
ORDER_PROPERTY, aspectElement.getAttribute(ORDER_PROPERTY));
|
||||
}
|
||||
|
||||
@@ -369,19 +366,19 @@ class ConfigBeanDefinitionParser implements BeanDefinitionParser {
|
||||
RootBeanDefinition adviceDefinition = new RootBeanDefinition(getAdviceClass(adviceElement, parserContext));
|
||||
adviceDefinition.setSource(parserContext.extractSource(adviceElement));
|
||||
|
||||
adviceDefinition.getPropertyValues().addPropertyValue(ASPECT_NAME_PROPERTY, aspectName);
|
||||
adviceDefinition.getPropertyValues().addPropertyValue(DECLARATION_ORDER_PROPERTY, order);
|
||||
adviceDefinition.getPropertyValues().add(ASPECT_NAME_PROPERTY, aspectName);
|
||||
adviceDefinition.getPropertyValues().add(DECLARATION_ORDER_PROPERTY, order);
|
||||
|
||||
if (adviceElement.hasAttribute(RETURNING)) {
|
||||
adviceDefinition.getPropertyValues().addPropertyValue(
|
||||
adviceDefinition.getPropertyValues().add(
|
||||
RETURNING_PROPERTY, adviceElement.getAttribute(RETURNING));
|
||||
}
|
||||
if (adviceElement.hasAttribute(THROWING)) {
|
||||
adviceDefinition.getPropertyValues().addPropertyValue(
|
||||
adviceDefinition.getPropertyValues().add(
|
||||
THROWING_PROPERTY, adviceElement.getAttribute(THROWING));
|
||||
}
|
||||
if (adviceElement.hasAttribute(ARG_NAMES)) {
|
||||
adviceDefinition.getPropertyValues().addPropertyValue(
|
||||
adviceDefinition.getPropertyValues().add(
|
||||
ARG_NAMES_PROPERTY, adviceElement.getAttribute(ARG_NAMES));
|
||||
}
|
||||
|
||||
@@ -507,7 +504,7 @@ class ConfigBeanDefinitionParser implements BeanDefinitionParser {
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(AspectJExpressionPointcut.class);
|
||||
beanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
beanDefinition.setSynthetic(true);
|
||||
beanDefinition.getPropertyValues().addPropertyValue(EXPRESSION, expression);
|
||||
beanDefinition.getPropertyValues().add(EXPRESSION, expression);
|
||||
return beanDefinition;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -162,7 +162,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
|
||||
this.targetSource = EmptyTargetSource.forClass(targetClass);
|
||||
}
|
||||
|
||||
public Class getTargetClass() {
|
||||
public Class<?> getTargetClass() {
|
||||
return this.targetSource.getTargetClass();
|
||||
}
|
||||
|
||||
|
||||
+7
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -76,7 +76,12 @@ public abstract class AopContext {
|
||||
*/
|
||||
static Object setCurrentProxy(Object proxy) {
|
||||
Object old = currentProxy.get();
|
||||
currentProxy.set(proxy);
|
||||
if (proxy != null) {
|
||||
currentProxy.set(proxy);
|
||||
}
|
||||
else {
|
||||
currentProxy.remove();
|
||||
}
|
||||
return old;
|
||||
}
|
||||
|
||||
|
||||
+36
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,10 @@ package org.springframework.aop.framework;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.springframework.aop.SpringProxy;
|
||||
import org.springframework.aop.TargetClassAware;
|
||||
import org.springframework.aop.TargetSource;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.aop.target.SingletonTargetSource;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -34,6 +38,37 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public abstract class AopProxyUtils {
|
||||
|
||||
/**
|
||||
* Determine the ultimate target class of the given bean instance, traversing
|
||||
* not only a top-level proxy but any number of nested proxies as well -
|
||||
* as long as possible without side effects, that is, just for singleton targets.
|
||||
* @param candidate the instance to check (might be an AOP proxy)
|
||||
* @return the target class (or the plain class of the given object as fallback;
|
||||
* never <code>null</code>)
|
||||
* @see org.springframework.aop.TargetClassAware#getTargetClass()
|
||||
* @see org.springframework.aop.framework.Advised#getTargetSource()
|
||||
*/
|
||||
public static Class<?> ultimateTargetClass(Object candidate) {
|
||||
Assert.notNull(candidate, "Candidate object must not be null");
|
||||
Object current = candidate;
|
||||
Class<?> result = null;
|
||||
while (current instanceof TargetClassAware) {
|
||||
result = ((TargetClassAware) current).getTargetClass();
|
||||
Object nested = null;
|
||||
if (current instanceof Advised) {
|
||||
TargetSource targetSource = ((Advised) current).getTargetSource();
|
||||
if (targetSource instanceof SingletonTargetSource) {
|
||||
nested = ((SingletonTargetSource) targetSource).getTarget();
|
||||
}
|
||||
}
|
||||
current = nested;
|
||||
}
|
||||
if (result == null) {
|
||||
result = (AopUtils.isCglibProxy(candidate) ? candidate.getClass().getSuperclass() : candidate.getClass());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the complete set of interfaces to proxy for the given AOP configuration.
|
||||
* <p>This will always add the {@link Advised} interface unless the AdvisedSupport's
|
||||
|
||||
+5
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -268,7 +268,7 @@ final class Cglib2AopProxy implements AopProxy, Serializable {
|
||||
|
||||
// Choose a "straight to target" interceptor. (used for calls that are
|
||||
// unadvised but can return this). May be required to expose the proxy.
|
||||
Callback targetInterceptor = null;
|
||||
Callback targetInterceptor;
|
||||
if (exposeProxy) {
|
||||
targetInterceptor = isStatic ?
|
||||
new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
|
||||
@@ -316,12 +316,8 @@ final class Cglib2AopProxy implements AopProxy, Serializable {
|
||||
// Now copy both the callbacks from mainCallbacks
|
||||
// and fixedCallbacks into the callbacks array.
|
||||
callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
|
||||
for (int x = 0; x < mainCallbacks.length; x++) {
|
||||
callbacks[x] = mainCallbacks[x];
|
||||
}
|
||||
for (int x = 0; x < fixedCallbacks.length; x++) {
|
||||
callbacks[x + mainCallbacks.length] = fixedCallbacks[x];
|
||||
}
|
||||
System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
|
||||
System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
|
||||
this.fixedInterceptorOffset = mainCallbacks.length;
|
||||
}
|
||||
else {
|
||||
@@ -610,7 +606,7 @@ final class Cglib2AopProxy implements AopProxy, Serializable {
|
||||
targetClass = target.getClass();
|
||||
}
|
||||
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
|
||||
Object retVal = null;
|
||||
Object retVal;
|
||||
// Check whether we only have one InvokerInterceptor: that is,
|
||||
// no real advice, but just reflective invocation of the target.
|
||||
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -146,7 +146,7 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
|
||||
* unless a hook method throws an exception.
|
||||
*/
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
MethodInvocation invocation = null;
|
||||
MethodInvocation invocation;
|
||||
Object oldProxy = null;
|
||||
boolean setProxyContext = false;
|
||||
|
||||
@@ -169,7 +169,7 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
|
||||
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
|
||||
}
|
||||
|
||||
Object retVal = null;
|
||||
Object retVal;
|
||||
|
||||
if (this.advised.exposeProxy) {
|
||||
// Make invocation available if necessary.
|
||||
@@ -239,7 +239,7 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
|
||||
return false;
|
||||
}
|
||||
|
||||
JdkDynamicAopProxy otherProxy = null;
|
||||
JdkDynamicAopProxy otherProxy;
|
||||
if (other instanceof JdkDynamicAopProxy) {
|
||||
otherProxy = (JdkDynamicAopProxy) other;
|
||||
}
|
||||
|
||||
+5
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -113,12 +113,14 @@ public class ProxyConfig implements Serializable {
|
||||
* ThreadLocal for retrieval via the AopContext class. This is useful
|
||||
* if an advised object needs to call another advised method on itself.
|
||||
* (If it uses <code>this</code>, the invocation will not be advised).
|
||||
* <p>Default is "false", for optimal performance.
|
||||
* <p>Default is "false", in order to avoid unnecessary extra interception.
|
||||
* This means that no guarantees are provided that AopContext access will
|
||||
* work consistently within any method of the advised object.
|
||||
*/
|
||||
public void setExposeProxy(boolean exposeProxy) {
|
||||
this.exposeProxy = exposeProxy;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return whether the AOP proxy will expose the AOP proxy for
|
||||
* each invocation.
|
||||
|
||||
+2
-2
@@ -102,8 +102,8 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea
|
||||
* but would complicate the code. And it would work only for static pointcuts.
|
||||
*/
|
||||
protected ReflectiveMethodInvocation(
|
||||
Object proxy, Object target, Method method, Object[] arguments,
|
||||
Class targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {
|
||||
Object proxy, Object target, Method method, Object[] arguments,
|
||||
Class targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {
|
||||
|
||||
this.proxy = proxy;
|
||||
this.target = target;
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -52,7 +52,7 @@ public abstract class AutoProxyUtils {
|
||||
* @return whether the given bean should be proxied with its target class
|
||||
*/
|
||||
public static boolean shouldProxyTargetClass(ConfigurableListableBeanFactory beanFactory, String beanName) {
|
||||
if (beanFactory.containsBeanDefinition(beanName)) {
|
||||
if (beanName != null && beanFactory.containsBeanDefinition(beanName)) {
|
||||
BeanDefinition bd = beanFactory.getBeanDefinition(beanName);
|
||||
return Boolean.TRUE.equals(bd.getAttribute(PRESERVE_TARGET_CLASS_ATTRIBUTE));
|
||||
}
|
||||
|
||||
+10
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -84,6 +84,15 @@ public class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator {
|
||||
if (isMatch(beanName, mappedName)) {
|
||||
return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
|
||||
}
|
||||
BeanFactory beanFactory = getBeanFactory();
|
||||
if (beanFactory != null) {
|
||||
String[] aliases = beanFactory.getAliases(beanName);
|
||||
for (String alias : aliases) {
|
||||
if (isMatch(alias, mappedName)) {
|
||||
return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return DO_NOT_PROXY;
|
||||
|
||||
+7
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -46,7 +46,12 @@ public class ProxyCreationContext {
|
||||
* @param beanName the name of the bean, or <code>null</code> to reset it
|
||||
*/
|
||||
static void setCurrentProxiedBeanName(String beanName) {
|
||||
currentProxiedBeanName.set(beanName);
|
||||
if (beanName != null) {
|
||||
currentProxiedBeanName.set(beanName);
|
||||
}
|
||||
else {
|
||||
currentProxiedBeanName.remove();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -45,7 +45,7 @@ public abstract class ExposeBeanNameAdvisors {
|
||||
* Binding for the bean name of the bean which is currently being invoked
|
||||
* in the ReflectiveMethodInvocation userAttributes Map.
|
||||
*/
|
||||
private static final String BEAN_NAME_ATTRIBUTE = ExposeBeanNameAdvisors.class.getName() + ".beanName";
|
||||
private static final String BEAN_NAME_ATTRIBUTE = ExposeBeanNameAdvisors.class.getName() + ".BEAN_NAME";
|
||||
|
||||
|
||||
/**
|
||||
@@ -114,7 +114,7 @@ public abstract class ExposeBeanNameAdvisors {
|
||||
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
|
||||
}
|
||||
ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
|
||||
pmi.setUserAttribute(BEAN_NAME_ATTRIBUTE, beanName);
|
||||
pmi.setUserAttribute(BEAN_NAME_ATTRIBUTE, this.beanName);
|
||||
return mi.proceed();
|
||||
}
|
||||
}
|
||||
@@ -137,7 +137,7 @@ public abstract class ExposeBeanNameAdvisors {
|
||||
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
|
||||
}
|
||||
ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
|
||||
pmi.setUserAttribute(BEAN_NAME_ATTRIBUTE, beanName);
|
||||
pmi.setUserAttribute(BEAN_NAME_ATTRIBUTE, this.beanName);
|
||||
return super.invoke(mi);
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -70,8 +70,9 @@ public class ExposeInvocationInterceptor implements MethodInterceptor, Ordered,
|
||||
MethodInvocation mi = invocation.get();
|
||||
if (mi == null)
|
||||
throw new IllegalStateException(
|
||||
"No MethodInvocation found: Check that an AOP invocation is in progress, " +
|
||||
"and that the ExposeInvocationInterceptor is in the interceptor chain.");
|
||||
"No MethodInvocation found: Check that an AOP invocation is in progress, and that the " +
|
||||
"ExposeInvocationInterceptor is upfront in the interceptor chain. Specifically, note that " +
|
||||
"advices with order HIGHEST_PRECEDENCE will execute before ExposeInvocationInterceptor!");
|
||||
return mi;
|
||||
}
|
||||
|
||||
|
||||
+12
-11
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -53,28 +53,29 @@ public abstract class ScopedProxyUtils {
|
||||
|
||||
// Create a scoped proxy definition for the original bean name,
|
||||
// "hiding" the target bean in an internal target definition.
|
||||
RootBeanDefinition scopedProxyDefinition = new RootBeanDefinition(ScopedProxyFactoryBean.class);
|
||||
scopedProxyDefinition.setOriginatingBeanDefinition(definition.getBeanDefinition());
|
||||
scopedProxyDefinition.setSource(definition.getSource());
|
||||
scopedProxyDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
RootBeanDefinition proxyDefinition = new RootBeanDefinition(ScopedProxyFactoryBean.class);
|
||||
proxyDefinition.setOriginatingBeanDefinition(definition.getBeanDefinition());
|
||||
proxyDefinition.setSource(definition.getSource());
|
||||
proxyDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
|
||||
String targetBeanName = getTargetBeanName(originalBeanName);
|
||||
scopedProxyDefinition.getPropertyValues().addPropertyValue("targetBeanName", targetBeanName);
|
||||
proxyDefinition.getPropertyValues().add("targetBeanName", targetBeanName);
|
||||
|
||||
if (proxyTargetClass) {
|
||||
targetDefinition.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
|
||||
// ScopedFactoryBean's "proxyTargetClass" default is TRUE, so we don't need to set it explicitly here.
|
||||
}
|
||||
else {
|
||||
scopedProxyDefinition.getPropertyValues().addPropertyValue("proxyTargetClass", Boolean.FALSE);
|
||||
proxyDefinition.getPropertyValues().add("proxyTargetClass", Boolean.FALSE);
|
||||
}
|
||||
|
||||
// Copy autowire settings from original bean definition.
|
||||
proxyDefinition.setAutowireCandidate(targetDefinition.isAutowireCandidate());
|
||||
proxyDefinition.setPrimary(targetDefinition.isPrimary());
|
||||
if (targetDefinition instanceof AbstractBeanDefinition) {
|
||||
scopedProxyDefinition.copyQualifiersFrom((AbstractBeanDefinition) targetDefinition);
|
||||
proxyDefinition.copyQualifiersFrom((AbstractBeanDefinition) targetDefinition);
|
||||
}
|
||||
scopedProxyDefinition.setAutowireCandidate(targetDefinition.isAutowireCandidate());
|
||||
scopedProxyDefinition.setPrimary(targetDefinition.isPrimary());
|
||||
|
||||
// The target bean should be ignored in favor of the scoped proxy.
|
||||
targetDefinition.setAutowireCandidate(false);
|
||||
targetDefinition.setPrimary(false);
|
||||
@@ -84,7 +85,7 @@ public abstract class ScopedProxyUtils {
|
||||
|
||||
// Return the scoped proxy definition as primary bean definition
|
||||
// (potentially an inner bean).
|
||||
return new BeanDefinitionHolder(scopedProxyDefinition, originalBeanName, definition.getAliases());
|
||||
return new BeanDefinitionHolder(proxyDefinition, originalBeanName, definition.getAliases());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+20
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package org.springframework.aop.support;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
|
||||
import org.aopalliance.aop.Advice;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
@@ -41,9 +44,9 @@ public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcu
|
||||
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
private Advice advice;
|
||||
private transient Advice advice;
|
||||
|
||||
private final Object adviceMonitor = new Object();
|
||||
private transient volatile Object adviceMonitor = new Object();
|
||||
|
||||
|
||||
/**
|
||||
@@ -74,7 +77,7 @@ public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcu
|
||||
synchronized (this.adviceMonitor) {
|
||||
if (this.advice == null && this.adviceBeanName != null) {
|
||||
Assert.state(this.beanFactory != null, "BeanFactory must be set to resolve 'adviceBeanName'");
|
||||
this.advice = (Advice) this.beanFactory.getBean(this.adviceBeanName, Advice.class);
|
||||
this.advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
|
||||
}
|
||||
return this.advice;
|
||||
}
|
||||
@@ -85,4 +88,17 @@ public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcu
|
||||
return getClass().getName() + ": advice bean '" + getAdviceBeanName() + "'";
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Serialization support
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
||||
// Rely on default serialization, just initialize state after deserialization.
|
||||
ois.defaultReadObject();
|
||||
|
||||
// Initialize transient fields.
|
||||
this.adviceMonitor = new Object();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+20
-18
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -85,7 +85,7 @@ public abstract class AopUtils {
|
||||
* Check whether the specified class is a CGLIB-generated class.
|
||||
* @param clazz the class to check
|
||||
*/
|
||||
public static boolean isCglibProxyClass(Class clazz) {
|
||||
public static boolean isCglibProxyClass(Class<?> clazz) {
|
||||
return (clazz != null && isCglibProxyClassName(clazz.getName()));
|
||||
}
|
||||
|
||||
@@ -98,22 +98,24 @@ public abstract class AopUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the target class of the given bean instance,
|
||||
* which might be an AOP proxy.
|
||||
* Determine the target class of the given bean instance which might be an AOP proxy.
|
||||
* <p>Returns the target class for an AOP proxy and the plain class else.
|
||||
* @param candidate the instance to check (might be an AOP proxy)
|
||||
* @return the target class (or the plain class of the given object as fallback)
|
||||
* @return the target class (or the plain class of the given object as fallback;
|
||||
* never <code>null</code>)
|
||||
* @see org.springframework.aop.TargetClassAware#getTargetClass()
|
||||
* @see org.springframework.aop.framework.AopProxyUtils#ultimateTargetClass(Object)
|
||||
*/
|
||||
public static Class getTargetClass(Object candidate) {
|
||||
public static Class<?> getTargetClass(Object candidate) {
|
||||
Assert.notNull(candidate, "Candidate object must not be null");
|
||||
Class<?> result = null;
|
||||
if (candidate instanceof TargetClassAware) {
|
||||
return ((TargetClassAware) candidate).getTargetClass();
|
||||
result = ((TargetClassAware) candidate).getTargetClass();
|
||||
}
|
||||
if (isCglibProxy(candidate)) {
|
||||
return candidate.getClass().getSuperclass();
|
||||
if (result == null) {
|
||||
result = (isCglibProxy(candidate) ? candidate.getClass().getSuperclass() : candidate.getClass());
|
||||
}
|
||||
return candidate.getClass();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,7 +167,7 @@ public abstract class AopUtils {
|
||||
* <code>targetClass</code> doesn't implement it or is <code>null</code>
|
||||
* @see org.springframework.util.ClassUtils#getMostSpecificMethod
|
||||
*/
|
||||
public static Method getMostSpecificMethod(Method method, Class targetClass) {
|
||||
public static Method getMostSpecificMethod(Method method, Class<?> targetClass) {
|
||||
Method resolvedMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
|
||||
// If we are dealing with method with generic parameters, find the original method.
|
||||
return BridgeMethodResolver.findBridgedMethod(resolvedMethod);
|
||||
@@ -180,7 +182,7 @@ public abstract class AopUtils {
|
||||
* @param targetClass the class to test
|
||||
* @return whether the pointcut can apply on any method
|
||||
*/
|
||||
public static boolean canApply(Pointcut pc, Class targetClass) {
|
||||
public static boolean canApply(Pointcut pc, Class<?> targetClass) {
|
||||
return canApply(pc, targetClass, false);
|
||||
}
|
||||
|
||||
@@ -194,7 +196,7 @@ public abstract class AopUtils {
|
||||
* for this bean includes any introductions
|
||||
* @return whether the pointcut can apply on any method
|
||||
*/
|
||||
public static boolean canApply(Pointcut pc, Class targetClass, boolean hasIntroductions) {
|
||||
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
|
||||
if (!pc.getClassFilter().matches(targetClass)) {
|
||||
return false;
|
||||
}
|
||||
@@ -207,7 +209,7 @@ public abstract class AopUtils {
|
||||
|
||||
Set<Class> classes = new HashSet<Class>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
|
||||
classes.add(targetClass);
|
||||
for (Class clazz : classes) {
|
||||
for (Class<?> clazz : classes) {
|
||||
Method[] methods = clazz.getMethods();
|
||||
for (Method method : methods) {
|
||||
if ((introductionAwareMethodMatcher != null &&
|
||||
@@ -229,7 +231,7 @@ public abstract class AopUtils {
|
||||
* @param targetClass class we're testing
|
||||
* @return whether the pointcut can apply on any method
|
||||
*/
|
||||
public static boolean canApply(Advisor advisor, Class targetClass) {
|
||||
public static boolean canApply(Advisor advisor, Class<?> targetClass) {
|
||||
return canApply(advisor, targetClass, false);
|
||||
}
|
||||
|
||||
@@ -243,7 +245,7 @@ public abstract class AopUtils {
|
||||
* any introductions
|
||||
* @return whether the pointcut can apply on any method
|
||||
*/
|
||||
public static boolean canApply(Advisor advisor, Class targetClass, boolean hasIntroductions) {
|
||||
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
|
||||
if (advisor instanceof IntroductionAdvisor) {
|
||||
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
|
||||
}
|
||||
@@ -265,7 +267,7 @@ public abstract class AopUtils {
|
||||
* @return sublist of Advisors that can apply to an object of the given class
|
||||
* (may be the incoming List as-is)
|
||||
*/
|
||||
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class clazz) {
|
||||
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
|
||||
if (candidateAdvisors.isEmpty()) {
|
||||
return candidateAdvisors;
|
||||
}
|
||||
@@ -299,7 +301,7 @@ public abstract class AopUtils {
|
||||
* @throws org.springframework.aop.AopInvocationException in case of a reflection error
|
||||
*/
|
||||
public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)
|
||||
throws Throwable {
|
||||
throws Throwable {
|
||||
|
||||
// Use reflection to invoke the method.
|
||||
try {
|
||||
|
||||
+8
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,15 +16,12 @@
|
||||
|
||||
package org.springframework.aop.target;
|
||||
|
||||
import java.io.NotSerializableException;
|
||||
import java.io.ObjectStreamException;
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.aop.TargetSource;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@@ -65,7 +62,7 @@ public abstract class AbstractBeanFactoryBasedTargetSource
|
||||
private String targetBeanName;
|
||||
|
||||
/** Class of the target */
|
||||
private Class targetClass;
|
||||
private Class<?> targetClass;
|
||||
|
||||
/**
|
||||
* BeanFactory that owns this TargetSource. We need to hold onto this
|
||||
@@ -108,7 +105,7 @@ public abstract class AbstractBeanFactoryBasedTargetSource
|
||||
* Set the owning BeanFactory. We need to save a reference so that we can
|
||||
* use the <code>getBean</code> method on every invocation.
|
||||
*/
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
if (this.targetBeanName == null) {
|
||||
throw new IllegalStateException("Property'targetBeanName' is required");
|
||||
}
|
||||
@@ -123,7 +120,7 @@ public abstract class AbstractBeanFactoryBasedTargetSource
|
||||
}
|
||||
|
||||
|
||||
public synchronized Class getTargetClass() {
|
||||
public synchronized Class<?> getTargetClass() {
|
||||
if (this.targetClass == null && this.beanFactory != null) {
|
||||
// Determine type of the target bean.
|
||||
this.targetClass = this.beanFactory.getType(this.targetBeanName);
|
||||
@@ -131,7 +128,10 @@ public abstract class AbstractBeanFactoryBasedTargetSource
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Getting bean with name '" + this.targetBeanName + "' in order to determine type");
|
||||
}
|
||||
this.targetClass = this.beanFactory.getBean(this.targetBeanName).getClass();
|
||||
Object beanInstance = this.beanFactory.getBean(this.targetBeanName);
|
||||
if (beanInstance != null) {
|
||||
this.targetClass = beanInstance.getClass();
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.targetClass;
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -64,7 +64,7 @@ public abstract class AbstractLazyCreationTargetSource implements TargetSource {
|
||||
* a meaningful value when the target is still <code>null</code>.
|
||||
* @see #isInitialized()
|
||||
*/
|
||||
public synchronized Class getTargetClass() {
|
||||
public synchronized Class<?> getTargetClass() {
|
||||
return (this.lazyTarget != null ? this.lazyTarget.getClass() : null);
|
||||
}
|
||||
|
||||
|
||||
+8
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,7 +16,9 @@
|
||||
|
||||
package org.springframework.aop.target;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.NotSerializableException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectStreamException;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
@@ -91,6 +93,11 @@ public abstract class AbstractPrototypeBasedTargetSource extends AbstractBeanFac
|
||||
// Serialization support
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
||||
throw new NotSerializableException("A prototype-based TargetSource itself is not deserializable - " +
|
||||
"just a disconnected SingletonTargetSource is");
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces this object with a SingletonTargetSource on serialization.
|
||||
* Protected as otherwise it won't be invoked for subclasses.
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -89,7 +89,7 @@ public class EmptyTargetSource implements TargetSource, Serializable {
|
||||
/**
|
||||
* Always returns the specified target Class, or <code>null</code> if none.
|
||||
*/
|
||||
public Class getTargetClass() {
|
||||
public Class<?> getTargetClass() {
|
||||
return this.targetClass;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -59,7 +59,7 @@ public class HotSwappableTargetSource implements TargetSource, Serializable {
|
||||
* Return the type of the current target object.
|
||||
* <p>The returned type should usually be constant across all target objects.
|
||||
*/
|
||||
public synchronized Class getTargetClass() {
|
||||
public synchronized Class<?> getTargetClass() {
|
||||
return this.target.getClass();
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -55,7 +55,7 @@ public class SingletonTargetSource implements TargetSource, Serializable {
|
||||
}
|
||||
|
||||
|
||||
public Class getTargetClass() {
|
||||
public Class<?> getTargetClass() {
|
||||
return this.target.getClass();
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -106,7 +106,7 @@ public class ThreadLocalTargetSource extends AbstractPrototypeBasedTargetSource
|
||||
this.targetSet.clear();
|
||||
}
|
||||
// Clear ThreadLocal, just in case.
|
||||
this.targetInThread.set(null);
|
||||
this.targetInThread.remove();
|
||||
}
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -63,7 +63,7 @@ public abstract class AbstractRefreshableTargetSource implements TargetSource, R
|
||||
}
|
||||
|
||||
|
||||
public synchronized Class getTargetClass() {
|
||||
public synchronized Class<?> getTargetClass() {
|
||||
if (this.targetObject == null) {
|
||||
refresh();
|
||||
}
|
||||
|
||||
+18
@@ -56,6 +56,15 @@
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="expose-proxy" type="xsd:boolean" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Indicate that the proxy should be exposed by the AOP framework as a
|
||||
ThreadLocal for retrieval via the AopContext class. Off by default,
|
||||
i.e. no guarantees that AopContext access will work.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
@@ -84,6 +93,15 @@
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="expose-proxy" type="xsd:boolean" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Indicate that the proxy should be exposed by the AOP framework as a
|
||||
ThreadLocal for retrieval via the AopContext class. Off by default,
|
||||
i.e. no guarantees that AopContext access will work.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
|
||||
+8
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,15 +16,14 @@
|
||||
|
||||
package org.springframework.aop.aspectj.annotation;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import test.aop.PerThisAspect;
|
||||
|
||||
import test.util.SerializationTestUtils;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
@@ -76,6 +75,7 @@ public final class AspectProxyFactoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore // InstantiationModelAwarePointcutAdvisorImpl not serializable yet
|
||||
public void testWithInstance() throws Exception {
|
||||
MultiplyReturnValue aspect = new MultiplyReturnValue();
|
||||
int multiple = 3;
|
||||
@@ -88,8 +88,10 @@ public final class AspectProxyFactoryTests {
|
||||
proxyFactory.addAspect(aspect);
|
||||
|
||||
ITestBean proxy = proxyFactory.getProxy();
|
||||
|
||||
assertEquals(target.getAge() * multiple, proxy.getAge());
|
||||
|
||||
ITestBean serializedProxy = (ITestBean) SerializationTestUtils.serializeAndDeserialize(proxy);
|
||||
assertEquals(target.getAge() * multiple, serializedProxy.getAge());
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
|
||||
+16
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -293,20 +293,33 @@ public final class ProxyFactoryTests {
|
||||
public void testProxyTargetClassWithInterfaceAsTarget() {
|
||||
ProxyFactory pf = new ProxyFactory();
|
||||
pf.setTargetClass(ITestBean.class);
|
||||
|
||||
Object proxy = pf.getProxy();
|
||||
assertTrue("Proxy is a JDK proxy", AopUtils.isJdkDynamicProxy(proxy));
|
||||
assertTrue(proxy instanceof ITestBean);
|
||||
assertEquals(ITestBean.class, AopProxyUtils.ultimateTargetClass(proxy));
|
||||
|
||||
ProxyFactory pf2 = new ProxyFactory(proxy);
|
||||
Object proxy2 = pf2.getProxy();
|
||||
assertTrue("Proxy is a JDK proxy", AopUtils.isJdkDynamicProxy(proxy2));
|
||||
assertTrue(proxy2 instanceof ITestBean);
|
||||
assertEquals(ITestBean.class, AopProxyUtils.ultimateTargetClass(proxy2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProxyTargetClassWithConcreteClassAsTarget() {
|
||||
ProxyFactory pf = new ProxyFactory();
|
||||
pf.setTargetClass(TestBean.class);
|
||||
|
||||
Object proxy = pf.getProxy();
|
||||
assertTrue("Proxy is a CGLIB proxy", AopUtils.isCglibProxy(proxy));
|
||||
assertTrue(proxy instanceof TestBean);
|
||||
assertEquals(TestBean.class, AopProxyUtils.ultimateTargetClass(proxy));
|
||||
|
||||
ProxyFactory pf2 = new ProxyFactory(proxy);
|
||||
pf2.setProxyTargetClass(true);
|
||||
Object proxy2 = pf2.getProxy();
|
||||
assertTrue("Proxy is a CGLIB proxy", AopUtils.isCglibProxy(proxy2));
|
||||
assertTrue(proxy2 instanceof TestBean);
|
||||
assertEquals(TestBean.class, AopProxyUtils.ultimateTargetClass(proxy2));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ public final class PrototypeBasedTargetSourceTests {
|
||||
@Test
|
||||
public void testSerializability() throws Exception {
|
||||
MutablePropertyValues tsPvs = new MutablePropertyValues();
|
||||
tsPvs.addPropertyValue("targetBeanName", "person");
|
||||
tsPvs.add("targetBeanName", "person");
|
||||
RootBeanDefinition tsBd = new RootBeanDefinition(TestTargetSource.class, tsPvs);
|
||||
|
||||
MutablePropertyValues pvs = new MutablePropertyValues();
|
||||
|
||||
@@ -4,14 +4,14 @@ Bundle-Vendor: SpringSource
|
||||
Bundle-ManifestVersion: 2
|
||||
Import-Template:
|
||||
com.jamonapi.*;version="[2.4.0, 3.0.0)";resolution:=optional,
|
||||
net.sf.cglib.*;version="[2.1.3, 2.2.0)";resolution:=optional,
|
||||
net.sf.cglib.*;version="[2.1.3, 3.0.0)";resolution:=optional,
|
||||
org.aopalliance.*;version="[1.0.0, 2.0.0)",
|
||||
org.apache.commons.logging.*;version="[1.1.1, 2.0.0)",
|
||||
org.apache.commons.pool.*;version="[1.3.0, 2.0.0)";resolution:=optional,
|
||||
org.aspectj.*;version="[1.5.4, 2.0.0)";resolution:=optional,
|
||||
org.springframework.beans.*;version="[3.0.0, 3.0.1)";resolution:=optional,
|
||||
org.springframework.core.*;version="[3.0.0, 3.0.1)",
|
||||
org.springframework.util.*;version="[3.0.0, 3.0.1)",
|
||||
org.aspectj.*;version=${aj.osgi.range};resolution:=optional,
|
||||
org.springframework.beans.*;version=${spring.osgi.range};resolution:=optional,
|
||||
org.springframework.core.*;version=${spring.osgi.range},
|
||||
org.springframework.util.*;version=${spring.osgi.range},
|
||||
org.w3c.dom.*;version="0";resolution:=optional
|
||||
Ignored-Existing-Headers:
|
||||
Bnd-LastModified,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="org.springframework.asm" xmlns:ivy="antlib:org.apache.ivy.ant">
|
||||
<project name="org.springframework.asm" xmlns:ivy="antlib:org.apache.ivy.ant"
|
||||
xmlns:bundlor="antlib:com.springsource.bundlor.ant">
|
||||
<property file="${basedir}/../build.properties"/>
|
||||
<import file="${basedir}/../build-spring-framework/package-bundle.xml"/>
|
||||
<import file="${basedir}/../spring-build/standard/default.xml"/>
|
||||
@@ -35,6 +36,7 @@
|
||||
<artifacts pattern="${jar.output.dir}/[artifact].[ext]"/>
|
||||
<artifacts pattern="${source-jar.output.dir}/[artifact].[ext]"/>
|
||||
<artifacts pattern="${ivy.output.dir}/[artifact].[ext]"/>
|
||||
<artifacts pattern="${license.dir}/[artifact].[ext]"/>
|
||||
</ivy:publish>
|
||||
</target>
|
||||
|
||||
@@ -45,4 +47,14 @@
|
||||
<taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask" classpathref="jarjar.classpath"/>
|
||||
</target>
|
||||
|
||||
<target name="bundlor" depends="bundlor.init" unless="disable.bundlor">
|
||||
<bundlor:bundlor inputPath="${jar.output.file}" outputPath="${jar.output.file}"
|
||||
bundleVersion="${bundle.version}" manifestTemplatePath="${manifest.template.file}"
|
||||
failOnWarnings="${fail.on.warnings}">
|
||||
<propertyset refid="bundlor.properties"/>
|
||||
<propertyset>
|
||||
<propertyref builtin="all"/>
|
||||
</propertyset>
|
||||
</bundlor:bundlor>
|
||||
</target>
|
||||
</project>
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
<publications>
|
||||
<artifact name="${ant.project.name}"/>
|
||||
<artifact name="${ant.project.name}-sources" type="src" ext="jar"/>
|
||||
<artifact name="license" type="license" ext="txt"/>
|
||||
<artifact name="notice" type="notice" ext="txt"/>
|
||||
</publications>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -1,56 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-asm</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>3.0.0.BUILD-SNAPSHOT</version>
|
||||
<parent>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-parent</artifactId>
|
||||
<relativePath>../org.springframework.spring-parent</relativePath>
|
||||
<version>3.0.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>jarjar</id>
|
||||
<phase>process-classes</phase>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<tasks>
|
||||
<taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask" classpathref="maven.plugin.classpath" />
|
||||
<jarjar jarfile="${project.build.directory}${file.separator}${project.build.finalName}-jarjar.jar">
|
||||
<zipfileset src="${project.build.directory}/jarjar-staging/com.springsource.org.objectweb.asm.jar"/>
|
||||
<zipfileset src="${project.build.directory}/jarjar-staging/com.springsource.org.objectweb.asm.commons.jar"/>
|
||||
<rule pattern="org.objectweb.asm.**" result="org.springframework.asm.@1"/>
|
||||
</jarjar>
|
||||
<unjar src="${project.build.directory}${file.separator}${project.build.finalName}-jarjar.jar"
|
||||
dest="${project.build.outputDirectory}">
|
||||
<patternset>
|
||||
<include name="**/*.class"/>
|
||||
<exclude name="*"/>
|
||||
</patternset>
|
||||
</unjar>
|
||||
</tasks>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.code</groupId>
|
||||
<artifactId>jarjar</artifactId>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-asm</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>3.0.7.RELEASE</version>
|
||||
<parent>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-parent</artifactId>
|
||||
<relativePath>../org.springframework.spring-parent</relativePath>
|
||||
<version>3.0.7.RELEASE</version>
|
||||
</parent>
|
||||
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>jarjar</id>
|
||||
<phase>process-classes</phase>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<tasks>
|
||||
<taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask" classpathref="maven.plugin.classpath" />
|
||||
<jarjar jarfile="${project.build.directory}${file.separator}${project.build.finalName}-jarjar.jar">
|
||||
<zipfileset src="${project.build.directory}/jarjar-staging/com.springsource.org.objectweb.asm.jar"/>
|
||||
<zipfileset src="${project.build.directory}/jarjar-staging/com.springsource.org.objectweb.asm.commons.jar"/>
|
||||
<rule pattern="org.objectweb.asm.**" result="org.springframework.asm.@1"/>
|
||||
</jarjar>
|
||||
<unjar src="${project.build.directory}${file.separator}${project.build.finalName}-jarjar.jar"
|
||||
dest="${project.build.outputDirectory}">
|
||||
<patternset>
|
||||
<include name="**/*.class"/>
|
||||
<exclude name="*"/>
|
||||
</patternset>
|
||||
</unjar>
|
||||
</tasks>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.code</groupId>
|
||||
<artifactId>jarjar</artifactId>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.transaction"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.test"/>
|
||||
<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.aspectj/com.springsource.org.aspectj.weaver/1.6.5.RELEASE/com.springsource.org.aspectj.weaver-1.6.5.RELEASE.jar" sourcepath="/IVY_CACHE/org.aspectj/com.springsource.org.aspectj.weaver/1.6.5.RELEASE/com.springsource.org.aspectj.weaver-sources-1.6.5.RELEASE.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/org.aspectj/com.springsource.org.aspectj.weaver/1.6.8.RELEASE/com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar" sourcepath="/IVY_CACHE/org.aspectj/com.springsource.org.aspectj.weaver/1.6.8.RELEASE/com.springsource.org.aspectj.weaver-sources-1.6.8.RELEASE.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-4.7.0.jar" sourcepath="/IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-sources-4.7.0.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/javax.persistence/com.springsource.javax.persistence/1.0.0/com.springsource.javax.persistence-1.0.0.jar" sourcepath="/IVY_CACHE/javax.persistence/com.springsource.javax.persistence/1.0.0/com.springsource.javax.persistence-sources-1.0.0.jar"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.orm"/>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="org.springframework.aspects">
|
||||
<property file="${basedir}/../build.properties"/>
|
||||
<property file="${basedir}/../build.versions"/>
|
||||
<import file="${basedir}/../build-spring-framework/package-bundle.xml"/>
|
||||
<import file="${basedir}/../spring-build/aspect/default.xml"/>
|
||||
|
||||
|
||||
@@ -1,38 +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="tx" extends="runtime" description="JARs needed to run transactional aspects"/>
|
||||
<conf name="orm" extends="runtime" description="JARs needed to compile JPA aspects"/>
|
||||
</configurations>
|
||||
|
||||
<publications>
|
||||
<artifact name="${ant.project.name}"/>
|
||||
<artifact name="${ant.project.name}-sources" type="src" ext="jar"/>
|
||||
</publications>
|
||||
|
||||
<dependencies>
|
||||
<dependency org="org.apache.commons" name="com.springsource.org.apache.commons.logging" rev="1.1.1" conf="compile->compile"/>
|
||||
<dependency org="org.aspectj" name="com.springsource.org.aspectj.weaver" rev="1.6.5.RELEASE" conf="optional, aspectj->compile"/>
|
||||
<dependency org="org.springframework" name="org.springframework.beans" rev="latest.integration" conf="test->compile"/>
|
||||
<dependency org="org.springframework" name="org.springframework.transaction" rev="latest.integration" conf="optional, tx->compile"/>
|
||||
<dependency org="org.springframework" name="org.springframework.orm" rev="latest.integration" conf="optional,orm->compile"/>
|
||||
<dependency org="org.springframework" name="org.springframework.test" rev="latest.integration" conf="test->runtime"/>
|
||||
<dependency org="org.springframework" name="org.springframework.context" rev="latest.integration" conf="test->runtime"/>
|
||||
<dependency org="org.springframework" name="org.springframework.context.support" rev="latest.integration" conf="test->runtime"/>
|
||||
<dependency org="org.junit" name="com.springsource.org.junit" rev="4.7.0" conf="compile->compile"/>
|
||||
<dependency org="javax.persistence" name="com.springsource.javax.persistence" rev="1.0.0" conf="provided, compile->compile"/>
|
||||
<dependency org="javax.mail" name="com.springsource.javax.mail" rev="1.4.0" conf="test->compile"/>
|
||||
</dependencies>
|
||||
|
||||
</ivy-module>
|
||||
<?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="commons-logging" extends="runtime" description="JARs needed to run with Commons Logging"/>
|
||||
<conf name="aspectj" extends="runtime" description="JARs needed to run with AspectJ"/>
|
||||
<conf name="tx" extends="runtime" description="JARs needed to run transactional aspects"/>
|
||||
<conf name="orm" extends="runtime" description="JARs needed to compile JPA aspects"/>
|
||||
</configurations>
|
||||
|
||||
<publications>
|
||||
<artifact name="${ant.project.name}"/>
|
||||
<artifact name="${ant.project.name}-sources" type="src" ext="jar"/>
|
||||
<artifact name="license" type="license" ext="txt"/>
|
||||
<artifact name="notice" type="notice" ext="txt"/>
|
||||
</publications>
|
||||
|
||||
<dependencies>
|
||||
<dependency org="org.apache.commons" name="com.springsource.org.apache.commons.logging" rev="1.1.1" conf="compile, commons-logging->compile"/>
|
||||
<dependency org="org.aspectj" name="com.springsource.org.aspectj.weaver" rev="${aspectj.version}" conf="optional, aspectj->compile"/>
|
||||
<dependency org="org.springframework" name="org.springframework.beans" rev="latest.integration" conf="test->compile"/>
|
||||
<dependency org="org.springframework" name="org.springframework.transaction" rev="latest.integration" conf="optional, tx->compile"/>
|
||||
<dependency org="org.springframework" name="org.springframework.orm" rev="latest.integration" conf="optional, orm->compile"/>
|
||||
<dependency org="org.springframework" name="org.springframework.test" rev="latest.integration" conf="test->runtime"/>
|
||||
<dependency org="org.springframework" name="org.springframework.context" rev="latest.integration" conf="test->runtime"/>
|
||||
<dependency org="org.springframework" name="org.springframework.context.support" rev="latest.integration" conf="test->runtime"/>
|
||||
<dependency org="javax.persistence" name="com.springsource.javax.persistence" rev="1.0.0" conf="optional, orm->compile"/>
|
||||
<dependency org="org.junit" name="com.springsource.org.junit" rev="${junit.version}" conf="test->compile"/>
|
||||
<dependency org="javax.mail" name="com.springsource.javax.mail" rev="1.4.0" conf="optional, test->compile"/>
|
||||
</dependencies>
|
||||
|
||||
</ivy-module>
|
||||
|
||||
@@ -1,77 +1,90 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aspects</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>3.0.0.BUILD-SNAPSHOT</version>
|
||||
<parent>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-parent</artifactId>
|
||||
<relativePath>../org.springframework.spring-parent</relativePath>
|
||||
<version>3.0.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<!-- common logging dependency is in spring-core -->
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context-support</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.mail</groupId>
|
||||
<artifactId>mail</artifactId>
|
||||
<version>1.4</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<junitArtifactName>junit:junit</junitArtifactName>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
</project>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aspects</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>3.0.7.RELEASE</version>
|
||||
<parent>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-parent</artifactId>
|
||||
<relativePath>../org.springframework.spring-parent</relativePath>
|
||||
<version>3.0.7.RELEASE</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<!-- commons logging dependency is in spring-core -->
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-orm</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context-support</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.persistence</groupId>
|
||||
<artifactId>persistence-api</artifactId>
|
||||
<version>1.0</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.mail</groupId>
|
||||
<artifactId>mail</artifactId>
|
||||
<version>1.4</version>
|
||||
<scope>test</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<junitArtifactName>junit:junit</junitArtifactName>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
+17
-2
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.mock.staticmock;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -12,7 +28,6 @@ import java.util.List;
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Ramnivas Laddad
|
||||
*
|
||||
*/
|
||||
public abstract aspect AbstractMethodMockingControl percflow(mockStaticsTestMethod()) {
|
||||
|
||||
@@ -151,7 +166,7 @@ public abstract aspect AbstractMethodMockingControl percflow(mockStaticsTestMeth
|
||||
expectations.verify();
|
||||
}
|
||||
|
||||
Object around() : methodToMock() {
|
||||
Object around() : methodToMock() && cflowbelow(mockStaticsTestMethod()) {
|
||||
if (recording) {
|
||||
expectations.expectCall(thisJoinPointStaticPart.toLongString(), thisJoinPoint.getArgs());
|
||||
// Return value doesn't matter
|
||||
|
||||
+26
-13
@@ -1,18 +1,33 @@
|
||||
package org.springframework.mock.staticmock;
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import javax.persistence.Entity;
|
||||
package org.springframework.mock.staticmock;
|
||||
|
||||
/**
|
||||
* Annotation-based aspect to use in test build to enable mocking static methods
|
||||
* on Entity classes, as used by Roo for finders.
|
||||
* <br>
|
||||
* Mocking will occur in the call stack of any method in a class (typically a test class)
|
||||
* on JPA-annotated <code>@Entity</code> classes, as used by Roo for finders.
|
||||
*
|
||||
* <p>Mocking will occur in the call stack of any method in a class (typically a test class)
|
||||
* that is annotated with the @MockStaticEntityMethods annotation.
|
||||
* <br>
|
||||
* Also provides static methods to simplify the programming model for
|
||||
*
|
||||
* <p>Also provides static methods to simplify the programming model for
|
||||
* entering playback mode and setting expected return values.
|
||||
* <br>
|
||||
* Usage:<ol>
|
||||
*
|
||||
* <p>Usage:
|
||||
* <ol>
|
||||
* <li>Annotate a test class with @MockStaticEntityMethods.
|
||||
* <li>In each test method, AnnotationDrivenStaticEntityMockingControl will begin in recording mode.
|
||||
* Invoke static methods on Entity classes, with each recording-mode invocation
|
||||
@@ -23,11 +38,9 @@ import javax.persistence.Entity;
|
||||
* occur automatically.
|
||||
* </ol>
|
||||
*
|
||||
* @see MockStaticEntityMethods
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Ramnivas Laddad
|
||||
*
|
||||
* @see MockStaticEntityMethods
|
||||
*/
|
||||
public aspect AnnotationDrivenStaticEntityMockingControl extends AbstractMethodMockingControl {
|
||||
|
||||
@@ -50,6 +63,6 @@ public aspect AnnotationDrivenStaticEntityMockingControl extends AbstractMethodM
|
||||
// @MockStatics classes to invoke each other without resetting the mocking environment
|
||||
protected pointcut mockStaticsTestMethod() : execution(public * (@MockStaticEntityMethods *).*(..));
|
||||
|
||||
protected pointcut methodToMock() : execution(public static * (@Entity *).*(..));
|
||||
protected pointcut methodToMock() : execution(public static * (@javax.persistence.Entity *).*(..));
|
||||
|
||||
}
|
||||
|
||||
+17
-4
@@ -1,3 +1,18 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.mock.staticmock;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
@@ -8,11 +23,9 @@ import java.lang.annotation.Target;
|
||||
/**
|
||||
* Annotation to indicate a test class for whose @Test methods
|
||||
* static methods on Entity classes should be mocked.
|
||||
*
|
||||
* @see AbstractMethodMockingControl
|
||||
*
|
||||
* @author Rod Johnson
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @see AbstractMethodMockingControl
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling.aspectj;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.core.task.AsyncTaskExecutor;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
import org.springframework.core.task.support.TaskExecutorAdapter;
|
||||
|
||||
/**
|
||||
* Abstract aspect that routes selected methods asynchronously.
|
||||
*
|
||||
* <p>This aspect needs to be injected with an implementation of
|
||||
* {@link Executor} to activate it for a specific thread pool.
|
||||
* Otherwise it will simply delegate all calls synchronously.
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0.5
|
||||
*/
|
||||
public abstract aspect AbstractAsyncExecutionAspect {
|
||||
|
||||
private AsyncTaskExecutor asyncExecutor;
|
||||
|
||||
public void setExecutor(Executor executor) {
|
||||
if (executor instanceof AsyncTaskExecutor) {
|
||||
this.asyncExecutor = (AsyncTaskExecutor) executor;
|
||||
}
|
||||
else {
|
||||
this.asyncExecutor = new TaskExecutorAdapter(executor);
|
||||
}
|
||||
}
|
||||
|
||||
Object around() : asyncMethod() {
|
||||
if (this.asyncExecutor == null) {
|
||||
return proceed();
|
||||
}
|
||||
Callable<Object> callable = new Callable<Object>() {
|
||||
public Object call() throws Exception {
|
||||
Object result = proceed();
|
||||
if (result instanceof Future) {
|
||||
return ((Future<?>) result).get();
|
||||
}
|
||||
return null;
|
||||
}};
|
||||
Future<?> result = this.asyncExecutor.submit(callable);
|
||||
if (Future.class.isAssignableFrom(((MethodSignature) thisJoinPointStaticPart.getSignature()).getReturnType())) {
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract pointcut asyncMethod();
|
||||
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling.aspectj;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
|
||||
/**
|
||||
* Aspect to route methods based on the {@link Async} annotation.
|
||||
*
|
||||
* <p>This aspect routes methods marked with the {@link Async} annotation
|
||||
* as well as methods in classes marked with the same. Any method expected
|
||||
* to be routed asynchronously must return either void, {@link Future},
|
||||
* or a subtype of {@link Future}. This aspect, therefore, will produce
|
||||
* a compile-time error for methods that violate this constraint on the return type.
|
||||
* If, however, a class marked with <code>@Async</code> contains a method that
|
||||
* violates this constraint, it produces only a warning.
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
* @since 3.0.5
|
||||
*/
|
||||
public aspect AnnotationAsyncExecutionAspect extends AbstractAsyncExecutionAspect {
|
||||
|
||||
private pointcut asyncMarkedMethod()
|
||||
: execution(@Async (void || Future+) *(..));
|
||||
|
||||
private pointcut asyncTypeMarkedMethod()
|
||||
: execution((void || Future+) (@Async *).*(..));
|
||||
|
||||
public pointcut asyncMethod() : asyncMarkedMethod() || asyncTypeMarkedMethod();
|
||||
|
||||
declare error:
|
||||
execution(@Async !(void||Future) *(..)):
|
||||
"Only methods that return void or Future may have an @Async annotation";
|
||||
|
||||
declare warning:
|
||||
execution(!(void||Future) (@Async *).*(..)):
|
||||
"Methods in a class marked with @Async that do not return void or Future will be routed synchronously";
|
||||
|
||||
}
|
||||
+93
-93
@@ -1,93 +1,93 @@
|
||||
/*
|
||||
* 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.transaction.aspectj;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.aspectj.lang.annotation.SuppressAjWarnings;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.transaction.interceptor.TransactionAspectSupport;
|
||||
import org.springframework.transaction.interceptor.TransactionAttributeSource;
|
||||
|
||||
/**
|
||||
* Abstract superaspect for AspectJ transaction aspects. Concrete
|
||||
* subaspects will implement the <code>transactionalMethodExecution()</code>
|
||||
* pointcut using a strategy such as Java 5 annotations.
|
||||
*
|
||||
* <p>Suitable for use inside or outside the Spring IoC container.
|
||||
* Set the "transactionManager" property appropriately, allowing
|
||||
* use of any transaction implementation supported by Spring.
|
||||
*
|
||||
* <p><b>NB:</b> If a method implements an interface that is itself
|
||||
* transactionally annotated, the relevant Spring transaction attribute
|
||||
* will <i>not</i> be resolved. This behavior will vary from that of Spring AOP
|
||||
* if proxying an interface (but not when proxying a class). We recommend that
|
||||
* transaction annotations should be added to classes, rather than business
|
||||
* interfaces, as they are an implementation detail rather than a contract
|
||||
* specification validation.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Ramnivas Laddad
|
||||
* @since 2.0
|
||||
*/
|
||||
public abstract aspect AbstractTransactionAspect extends TransactionAspectSupport {
|
||||
|
||||
/**
|
||||
* Construct object using the given transaction metadata retrieval strategy.
|
||||
* @param tas TransactionAttributeSource implementation, retrieving Spring
|
||||
* transaction metadata for each joinpoint. Write the subclass to pass in null
|
||||
* if it's intended to be configured by Setter Injection.
|
||||
*/
|
||||
protected AbstractTransactionAspect(TransactionAttributeSource tas) {
|
||||
setTransactionAttributeSource(tas);
|
||||
}
|
||||
|
||||
@SuppressAjWarnings("adviceDidNotMatch")
|
||||
before(Object txObject) : transactionalMethodExecution(txObject) {
|
||||
MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature();
|
||||
Method method = methodSignature.getMethod();
|
||||
TransactionInfo txInfo = createTransactionIfNecessary(method, txObject.getClass());
|
||||
}
|
||||
|
||||
@SuppressAjWarnings("adviceDidNotMatch")
|
||||
after(Object txObject) throwing(Throwable t) : transactionalMethodExecution(txObject) {
|
||||
try {
|
||||
completeTransactionAfterThrowing(TransactionAspectSupport.currentTransactionInfo(), t);
|
||||
}
|
||||
catch (Throwable t2) {
|
||||
logger.error("Failed to close transaction after throwing in a transactional method", t2);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressAjWarnings("adviceDidNotMatch")
|
||||
after(Object txObject) returning() : transactionalMethodExecution(txObject) {
|
||||
commitTransactionAfterReturning(TransactionAspectSupport.currentTransactionInfo());
|
||||
}
|
||||
|
||||
@SuppressAjWarnings("adviceDidNotMatch")
|
||||
after(Object txObject) : transactionalMethodExecution(txObject) {
|
||||
cleanupTransactionInfo(TransactionAspectSupport.currentTransactionInfo());
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete subaspects must implement this pointcut, to identify
|
||||
* transactional methods. For each selected joinpoint, TransactionMetadata
|
||||
* will be retrieved using Spring's TransactionAttributeSource interface.
|
||||
*/
|
||||
protected abstract pointcut transactionalMethodExecution(Object txObject);
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.aspectj.lang.annotation.SuppressAjWarnings;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.transaction.interceptor.TransactionAspectSupport;
|
||||
import org.springframework.transaction.interceptor.TransactionAttributeSource;
|
||||
|
||||
/**
|
||||
* Abstract superaspect for AspectJ transaction aspects. Concrete
|
||||
* subaspects will implement the <code>transactionalMethodExecution()</code>
|
||||
* pointcut using a strategy such as Java 5 annotations.
|
||||
*
|
||||
* <p>Suitable for use inside or outside the Spring IoC container.
|
||||
* Set the "transactionManager" property appropriately, allowing
|
||||
* use of any transaction implementation supported by Spring.
|
||||
*
|
||||
* <p><b>NB:</b> If a method implements an interface that is itself
|
||||
* transactionally annotated, the relevant Spring transaction attribute
|
||||
* will <i>not</i> be resolved. This behavior will vary from that of Spring AOP
|
||||
* if proxying an interface (but not when proxying a class). We recommend that
|
||||
* transaction annotations should be added to classes, rather than business
|
||||
* interfaces, as they are an implementation detail rather than a contract
|
||||
* specification validation.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Ramnivas Laddad
|
||||
* @since 2.0
|
||||
*/
|
||||
public abstract aspect AbstractTransactionAspect extends TransactionAspectSupport {
|
||||
|
||||
/**
|
||||
* Construct object using the given transaction metadata retrieval strategy.
|
||||
* @param tas TransactionAttributeSource implementation, retrieving Spring
|
||||
* transaction metadata for each joinpoint. Write the subclass to pass in null
|
||||
* if it's intended to be configured by Setter Injection.
|
||||
*/
|
||||
protected AbstractTransactionAspect(TransactionAttributeSource tas) {
|
||||
setTransactionAttributeSource(tas);
|
||||
}
|
||||
|
||||
@SuppressAjWarnings("adviceDidNotMatch")
|
||||
before(Object txObject) : transactionalMethodExecution(txObject) {
|
||||
MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature();
|
||||
Method method = methodSignature.getMethod();
|
||||
TransactionInfo txInfo = createTransactionIfNecessary(method, txObject.getClass());
|
||||
}
|
||||
|
||||
@SuppressAjWarnings("adviceDidNotMatch")
|
||||
after(Object txObject) throwing(Throwable t) : transactionalMethodExecution(txObject) {
|
||||
try {
|
||||
completeTransactionAfterThrowing(TransactionAspectSupport.currentTransactionInfo(), t);
|
||||
}
|
||||
catch (Throwable t2) {
|
||||
logger.error("Failed to close transaction after throwing in a transactional method", t2);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressAjWarnings("adviceDidNotMatch")
|
||||
after(Object txObject) returning() : transactionalMethodExecution(txObject) {
|
||||
commitTransactionAfterReturning(TransactionAspectSupport.currentTransactionInfo());
|
||||
}
|
||||
|
||||
@SuppressAjWarnings("adviceDidNotMatch")
|
||||
after(Object txObject) : transactionalMethodExecution(txObject) {
|
||||
cleanupTransactionInfo(TransactionAspectSupport.currentTransactionInfo());
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete subaspects must implement this pointcut, to identify
|
||||
* transactional methods. For each selected joinpoint, TransactionMetadata
|
||||
* will be retrieved using Spring's TransactionAttributeSource interface.
|
||||
*/
|
||||
protected abstract pointcut transactionalMethodExecution(Object txObject);
|
||||
|
||||
}
|
||||
|
||||
+75
-76
@@ -1,76 +1,75 @@
|
||||
/*
|
||||
* 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.transaction.aspectj;
|
||||
|
||||
import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* Concrete AspectJ transaction aspect using Spring Transactional annotation
|
||||
* for JDK 1.5+.
|
||||
*
|
||||
* <p>When using this aspect, you <i>must</i> annotate the implementation class
|
||||
* (and/or methods within that class), <i>not</i> the interface (if any) that
|
||||
* the class implements. AspectJ follows Java's rule that annotations on
|
||||
* interfaces are <i>not</i> inherited.
|
||||
*
|
||||
* <p>A @Transactional annotation on a class specifies the default transaction
|
||||
* semantics for the execution of any <b>public</b> operation in the class.
|
||||
*
|
||||
* <p>A @Transactional annotation on a method within the class overrides the
|
||||
* default transaction semantics given by the class annotation (if present).
|
||||
* Any method may be annotated (regardless of visibility).
|
||||
* Annotating non-public methods directly is the only way
|
||||
* to get transaction demarcation for the execution of such operations.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Ramnivas Laddad
|
||||
* @author Adrian Colyer
|
||||
* @since 2.0
|
||||
* @see org.springframework.transaction.annotation.Transactional
|
||||
*/
|
||||
public aspect AnnotationTransactionAspect extends AbstractTransactionAspect {
|
||||
|
||||
public AnnotationTransactionAspect() {
|
||||
super(new AnnotationTransactionAttributeSource(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches the execution of any public method in a type with the
|
||||
* Transactional annotation, or any subtype of a type with the
|
||||
* Transactional annotation.
|
||||
*/
|
||||
private pointcut executionOfAnyPublicMethodInAtTransactionalType() :
|
||||
execution(public * ((@Transactional *)+).*(..)) && @this(Transactional);
|
||||
|
||||
/**
|
||||
* Matches the execution of any method with the
|
||||
* Transactional annotation.
|
||||
*/
|
||||
private pointcut executionOfTransactionalMethod() :
|
||||
execution(* *(..)) && @annotation(Transactional);
|
||||
|
||||
/**
|
||||
* Definition of pointcut from super aspect - matched join points
|
||||
* will have Spring transaction management applied.
|
||||
*/
|
||||
protected pointcut transactionalMethodExecution(Object txObject) :
|
||||
(executionOfAnyPublicMethodInAtTransactionalType()
|
||||
|| executionOfTransactionalMethod() )
|
||||
&& this(txObject);
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* Concrete AspectJ transaction aspect using Spring's @Transactional annotation.
|
||||
*
|
||||
* <p>When using this aspect, you <i>must</i> annotate the implementation class
|
||||
* (and/or methods within that class), <i>not</i> the interface (if any) that
|
||||
* the class implements. AspectJ follows Java's rule that annotations on
|
||||
* interfaces are <i>not</i> inherited.
|
||||
*
|
||||
* <p>A @Transactional annotation on a class specifies the default transaction
|
||||
* semantics for the execution of any <b>public</b> operation in the class.
|
||||
*
|
||||
* <p>A @Transactional annotation on a method within the class overrides the
|
||||
* default transaction semantics given by the class annotation (if present).
|
||||
* Any method may be annotated (regardless of visibility).
|
||||
* Annotating non-public methods directly is the only way
|
||||
* to get transaction demarcation for the execution of such operations.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Ramnivas Laddad
|
||||
* @author Adrian Colyer
|
||||
* @since 2.0
|
||||
* @see org.springframework.transaction.annotation.Transactional
|
||||
*/
|
||||
public aspect AnnotationTransactionAspect extends AbstractTransactionAspect {
|
||||
|
||||
public AnnotationTransactionAspect() {
|
||||
super(new AnnotationTransactionAttributeSource(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches the execution of any public method in a type with the
|
||||
* Transactional annotation, or any subtype of a type with the
|
||||
* Transactional annotation.
|
||||
*/
|
||||
private pointcut executionOfAnyPublicMethodInAtTransactionalType() :
|
||||
execution(public * ((@Transactional *)+).*(..)) && @this(Transactional);
|
||||
|
||||
/**
|
||||
* Matches the execution of any method with the
|
||||
* Transactional annotation.
|
||||
*/
|
||||
private pointcut executionOfTransactionalMethod() :
|
||||
execution(* *(..)) && @annotation(Transactional);
|
||||
|
||||
/**
|
||||
* Definition of pointcut from super aspect - matched join points
|
||||
* will have Spring transaction management applied.
|
||||
*/
|
||||
protected pointcut transactionalMethodExecution(Object txObject) :
|
||||
(executionOfAnyPublicMethodInAtTransactionalType()
|
||||
|| executionOfTransactionalMethod() )
|
||||
&& this(txObject);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!--
|
||||
AspectJ load-time weaving config file to install common Spring aspects.
|
||||
-->
|
||||
<aspectj>
|
||||
|
||||
<!--
|
||||
<weaver options="-showWeaveInfo"/>
|
||||
-->
|
||||
|
||||
<aspects>
|
||||
<aspect name="org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect"/>
|
||||
<aspect name="org.springframework.transaction.aspectj.AnnotationTransactionAspect"/>
|
||||
</aspects>
|
||||
|
||||
</aspectj>
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!--
|
||||
AspectJ load-time weaving config file to install common Spring aspects.
|
||||
-->
|
||||
<aspectj>
|
||||
|
||||
<!--
|
||||
<weaver options="-showWeaveInfo"/>
|
||||
-->
|
||||
|
||||
<aspects>
|
||||
<aspect name="org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect"/>
|
||||
<aspect name="org.springframework.scheduling.aspectj.AnnotationAsyncExecutionAspect"/>
|
||||
<aspect name="org.springframework.transaction.aspectj.AnnotationTransactionAspect"/>
|
||||
</aspects>
|
||||
|
||||
</aspectj>
|
||||
|
||||
+1
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,12 +16,9 @@
|
||||
|
||||
package org.springframework.aop.aspectj.autoproxy;
|
||||
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
|
||||
/**
|
||||
* @author Adrian Colyer
|
||||
*/
|
||||
@Aspect
|
||||
public aspect CodeStyleAspect {
|
||||
|
||||
private String foo;
|
||||
|
||||
+146
-146
@@ -1,146 +1,146 @@
|
||||
/*
|
||||
* Copyright 2009 SpringSource Inc.
|
||||
*
|
||||
* 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.mock.staticmock;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
import static org.springframework.mock.staticmock.AnnotationDrivenStaticEntityMockingControl.*;
|
||||
|
||||
|
||||
/**
|
||||
* Test for static entity mocking framework.
|
||||
* @author Rod Johnson
|
||||
* @author Ramnivas Laddad
|
||||
*
|
||||
*/
|
||||
@MockStaticEntityMethods
|
||||
@RunWith(JUnit4.class)
|
||||
public class AnnotationDrivenStaticEntityMockingControlTest {
|
||||
|
||||
@Test
|
||||
public void testNoArgIntReturn() {
|
||||
int expectedCount = 13;
|
||||
Person.countPeople();
|
||||
expectReturn(expectedCount);
|
||||
playback();
|
||||
Assert.assertEquals(expectedCount, Person.countPeople());
|
||||
}
|
||||
|
||||
@Test(expected=PersistenceException.class)
|
||||
public void testNoArgThrows() {
|
||||
Person.countPeople();
|
||||
expectThrow(new PersistenceException());
|
||||
playback();
|
||||
Person.countPeople();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArgMethodMatches() {
|
||||
long id = 13;
|
||||
Person found = new Person();
|
||||
Person.findPerson(id);
|
||||
expectReturn(found);
|
||||
playback();
|
||||
Assert.assertEquals(found, Person.findPerson(id));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testLongSeriesOfCalls() {
|
||||
long id1 = 13;
|
||||
long id2 = 24;
|
||||
Person found1 = new Person();
|
||||
Person.findPerson(id1);
|
||||
expectReturn(found1);
|
||||
Person found2 = new Person();
|
||||
Person.findPerson(id2);
|
||||
expectReturn(found2);
|
||||
Person.findPerson(id1);
|
||||
expectReturn(found1);
|
||||
Person.countPeople();
|
||||
expectReturn(0);
|
||||
playback();
|
||||
|
||||
Assert.assertEquals(found1, Person.findPerson(id1));
|
||||
Assert.assertEquals(found2, Person.findPerson(id2));
|
||||
Assert.assertEquals(found1, Person.findPerson(id1));
|
||||
Assert.assertEquals(0, Person.countPeople());
|
||||
}
|
||||
|
||||
// Note delegation is used when tests are invalid and should fail, as otherwise
|
||||
// the failure will occur on the verify() method in the aspect after
|
||||
// this method returns, failing the test case
|
||||
@Test
|
||||
public void testArgMethodNoMatchExpectReturn() {
|
||||
try {
|
||||
new Delegate().testArgMethodNoMatchExpectReturn();
|
||||
Assert.fail();
|
||||
} catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testArgMethodNoMatchExpectThrow() {
|
||||
new Delegate().testArgMethodNoMatchExpectThrow();
|
||||
}
|
||||
|
||||
private void called(Person found, long id) {
|
||||
Assert.assertEquals(found, Person.findPerson(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReentrant() {
|
||||
long id = 13;
|
||||
Person found = new Person();
|
||||
Person.findPerson(id);
|
||||
expectReturn(found);
|
||||
playback();
|
||||
called(found, id);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void testRejectUnexpectedCall() {
|
||||
new Delegate().rejectUnexpectedCall();
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void testFailTooFewCalls() {
|
||||
new Delegate().failTooFewCalls();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmpty() {
|
||||
// Test that verification check doesn't blow up if no replay() call happened
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void testDoesntEverReplay() {
|
||||
new Delegate().doesntEverReplay();
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void testDoesntEverSetReturn() {
|
||||
new Delegate().doesntEverSetReturn();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.mock.staticmock;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
import static org.springframework.mock.staticmock.AnnotationDrivenStaticEntityMockingControl.*;
|
||||
|
||||
|
||||
/**
|
||||
* Test for static entity mocking framework.
|
||||
* @author Rod Johnson
|
||||
* @author Ramnivas Laddad
|
||||
*
|
||||
*/
|
||||
@MockStaticEntityMethods
|
||||
@RunWith(JUnit4.class)
|
||||
public class AnnotationDrivenStaticEntityMockingControlTest {
|
||||
|
||||
@Test
|
||||
public void testNoArgIntReturn() {
|
||||
int expectedCount = 13;
|
||||
Person.countPeople();
|
||||
expectReturn(expectedCount);
|
||||
playback();
|
||||
Assert.assertEquals(expectedCount, Person.countPeople());
|
||||
}
|
||||
|
||||
@Test(expected=PersistenceException.class)
|
||||
public void testNoArgThrows() {
|
||||
Person.countPeople();
|
||||
expectThrow(new PersistenceException());
|
||||
playback();
|
||||
Person.countPeople();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArgMethodMatches() {
|
||||
long id = 13;
|
||||
Person found = new Person();
|
||||
Person.findPerson(id);
|
||||
expectReturn(found);
|
||||
playback();
|
||||
Assert.assertEquals(found, Person.findPerson(id));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testLongSeriesOfCalls() {
|
||||
long id1 = 13;
|
||||
long id2 = 24;
|
||||
Person found1 = new Person();
|
||||
Person.findPerson(id1);
|
||||
expectReturn(found1);
|
||||
Person found2 = new Person();
|
||||
Person.findPerson(id2);
|
||||
expectReturn(found2);
|
||||
Person.findPerson(id1);
|
||||
expectReturn(found1);
|
||||
Person.countPeople();
|
||||
expectReturn(0);
|
||||
playback();
|
||||
|
||||
Assert.assertEquals(found1, Person.findPerson(id1));
|
||||
Assert.assertEquals(found2, Person.findPerson(id2));
|
||||
Assert.assertEquals(found1, Person.findPerson(id1));
|
||||
Assert.assertEquals(0, Person.countPeople());
|
||||
}
|
||||
|
||||
// Note delegation is used when tests are invalid and should fail, as otherwise
|
||||
// the failure will occur on the verify() method in the aspect after
|
||||
// this method returns, failing the test case
|
||||
@Test
|
||||
public void testArgMethodNoMatchExpectReturn() {
|
||||
try {
|
||||
new Delegate().testArgMethodNoMatchExpectReturn();
|
||||
Assert.fail();
|
||||
} catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testArgMethodNoMatchExpectThrow() {
|
||||
new Delegate().testArgMethodNoMatchExpectThrow();
|
||||
}
|
||||
|
||||
private void called(Person found, long id) {
|
||||
Assert.assertEquals(found, Person.findPerson(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReentrant() {
|
||||
long id = 13;
|
||||
Person found = new Person();
|
||||
Person.findPerson(id);
|
||||
expectReturn(found);
|
||||
playback();
|
||||
called(found, id);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void testRejectUnexpectedCall() {
|
||||
new Delegate().rejectUnexpectedCall();
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void testFailTooFewCalls() {
|
||||
new Delegate().failTooFewCalls();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmpty() {
|
||||
// Test that verification check doesn't blow up if no replay() call happened
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void testDoesntEverReplay() {
|
||||
new Delegate().doesntEverReplay();
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void testDoesntEverSetReturn() {
|
||||
new Delegate().doesntEverSetReturn();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+92
-76
@@ -1,76 +1,92 @@
|
||||
package org.springframework.mock.staticmock;
|
||||
|
||||
import java.rmi.RemoteException;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.mock.staticmock.AnnotationDrivenStaticEntityMockingControl;
|
||||
import org.springframework.mock.staticmock.MockStaticEntityMethods;
|
||||
|
||||
//Used because verification failures occur after method returns,
|
||||
//so we can't test for them in the test case itself
|
||||
@MockStaticEntityMethods
|
||||
@Ignore // This isn't meant for direct testing; rather it is driven from AnnotationDrivenStaticEntityMockingControl
|
||||
public class Delegate {
|
||||
|
||||
@Test
|
||||
public void testArgMethodNoMatchExpectReturn() {
|
||||
long id = 13;
|
||||
Person found = new Person();
|
||||
Person.findPerson(id);
|
||||
AnnotationDrivenStaticEntityMockingControl.expectReturn(found);
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
Assert.assertEquals(found, Person.findPerson(id + 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArgMethodNoMatchExpectThrow() {
|
||||
long id = 13;
|
||||
Person found = new Person();
|
||||
Person.findPerson(id);
|
||||
AnnotationDrivenStaticEntityMockingControl.expectThrow(new PersistenceException());
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
Assert.assertEquals(found, Person.findPerson(id + 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failTooFewCalls() {
|
||||
long id = 13;
|
||||
Person found = new Person();
|
||||
Person.findPerson(id);
|
||||
AnnotationDrivenStaticEntityMockingControl.expectReturn(found);
|
||||
Person.countPeople();
|
||||
AnnotationDrivenStaticEntityMockingControl.expectReturn(25);
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
Assert.assertEquals(found, Person.findPerson(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesntEverReplay() {
|
||||
Person.countPeople();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesntEverSetReturn() {
|
||||
Person.countPeople();
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rejectUnexpectedCall() {
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
Person.countPeople();
|
||||
}
|
||||
|
||||
@Test(expected=RemoteException.class)
|
||||
public void testVerificationFailsEvenWhenTestFailsInExpectedManner() throws RemoteException {
|
||||
Person.countPeople();
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
// No calls to allow verification failure
|
||||
throw new RemoteException();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.mock.staticmock;
|
||||
|
||||
import java.rmi.RemoteException;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.mock.staticmock.AnnotationDrivenStaticEntityMockingControl;
|
||||
import org.springframework.mock.staticmock.MockStaticEntityMethods;
|
||||
|
||||
//Used because verification failures occur after method returns,
|
||||
//so we can't test for them in the test case itself
|
||||
@MockStaticEntityMethods
|
||||
@Ignore // This isn't meant for direct testing; rather it is driven from AnnotationDrivenStaticEntityMockingControl
|
||||
public class Delegate {
|
||||
|
||||
@Test
|
||||
public void testArgMethodNoMatchExpectReturn() {
|
||||
long id = 13;
|
||||
Person found = new Person();
|
||||
Person.findPerson(id);
|
||||
AnnotationDrivenStaticEntityMockingControl.expectReturn(found);
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
Assert.assertEquals(found, Person.findPerson(id + 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArgMethodNoMatchExpectThrow() {
|
||||
long id = 13;
|
||||
Person found = new Person();
|
||||
Person.findPerson(id);
|
||||
AnnotationDrivenStaticEntityMockingControl.expectThrow(new PersistenceException());
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
Assert.assertEquals(found, Person.findPerson(id + 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failTooFewCalls() {
|
||||
long id = 13;
|
||||
Person found = new Person();
|
||||
Person.findPerson(id);
|
||||
AnnotationDrivenStaticEntityMockingControl.expectReturn(found);
|
||||
Person.countPeople();
|
||||
AnnotationDrivenStaticEntityMockingControl.expectReturn(25);
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
Assert.assertEquals(found, Person.findPerson(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesntEverReplay() {
|
||||
Person.countPeople();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesntEverSetReturn() {
|
||||
Person.countPeople();
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rejectUnexpectedCall() {
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
Person.countPeople();
|
||||
}
|
||||
|
||||
@Test(expected=RemoteException.class)
|
||||
public void testVerificationFailsEvenWhenTestFailsInExpectedManner() throws RemoteException {
|
||||
Person.countPeople();
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
// No calls to allow verification failure
|
||||
throw new RemoteException();
|
||||
}
|
||||
}
|
||||
|
||||
+24
-8
@@ -1,8 +1,24 @@
|
||||
package org.springframework.mock.staticmock;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
|
||||
@Entity
|
||||
public class Person {
|
||||
}
|
||||
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.mock.staticmock;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
|
||||
@Entity
|
||||
public class Person {
|
||||
}
|
||||
|
||||
|
||||
+100
-84
@@ -1,84 +1,100 @@
|
||||
package org.springframework.mock.staticmock;
|
||||
|
||||
privileged aspect Person_Roo_Entity {
|
||||
|
||||
@javax.persistence.PersistenceContext
|
||||
transient javax.persistence.EntityManager Person.entityManager;
|
||||
|
||||
@javax.persistence.Id
|
||||
@javax.persistence.GeneratedValue(strategy = javax.persistence.GenerationType.AUTO)
|
||||
@javax.persistence.Column(name = "id")
|
||||
private java.lang.Long Person.id;
|
||||
|
||||
@javax.persistence.Version
|
||||
@javax.persistence.Column(name = "version")
|
||||
private java.lang.Integer Person.version;
|
||||
|
||||
public java.lang.Long Person.getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void Person.setId(java.lang.Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public java.lang.Integer Person.getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
public void Person.setVersion(java.lang.Integer version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@org.springframework.transaction.annotation.Transactional
|
||||
public void Person.persist() {
|
||||
if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||
this.entityManager.persist(this);
|
||||
}
|
||||
|
||||
@org.springframework.transaction.annotation.Transactional
|
||||
public void Person.remove() {
|
||||
if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||
this.entityManager.remove(this);
|
||||
}
|
||||
|
||||
@org.springframework.transaction.annotation.Transactional
|
||||
public void Person.flush() {
|
||||
if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||
this.entityManager.flush();
|
||||
}
|
||||
|
||||
@org.springframework.transaction.annotation.Transactional
|
||||
public void Person.merge() {
|
||||
if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||
Person merged = this.entityManager.merge(this);
|
||||
this.entityManager.flush();
|
||||
this.id = merged.getId();
|
||||
}
|
||||
|
||||
public static long Person.countPeople() {
|
||||
javax.persistence.EntityManager em = new Person().entityManager;
|
||||
if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||
return (Long) em.createQuery("select count(o) from Person o").getSingleResult();
|
||||
}
|
||||
|
||||
public static java.util.List<Person> Person.findAllPeople() {
|
||||
javax.persistence.EntityManager em = new Person().entityManager;
|
||||
if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||
return em.createQuery("select o from Person o").getResultList();
|
||||
}
|
||||
|
||||
public static Person Person.findPerson(java.lang.Long id) {
|
||||
if (id == null) throw new IllegalArgumentException("An identifier is required to retrieve an instance of Person");
|
||||
javax.persistence.EntityManager em = new Person().entityManager;
|
||||
if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||
return em.find(Person.class, id);
|
||||
}
|
||||
|
||||
public static java.util.List<Person> Person.findPersonEntries(int firstResult, int maxResults) {
|
||||
javax.persistence.EntityManager em = new Person().entityManager;
|
||||
if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||
return em.createQuery("select o from Person o").setFirstResult(firstResult).setMaxResults(maxResults).getResultList();
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.mock.staticmock;
|
||||
|
||||
privileged aspect Person_Roo_Entity {
|
||||
|
||||
@javax.persistence.PersistenceContext
|
||||
transient javax.persistence.EntityManager Person.entityManager;
|
||||
|
||||
@javax.persistence.Id
|
||||
@javax.persistence.GeneratedValue(strategy = javax.persistence.GenerationType.AUTO)
|
||||
@javax.persistence.Column(name = "id")
|
||||
private java.lang.Long Person.id;
|
||||
|
||||
@javax.persistence.Version
|
||||
@javax.persistence.Column(name = "version")
|
||||
private java.lang.Integer Person.version;
|
||||
|
||||
public java.lang.Long Person.getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void Person.setId(java.lang.Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public java.lang.Integer Person.getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
public void Person.setVersion(java.lang.Integer version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@org.springframework.transaction.annotation.Transactional
|
||||
public void Person.persist() {
|
||||
if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||
this.entityManager.persist(this);
|
||||
}
|
||||
|
||||
@org.springframework.transaction.annotation.Transactional
|
||||
public void Person.remove() {
|
||||
if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||
this.entityManager.remove(this);
|
||||
}
|
||||
|
||||
@org.springframework.transaction.annotation.Transactional
|
||||
public void Person.flush() {
|
||||
if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||
this.entityManager.flush();
|
||||
}
|
||||
|
||||
@org.springframework.transaction.annotation.Transactional
|
||||
public void Person.merge() {
|
||||
if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||
Person merged = this.entityManager.merge(this);
|
||||
this.entityManager.flush();
|
||||
this.id = merged.getId();
|
||||
}
|
||||
|
||||
public static long Person.countPeople() {
|
||||
javax.persistence.EntityManager em = new Person().entityManager;
|
||||
if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||
return (Long) em.createQuery("select count(o) from Person o").getSingleResult();
|
||||
}
|
||||
|
||||
public static java.util.List<Person> Person.findAllPeople() {
|
||||
javax.persistence.EntityManager em = new Person().entityManager;
|
||||
if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||
return em.createQuery("select o from Person o").getResultList();
|
||||
}
|
||||
|
||||
public static Person Person.findPerson(java.lang.Long id) {
|
||||
if (id == null) throw new IllegalArgumentException("An identifier is required to retrieve an instance of Person");
|
||||
javax.persistence.EntityManager em = new Person().entityManager;
|
||||
if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||
return em.find(Person.class, id);
|
||||
}
|
||||
|
||||
public static java.util.List<Person> Person.findPersonEntries(int firstResult, int maxResults) {
|
||||
javax.persistence.EntityManager em = new Person().entityManager;
|
||||
if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||
return em.createQuery("select o from Person o").setFirstResult(firstResult).setMaxResults(maxResults).getResultList();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling.aspectj;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import static junit.framework.Assert.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.scheduling.annotation.AsyncResult;
|
||||
|
||||
/**
|
||||
* @author Ramnivas Laddad
|
||||
*/
|
||||
public class AnnotationAsyncExecutionAspectTests {
|
||||
|
||||
private static final long WAIT_TIME = 1000; //milli seconds
|
||||
|
||||
private CountingExecutor executor;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
executor = new CountingExecutor();
|
||||
AnnotationAsyncExecutionAspect.aspectOf().setExecutor(executor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void asyncMethodGetsRoutedAsynchronously() {
|
||||
ClassWithoutAsyncAnnotation obj = new ClassWithoutAsyncAnnotation();
|
||||
obj.incrementAsync();
|
||||
executor.waitForCompletion();
|
||||
assertEquals(1, obj.counter);
|
||||
assertEquals(1, executor.submitStartCounter);
|
||||
assertEquals(1, executor.submitCompleteCounter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void asyncMethodReturningFutureGetsRoutedAsynchronouslyAndReturnsAFuture() throws InterruptedException, ExecutionException {
|
||||
ClassWithoutAsyncAnnotation obj = new ClassWithoutAsyncAnnotation();
|
||||
Future<Integer> future = obj.incrementReturningAFuture();
|
||||
// No need to executor.waitForCompletion() as future.get() will have the same effect
|
||||
assertEquals(5, future.get().intValue());
|
||||
assertEquals(1, obj.counter);
|
||||
assertEquals(1, executor.submitStartCounter);
|
||||
assertEquals(1, executor.submitCompleteCounter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void syncMethodGetsRoutedSynchronously() {
|
||||
ClassWithoutAsyncAnnotation obj = new ClassWithoutAsyncAnnotation();
|
||||
obj.increment();
|
||||
assertEquals(1, obj.counter);
|
||||
assertEquals(0, executor.submitStartCounter);
|
||||
assertEquals(0, executor.submitCompleteCounter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void voidMethodInAsyncClassGetsRoutedAsynchronously() {
|
||||
ClassWithAsyncAnnotation obj = new ClassWithAsyncAnnotation();
|
||||
obj.increment();
|
||||
executor.waitForCompletion();
|
||||
assertEquals(1, obj.counter);
|
||||
assertEquals(1, executor.submitStartCounter);
|
||||
assertEquals(1, executor.submitCompleteCounter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void methodReturningFutureInAsyncClassGetsRoutedAsynchronouslyAndReturnsAFuture() throws InterruptedException, ExecutionException {
|
||||
ClassWithAsyncAnnotation obj = new ClassWithAsyncAnnotation();
|
||||
Future<Integer> future = obj.incrementReturningAFuture();
|
||||
assertEquals(5, future.get().intValue());
|
||||
assertEquals(1, obj.counter);
|
||||
assertEquals(1, executor.submitStartCounter);
|
||||
assertEquals(1, executor.submitCompleteCounter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void methodReturningNonVoidNonFutureInAsyncClassGetsRoutedSynchronously() {
|
||||
ClassWithAsyncAnnotation obj = new ClassWithAsyncAnnotation();
|
||||
int returnValue = obj.return5();
|
||||
assertEquals(5, returnValue);
|
||||
assertEquals(0, executor.submitStartCounter);
|
||||
assertEquals(0, executor.submitCompleteCounter);
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
private static class CountingExecutor extends SimpleAsyncTaskExecutor {
|
||||
int submitStartCounter;
|
||||
int submitCompleteCounter;
|
||||
|
||||
@Override
|
||||
public <T> Future<T> submit(Callable<T> task) {
|
||||
submitStartCounter++;
|
||||
Future<T> future = super.submit(task);
|
||||
submitCompleteCounter++;
|
||||
synchronized (this) {
|
||||
notifyAll();
|
||||
}
|
||||
return future;
|
||||
}
|
||||
|
||||
public synchronized void waitForCompletion() {
|
||||
try {
|
||||
wait(WAIT_TIME);
|
||||
} catch (InterruptedException e) {
|
||||
Assert.fail("Didn't finish the async job in " + WAIT_TIME + " milliseconds");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class ClassWithoutAsyncAnnotation {
|
||||
int counter;
|
||||
|
||||
@Async public void incrementAsync() {
|
||||
counter++;
|
||||
}
|
||||
|
||||
public void increment() {
|
||||
counter++;
|
||||
}
|
||||
|
||||
@Async public Future<Integer> incrementReturningAFuture() {
|
||||
counter++;
|
||||
return new AsyncResult<Integer>(5);
|
||||
}
|
||||
|
||||
// It should be an error to attach @Async to a method that returns a non-void
|
||||
// or non-Future.
|
||||
// We need to keep this commented out, otherwise there will be a compile-time error.
|
||||
// Please uncomment and re-comment this periodically to check that the compiler
|
||||
// produces an error message due to the 'declare error' statement
|
||||
// in AnnotationAsyncExecutionAspect
|
||||
// @Async public int getInt() {
|
||||
// return 0;
|
||||
// }
|
||||
}
|
||||
|
||||
@Async
|
||||
static class ClassWithAsyncAnnotation {
|
||||
int counter;
|
||||
|
||||
public void increment() {
|
||||
counter++;
|
||||
}
|
||||
|
||||
// Manually check that there is a warning from the 'declare warning' statement in AnnotationAsynchExecutionAspect
|
||||
public int return5() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
public Future<Integer> incrementReturningAFuture() {
|
||||
counter++;
|
||||
return new AsyncResult<Integer>(5);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,11 +4,12 @@ Bundle-Vendor: SpringSource
|
||||
Bundle-ManifestVersion: 2
|
||||
Import-Template:
|
||||
org.apache.commons.logging.*;version="[1.1.1, 2.0.0)",
|
||||
org.aspectj.*;version="[1.5.4, 2.0.0)";resolution:=optional,
|
||||
org.springframework.beans.*;version="[3.0.0, 3.0.1)",
|
||||
org.springframework.transaction.*;version="[3.0.0, 3.0.1)";resolution:=optional,
|
||||
org.springframework.orm.jpa.*;version="[3.0.0, 3.0.1)";resolution:=optional,
|
||||
org.springframework.dao.*;version="[3.0.0, 3.0.1)";resolution:=optional
|
||||
org.aspectj.*;version=${aj.osgi.range};resolution:=optional,
|
||||
org.springframework.beans.*;version=${spring.osgi.range},
|
||||
org.springframework.transaction.*;version=${spring.osgi.range};resolution:=optional,
|
||||
org.springframework.core.task.*;version=${spring.osgi.range};resolution:=optional,
|
||||
org.springframework.orm.jpa.*;version=${spring.osgi.range};resolution:=optional,
|
||||
org.springframework.dao.*;version=${spring.osgi.range};resolution:=optional
|
||||
Ignored-Existing-Headers:
|
||||
Bnd-LastModified,
|
||||
Import-Package,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="org.springframework.beans">
|
||||
<property file="${basedir}/../build.properties"/>
|
||||
<property file="${basedir}/../build.versions"/>
|
||||
<import file="${basedir}/../build-spring-framework/package-bundle.xml"/>
|
||||
<import file="${basedir}/../spring-build/standard/default.xml"/>
|
||||
</project>
|
||||
|
||||
@@ -11,23 +11,26 @@
|
||||
|
||||
<configurations>
|
||||
<include file="${spring.build.dir}/common/default-ivy-configurations.xml"/>
|
||||
<conf name="commons-logging" extends="runtime" description="JARs needed to run with Commons Logging"/>
|
||||
<conf name="bytecode-proxy" extends="runtime" description="JARs needed to run with CGLIB bytecode proxies"/>
|
||||
</configurations>
|
||||
|
||||
<publications>
|
||||
<artifact name="${ant.project.name}"/>
|
||||
<artifact name="${ant.project.name}-sources" type="src" ext="jar"/>
|
||||
<artifact name="license" type="license" ext="txt"/>
|
||||
<artifact name="notice" type="notice" ext="txt"/>
|
||||
</publications>
|
||||
|
||||
<dependencies>
|
||||
<dependency org="javax.el" name="com.springsource.javax.el" rev="1.0.0" conf="provided->compile"/>
|
||||
<dependency org="javax.inject" name="com.springsource.javax.inject" rev="1.0.0" conf="provided->compile"/>
|
||||
<dependency org="net.sourceforge.cglib" name="com.springsource.net.sf.cglib" rev="2.2.0" conf="optional, bytecode-proxy->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.logging" rev="1.1.1" conf="compile, commons-logging->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.junit" name="com.springsource.org.junit" rev="4.7.0" conf="test->runtime"/>
|
||||
<dependency org="org.junit" name="com.springsource.org.junit" rev="${junit.version}" conf="test->runtime"/>
|
||||
<dependency org="org.easymock" name="com.springsource.org.easymock" rev="2.5.1" conf="test->compile"/>
|
||||
<dependency org="org.springframework" name="org.springframework.asm" rev="latest.integration" conf="compile->compile"/>
|
||||
</dependencies>
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>3.0.0.BUILD-SNAPSHOT</version>
|
||||
<version>3.0.7.RELEASE</version>
|
||||
<parent>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-parent</artifactId>
|
||||
<relativePath>../org.springframework.spring-parent</relativePath>
|
||||
<version>3.0.0.BUILD-SNAPSHOT</version>
|
||||
<version>3.0.7.RELEASE</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
@@ -21,8 +21,8 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
<artifactId>com.springsource.javax.inject</artifactId>
|
||||
<version>0.9.0.PFD</version>
|
||||
<artifactId>javax.inject</artifactId>
|
||||
<version>1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@ public abstract class AbstractPropertyAccessor extends PropertyEditorRegistrySup
|
||||
setPropertyValue(pv.getName(), pv.getValue());
|
||||
}
|
||||
|
||||
public void setPropertyValues(Map map) throws BeansException {
|
||||
public void setPropertyValues(Map<?, ?> map) throws BeansException {
|
||||
setPropertyValues(new MutablePropertyValues(map));
|
||||
}
|
||||
|
||||
|
||||
-90
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* 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.beans;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* {@link TypeDescriptor} extension that exposes additional annotations
|
||||
* as conversion metadata: namely, annotations on other accessor methods
|
||||
* (getter/setter) and on the underlying field, if found.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
class BeanTypeDescriptor extends TypeDescriptor {
|
||||
|
||||
private final PropertyDescriptor propertyDescriptor;
|
||||
|
||||
private Annotation[] cachedAnnotations;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new BeanTypeDescriptor for the given bean property.
|
||||
* @param methodParameter the target method parameter
|
||||
* @param propertyDescriptor the corresponding JavaBean PropertyDescriptor
|
||||
*/
|
||||
public BeanTypeDescriptor(MethodParameter methodParameter, PropertyDescriptor propertyDescriptor) {
|
||||
super(methodParameter);
|
||||
this.propertyDescriptor = propertyDescriptor;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Annotation[] getAnnotations() {
|
||||
Annotation[] anns = this.cachedAnnotations;
|
||||
if (anns == null) {
|
||||
Field underlyingField = ReflectionUtils.findField(
|
||||
getMethodParameter().getMethod().getDeclaringClass(), this.propertyDescriptor.getName());
|
||||
Map<Class, Annotation> annMap = new LinkedHashMap<Class, Annotation>();
|
||||
if (underlyingField != null) {
|
||||
for (Annotation ann : underlyingField.getAnnotations()) {
|
||||
annMap.put(ann.annotationType(), ann);
|
||||
}
|
||||
}
|
||||
Method targetMethod = getMethodParameter().getMethod();
|
||||
Method writeMethod = this.propertyDescriptor.getWriteMethod();
|
||||
Method readMethod = this.propertyDescriptor.getReadMethod();
|
||||
if (writeMethod != null && writeMethod != targetMethod) {
|
||||
for (Annotation ann : writeMethod.getAnnotations()) {
|
||||
annMap.put(ann.annotationType(), ann);
|
||||
}
|
||||
}
|
||||
if (readMethod != null && readMethod != targetMethod) {
|
||||
for (Annotation ann : readMethod.getAnnotations()) {
|
||||
annMap.put(ann.annotationType(), ann);
|
||||
}
|
||||
}
|
||||
for (Annotation ann : targetMethod.getAnnotations()) {
|
||||
annMap.put(ann.annotationType(), ann);
|
||||
}
|
||||
anns = annMap.values().toArray(new Annotation[annMap.size()]);
|
||||
this.cachedAnnotations = anns;
|
||||
}
|
||||
return anns;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -389,8 +389,17 @@ public abstract class BeanUtils {
|
||||
}
|
||||
ClassLoader cl = targetType.getClassLoader();
|
||||
if (cl == null) {
|
||||
cl = ClassLoader.getSystemClassLoader();
|
||||
if (cl == null) {
|
||||
try {
|
||||
cl = ClassLoader.getSystemClassLoader();
|
||||
if (cl == null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
// e.g. AccessControlException on Google App Engine
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Could not access system ClassLoader: " + ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -398,8 +407,10 @@ public abstract class BeanUtils {
|
||||
try {
|
||||
Class<?> editorClass = cl.loadClass(editorName);
|
||||
if (!PropertyEditor.class.isAssignableFrom(editorClass)) {
|
||||
logger.warn("Editor class [" + editorName +
|
||||
"] does not implement [java.beans.PropertyEditor] interface");
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Editor class [" + editorName +
|
||||
"] does not implement [java.beans.PropertyEditor] interface");
|
||||
}
|
||||
unknownEditorTypes.put(targetType, Boolean.TRUE);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -79,11 +79,11 @@ public interface BeanWrapper extends ConfigurablePropertyAccessor {
|
||||
PropertyDescriptor getPropertyDescriptor(String propertyName) throws InvalidPropertyException;
|
||||
|
||||
/**
|
||||
* Set if this BeanWrapper should attempt to "auto-grow" a nested path that contains a null value.
|
||||
* <p>If true, a null path location will be populated with a default object value and traversed
|
||||
* Set whether this BeanWrapper should attempt to "auto-grow" a nested path that contains a null value.
|
||||
* <p>If "true", a null path location will be populated with a default object value and traversed
|
||||
* instead of resulting in a {@link NullValueInNestedPathException}. Turning this flag on also
|
||||
* enables auto-growth of collection elements when an index that is out of bounds is accessed.
|
||||
* <p>Default is false.
|
||||
* enables auto-growth of collection elements when accessing an out-of-bounds index.
|
||||
* <p>Default is "false" on a plain BeanWrapper.
|
||||
*/
|
||||
void setAutoGrowNestedPaths(boolean autoGrowNestedPaths);
|
||||
|
||||
@@ -92,4 +92,15 @@ public interface BeanWrapper extends ConfigurablePropertyAccessor {
|
||||
*/
|
||||
boolean isAutoGrowNestedPaths();
|
||||
|
||||
/**
|
||||
* Specify a limit for array and collection auto-growing.
|
||||
* <p>Default is unlimited on a plain BeanWrapper.
|
||||
*/
|
||||
void setAutoGrowCollectionLimit(int autoGrowCollectionLimit);
|
||||
|
||||
/**
|
||||
* Return the limit for array and collection auto-growing.
|
||||
*/
|
||||
int getAutoGrowCollectionLimit();
|
||||
|
||||
}
|
||||
|
||||
+201
-165
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,11 +37,14 @@ import java.util.Set;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.core.CollectionFactory;
|
||||
import org.springframework.core.GenericCollectionTypeResolver;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.convert.ConversionException;
|
||||
import org.springframework.core.convert.ConverterNotFoundException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.support.PropertyTypeDescriptor;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -99,6 +102,11 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
|
||||
private TypeConverterDelegate typeConverterDelegate;
|
||||
|
||||
/**
|
||||
* The security context used for invoking the property methods
|
||||
*/
|
||||
private AccessControlContext acc;
|
||||
|
||||
/**
|
||||
* Cached introspections results for this object, to prevent encountering
|
||||
* the cost of JavaBeans introspection every time.
|
||||
@@ -110,11 +118,10 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
*/
|
||||
private Map<String, BeanWrapperImpl> nestedBeanWrappers;
|
||||
|
||||
/** The security context used for invoking the property methods */
|
||||
private AccessControlContext acc;
|
||||
|
||||
private boolean autoGrowNestedPaths = false;
|
||||
|
||||
private int autoGrowCollectionLimit = Integer.MAX_VALUE;
|
||||
|
||||
|
||||
/**
|
||||
* Create new empty BeanWrapperImpl. Wrapped instance needs to be set afterwards.
|
||||
@@ -179,6 +186,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
setWrappedInstance(object, nestedPath, superBw.getWrappedInstance());
|
||||
setExtractOldValueForEditor(superBw.isExtractOldValueForEditor());
|
||||
setAutoGrowNestedPaths(superBw.isAutoGrowNestedPaths());
|
||||
setAutoGrowCollectionLimit(superBw.getAutoGrowCollectionLimit());
|
||||
setConversionService(superBw.getConversionService());
|
||||
setSecurityContext(superBw.acc);
|
||||
}
|
||||
@@ -214,16 +222,6 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
setIntrospectionClass(object.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the security context used during the invocation of the wrapped instance methods.
|
||||
* Can be null.
|
||||
*
|
||||
* @param acc
|
||||
*/
|
||||
public void setSecurityContext(AccessControlContext acc) {
|
||||
this.acc = acc;
|
||||
}
|
||||
|
||||
public final Object getWrappedInstance() {
|
||||
return this.object;
|
||||
}
|
||||
@@ -256,22 +254,54 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
}
|
||||
|
||||
/**
|
||||
* If this BeanWrapper should "auto grow" nested paths.
|
||||
* When true, auto growth is triggered on nested paths when null values are encountered.
|
||||
* When true, auto growth is triggered on collection properties when out of bounds indexes are accessed.
|
||||
* Default is false.
|
||||
* Set whether this BeanWrapper should attempt to "auto-grow" a nested path that contains a null value.
|
||||
* <p>If "true", a null path location will be populated with a default object value and traversed
|
||||
* instead of resulting in a {@link NullValueInNestedPathException}. Turning this flag on also
|
||||
* enables auto-growth of collection elements when accessing an out-of-bounds index.
|
||||
* <p>Default is "false" on a plain BeanWrapper.
|
||||
*/
|
||||
public void setAutoGrowNestedPaths(boolean autoGrowNestedPaths) {
|
||||
this.autoGrowNestedPaths = autoGrowNestedPaths;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this BeanWrapper should "auto grow" nested paths.
|
||||
* Return whether "auto-growing" of nested paths has been activated.
|
||||
*/
|
||||
public boolean isAutoGrowNestedPaths() {
|
||||
return this.autoGrowNestedPaths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a limit for array and collection auto-growing.
|
||||
* <p>Default is unlimited on a plain BeanWrapper.
|
||||
*/
|
||||
public void setAutoGrowCollectionLimit(int autoGrowCollectionLimit) {
|
||||
this.autoGrowCollectionLimit = autoGrowCollectionLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the limit for array and collection auto-growing.
|
||||
*/
|
||||
public int getAutoGrowCollectionLimit() {
|
||||
return this.autoGrowCollectionLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the security context used during the invocation of the wrapped instance methods.
|
||||
* Can be null.
|
||||
*/
|
||||
public void setSecurityContext(AccessControlContext acc) {
|
||||
this.acc = acc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the security context used during the invocation of the wrapped instance methods.
|
||||
* Can be null.
|
||||
*/
|
||||
public AccessControlContext getSecurityContext() {
|
||||
return this.acc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the class to introspect.
|
||||
* Needs to be called when the target object changes.
|
||||
@@ -353,13 +383,15 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
|
||||
public TypeDescriptor getPropertyTypeDescriptor(String propertyName) throws BeansException {
|
||||
try {
|
||||
PropertyDescriptor pd = getPropertyDescriptorInternal(propertyName);
|
||||
String actualPropertyName = PropertyAccessorUtils.getPropertyName(propertyName);
|
||||
PropertyDescriptor pd = getPropertyDescriptorInternal(actualPropertyName);
|
||||
if (pd != null) {
|
||||
Class type = getPropertyType(propertyName);
|
||||
if (pd.getReadMethod() != null) {
|
||||
return new BeanTypeDescriptor(new MethodParameter(pd.getReadMethod(), -1), pd);
|
||||
return new PropertyTypeDescriptor(pd, new MethodParameter(pd.getReadMethod(), -1), type);
|
||||
}
|
||||
else if (pd.getWriteMethod() != null) {
|
||||
return new BeanTypeDescriptor(BeanUtils.getWriteMethodParameter(pd), pd);
|
||||
return new PropertyTypeDescriptor(pd, BeanUtils.getWriteMethodParameter(pd), type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -409,17 +441,56 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
return false;
|
||||
}
|
||||
|
||||
public <T> T convertIfNecessary(
|
||||
Object value, Class<T> requiredType, MethodParameter methodParam) throws TypeMismatchException {
|
||||
public <T> T convertIfNecessary(Object value, Class<T> requiredType, MethodParameter methodParam)
|
||||
throws TypeMismatchException {
|
||||
try {
|
||||
return this.typeConverterDelegate.convertIfNecessary(value, requiredType, methodParam);
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
catch (ConverterNotFoundException ex) {
|
||||
throw new ConversionNotSupportedException(value, requiredType, ex);
|
||||
}
|
||||
catch (ConversionException ex) {
|
||||
throw new TypeMismatchException(value, requiredType, ex);
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
throw new ConversionNotSupportedException(value, requiredType, ex);
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
throw new TypeMismatchException(value, requiredType, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private Object convertIfNecessary(String propertyName, Object oldValue, Object newValue, Class<?> requiredType,
|
||||
TypeDescriptor td) throws TypeMismatchException {
|
||||
try {
|
||||
return this.typeConverterDelegate.convertIfNecessary(propertyName, oldValue, newValue, requiredType, td);
|
||||
}
|
||||
catch (ConverterNotFoundException ex) {
|
||||
PropertyChangeEvent pce =
|
||||
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, newValue);
|
||||
throw new ConversionNotSupportedException(pce, td.getType(), ex);
|
||||
}
|
||||
catch (ConversionException ex) {
|
||||
PropertyChangeEvent pce =
|
||||
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, newValue);
|
||||
throw new TypeMismatchException(pce, requiredType, ex);
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
PropertyChangeEvent pce =
|
||||
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, newValue);
|
||||
throw new ConversionNotSupportedException(pce, requiredType, ex);
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
PropertyChangeEvent pce =
|
||||
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, newValue);
|
||||
throw new TypeMismatchException(pce, requiredType, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private Object convertIfNecessary(String propertyName, Object oldValue, Object newValue, Class<?> requiredType)
|
||||
throws TypeMismatchException {
|
||||
|
||||
return convertIfNecessary(propertyName, oldValue, newValue, requiredType, TypeDescriptor.valueOf(requiredType));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -438,19 +509,14 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
|
||||
"No property '" + propertyName + "' found");
|
||||
}
|
||||
try {
|
||||
return this.typeConverterDelegate.convertIfNecessary(null, value, pd);
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
PropertyChangeEvent pce =
|
||||
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, null, value);
|
||||
throw new TypeMismatchException(pce, pd.getPropertyType(), ex);
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
PropertyChangeEvent pce =
|
||||
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, null, value);
|
||||
throw new ConversionNotSupportedException(pce, pd.getPropertyType(), ex);
|
||||
}
|
||||
return convertForProperty(propertyName, null, value, pd);
|
||||
}
|
||||
|
||||
private Object convertForProperty(String propertyName, Object oldValue, Object newValue, PropertyDescriptor pd)
|
||||
throws TypeMismatchException {
|
||||
|
||||
return convertIfNecessary(propertyName, oldValue, newValue, pd.getPropertyType(),
|
||||
new PropertyTypeDescriptor(pd, BeanUtils.getWriteMethodParameter(pd)));
|
||||
}
|
||||
|
||||
|
||||
@@ -539,21 +605,25 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
PropertyTokenHolder tokens = new PropertyTokenHolder();
|
||||
tokens.actualName = propertyName;
|
||||
tokens.canonicalName = propertyName;
|
||||
setPropertyValue(tokens, createDefaultPropertyValue(tokens));
|
||||
return getPropertyValue(tokens);
|
||||
return setDefaultValue(tokens);
|
||||
}
|
||||
|
||||
private Object setDefaultValue(PropertyTokenHolder tokens) {
|
||||
setPropertyValue(tokens, createDefaultPropertyValue(tokens));
|
||||
PropertyValue pv = createDefaultPropertyValue(tokens);
|
||||
setPropertyValue(tokens, pv);
|
||||
return getPropertyValue(tokens);
|
||||
}
|
||||
|
||||
|
||||
private PropertyValue createDefaultPropertyValue(PropertyTokenHolder tokens) {
|
||||
PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(tokens.actualName);
|
||||
Object defaultValue = newValue(pd.getPropertyType(), tokens.canonicalName);
|
||||
Class type = getPropertyType(tokens.canonicalName);
|
||||
if (type == null) {
|
||||
throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + tokens.canonicalName,
|
||||
"Could not determine property type for auto-growing a default value");
|
||||
}
|
||||
Object defaultValue = newValue(type, tokens.canonicalName);
|
||||
return new PropertyValue(tokens.canonicalName, defaultValue);
|
||||
}
|
||||
|
||||
|
||||
private Object newValue(Class<?> type, String name) {
|
||||
try {
|
||||
if (type.isArray()) {
|
||||
@@ -568,20 +638,22 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
return Array.newInstance(componentType, 0);
|
||||
}
|
||||
}
|
||||
else if (Collection.class.isAssignableFrom(type)) {
|
||||
return CollectionFactory.createCollection(type, 16);
|
||||
}
|
||||
else if (Map.class.isAssignableFrom(type)) {
|
||||
return CollectionFactory.createMap(type, 16);
|
||||
}
|
||||
else {
|
||||
if (Collection.class.isAssignableFrom(type)) {
|
||||
return CollectionFactory.createCollection(type, 16);
|
||||
}
|
||||
else {
|
||||
return type.newInstance();
|
||||
}
|
||||
return type.newInstance();
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + name, "Could not instantiate property type [" + type.getName() + "] to auto-grow nested property path: " + ex);
|
||||
throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + name,
|
||||
"Could not instantiate property type [" + type.getName() + "] to auto-grow nested property path: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new nested BeanWrapper instance.
|
||||
* <p>Default implementation creates a BeanWrapperImpl instance.
|
||||
@@ -670,7 +742,6 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
}
|
||||
|
||||
Object value;
|
||||
|
||||
if (System.getSecurityManager() != null) {
|
||||
try {
|
||||
value = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
|
||||
@@ -684,7 +755,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
}
|
||||
}
|
||||
else {
|
||||
value = readMethod.invoke(object, (Object[]) null);
|
||||
value = readMethod.invoke(object, (Object[]) null);
|
||||
}
|
||||
|
||||
if (tokens.keys != null) {
|
||||
@@ -741,9 +812,8 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
Class<?> mapKeyType = GenericCollectionTypeResolver.getMapKeyReturnType(pd.getReadMethod(), i + 1);
|
||||
// IMPORTANT: Do not pass full property name in here - property editors
|
||||
// must not kick in for map keys but rather only for map values.
|
||||
Object convertedMapKey = this.typeConverterDelegate.convertIfNecessary(key, mapKeyType);
|
||||
// Pass full property name and old value in here, since we want full
|
||||
// conversion ability for map values.
|
||||
Object convertedMapKey = convertIfNecessary(null, null, key, mapKeyType,
|
||||
new PropertyTypeDescriptor(pd, new MethodParameter(pd.getReadMethod(), -1), mapKeyType));
|
||||
value = map.get(convertedMapKey);
|
||||
}
|
||||
else {
|
||||
@@ -756,15 +826,6 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
}
|
||||
return value;
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
|
||||
"Getter for property '" + actualName + "' threw exception", ex);
|
||||
}
|
||||
|
||||
catch(IllegalAccessException ex) {
|
||||
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
|
||||
"Illegal attempt to get property '" + actualName + "' threw exception", ex);
|
||||
}
|
||||
catch (IndexOutOfBoundsException ex) {
|
||||
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
|
||||
"Index of out of bounds in property path '" + propertyName + "'", ex);
|
||||
@@ -773,10 +834,18 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
|
||||
"Invalid index in property path '" + propertyName + "'", ex);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
catch (TypeMismatchException ex) {
|
||||
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
|
||||
"Invalid index in property path '" + propertyName + "'", ex);
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
|
||||
"Getter for property '" + actualName + "' threw exception", ex);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
|
||||
"Illegal attempt to get property '" + actualName + "' threw exception", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private Object growArrayIfNecessary(Object array, int index, String name) {
|
||||
@@ -784,25 +853,31 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
return array;
|
||||
}
|
||||
int length = Array.getLength(array);
|
||||
if (index >= length) {
|
||||
if (index >= length && index < this.autoGrowCollectionLimit) {
|
||||
Class<?> componentType = array.getClass().getComponentType();
|
||||
Object newArray = Array.newInstance(componentType, index + 1);
|
||||
System.arraycopy(array, 0, newArray, 0, length);
|
||||
for (int i = length; i < Array.getLength(newArray); i++) {
|
||||
Array.set(newArray, i, newValue(componentType, name));
|
||||
}
|
||||
// TODO this is not efficient because conversion may create a copy ... set directly because we know it is assignable.
|
||||
setPropertyValue(name, newArray);
|
||||
return newArray;
|
||||
} else {
|
||||
return getPropertyValue(name);
|
||||
}
|
||||
else {
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
||||
private void growCollectionIfNecessary(Collection collection, int index, String name, PropertyDescriptor pd, int nestingLevel) {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void growCollectionIfNecessary(
|
||||
Collection collection, int index, String name, PropertyDescriptor pd, int nestingLevel) {
|
||||
|
||||
if (!this.autoGrowNestedPaths) {
|
||||
return;
|
||||
}
|
||||
if (index >= collection.size()) {
|
||||
int size = collection.size();
|
||||
if (index >= size && index < this.autoGrowCollectionLimit) {
|
||||
Class elementType = GenericCollectionTypeResolver.getCollectionReturnType(pd.getReadMethod(), nestingLevel);
|
||||
if (elementType != null) {
|
||||
for (int i = collection.size(); i < index + 1; i++) {
|
||||
@@ -811,7 +886,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setPropertyValue(String propertyName, Object value) throws BeansException {
|
||||
BeanWrapperImpl nestedBw;
|
||||
@@ -878,27 +953,18 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
"Cannot access indexed value in property referenced " +
|
||||
"in indexed property path '" + propertyName + "': returned null");
|
||||
}
|
||||
else if (propValue.getClass().isArray()) {
|
||||
if (propValue.getClass().isArray()) {
|
||||
PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
|
||||
Class requiredType = propValue.getClass().getComponentType();
|
||||
int arrayIndex = Integer.parseInt(key);
|
||||
Object oldValue = null;
|
||||
try {
|
||||
if (isExtractOldValueForEditor()) {
|
||||
if (isExtractOldValueForEditor() && arrayIndex < Array.getLength(propValue)) {
|
||||
oldValue = Array.get(propValue, arrayIndex);
|
||||
}
|
||||
Object convertedValue = this.typeConverterDelegate.convertIfNecessary(
|
||||
propertyName, oldValue, pv.getValue(), requiredType);
|
||||
Array.set(propValue, Integer.parseInt(key), convertedValue);
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
PropertyChangeEvent pce =
|
||||
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
|
||||
throw new TypeMismatchException(pce, requiredType, ex);
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
PropertyChangeEvent pce =
|
||||
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
|
||||
throw new ConversionNotSupportedException(pce, requiredType, ex);
|
||||
Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(), requiredType,
|
||||
new PropertyTypeDescriptor(pd, new MethodParameter(pd.getReadMethod(), -1), requiredType));
|
||||
Array.set(propValue, arrayIndex, convertedValue);
|
||||
}
|
||||
catch (IndexOutOfBoundsException ex) {
|
||||
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
|
||||
@@ -915,32 +981,32 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
if (isExtractOldValueForEditor() && index < list.size()) {
|
||||
oldValue = list.get(index);
|
||||
}
|
||||
try {
|
||||
Object convertedValue = this.typeConverterDelegate.convertIfNecessary(
|
||||
propertyName, oldValue, pv.getValue(), requiredType);
|
||||
if (index < list.size()) {
|
||||
Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(), requiredType,
|
||||
new PropertyTypeDescriptor(pd, new MethodParameter(pd.getReadMethod(), -1), requiredType));
|
||||
int size = list.size();
|
||||
if (index >= size && index < this.autoGrowCollectionLimit) {
|
||||
for (int i = size; i < index; i++) {
|
||||
try {
|
||||
list.add(null);
|
||||
}
|
||||
catch (NullPointerException ex) {
|
||||
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
|
||||
"Cannot set element with index " + index + " in List of size " +
|
||||
size + ", accessed using property path '" + propertyName +
|
||||
"': List does not support filling up gaps with null elements");
|
||||
}
|
||||
}
|
||||
list.add(convertedValue);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
list.set(index, convertedValue);
|
||||
}
|
||||
else if (index >= list.size()) {
|
||||
for (int i = list.size(); i < index; i++) {
|
||||
try {
|
||||
list.add(null);
|
||||
}
|
||||
catch (NullPointerException ex) {
|
||||
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
|
||||
"Cannot set element with index " + index + " in List of size " +
|
||||
list.size() + ", accessed using property path '" + propertyName +
|
||||
"': List does not support filling up gaps with null elements");
|
||||
}
|
||||
}
|
||||
list.add(convertedValue);
|
||||
catch (IndexOutOfBoundsException ex) {
|
||||
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
|
||||
"Invalid list index in property path '" + propertyName + "'", ex);
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
PropertyChangeEvent pce =
|
||||
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
|
||||
throw new TypeMismatchException(pce, requiredType, ex);
|
||||
}
|
||||
}
|
||||
else if (propValue instanceof Map) {
|
||||
PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
|
||||
@@ -949,34 +1015,19 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
Class mapValueType = GenericCollectionTypeResolver.getMapValueReturnType(
|
||||
pd.getReadMethod(), tokens.keys.length);
|
||||
Map map = (Map) propValue;
|
||||
Object convertedMapKey;
|
||||
Object convertedMapValue;
|
||||
try {
|
||||
// IMPORTANT: Do not pass full property name in here - property editors
|
||||
// must not kick in for map keys but rather only for map values.
|
||||
convertedMapKey = this.typeConverterDelegate.convertIfNecessary(key, mapKeyType);
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
PropertyChangeEvent pce =
|
||||
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, null, pv.getValue());
|
||||
throw new TypeMismatchException(pce, mapKeyType, ex);
|
||||
}
|
||||
// IMPORTANT: Do not pass full property name in here - property editors
|
||||
// must not kick in for map keys but rather only for map values.
|
||||
Object convertedMapKey = convertIfNecessary(null, null, key, mapKeyType,
|
||||
new PropertyTypeDescriptor(pd, new MethodParameter(pd.getReadMethod(), -1), mapKeyType));
|
||||
Object oldValue = null;
|
||||
if (isExtractOldValueForEditor()) {
|
||||
oldValue = map.get(convertedMapKey);
|
||||
}
|
||||
try {
|
||||
// Pass full property name and old value in here, since we want full
|
||||
// conversion ability for map values.
|
||||
convertedMapValue = this.typeConverterDelegate.convertIfNecessary(
|
||||
propertyName, oldValue, pv.getValue(), mapValueType, null,
|
||||
new MethodParameter(pd.getReadMethod(), -1, tokens.keys.length + 1));
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
PropertyChangeEvent pce =
|
||||
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
|
||||
throw new TypeMismatchException(pce, mapValueType, ex);
|
||||
}
|
||||
// Pass full property name and old value in here, since we want full
|
||||
// conversion ability for map values.
|
||||
Object convertedMapValue = convertIfNecessary(
|
||||
propertyName, oldValue, pv.getValue(), mapValueType,
|
||||
new TypeDescriptor(new MethodParameter(pd.getReadMethod(), -1, tokens.keys.length + 1)));
|
||||
map.put(convertedMapKey, convertedMapValue);
|
||||
}
|
||||
else {
|
||||
@@ -1017,7 +1068,8 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
else {
|
||||
if (isExtractOldValueForEditor() && pd.getReadMethod() != null) {
|
||||
final Method readMethod = pd.getReadMethod();
|
||||
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers()) && !readMethod.isAccessible()) {
|
||||
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers()) &&
|
||||
!readMethod.isAccessible()) {
|
||||
if (System.getSecurityManager()!= null) {
|
||||
AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||
public Object run() {
|
||||
@@ -1036,7 +1088,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
public Object run() throws Exception {
|
||||
return readMethod.invoke(object);
|
||||
}
|
||||
},acc);
|
||||
}, acc);
|
||||
}
|
||||
else {
|
||||
oldValue = readMethod.invoke(object);
|
||||
@@ -1052,11 +1104,13 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
}
|
||||
}
|
||||
}
|
||||
valueToApply = this.typeConverterDelegate.convertIfNecessary(oldValue, originalValue, pd);
|
||||
valueToApply = convertForProperty(propertyName, oldValue, originalValue, pd);
|
||||
}
|
||||
pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
|
||||
}
|
||||
final Method writeMethod = pd.getWriteMethod();
|
||||
final Method writeMethod = (pd instanceof GenericTypeAwarePropertyDescriptor ?
|
||||
((GenericTypeAwarePropertyDescriptor) pd).getWriteMethodForActualAccess() :
|
||||
pd.getWriteMethod());
|
||||
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers()) && !writeMethod.isAccessible()) {
|
||||
if (System.getSecurityManager()!= null) {
|
||||
AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||
@@ -1071,7 +1125,6 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
}
|
||||
}
|
||||
final Object value = valueToApply;
|
||||
|
||||
if (System.getSecurityManager() != null) {
|
||||
try {
|
||||
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
|
||||
@@ -1080,14 +1133,17 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
return null;
|
||||
}
|
||||
}, acc);
|
||||
} catch (PrivilegedActionException ex) {
|
||||
}
|
||||
catch (PrivilegedActionException ex) {
|
||||
throw ex.getException();
|
||||
}
|
||||
}
|
||||
else {
|
||||
writeMethod.invoke(object, value);
|
||||
writeMethod.invoke(this.object, value);
|
||||
}
|
||||
|
||||
}
|
||||
catch (TypeMismatchException ex) {
|
||||
throw ex;
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
PropertyChangeEvent propertyChangeEvent =
|
||||
@@ -1099,29 +1155,9 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
throw new MethodInvocationException(propertyChangeEvent, ex.getTargetException());
|
||||
}
|
||||
}
|
||||
catch (ConversionException ex) {
|
||||
PropertyChangeEvent pce =
|
||||
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
|
||||
throw new TypeMismatchException(pce, pd.getPropertyType(), ex);
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
PropertyChangeEvent pce =
|
||||
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
|
||||
throw new TypeMismatchException(pce, pd.getPropertyType(), ex);
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
PropertyChangeEvent pce =
|
||||
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
|
||||
throw new ConversionNotSupportedException(pce, pd.getPropertyType(), ex);
|
||||
}
|
||||
catch (IllegalAccessException ex) {
|
||||
PropertyChangeEvent pce =
|
||||
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
|
||||
throw new MethodInvocationException(pce, ex);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
PropertyChangeEvent pce =
|
||||
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
|
||||
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
|
||||
throw new MethodInvocationException(pce, ex);
|
||||
}
|
||||
}
|
||||
|
||||
+49
-18
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,18 +23,18 @@ import java.beans.PropertyDescriptor;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Internal class that caches JavaBeans {@link java.beans.PropertyDescriptor}
|
||||
@@ -130,7 +130,7 @@ public class CachedIntrospectionResults {
|
||||
* @throws BeansException in case of introspection failure
|
||||
*/
|
||||
static CachedIntrospectionResults forClass(Class beanClass) throws BeansException {
|
||||
CachedIntrospectionResults results = null;
|
||||
CachedIntrospectionResults results;
|
||||
Object value = classCache.get(beanClass);
|
||||
if (value instanceof Reference) {
|
||||
Reference ref = (Reference) value;
|
||||
@@ -140,19 +140,20 @@ public class CachedIntrospectionResults {
|
||||
results = (CachedIntrospectionResults) value;
|
||||
}
|
||||
if (results == null) {
|
||||
// can throw BeansException
|
||||
results = new CachedIntrospectionResults(beanClass);
|
||||
// On JDK 1.5 and higher, it is almost always safe to cache the bean class...
|
||||
// The sole exception is a custom BeanInfo class being provided in a non-safe ClassLoader.
|
||||
if (ClassUtils.isCacheSafe(beanClass, CachedIntrospectionResults.class.getClassLoader()) ||
|
||||
isClassLoaderAccepted(beanClass.getClassLoader()) ||
|
||||
!ClassUtils.isPresent(beanClass.getName() + "BeanInfo", beanClass.getClassLoader())) {
|
||||
boolean fullyCacheable =
|
||||
ClassUtils.isCacheSafe(beanClass, CachedIntrospectionResults.class.getClassLoader()) ||
|
||||
isClassLoaderAccepted(beanClass.getClassLoader());
|
||||
if (fullyCacheable || !ClassUtils.isPresent(beanClass.getName() + "BeanInfo", beanClass.getClassLoader())) {
|
||||
results = new CachedIntrospectionResults(beanClass, fullyCacheable);
|
||||
classCache.put(beanClass, results);
|
||||
}
|
||||
else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Not strongly caching class [" + beanClass.getName() + "] because it is not cache-safe");
|
||||
}
|
||||
results = new CachedIntrospectionResults(beanClass, true);
|
||||
classCache.put(beanClass, new WeakReference<CachedIntrospectionResults>(results));
|
||||
}
|
||||
}
|
||||
@@ -215,7 +216,7 @@ public class CachedIntrospectionResults {
|
||||
* @param beanClass the bean class to analyze
|
||||
* @throws BeansException in case of introspection failure
|
||||
*/
|
||||
private CachedIntrospectionResults(Class beanClass) throws BeansException {
|
||||
private CachedIntrospectionResults(Class beanClass, boolean cacheFullMetadata) throws BeansException {
|
||||
try {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Getting BeanInfo for class [" + beanClass.getName() + "]");
|
||||
@@ -236,24 +237,29 @@ public class CachedIntrospectionResults {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Caching PropertyDescriptors for class [" + beanClass.getName() + "]");
|
||||
}
|
||||
this.propertyDescriptorCache = new HashMap<String, PropertyDescriptor>();
|
||||
this.propertyDescriptorCache = new LinkedHashMap<String, PropertyDescriptor>();
|
||||
|
||||
// This call is slow so we do it once.
|
||||
PropertyDescriptor[] pds = this.beanInfo.getPropertyDescriptors();
|
||||
for (PropertyDescriptor pd : pds) {
|
||||
if (Class.class.equals(beanClass) && "classLoader".equals(pd.getName())) {
|
||||
// Ignore Class.getClassLoader() method - nobody needs to bind to that
|
||||
continue;
|
||||
}
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Found bean property '" + pd.getName() + "'" +
|
||||
(pd.getPropertyType() != null ? " of type [" + pd.getPropertyType().getName() + "]" : "") +
|
||||
(pd.getPropertyEditorClass() != null ?
|
||||
"; editor [" + pd.getPropertyEditorClass().getName() + "]" : ""));
|
||||
}
|
||||
pd = new GenericTypeAwarePropertyDescriptor(beanClass, pd.getName(), pd.getReadMethod(),
|
||||
pd.getWriteMethod(), pd.getPropertyEditorClass());
|
||||
if (cacheFullMetadata) {
|
||||
pd = buildGenericTypeAwarePropertyDescriptor(beanClass, pd);
|
||||
}
|
||||
this.propertyDescriptorCache.put(pd.getName(), pd);
|
||||
}
|
||||
}
|
||||
catch (IntrospectionException ex) {
|
||||
throw new FatalBeanException("Cannot get BeanInfo for object of class [" + beanClass.getName() + "]", ex);
|
||||
throw new FatalBeanException("Failed to obtain BeanInfo for class [" + beanClass.getName() + "]", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,13 +271,38 @@ public class CachedIntrospectionResults {
|
||||
return this.beanInfo.getBeanDescriptor().getBeanClass();
|
||||
}
|
||||
|
||||
PropertyDescriptor getPropertyDescriptor(String propertyName) {
|
||||
return this.propertyDescriptorCache.get(propertyName);
|
||||
PropertyDescriptor getPropertyDescriptor(String name) {
|
||||
PropertyDescriptor pd = this.propertyDescriptorCache.get(name);
|
||||
if (pd == null && StringUtils.hasLength(name)) {
|
||||
// Same lenient fallback checking as in PropertyTypeDescriptor...
|
||||
pd = this.propertyDescriptorCache.get(name.substring(0, 1).toLowerCase() + name.substring(1));
|
||||
if (pd == null) {
|
||||
pd = this.propertyDescriptorCache.get(name.substring(0, 1).toUpperCase() + name.substring(1));
|
||||
}
|
||||
}
|
||||
return (pd == null || pd instanceof GenericTypeAwarePropertyDescriptor ? pd :
|
||||
buildGenericTypeAwarePropertyDescriptor(getBeanClass(), pd));
|
||||
}
|
||||
|
||||
PropertyDescriptor[] getPropertyDescriptors() {
|
||||
Collection<PropertyDescriptor> descriptorCollection = this.propertyDescriptorCache.values();
|
||||
return descriptorCollection.toArray(new PropertyDescriptor[descriptorCollection.size()]);
|
||||
PropertyDescriptor[] pds = new PropertyDescriptor[this.propertyDescriptorCache.size()];
|
||||
int i = 0;
|
||||
for (PropertyDescriptor pd : this.propertyDescriptorCache.values()) {
|
||||
pds[i] = (pd instanceof GenericTypeAwarePropertyDescriptor ? pd :
|
||||
buildGenericTypeAwarePropertyDescriptor(getBeanClass(), pd));
|
||||
i++;
|
||||
}
|
||||
return pds;
|
||||
}
|
||||
|
||||
private PropertyDescriptor buildGenericTypeAwarePropertyDescriptor(Class beanClass, PropertyDescriptor pd) {
|
||||
try {
|
||||
return new GenericTypeAwarePropertyDescriptor(beanClass, pd.getName(), pd.getReadMethod(),
|
||||
pd.getWriteMethod(), pd.getPropertyEditorClass());
|
||||
}
|
||||
catch (IntrospectionException ex) {
|
||||
throw new FatalBeanException("Failed to re-introspect class [" + beanClass.getName() + "]", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+15
-9
@@ -19,26 +19,32 @@ package org.springframework.beans;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
|
||||
/**
|
||||
* Exception thrown when no suitable editor can be found to set a bean property.
|
||||
* Exception thrown when no suitable editor or converter can be found for a bean property.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
public class ConversionNotSupportedException extends TypeMismatchException {
|
||||
|
||||
public ConversionNotSupportedException(PropertyChangeEvent propertyChangeEvent, Class requiredType) {
|
||||
super(propertyChangeEvent, requiredType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new ConversionNotSupportedException.
|
||||
* @param propertyChangeEvent the PropertyChangeEvent that resulted in the problem
|
||||
* @param requiredType the required target type (or <code>null</code> if not known)
|
||||
* @param cause the root cause (may be <code>null</code>)
|
||||
*/
|
||||
public ConversionNotSupportedException(PropertyChangeEvent propertyChangeEvent, Class requiredType, Throwable cause) {
|
||||
super(propertyChangeEvent, requiredType, cause);
|
||||
}
|
||||
|
||||
public ConversionNotSupportedException(Object value, Class requiredType) {
|
||||
super(value, requiredType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new ConversionNotSupportedException.
|
||||
* @param value the offending value that couldn't be converted (may be <code>null</code>)
|
||||
* @param requiredType the required target type (or <code>null</code> if not known)
|
||||
* @param cause the root cause (may be <code>null</code>)
|
||||
*/
|
||||
public ConversionNotSupportedException(Object value, Class requiredType, Throwable cause) {
|
||||
super(value, requiredType, cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+18
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,6 +22,8 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.convert.ConversionException;
|
||||
import org.springframework.core.convert.ConverterNotFoundException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
@@ -122,14 +124,15 @@ public class DirectFieldAccessor extends AbstractPropertyAccessor {
|
||||
try {
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
oldValue = field.get(this.target);
|
||||
Object convertedValue =
|
||||
this.typeConverterDelegate.convertIfNecessary(propertyName, oldValue, newValue, field.getType());
|
||||
Object convertedValue = this.typeConverterDelegate.convertIfNecessary(
|
||||
field.getName(), oldValue, newValue, field.getType(), new TypeDescriptor(field));
|
||||
field.set(this.target, convertedValue);
|
||||
}
|
||||
catch (IllegalAccessException ex) {
|
||||
throw new InvalidPropertyException(this.target.getClass(), propertyName, "Field is not accessible", ex);
|
||||
catch (ConverterNotFoundException ex) {
|
||||
PropertyChangeEvent pce = new PropertyChangeEvent(this.target, propertyName, oldValue, newValue);
|
||||
throw new ConversionNotSupportedException(pce, field.getType(), ex);
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
catch (ConversionException ex) {
|
||||
PropertyChangeEvent pce = new PropertyChangeEvent(this.target, propertyName, oldValue, newValue);
|
||||
throw new TypeMismatchException(pce, field.getType(), ex);
|
||||
}
|
||||
@@ -137,10 +140,17 @@ public class DirectFieldAccessor extends AbstractPropertyAccessor {
|
||||
PropertyChangeEvent pce = new PropertyChangeEvent(this.target, propertyName, oldValue, newValue);
|
||||
throw new ConversionNotSupportedException(pce, field.getType(), ex);
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
PropertyChangeEvent pce = new PropertyChangeEvent(this.target, propertyName, oldValue, newValue);
|
||||
throw new TypeMismatchException(pce, field.getType(), ex);
|
||||
}
|
||||
catch (IllegalAccessException ex) {
|
||||
throw new InvalidPropertyException(this.target.getClass(), propertyName, "Field is not accessible", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public Object convertIfNecessary(
|
||||
Object value, Class requiredType, MethodParameter methodParam) throws TypeMismatchException {
|
||||
public <T> T convertIfNecessary(
|
||||
Object value, Class<T> requiredType, MethodParameter methodParam) throws TypeMismatchException {
|
||||
try {
|
||||
return this.typeConverterDelegate.convertIfNecessary(value, requiredType, methodParam);
|
||||
}
|
||||
|
||||
+4
@@ -100,6 +100,10 @@ class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor {
|
||||
|
||||
@Override
|
||||
public Method getWriteMethod() {
|
||||
return this.writeMethod;
|
||||
}
|
||||
|
||||
public Method getWriteMethodForActualAccess() {
|
||||
Set<Method> ambiguousCandidates = this.ambiguousWriteMethods;
|
||||
if (ambiguousCandidates != null) {
|
||||
this.ambiguousWriteMethods = null;
|
||||
|
||||
+63
-56
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,7 +37,6 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class MutablePropertyValues implements PropertyValues, Serializable {
|
||||
|
||||
/** List of PropertyValue objects */
|
||||
private final List<PropertyValue> propertyValueList;
|
||||
|
||||
private Set<String> processedProperties;
|
||||
@@ -47,12 +46,11 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
|
||||
|
||||
/**
|
||||
* Creates a new empty MutablePropertyValues object.
|
||||
* Property values can be added with the <code>addPropertyValue</code> methods.
|
||||
* @see #addPropertyValue(PropertyValue)
|
||||
* @see #addPropertyValue(String, Object)
|
||||
* <p>Property values can be added with the <code>add</code> method.
|
||||
* @see #add(String, Object)
|
||||
*/
|
||||
public MutablePropertyValues() {
|
||||
this.propertyValueList = new ArrayList<PropertyValue>();
|
||||
this.propertyValueList = new ArrayList<PropertyValue>(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,13 +117,19 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
|
||||
return this.propertyValueList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of PropertyValue entries in the list.
|
||||
*/
|
||||
public int size() {
|
||||
return this.propertyValueList.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy all given PropertyValues into this object. Guarantees PropertyValue
|
||||
* references are independent, although it can't deep copy objects currently
|
||||
* referenced by individual PropertyValue objects.
|
||||
* @param other the PropertyValues to copy
|
||||
* @return this object to allow creating objects, adding multiple PropertyValues
|
||||
* in a single statement
|
||||
* @return this in order to allow for adding multiple property values in a chain
|
||||
*/
|
||||
public MutablePropertyValues addPropertyValues(PropertyValues other) {
|
||||
if (other != null) {
|
||||
@@ -141,8 +145,7 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
|
||||
* Add all property values from the given Map.
|
||||
* @param other Map with property values keyed by property name,
|
||||
* which must be a String
|
||||
* @return this object to allow creating objects, adding multiple
|
||||
* PropertyValues in a single statement
|
||||
* @return this in order to allow for adding multiple property values in a chain
|
||||
*/
|
||||
public MutablePropertyValues addPropertyValues(Map<?, ?> other) {
|
||||
if (other != null) {
|
||||
@@ -154,11 +157,10 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a PropertyValue object, replacing any existing one
|
||||
* for the corresponding property.
|
||||
* Add a PropertyValue object, replacing any existing one for the
|
||||
* corresponding property or getting merged with it (if applicable).
|
||||
* @param pv PropertyValue object to add
|
||||
* @return this object to allow creating objects, adding multiple
|
||||
* PropertyValues in a single statement
|
||||
* @return this in order to allow for adding multiple property values in a chain
|
||||
*/
|
||||
public MutablePropertyValues addPropertyValue(PropertyValue pv) {
|
||||
for (int i = 0; i < this.propertyValueList.size(); i++) {
|
||||
@@ -176,6 +178,8 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
|
||||
/**
|
||||
* Overloaded version of <code>addPropertyValue</code> that takes
|
||||
* a property name and a property value.
|
||||
* <p>Note: As of Spring 3.0, we recommend using the more concise
|
||||
* and chaining-capable variant {@link #add}.
|
||||
* @param propertyName name of the property
|
||||
* @param propertyValue value of the property
|
||||
* @see #addPropertyValue(PropertyValue)
|
||||
@@ -184,6 +188,18 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
|
||||
addPropertyValue(new PropertyValue(propertyName, propertyValue));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a PropertyValue object, replacing any existing one for the
|
||||
* corresponding property or getting merged with it (if applicable).
|
||||
* @param propertyName name of the property
|
||||
* @param propertyValue value of the property
|
||||
* @return this in order to allow for adding multiple property values in a chain
|
||||
*/
|
||||
public MutablePropertyValues add(String propertyName, Object propertyValue) {
|
||||
addPropertyValue(new PropertyValue(propertyName, propertyValue));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify a PropertyValue object held in this object.
|
||||
* Indexed from 0.
|
||||
@@ -209,15 +225,6 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
|
||||
return newPv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overloaded version of <code>removePropertyValue</code> that takes a property name.
|
||||
* @param propertyName name of the property
|
||||
* @see #removePropertyValue(PropertyValue)
|
||||
*/
|
||||
public void removePropertyValue(String propertyName) {
|
||||
removePropertyValue(getPropertyValue(propertyName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the given PropertyValue, if contained.
|
||||
* @param pv the PropertyValue to remove
|
||||
@@ -227,10 +234,12 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear this holder, removing all PropertyValues.
|
||||
* Overloaded version of <code>removePropertyValue</code> that takes a property name.
|
||||
* @param propertyName name of the property
|
||||
* @see #removePropertyValue(PropertyValue)
|
||||
*/
|
||||
public void clear() {
|
||||
this.propertyValueList.clear();
|
||||
public void removePropertyValue(String propertyName) {
|
||||
this.propertyValueList.remove(getPropertyValue(propertyName));
|
||||
}
|
||||
|
||||
|
||||
@@ -247,34 +256,6 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the specified property as "processed" in the sense
|
||||
* of some processor calling the corresponding setter method
|
||||
* outside of the PropertyValue(s) mechanism.
|
||||
* <p>This will lead to <code>true</code> being returned from
|
||||
* a {@link #contains} call for the specified property.
|
||||
* @param propertyName the name of the property.
|
||||
*/
|
||||
public void registerProcessedProperty(String propertyName) {
|
||||
if (this.processedProperties == null) {
|
||||
this.processedProperties = new HashSet<String>();
|
||||
}
|
||||
this.processedProperties.add(propertyName);
|
||||
}
|
||||
|
||||
public boolean contains(String propertyName) {
|
||||
return (getPropertyValue(propertyName) != null ||
|
||||
(this.processedProperties != null && this.processedProperties.contains(propertyName)));
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this.propertyValueList.isEmpty();
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this.propertyValueList.size();
|
||||
}
|
||||
|
||||
public PropertyValues changesSince(PropertyValues old) {
|
||||
MutablePropertyValues changes = new MutablePropertyValues();
|
||||
if (old == this) {
|
||||
@@ -296,6 +277,30 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
|
||||
return changes;
|
||||
}
|
||||
|
||||
public boolean contains(String propertyName) {
|
||||
return (getPropertyValue(propertyName) != null ||
|
||||
(this.processedProperties != null && this.processedProperties.contains(propertyName)));
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this.propertyValueList.isEmpty();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register the specified property as "processed" in the sense
|
||||
* of some processor calling the corresponding setter method
|
||||
* outside of the PropertyValue(s) mechanism.
|
||||
* <p>This will lead to <code>true</code> being returned from
|
||||
* a {@link #contains} call for the specified property.
|
||||
* @param propertyName the name of the property.
|
||||
*/
|
||||
public void registerProcessedProperty(String propertyName) {
|
||||
if (this.processedProperties == null) {
|
||||
this.processedProperties = new HashSet<String>();
|
||||
}
|
||||
this.processedProperties.add(propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark this holder as containing converted values only
|
||||
@@ -334,8 +339,10 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
|
||||
@Override
|
||||
public String toString() {
|
||||
PropertyValue[] pvs = getPropertyValues();
|
||||
StringBuilder sb = new StringBuilder("PropertyValues: length=" + pvs.length + "; ");
|
||||
sb.append(StringUtils.arrayToDelimitedString(pvs, "; "));
|
||||
StringBuilder sb = new StringBuilder("PropertyValues: length=").append(pvs.length);
|
||||
if (pvs.length > 0) {
|
||||
sb.append("; ").append(StringUtils.arrayToDelimitedString(pvs, "; "));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -148,7 +148,7 @@ public interface PropertyAccessor {
|
||||
* all individual PropertyAccessExceptions. All other properties will have been
|
||||
* successfully updated.
|
||||
*/
|
||||
void setPropertyValues(Map map) throws BeansException;
|
||||
void setPropertyValues(Map<?, ?> map) throws BeansException;
|
||||
|
||||
/**
|
||||
* The preferred way to perform a batch update.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user