Compare commits
569 Commits
1.0.0.M2-M
...
1.2.0.RELE
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2bc6ebc250 | ||
|
|
909110cf4e | ||
|
|
ba094da5a7 | ||
|
|
876b31bc52 | ||
|
|
dc8e8281eb | ||
|
|
48deb1a150 | ||
|
|
48625956b7 | ||
|
|
782cf6e10d | ||
|
|
c28e51cf86 | ||
|
|
4b1065cac5 | ||
|
|
c807b2abcf | ||
|
|
19ad2d3aac | ||
|
|
bd7fe5bfd3 | ||
|
|
a237999037 | ||
|
|
d8a9752724 | ||
|
|
4c8bf0dec2 | ||
|
|
cffc27d83a | ||
|
|
42ab4cb7b4 | ||
|
|
42df25434f | ||
|
|
4e16f7ebe2 | ||
|
|
04a87b373d | ||
|
|
c4eca7eadd | ||
|
|
3a9dc2b98c | ||
|
|
c568b7cbc2 | ||
|
|
9482350062 | ||
|
|
772a140def | ||
|
|
936259a766 | ||
|
|
533d21281e | ||
|
|
6977fa87e6 | ||
|
|
41dcebb010 | ||
|
|
ef077182f6 | ||
|
|
21e7c63766 | ||
|
|
4b018a9d7d | ||
|
|
ecf15b93e0 | ||
|
|
6323a86560 | ||
|
|
3b0b7315e1 | ||
|
|
4aeba6f92d | ||
|
|
342f9ae837 | ||
|
|
66d98b355e | ||
|
|
cabbe747f8 | ||
|
|
5ff3064acd | ||
|
|
3001e2941f | ||
|
|
9cf72fbdd4 | ||
|
|
cb5144de0f | ||
|
|
4be90e51ae | ||
|
|
6c368d557b | ||
|
|
a8432e13a1 | ||
|
|
05ac139554 | ||
|
|
3661b2981e | ||
|
|
69bd7acf74 | ||
|
|
d882af257f | ||
|
|
c92058a79a | ||
|
|
ed2b576261 | ||
|
|
6744446a48 | ||
|
|
fdecec48b2 | ||
|
|
f1289c46e6 | ||
|
|
aa0b87be57 | ||
|
|
2040f02d07 | ||
|
|
13a69ecdfd | ||
|
|
f0051deff0 | ||
|
|
05a8148084 | ||
|
|
aaa44b3369 | ||
|
|
7f35c4430d | ||
|
|
114489d19a | ||
|
|
eda8200d51 | ||
|
|
b078ea9ceb | ||
|
|
d90b1a0ddd | ||
|
|
737a42e07a | ||
|
|
22d5d4c019 | ||
|
|
7ac1e7b6e1 | ||
|
|
e86ab783f3 | ||
|
|
6fe3e67ecb | ||
|
|
3b78034c55 | ||
|
|
a06a69797f | ||
|
|
8b1557e38c | ||
|
|
fcdc6d0df2 | ||
|
|
83b6cd7f05 | ||
|
|
38a9a6d51d | ||
|
|
5e2f16c678 | ||
|
|
d7ae95a779 | ||
|
|
8fbdf9afbd | ||
|
|
f5a4d78e62 | ||
|
|
1f4264e6a7 | ||
|
|
05baa851d8 | ||
|
|
35e8ae1224 | ||
|
|
ceec0bcc4a | ||
|
|
0d87e7fa5f | ||
|
|
a530629d97 | ||
|
|
ba0232b187 | ||
|
|
04a17cacb7 | ||
|
|
761d725fce | ||
|
|
726b0b1bcc | ||
|
|
888e031452 | ||
|
|
91b818b8c1 | ||
|
|
7646a64770 | ||
|
|
94c057e89c | ||
|
|
190d7cefb0 | ||
|
|
669bc071b1 | ||
|
|
31b9b6b5c0 | ||
|
|
914ecd34fe | ||
|
|
74532ff199 | ||
|
|
c7bcb55bda | ||
|
|
afe560ca7d | ||
|
|
1380c49fd0 | ||
|
|
90240a8da5 | ||
|
|
ad587f63ed | ||
|
|
3c7cb592b3 | ||
|
|
5b15c9500a | ||
|
|
2d25f0d6e4 | ||
|
|
557fc869eb | ||
|
|
033f44e802 | ||
|
|
ee3c1bc007 | ||
|
|
f507fe2e4d | ||
|
|
4a27ba0a3f | ||
|
|
e2e5fd8b31 | ||
|
|
ba9abd1dd0 | ||
|
|
ab66614843 | ||
|
|
caa2f5f030 | ||
|
|
6e7c8f5771 | ||
|
|
44c4566c9d | ||
|
|
9a1e6226b1 | ||
|
|
cdb6d54d6a | ||
|
|
1fbfd3f0cb | ||
|
|
848e6f59c2 | ||
|
|
b3a891c69b | ||
|
|
54e105d19d | ||
|
|
4cfb62a413 | ||
|
|
7cdf9cedf3 | ||
|
|
fd198c172b | ||
|
|
4be229312c | ||
|
|
54ec7af462 | ||
|
|
7162677992 | ||
|
|
cf131aaa7e | ||
|
|
6cd3b7a3aa | ||
|
|
71e639402c | ||
|
|
fed31c74e1 | ||
|
|
5b13307e39 | ||
|
|
d317bcfa71 | ||
|
|
883bfbe79e | ||
|
|
7502ac137c | ||
|
|
3dfc59bfb8 | ||
|
|
9e50621c1b | ||
|
|
472beaf6d2 | ||
|
|
d6d8a13b0c | ||
|
|
3dcf93744b | ||
|
|
6373a70ca4 | ||
|
|
858afa80f1 | ||
|
|
97f57e3541 | ||
|
|
05c2045e45 | ||
|
|
d3598198a6 | ||
|
|
2a8fe5bac7 | ||
|
|
cdc8f52bad | ||
|
|
39492daa50 | ||
|
|
16904ba1a7 | ||
|
|
51a469b46f | ||
|
|
9f2b1f4ed0 | ||
|
|
e0ea8a6088 | ||
|
|
8861934336 | ||
|
|
93c9713adf | ||
|
|
68a0c1ee2c | ||
|
|
c3d533d59d | ||
|
|
e4b9be6b38 | ||
|
|
09a8b9c9c4 | ||
|
|
e531508bdc | ||
|
|
289c4b95ae | ||
|
|
25e6d6e025 | ||
|
|
83d18b5ce6 | ||
|
|
8f09748d78 | ||
|
|
4429971548 | ||
|
|
065a50bc8c | ||
|
|
f8daa69e53 | ||
|
|
8a18cd4aef | ||
|
|
3320208a1d | ||
|
|
4ebc6e96d3 | ||
|
|
91fe5480a8 | ||
|
|
b6322d7bbc | ||
|
|
572c4bb2cd | ||
|
|
9caa8b15cd | ||
|
|
275f4fe6b8 | ||
|
|
4c40ef7e3d | ||
|
|
609097c0dc | ||
|
|
307d86498e | ||
|
|
19879b8dab | ||
|
|
b190f22551 | ||
|
|
0e9c6a5de8 | ||
|
|
5ec0cc7327 | ||
|
|
817e167056 | ||
|
|
4a6fa5cade | ||
|
|
9cd33763b6 | ||
|
|
de8d2a1c74 | ||
|
|
9f940cd2b6 | ||
|
|
0d69baa32c | ||
|
|
433e5a660e | ||
|
|
ee33ce1571 | ||
|
|
9ac11e967a | ||
|
|
a89a0ac542 | ||
|
|
0ad0dad124 | ||
|
|
8f2771416e | ||
|
|
7af009cc7f | ||
|
|
35ad949c18 | ||
|
|
8206b5f950 | ||
|
|
170081137a | ||
|
|
6862bd8a45 | ||
|
|
490db7c39f | ||
|
|
f3979c3676 | ||
|
|
8d18729898 | ||
|
|
b5e0b2bec2 | ||
|
|
9eb47827c1 | ||
|
|
f97ab25411 | ||
|
|
6616761f50 | ||
|
|
89de566893 | ||
|
|
ea1f090b40 | ||
|
|
b5958fb5cc | ||
|
|
75b7aff80a | ||
|
|
7da0fcdd0c | ||
|
|
c88b6d89db | ||
|
|
de1540aadc | ||
|
|
d1b24d6cfb | ||
|
|
e85f3d3299 | ||
|
|
ef6e08d3f4 | ||
|
|
21010fbd49 | ||
|
|
4325d6c9fa | ||
|
|
bc16ccfded | ||
|
|
04f5f9f662 | ||
|
|
b1f1b8efaa | ||
|
|
de300e2643 | ||
|
|
20088b83d9 | ||
|
|
58f200f15e | ||
|
|
8718700249 | ||
|
|
f4063d1679 | ||
|
|
ef063613c7 | ||
|
|
2eda0f1701 | ||
|
|
ec7b65e21d | ||
|
|
c7f7571f3f | ||
|
|
9f71af42e8 | ||
|
|
92775170e1 | ||
|
|
4c7e338770 | ||
|
|
e3fff52d17 | ||
|
|
5477ab20b2 | ||
|
|
4cf3567f42 | ||
|
|
b26bb62a63 | ||
|
|
f156d7b5af | ||
|
|
7bf3643902 | ||
|
|
201ae3e92d | ||
|
|
07556ec58c | ||
|
|
39807b17e1 | ||
|
|
4913fe26ac | ||
|
|
7642a719ff | ||
|
|
6c1ce576a4 | ||
|
|
c99882201d | ||
|
|
ce6a64e4a9 | ||
|
|
2fcc323bcd | ||
|
|
17c7b1d2b5 | ||
|
|
cfefe46cd4 | ||
|
|
64921ddad1 | ||
|
|
edda1764fe | ||
|
|
8113b79109 | ||
|
|
9fde4dff3e | ||
|
|
d4b3e2b99d | ||
|
|
68a31d75f3 | ||
|
|
3e15c21419 | ||
|
|
e9f253d34f | ||
|
|
80aa057acb | ||
|
|
613b183b70 | ||
|
|
5d1320a82a | ||
|
|
8ccaf61d12 | ||
|
|
2c46cfd8fe | ||
|
|
45f2900d15 | ||
|
|
79934538b6 | ||
|
|
0e4e0094a5 | ||
|
|
5df61563f4 | ||
|
|
04ebec993d | ||
|
|
caa245dd08 | ||
|
|
717ff38319 | ||
|
|
33155ba0f4 | ||
|
|
9f62efa47c | ||
|
|
620fc876f4 | ||
|
|
cfcf839232 | ||
|
|
7ce1e5fbd3 | ||
|
|
2d12ba38f8 | ||
|
|
1554d489ca | ||
|
|
f030d304f4 | ||
|
|
105e1da82b | ||
|
|
dbc7601d7b | ||
|
|
ccf981b8fb | ||
|
|
8a43b4bbc0 | ||
|
|
1c2c592b96 | ||
|
|
cd4b409bf2 | ||
|
|
f71477f17d | ||
|
|
454df1e7f1 | ||
|
|
80641a0943 | ||
|
|
e405bf574c | ||
|
|
9f8e406aff | ||
|
|
7d26366352 | ||
|
|
864ae831dd | ||
|
|
bfb13d99e3 | ||
|
|
f39de4c28e | ||
|
|
3bdeb68617 | ||
|
|
6b40a27c92 | ||
|
|
237cbec945 | ||
|
|
39bc6771b7 | ||
|
|
73b2d5a99c | ||
|
|
5dab0c721e | ||
|
|
bf7c9663cf | ||
|
|
135742b7e4 | ||
|
|
dee0307055 | ||
|
|
06fb4144e0 | ||
|
|
5fdc600570 | ||
|
|
f54c69b6ef | ||
|
|
decdcff79f | ||
|
|
be8daa5268 | ||
|
|
c4cd074d4d | ||
|
|
8b7521a93b | ||
|
|
ba508f497c | ||
|
|
091246a9aa | ||
|
|
745e1f313d | ||
|
|
234e04f4a3 | ||
|
|
15ab529596 | ||
|
|
00bea23eed | ||
|
|
c646c1f3b2 | ||
|
|
069f491603 | ||
|
|
e426ba4d43 | ||
|
|
756f886cef | ||
|
|
9bb42245bb | ||
|
|
c15263a259 | ||
|
|
758ee97a8d | ||
|
|
4f92690f58 | ||
|
|
595ed69820 | ||
|
|
48bf08afa3 | ||
|
|
98bdae4a00 | ||
|
|
f08b87d8d6 | ||
|
|
6c3ffeac5f | ||
|
|
490ddc4a0e | ||
|
|
ae26f4fea1 | ||
|
|
e9ea756a3a | ||
|
|
c4c95813b7 | ||
|
|
bfeb1b34c1 | ||
|
|
44def7dddb | ||
|
|
df10bb2168 | ||
|
|
f98607f5dc | ||
|
|
da23133327 | ||
|
|
ce5046c35f | ||
|
|
95245015bc | ||
|
|
fc40e6b08c | ||
|
|
eac5cb8c46 | ||
|
|
54377031bb | ||
|
|
213963f2ff | ||
|
|
0fb21aa2a1 | ||
|
|
e0da98ec51 | ||
|
|
7610246a1d | ||
|
|
ce59d893ba | ||
|
|
e130fb5a2d | ||
|
|
fedcbdae4f | ||
|
|
7cd020ffa7 | ||
|
|
b01e1a994b | ||
|
|
dd02338b5e | ||
|
|
7084839df1 | ||
|
|
09aad4343f | ||
|
|
c6a97ef407 | ||
|
|
ceac760d19 | ||
|
|
244e9bc6d8 | ||
|
|
2016aab969 | ||
|
|
35f180f999 | ||
|
|
ad8b6fccb4 | ||
|
|
d237ee80c8 | ||
|
|
eb276841dd | ||
|
|
1d51052ab1 | ||
|
|
58898e97c2 | ||
|
|
a5328da460 | ||
|
|
fd7e41b753 | ||
|
|
f349f5ea10 | ||
|
|
aa9d69d584 | ||
|
|
764317635c | ||
|
|
9ed5e6886c | ||
|
|
94f36d27fc | ||
|
|
a5fb4872b7 | ||
|
|
2f577c9678 | ||
|
|
9bcd19866f | ||
|
|
2af45518bd | ||
|
|
e1daf36ed8 | ||
|
|
101064769c | ||
|
|
ac9c804aae | ||
|
|
992f09d731 | ||
|
|
4324ed8231 | ||
|
|
eebe973209 | ||
|
|
bb01cccac5 | ||
|
|
2bdd49e3b7 | ||
|
|
f424b7c760 | ||
|
|
58b9db28a8 | ||
|
|
3e56210c78 | ||
|
|
523612a3a9 | ||
|
|
1604c80d32 | ||
|
|
d27a1ad310 | ||
|
|
d2cca2c52a | ||
|
|
ce0539a3dc | ||
|
|
4b4c35b904 | ||
|
|
f0df16a340 | ||
|
|
a9670de959 | ||
|
|
2d5f41f65c | ||
|
|
2e3f2c602c | ||
|
|
a2687b6688 | ||
|
|
e89ea320bc | ||
|
|
df24218a4f | ||
|
|
2d09b8b7d1 | ||
|
|
dd06973f50 | ||
|
|
2256ebac1b | ||
|
|
f4373957b3 | ||
|
|
af0cd9049a | ||
|
|
99edcb82cf | ||
|
|
7a98877e75 | ||
|
|
d856a7cad9 | ||
|
|
c1b396cca5 | ||
|
|
2e86012b3f | ||
|
|
538a62efce | ||
|
|
3573851bfc | ||
|
|
e47ddf4bf2 | ||
|
|
c59711a409 | ||
|
|
b1ab3f6ade | ||
|
|
fa094eef25 | ||
|
|
8ac2ff6b81 | ||
|
|
46d6dffdd4 | ||
|
|
06632cc3ae | ||
|
|
df0427442a | ||
|
|
eb20aea7fe | ||
|
|
1e52f8641c | ||
|
|
37f2fcee31 | ||
|
|
9a0e45de83 | ||
|
|
b140fc1698 | ||
|
|
ac4b27159b | ||
|
|
e8b130691c | ||
|
|
836b5ad258 | ||
|
|
dc9f96908f | ||
|
|
f9fdbb469f | ||
|
|
134996d079 | ||
|
|
25b9a56030 | ||
|
|
2c585d49d6 | ||
|
|
7bed1264b1 | ||
|
|
523d48759f | ||
|
|
1a5bffb52a | ||
|
|
467f7c61af | ||
|
|
89e83d1f69 | ||
|
|
b4b61a96e9 | ||
|
|
131a2912e9 | ||
|
|
b4236bdd78 | ||
|
|
43d0f74a3e | ||
|
|
aeea1bc5d5 | ||
|
|
187f087270 | ||
|
|
115d419d0a | ||
|
|
e0bd465649 | ||
|
|
6a73e94c57 | ||
|
|
7ea14bb4d5 | ||
|
|
bfc4bc2100 | ||
|
|
842c87389d | ||
|
|
e751666f90 | ||
|
|
f2305681d3 | ||
|
|
fb39f01f25 | ||
|
|
e1f8eee2d1 | ||
|
|
c7c2a66c3b | ||
|
|
69b1b9b96b | ||
|
|
2284a5137e | ||
|
|
46e2cf698e | ||
|
|
1087b07086 | ||
|
|
d55505f1e5 | ||
|
|
de06029ea2 | ||
|
|
4d33c9c360 | ||
|
|
8474a28538 | ||
|
|
edba941dd0 | ||
|
|
c75218387b | ||
|
|
2e5906fa56 | ||
|
|
c6c3dfef15 | ||
|
|
43925c9cf6 | ||
|
|
3893eb126d | ||
|
|
c8e16318e8 | ||
|
|
c48f892124 | ||
|
|
4c01993666 | ||
|
|
bf8b85ef98 | ||
|
|
974faec6dd | ||
|
|
b5e83d4350 | ||
|
|
c79989ce99 | ||
|
|
208c977e0a | ||
|
|
df1e900c55 | ||
|
|
22ab2007da | ||
|
|
fdc81440bd | ||
|
|
4052506df1 | ||
|
|
4356297421 | ||
|
|
d0da787f70 | ||
|
|
e89d09cc86 | ||
|
|
3e38595fe8 | ||
|
|
ad287efb4e | ||
|
|
98da8beb67 | ||
|
|
9324ae2593 | ||
|
|
adc56ce79f | ||
|
|
2832b524d3 | ||
|
|
1640db5d7c | ||
|
|
ac762b2289 | ||
|
|
9429326ec2 | ||
|
|
3e840e2380 | ||
|
|
5b57b40274 | ||
|
|
63d9d35cba | ||
|
|
bf5fc0ff1f | ||
|
|
6287fa425d | ||
|
|
345e6ebf8b | ||
|
|
4aaa32fe1d | ||
|
|
60774dca26 | ||
|
|
c9d5565aaa | ||
|
|
30e96f9c97 | ||
|
|
9641434090 | ||
|
|
86960006cb | ||
|
|
21cd013cf1 | ||
|
|
95750ffde1 | ||
|
|
6ed1d2b226 | ||
|
|
4e04d0acd1 | ||
|
|
2212ca4b00 | ||
|
|
025691a97a | ||
|
|
94e4d2b095 | ||
|
|
41e49ad3e2 | ||
|
|
35629f5370 | ||
|
|
0b50e58020 | ||
|
|
9b86637031 | ||
|
|
d7f33774e0 | ||
|
|
12ddfcc9f9 | ||
|
|
47f184dbf0 | ||
|
|
2ca10c13c5 | ||
|
|
965f9fd260 | ||
|
|
d5c625dc2a | ||
|
|
55ce0b8272 | ||
|
|
1c8a55a081 | ||
|
|
35259f4e12 | ||
|
|
c9facf5338 | ||
|
|
283e5cb76b | ||
|
|
f05d200cd3 | ||
|
|
62ecfc8416 | ||
|
|
dfbc89c3b6 | ||
|
|
b6c6016b1e | ||
|
|
c9fe785c32 | ||
|
|
7b3d030794 | ||
|
|
02448bc0ee | ||
|
|
e4fdabba1d | ||
|
|
0c9ee0eacd | ||
|
|
7f6a6094e6 | ||
|
|
68f8bd62d1 | ||
|
|
caa8faf769 | ||
|
|
6e4e487eb4 | ||
|
|
d065bd74b3 | ||
|
|
d648c95b62 | ||
|
|
ef2b0235c7 | ||
|
|
321948d4a2 | ||
|
|
21f859e222 | ||
|
|
224934a28c | ||
|
|
a74d9ca7cd | ||
|
|
76159a2216 | ||
|
|
9c9138c4e9 | ||
|
|
7567ba0355 | ||
|
|
dc36d91d8e | ||
|
|
f0b30ec39e | ||
|
|
178b220d2d | ||
|
|
fe74557c95 | ||
|
|
399beff795 | ||
|
|
9380a88f26 | ||
|
|
5e4583110e | ||
|
|
8a3296758d | ||
|
|
60ba9bfcc2 | ||
|
|
db75aca336 | ||
|
|
36d62e12fc | ||
|
|
f9b1fb57cd | ||
|
|
3ab2aeb5c1 | ||
|
|
99e96958ed | ||
|
|
20c9af6550 | ||
|
|
df50623fc7 |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -2,11 +2,16 @@
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
*.orig
|
||||
target
|
||||
.springBeans
|
||||
.sonar4clipse
|
||||
*.sonar4clipseExternals
|
||||
.ant-targets-build.xml
|
||||
.settings/
|
||||
.project
|
||||
.classpath
|
||||
src/ant/.ant-targets-upload-dist.xml
|
||||
atlassian-ide-plugin.xml
|
||||
/.gradle/
|
||||
/.idea/
|
||||
|
||||
41
README.md
41
README.md
@@ -1,16 +1,22 @@
|
||||
Spring Data - Document
|
||||
Spring Data MongoDB
|
||||
======================
|
||||
|
||||
The primary goal of the [Spring Data](http://www.springsource.org/spring-data) project is to make it easier to build Spring-powered applications that use new data access technologies such as non-relational databases, map-reduce frameworks, and cloud based data services.
|
||||
As the name implies, the **Document** modules provides integration with document databases such as [MongoDB](http://www.mongodb.org/) and [CouchDB](http://couchdb.apache.org/).
|
||||
|
||||
The Spring Data MongoDB aims to provide a familiar and consistent Spring-based programming model for for new datastores while retaining store-specific features and capabilities. The Spring Data MongoDB project provides integration with the MongoDB document database. Key functional areas of Spring Data MongoDB are a POJO centric model for interacting with a MongoDB DBCollection and easily writing a Repository style data access layer
|
||||
|
||||
Getting Help
|
||||
------------
|
||||
|
||||
At this point your best bet is to look at the Look at the [JavaDocs](http://static.springsource.org/spring-data/data-document/docs/1.0.0.BUILD-SNAPSHOT/spring-data-mongodb/apidocs/) for MongoDB integration and corresponding and source code. For more detailed questions, use the [forum](http://forum.springsource.org/forumdisplay.php?f=80). If you are new to Spring as well as to Spring Data, look for information about [Spring projects](http://www.springsource.org/projects).
|
||||
For a comprehensive treatmet of all the Spring Data MongoDB features, please refer to the The [User Guide](http://static.springsource.org/spring-data/data-mongodb/docs/current/reference/html/)
|
||||
|
||||
The [User Guide](http://static.springsource.org/spring-data/data-document/docs/1.0.0.BUILD-SNAPSHOT/reference/html/) (A work in progress).
|
||||
The [JavaDocs](http://static.springsource.org/spring-data/data-mongodb/docs/current/api/) have extensive comments in them as well.
|
||||
|
||||
The home page of [Spring Data MongoDB](http://www.springsource.org/spring-data/mongodb) contains links to articles and other resources.
|
||||
|
||||
For more detailed questions, use the [forum](http://forum.springsource.org/forumdisplay.php?f=80).
|
||||
|
||||
If you are new to Spring as well as to Spring Data, look for information about [Spring projects](http://www.springsource.org/projects).
|
||||
|
||||
|
||||
Quick Start
|
||||
@@ -23,19 +29,19 @@ For those in a hurry:
|
||||
|
||||
* Download the jar through Maven:
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
<version>1.2.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<repository>
|
||||
<id>spring-maven-snapshot</id>
|
||||
<snapshots><enabled>true</enabled></snapshots>
|
||||
<name>Springframework Maven SNAPSHOT Repository</name>
|
||||
<url>http://maven.springframework.org/snapshot</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-maven-snapshot</id>
|
||||
<snapshots><enabled>true</enabled></snapshots>
|
||||
<name>Springframework Maven SNAPSHOT Repository</name>
|
||||
<url>http://maven.springframework.org/snapshot</url>
|
||||
</repository>
|
||||
|
||||
### MongoTemplate
|
||||
MongoTemplate is the central support class for Mongo database operations. It provides
|
||||
@@ -137,11 +143,6 @@ This will register an object in the container named PersonRepository. You can u
|
||||
}
|
||||
|
||||
|
||||
## CouchDB
|
||||
|
||||
TBD
|
||||
|
||||
|
||||
Contributing to Spring Data
|
||||
---------------------------
|
||||
|
||||
|
||||
291
etc/formatting.xml
Normal file
291
etc/formatting.xml
Normal file
@@ -0,0 +1,291 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<profiles version="12">
|
||||
<profile kind="CodeFormatterProfile" name="Spring Data" version="12">
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.source" value="1.7"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="120"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="2"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="tab"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="2"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.7"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="120"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.7"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
|
||||
</profile>
|
||||
</profiles>
|
||||
363
pom.xml
363
pom.xml
@@ -1,288 +1,93 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-document-dist</artifactId>
|
||||
<name>Spring Data Document Distribution</name>
|
||||
<version>1.0.0.M2</version>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>spring-data-document-parent</module>
|
||||
<module>spring-data-document-core</module>
|
||||
<module>spring-data-mongodb</module>
|
||||
<module>spring-data-mongodb-cross-store</module>
|
||||
<module>spring-data-mongodb-log4j</module>
|
||||
<!-- <module>spring-data-couchdb</module> -->
|
||||
</modules>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<id>trisberg</id>
|
||||
<name>Thomas Risberg</name>
|
||||
<email>trisberg at vmware.com</email>
|
||||
<organization>SpringSource</organization>
|
||||
<organizationUrl>http://www.SpringSource.com</organizationUrl>
|
||||
<roles>
|
||||
<role>Project Admin</role>
|
||||
<role>Developer</role>
|
||||
</roles>
|
||||
<timezone>-5</timezone>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>mpollack</id>
|
||||
<name>Mark Pollack</name>
|
||||
<email>mpollack at vmware.com</email>
|
||||
<organization>SpringSource</organization>
|
||||
<organizationUrl>http://www.SpringSource.com</organizationUrl>
|
||||
<roles>
|
||||
<role>Project Admin</role>
|
||||
<role>Developer</role>
|
||||
</roles>
|
||||
<timezone>-5</timezone>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>ogierke</id>
|
||||
<name>Oliver Gierke</name>
|
||||
<email>ogierke at vmware.com</email>
|
||||
<organization>SpringSource</organization>
|
||||
<organizationUrl>http://www.springsource.com</organizationUrl>
|
||||
<roles>
|
||||
<role>Developer</role>
|
||||
</roles>
|
||||
<timezone>+1</timezone>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>jbrisbin</id>
|
||||
<name>Jon Brisbin</name>
|
||||
<email>jbrisbin at vmware.com</email>
|
||||
<organization>SpringSource</organization>
|
||||
<organizationUrl>http://www.springsource.com</organizationUrl>
|
||||
<roles>
|
||||
<role>Developer</role>
|
||||
</roles>
|
||||
<timezone>-6</timezone>
|
||||
</developer>
|
||||
</developers>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.2.0.RELEASE</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>Apache License, Version 2.0</name>
|
||||
<url>http://www.apache.org/licenses/LICENSE-2.0</url>
|
||||
<comments>
|
||||
Copyright 2010 the original author or authors.
|
||||
<name>Spring Data MongoDB</name>
|
||||
<description>MongoDB support for Spring Data</description>
|
||||
<url>http://www.springsource.org/spring-data/mongodb</url>
|
||||
|
||||
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
|
||||
<parent>
|
||||
<groupId>org.springframework.data.build</groupId>
|
||||
<artifactId>spring-data-parent</artifactId>
|
||||
<version>1.0.0.RELEASE</version>
|
||||
<relativePath>../spring-data-build/parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
<module>spring-data-mongodb</module>
|
||||
<module>spring-data-mongodb-cross-store</module>
|
||||
<module>spring-data-mongodb-log4j</module>
|
||||
<module>spring-data-mongodb-distribution</module>
|
||||
</modules>
|
||||
|
||||
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.
|
||||
</comments>
|
||||
</license>
|
||||
</licenses>
|
||||
<properties>
|
||||
<project.type>multi</project.type>
|
||||
<dist.name>spring-data-mongodb</dist.name>
|
||||
<springdata.commons>1.5.0.RELEASE</springdata.commons>
|
||||
<mongo>2.10.1</mongo>
|
||||
</properties>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<id>ogierke</id>
|
||||
<name>Oliver Gierke</name>
|
||||
<email>ogierke at vmware.com</email>
|
||||
<organization>SpringSource</organization>
|
||||
<organizationUrl>http://www.springsource.com</organizationUrl>
|
||||
<roles>
|
||||
<role>Project Lean</role>
|
||||
</roles>
|
||||
<timezone>+1</timezone>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>trisberg</id>
|
||||
<name>Thomas Risberg</name>
|
||||
<email>trisberg at vmware.com</email>
|
||||
<organization>SpringSource</organization>
|
||||
<organizationUrl>http://www.springsource.com</organizationUrl>
|
||||
<roles>
|
||||
<role>Developer</role>
|
||||
</roles>
|
||||
<timezone>-5</timezone>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>mpollack</id>
|
||||
<name>Mark Pollack</name>
|
||||
<email>mpollack at vmware.com</email>
|
||||
<organization>SpringSource</organization>
|
||||
<organizationUrl>http://www.springsource.com</organizationUrl>
|
||||
<roles>
|
||||
<role>Developer</role>
|
||||
</roles>
|
||||
<timezone>-5</timezone>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>jbrisbin</id>
|
||||
<name>Jon Brisbin</name>
|
||||
<email>jbrisbin at vmware.com</email>
|
||||
<organization>SpringSource</organization>
|
||||
<organizationUrl>http://www.springsource.com</organizationUrl>
|
||||
<roles>
|
||||
<role>Developer</role>
|
||||
</roles>
|
||||
<timezone>-6</timezone>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<!-- dist.* properties are used by the antrun tasks below -->
|
||||
<dist.id>spring-data-document</dist.id>
|
||||
<dist.name>Spring Data</dist.name>
|
||||
<dist.key>DATADOC</dist.key>
|
||||
<dist.version>${project.version}</dist.version>
|
||||
<dist.releaseType>snapshot</dist.releaseType>
|
||||
<dist.finalName>${dist.id}-${dist.version}</dist.finalName>
|
||||
<dist.fileName>${dist.finalName}.zip</dist.fileName>
|
||||
<dist.filePath>target/${dist.fileName}</dist.filePath>
|
||||
<dist.bucketName>dist.springframework.org</dist.bucketName>
|
||||
<!-- these properties should be in ~/.m2/settings.xml
|
||||
<dist.accessKey>s3 access key</dist.accessKey>
|
||||
<dist.secretKey>s3 secret key</dist.secretKey>
|
||||
-->
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<extensions>
|
||||
<extension>
|
||||
<groupId>org.springframework.build.aws</groupId>
|
||||
<artifactId>org.springframework.build.aws.maven</artifactId>
|
||||
<version>3.1.0.RELEASE</version>
|
||||
</extension>
|
||||
</extensions>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.agilejava.docbkx</groupId>
|
||||
<artifactId>docbkx-maven-plugin</artifactId>
|
||||
<!-- yes it really needs to be this (2.0.7) otherwise pdf generation from a clean build doesn't work -->
|
||||
<version>2.0.7</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>generate-html</goal>
|
||||
<goal>generate-pdf</goal>
|
||||
</goals>
|
||||
<phase>pre-site</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.docbook</groupId>
|
||||
<artifactId>docbook-xml</artifactId>
|
||||
<version>4.4</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<configuration>
|
||||
<includes>index.xml</includes>
|
||||
<xincludeSupported>true</xincludeSupported>
|
||||
<foCustomization>${project.basedir}/src/docbkx/resources/xsl/fopdf.xsl</foCustomization>
|
||||
<htmlStylesheet>css/html.css</htmlStylesheet>
|
||||
<chunkedOutput>false</chunkedOutput>
|
||||
<htmlCustomization>${project.basedir}/src/docbkx/resources/xsl/html.xsl</htmlCustomization>
|
||||
<useExtensions>1</useExtensions>
|
||||
<highlightSource>1</highlightSource>
|
||||
<highlightDefaultLanguage></highlightDefaultLanguage>
|
||||
<!-- callouts -->
|
||||
<entities>
|
||||
<entity>
|
||||
<name>version</name>
|
||||
<value>${pom.version}</value>
|
||||
</entity>
|
||||
</entities>
|
||||
<postProcess>
|
||||
<copy todir="${project.basedir}/target/site/reference">
|
||||
<fileset dir="${project.basedir}/target/docbkx">
|
||||
<include name="**/*.html"/>
|
||||
<include name="**/*.pdf"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
<copy todir="${project.basedir}/target/site/reference/html">
|
||||
<fileset dir="${project.basedir}/src/docbkx/resources">
|
||||
<include name="**/*.css"/>
|
||||
<include name="**/*.png"/>
|
||||
<include name="**/*.gif"/>
|
||||
<include name="**/*.jpg"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
<copy todir="${project.basedir}/target/site/reference/html">
|
||||
<fileset dir="${project.basedir}/src/docbkx/resources/images">
|
||||
<include name="*.png"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
<move file="${project.basedir}/target/site/reference/pdf/index.pdf"
|
||||
tofile="${project.basedir}/target/site/reference/pdf/spring-data-document-reference.pdf"
|
||||
failonerror="false"/>
|
||||
</postProcess>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.5</version>
|
||||
<configuration>
|
||||
<javadoc:aggregate>true</javadoc:aggregate>
|
||||
<breakiterator>true</breakiterator>
|
||||
<header>Spring Data Document</header>
|
||||
<source>1.5</source>
|
||||
<quiet>true</quiet>
|
||||
<javadocDirectory>${project.basedir}/src/main/javadoc</javadocDirectory>
|
||||
<overview>${project.basedir}/src/main/javadoc/overview.html</overview>
|
||||
<stylesheetfile>${project.basedir}/src/main/javadoc/spring-javadoc.css</stylesheetfile>
|
||||
<!-- copies doc-files subdirectory which contains image resources -->
|
||||
<docfilessubdirs>true</docfilessubdirs>
|
||||
<links>
|
||||
<link>http://static.springframework.org/spring/docs/3.0.x/javadoc-api</link>
|
||||
<link>http://download.oracle.com/javase/1.5.0/docs/api</link>
|
||||
<link>http://api.mongodb.org/java/2.3</link>
|
||||
</links>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin><!--
|
||||
run `mvn package assembly:assembly` to trigger assembly creation.
|
||||
see http://www.sonatype.com/books/mvnref-book/reference/assemblies-set-dist-assemblies.html -->
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>2.2-beta-5</version>
|
||||
<inherited>false</inherited>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>distribution</id>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
<phase>package</phase>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>${project.basedir}/src/assembly/distribution.xml</descriptor>
|
||||
</descriptors>
|
||||
<appendAssemblyId>false</appendAssemblyId>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<version>1.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>upload-dist</id>
|
||||
<phase>deploy</phase>
|
||||
<configuration>
|
||||
<tasks>
|
||||
<ant antfile="${basedir}/src/ant/upload-dist.xml">
|
||||
<target name="upload-dist"/>
|
||||
</ant>
|
||||
</tasks>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.build</groupId>
|
||||
<artifactId>org.springframework.build.aws.ant</artifactId>
|
||||
<version>3.0.5.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.java.dev.jets3t</groupId>
|
||||
<artifactId>jets3t</artifactId>
|
||||
<version>0.7.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<!-- the name of this project is 'spring-data-document-dist';
|
||||
make sure the zip file is just 'spring-data-document'. -->
|
||||
<finalName>${dist.finalName}</finalName>
|
||||
</build>
|
||||
|
||||
<distributionManagement>
|
||||
<!-- see 'staging' profile for dry-run deployment settings -->
|
||||
<downloadUrl>http://www.springsource.com/spring-data</downloadUrl>
|
||||
<site>
|
||||
<id>static.springframework.org</id>
|
||||
<url>
|
||||
scp://static.springframework.org/var/www/domains/springframework.org/static/htdocs/spring-data/data-document/snapshot-site/
|
||||
</url>
|
||||
</site>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<name>Spring Milestone Repository</name>
|
||||
<url>s3://maven.springframework.org/milestone</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>spring-snapshot</id>
|
||||
<name>Spring Snapshot Repository</name>
|
||||
<url>s3://maven.springframework.org/snapshot</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
<dependencies>
|
||||
<!-- MongoDB -->
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongo-java-driver</artifactId>
|
||||
<version>${mongo}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-document-parent</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../spring-data-document-parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-data-couchdb</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Data CouchDB Support</name>
|
||||
|
||||
<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>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<id>tareq.abedrabbo</id>
|
||||
<name>Tareq Abedrabbo</name>
|
||||
<email>tareq.abedrabbo@opencredo.com</email>
|
||||
<organization>OpenCredo</organization>
|
||||
<organizationUrl>http://www.opencredo.org</organizationUrl>
|
||||
<roles>
|
||||
<role>Project Admin</role>
|
||||
<role>Developer</role>
|
||||
</roles>
|
||||
<timezone>+0</timezone>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>tomas.lukosius</id>
|
||||
<name>Tomas Lukosius</name>
|
||||
<email>tomas.lukosius@opencredo.com</email>
|
||||
<organization>OpenCredo</organization>
|
||||
<organizationUrl>http://www.opencredo.org</organizationUrl>
|
||||
<roles>
|
||||
<role>Project Admin</role>
|
||||
<role>Developer</role>
|
||||
</roles>
|
||||
<timezone>+0</timezone>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- Spring -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring Data -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-document-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Jackson JSON -->
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-core-asl</artifactId>
|
||||
<version>1.6.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-mapper-asl</artifactId>
|
||||
<version>1.6.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>jsr250-api</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-all</artifactId>
|
||||
<version>1.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Couch DB -->
|
||||
<dependency>
|
||||
<groupId>com.google.code.jcouchdb</groupId>
|
||||
<artifactId>jcouchdb</artifactId>
|
||||
<version>0.11.0-1</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.springsource.bundlor</groupId>
|
||||
<artifactId>com.springsource.bundlor.maven</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.couchdb;
|
||||
|
||||
import org.springframework.dao.InvalidDataAccessResourceUsageException;
|
||||
import org.springframework.web.client.HttpServerErrorException;
|
||||
|
||||
public class CouchServerResourceUsageException extends InvalidDataAccessResourceUsageException {
|
||||
|
||||
/**
|
||||
* Create a new CouchServerResourceUsageException,
|
||||
* wrapping an arbitrary HttpServerErrorException.
|
||||
*
|
||||
* @param cause the HttpServerErrorException thrown
|
||||
*/
|
||||
public CouchServerResourceUsageException(HttpServerErrorException cause) {
|
||||
super(cause != null ? cause.getMessage() : null, cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.couchdb;
|
||||
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
|
||||
public class CouchUsageException extends InvalidDataAccessApiUsageException {
|
||||
|
||||
/**
|
||||
* Create a new CouchUsageException,
|
||||
* wrapping an arbitrary HttpServerErrorException.
|
||||
*
|
||||
* @param cause the HttpServerErrorException thrown
|
||||
*/
|
||||
public CouchUsageException(HttpClientErrorException cause) {
|
||||
super(cause != null ? cause.getMessage() : null, cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.couchdb;
|
||||
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.web.client.HttpStatusCodeException;
|
||||
|
||||
public class DocumentExistsException extends DataIntegrityViolationException {
|
||||
|
||||
/**
|
||||
* Create a new DocumentExistsException,
|
||||
* wrapping an arbitrary HttpServerErrorException.
|
||||
*
|
||||
* @param cause the HttpServerErrorException thrown
|
||||
*/
|
||||
public DocumentExistsException(String documentId, HttpStatusCodeException cause) {
|
||||
super(cause != null ? cause.getMessage() : null, cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.couchdb;
|
||||
|
||||
import org.springframework.dao.UncategorizedDataAccessException;
|
||||
import org.springframework.web.client.RestClientException;
|
||||
|
||||
public class UncategorizedCouchDataAccessException extends UncategorizedDataAccessException {
|
||||
|
||||
/**
|
||||
* Create a new HibernateSystemException,
|
||||
* wrapping an arbitrary HibernateException.
|
||||
*
|
||||
* @param cause the HibernateException thrown
|
||||
*/
|
||||
public UncategorizedCouchDataAccessException(RestClientException cause) {
|
||||
super(cause != null ? cause.getMessage() : null, cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.couchdb.admin;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.data.document.couchdb.support.CouchUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.client.RestOperations;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
public class CouchAdmin implements CouchAdminOperations {
|
||||
|
||||
private String databaseUrl;
|
||||
private RestOperations restOperations = new RestTemplate();
|
||||
|
||||
public CouchAdmin(String databaseUrl) {
|
||||
|
||||
if (!databaseUrl.trim().endsWith("/")) {
|
||||
this.databaseUrl = databaseUrl.trim() + "/";
|
||||
} else {
|
||||
this.databaseUrl = databaseUrl.trim();
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> listDatabases() {
|
||||
String dbs = restOperations.getForObject(databaseUrl + "_all_dbs", String.class);
|
||||
return Arrays.asList(StringUtils.commaDelimitedListToStringArray(dbs));
|
||||
}
|
||||
|
||||
public void createDatabase(String dbName) {
|
||||
org.springframework.util.Assert.hasText(dbName);
|
||||
restOperations.put(databaseUrl + dbName, null);
|
||||
|
||||
}
|
||||
|
||||
public void deleteDatabase(String dbName) {
|
||||
org.springframework.util.Assert.hasText(dbName);
|
||||
restOperations.delete(CouchUtils.ensureTrailingSlash(databaseUrl + dbName));
|
||||
|
||||
}
|
||||
|
||||
public DbInfo getDatabaseInfo(String dbName) {
|
||||
String url = CouchUtils.ensureTrailingSlash(databaseUrl + dbName);
|
||||
Map dbInfoMap = (Map) restOperations.getForObject(url, Map.class);
|
||||
return new DbInfo(dbInfoMap);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.couchdb.admin;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface CouchAdminOperations {
|
||||
|
||||
|
||||
// functionality for /_special - replication, logs, UUIDs
|
||||
|
||||
List<String> listDatabases();
|
||||
|
||||
void createDatabase(String name);
|
||||
|
||||
void deleteDatabase(String name);
|
||||
|
||||
DbInfo getDatabaseInfo(String name);
|
||||
|
||||
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.document.couchdb.admin;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
public class DbInfo {
|
||||
|
||||
private Map dbInfoMap;
|
||||
|
||||
public DbInfo(Map dbInfoMap) {
|
||||
super();
|
||||
this.dbInfoMap = dbInfoMap;
|
||||
}
|
||||
|
||||
public boolean isCompactRunning() {
|
||||
return (Boolean) this.dbInfoMap.get("compact_running");
|
||||
}
|
||||
|
||||
public String getDbName() {
|
||||
return (String) this.dbInfoMap.get("db_name");
|
||||
}
|
||||
|
||||
public long getDiskFormatVersion() {
|
||||
return (Long) this.dbInfoMap.get("disk_format_version");
|
||||
}
|
||||
|
||||
public long getDiskSize() {
|
||||
return (Long) this.dbInfoMap.get("disk_size");
|
||||
}
|
||||
|
||||
public long getDocCount() {
|
||||
return (Long) this.dbInfoMap.get("doc_count");
|
||||
}
|
||||
|
||||
public long getDocDeleteCount() {
|
||||
return (Long) this.dbInfoMap.get("doc_del_count");
|
||||
}
|
||||
|
||||
public long getInstanceStartTime() {
|
||||
return (Long) this.dbInfoMap.get("instance_start_time");
|
||||
}
|
||||
|
||||
public long getPurgeSequence() {
|
||||
return (Long) this.dbInfoMap.get("purge_seq");
|
||||
}
|
||||
|
||||
public long getUpdateSequence() {
|
||||
return (Long) this.dbInfoMap.get("update_seq");
|
||||
}
|
||||
|
||||
public Map getDbInfoMap() {
|
||||
return Collections.unmodifiableMap(dbInfoMap);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.couchdb.config;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
|
||||
import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.data.document.couchdb.monitor.ServerInfo;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
public class CouchJmxParser implements BeanDefinitionParser {
|
||||
|
||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||
String databaseUrl = element.getAttribute("database-url");
|
||||
if (!StringUtils.hasText(databaseUrl)) {
|
||||
databaseUrl = "http://localhost:5984";
|
||||
}
|
||||
registerJmxComponents(databaseUrl, element, parserContext);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void registerJmxComponents(String databaseUrl, Element element, ParserContext parserContext) {
|
||||
Object eleSource = parserContext.extractSource(element);
|
||||
|
||||
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
|
||||
|
||||
/*
|
||||
createBeanDefEntry(AssertMetrics.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(BackgroundFlushingMetrics.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(BtreeIndexCounters.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(ConnectionMetrics.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(GlobalLockMetrics.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(MemoryMetrics.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(OperationCounters.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
*/
|
||||
createBeanDefEntry(ServerInfo.class, compositeDef, databaseUrl, eleSource, parserContext);
|
||||
//createBeanDefEntry(MongoAdmin.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
|
||||
|
||||
parserContext.registerComponent(compositeDef);
|
||||
|
||||
}
|
||||
|
||||
protected void createBeanDefEntry(Class clazz, CompositeComponentDefinition compositeDef, String databaseUrl, Object eleSource, ParserContext parserContext) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
|
||||
builder.getRawBeanDefinition().setSource(eleSource);
|
||||
builder.addConstructorArg(databaseUrl);
|
||||
BeanDefinition assertDef = builder.getBeanDefinition();
|
||||
String assertName = parserContext.getReaderContext().registerWithGeneratedName(assertDef);
|
||||
compositeDef.addNestedComponent(new BeanComponentDefinition(assertDef, assertName));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.couchdb.core;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
|
||||
public interface CouchOperations {
|
||||
|
||||
/**
|
||||
* Reads a document from the database and maps it a Java object.
|
||||
* </p>
|
||||
* This method is intended to work when a default database
|
||||
* is set on the CouchDbDocumentOperations instance.
|
||||
*
|
||||
* @param id the id of the CouchDB document to read
|
||||
* @param targetClass the target type to map to
|
||||
* @return the mapped object
|
||||
*/
|
||||
<T> T findOne(String id, Class<T> targetClass);
|
||||
|
||||
/**
|
||||
* Reads a document from the database and maps it a Java object.
|
||||
*
|
||||
* @param uri the full URI of the document to read
|
||||
* @param targetClass the target type to map to
|
||||
* @return the mapped object
|
||||
*/
|
||||
<T> T findOne(URI uri, Class<T> targetClass);
|
||||
|
||||
|
||||
/**
|
||||
* Maps a Java object to JSON and writes it to the database
|
||||
* </p>
|
||||
* This method is intended to work when a default database
|
||||
* is set on the CouchDbDocumentOperations instance.
|
||||
*
|
||||
* @param id the id of the document to write
|
||||
* @param document the object to write
|
||||
*/
|
||||
void save(String id, Object document);
|
||||
|
||||
/**
|
||||
* Maps a Java object to JSON and writes it to the database
|
||||
*
|
||||
* @param uri the full URI of the document to write
|
||||
* @param document the object to write
|
||||
*/
|
||||
void save(URI uri, Object document);
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.document.couchdb.core;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.data.document.couchdb.CouchServerResourceUsageException;
|
||||
import org.springframework.data.document.couchdb.CouchUsageException;
|
||||
import org.springframework.data.document.couchdb.DocumentRetrievalFailureException;
|
||||
import org.springframework.data.document.couchdb.UncategorizedCouchDataAccessException;
|
||||
import org.springframework.data.document.couchdb.support.CouchUtils;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.client.*;
|
||||
|
||||
|
||||
public class CouchTemplate implements CouchOperations {
|
||||
|
||||
protected final Log logger = LogFactory.getLog(this.getClass());
|
||||
|
||||
private String defaultDocumentUrl;
|
||||
|
||||
private RestOperations restOperations = new RestTemplate();
|
||||
|
||||
/**
|
||||
* Constructs an instance of CouchDbDocumentTemplate with a default database
|
||||
*
|
||||
* @param defaultDatabaseUrl the default database to connect to
|
||||
*/
|
||||
public CouchTemplate(String defaultDatabaseUrl) {
|
||||
Assert.hasText(defaultDatabaseUrl, "defaultDatabaseUrl must not be empty");
|
||||
defaultDocumentUrl = CouchUtils.addId(defaultDatabaseUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance of CouchDbDocumentTemplate with a default database
|
||||
*
|
||||
* @param defaultDatabaseUrl the default database to connect to
|
||||
*/
|
||||
public CouchTemplate(String defaultDatabaseUrl, RestOperations restOperations) {
|
||||
this(defaultDatabaseUrl);
|
||||
Assert.notNull(restOperations, "restOperations must not be null");
|
||||
this.restOperations = restOperations;
|
||||
}
|
||||
|
||||
|
||||
public <T> T findOne(String id, Class<T> targetClass) {
|
||||
Assert.state(defaultDocumentUrl != null, "defaultDatabaseUrl must be set to use this method");
|
||||
try {
|
||||
return restOperations.getForObject(defaultDocumentUrl, targetClass, id);
|
||||
//TODO check this exception translation and centralize.
|
||||
} catch (HttpClientErrorException clientError) {
|
||||
if (clientError.getStatusCode() == HttpStatus.NOT_FOUND) {
|
||||
throw new DocumentRetrievalFailureException(defaultDocumentUrl + "/" + id);
|
||||
}
|
||||
throw new CouchUsageException(clientError);
|
||||
} catch (HttpServerErrorException serverError) {
|
||||
throw new CouchServerResourceUsageException(serverError);
|
||||
} catch (RestClientException otherError) {
|
||||
throw new UncategorizedCouchDataAccessException(otherError);
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T findOne(URI uri, Class<T> targetClass) {
|
||||
Assert.state(uri != null, "uri must be set to use this method");
|
||||
try {
|
||||
return restOperations.getForObject(uri, targetClass);
|
||||
//TODO check this exception translation and centralize.
|
||||
} catch (HttpClientErrorException clientError) {
|
||||
if (clientError.getStatusCode() == HttpStatus.NOT_FOUND) {
|
||||
throw new DocumentRetrievalFailureException(uri.getPath());
|
||||
}
|
||||
throw new CouchUsageException(clientError);
|
||||
} catch (HttpServerErrorException serverError) {
|
||||
throw new CouchServerResourceUsageException(serverError);
|
||||
} catch (RestClientException otherError) {
|
||||
throw new UncategorizedCouchDataAccessException(otherError);
|
||||
}
|
||||
}
|
||||
|
||||
public void save(String id, Object document) {
|
||||
Assert.notNull(document, "document must not be null for save");
|
||||
HttpEntity<?> httpEntity = createHttpEntity(document);
|
||||
try {
|
||||
ResponseEntity<Map> response = restOperations.exchange(defaultDocumentUrl, HttpMethod.PUT, httpEntity, Map.class, id);
|
||||
//TODO update the document revision id on the object from the returned value
|
||||
//TODO better exception translation
|
||||
} catch (RestClientException e) {
|
||||
throw new UncategorizedCouchDataAccessException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void save(URI uri, Object document) {
|
||||
Assert.notNull(document, "document must not be null for save");
|
||||
Assert.notNull(uri, "URI must not be null for save");
|
||||
HttpEntity<?> httpEntity = createHttpEntity(document);
|
||||
try {
|
||||
ResponseEntity<Map> response = restOperations.exchange(uri, HttpMethod.PUT, httpEntity, Map.class);
|
||||
//TODO update the document revision id on the object from the returned value
|
||||
//TODO better exception translation
|
||||
} catch (RestClientException e) {
|
||||
throw new UncategorizedCouchDataAccessException(e);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private HttpEntity<?> createHttpEntity(Object document) {
|
||||
|
||||
if (document instanceof HttpEntity) {
|
||||
HttpEntity httpEntity = (HttpEntity) document;
|
||||
Assert.isTrue(httpEntity.getHeaders().getContentType().equals(MediaType.APPLICATION_JSON),
|
||||
"HttpEntity payload with non application/json content type found.");
|
||||
return httpEntity;
|
||||
}
|
||||
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
|
||||
HttpEntity<Object> httpEntity = new HttpEntity<Object>(document, httpHeaders);
|
||||
|
||||
return httpEntity;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,315 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.couchdb.core.support;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.*;
|
||||
|
||||
import org.codehaus.jackson.*;
|
||||
import org.codehaus.jackson.map.JsonMappingException;
|
||||
import org.codehaus.jackson.map.ObjectMapper;
|
||||
import org.codehaus.jackson.map.type.TypeFactory;
|
||||
import org.codehaus.jackson.type.JavaType;
|
||||
import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.http.HttpOutputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.AbstractHttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.http.converter.HttpMessageNotWritableException;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
public class CouchDbMappingJacksonHttpMessageConverter extends
|
||||
AbstractHttpMessageConverter<Object> {
|
||||
|
||||
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
|
||||
|
||||
private static final String ROWS_FIELD_NAME = "rows";
|
||||
private static final String VALUE_FIELD_NAME = "value";
|
||||
private static final String INCLUDED_DOC_FIELD_NAME = "doc";
|
||||
private static final String TOTAL_ROWS_FIELD_NAME = "total_rows";
|
||||
|
||||
private ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
private boolean prefixJson = false;
|
||||
|
||||
/**
|
||||
* Construct a new {@code BindingJacksonHttpMessageConverter}.
|
||||
*/
|
||||
public CouchDbMappingJacksonHttpMessageConverter() {
|
||||
super(new MediaType("application", "json", DEFAULT_CHARSET));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@code ObjectMapper} for this view. If not set, a default
|
||||
* {@link ObjectMapper#ObjectMapper() ObjectMapper} is used.
|
||||
* <p/>
|
||||
* Setting a custom-configured {@code ObjectMapper} is one way to take
|
||||
* further control of the JSON serialization process. For example, an
|
||||
* extended {@link org.codehaus.jackson.map.SerializerFactory} can be
|
||||
* configured that provides custom serializers for specific types. The other
|
||||
* option for refining the serialization process is to use Jackson's
|
||||
* provided annotations on the types to be serialized, in which case a
|
||||
* custom-configured ObjectMapper is unnecessary.
|
||||
*/
|
||||
public void setObjectMapper(ObjectMapper objectMapper) {
|
||||
Assert.notNull(objectMapper, "'objectMapper' must not be null");
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the JSON output by this view should be prefixed with
|
||||
* "{} &&". Default is false.
|
||||
* <p/>
|
||||
* Prefixing the JSON string in this manner is used to help prevent JSON
|
||||
* Hijacking. The prefix renders the string syntactically invalid as a
|
||||
* script so that it cannot be hijacked. This prefix does not affect the
|
||||
* evaluation of JSON, but if JSON validation is performed on the string,
|
||||
* the prefix would need to be ignored.
|
||||
*/
|
||||
public void setPrefixJson(boolean prefixJson) {
|
||||
this.prefixJson = prefixJson;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRead(Class<?> clazz, MediaType mediaType) {
|
||||
JavaType javaType = getJavaType(clazz);
|
||||
return this.objectMapper.canDeserialize(javaType) && canRead(mediaType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Jackson {@link JavaType} for the specific class.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* Default implementation returns
|
||||
* {@link TypeFactory#type(java.lang.reflect.Type)}, but this can be
|
||||
* overridden in subclasses, to allow for custom generic collection
|
||||
* handling. For instance:
|
||||
* <p/>
|
||||
* <pre class="code">
|
||||
* protected JavaType getJavaType(Class<?> clazz) {
|
||||
* if (List.class.isAssignableFrom(clazz)) {
|
||||
* return TypeFactory.collectionType(ArrayList.class, MyBean.class);
|
||||
* } else {
|
||||
* return super.getJavaType(clazz);
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @param clazz the class to return the java type for
|
||||
* @return the java type
|
||||
*/
|
||||
protected JavaType getJavaType(Class<?> clazz) {
|
||||
return TypeFactory.type(clazz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canWrite(Class<?> clazz, MediaType mediaType) {
|
||||
return this.objectMapper.canSerialize(clazz) && canWrite(mediaType);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supports(Class<?> clazz) {
|
||||
// should not be called, since we override canRead/Write instead
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage)
|
||||
throws IOException, HttpMessageNotReadableException {
|
||||
JavaType javaType = getJavaType(clazz);
|
||||
try {
|
||||
return success(clazz, inputMessage);
|
||||
|
||||
// return this.objectMapper.readValue(inputMessage.getBody(),
|
||||
// javaType);
|
||||
} catch (Exception ex) {
|
||||
throw new HttpMessageNotReadableException("Could not read JSON: "
|
||||
+ ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private Object success(Class<?> clazz, HttpInputMessage inputMessage)
|
||||
throws JsonParseException, IOException {
|
||||
|
||||
//Note, parsing code used from ektorp project
|
||||
JsonParser jp = objectMapper.getJsonFactory().createJsonParser(
|
||||
inputMessage.getBody());
|
||||
if (jp.nextToken() != JsonToken.START_OBJECT) {
|
||||
throw new RuntimeException("Expected data to start with an Object");
|
||||
}
|
||||
Map<String, Integer> fields = readHeaderFields(jp);
|
||||
|
||||
List result;
|
||||
if (fields.containsKey(TOTAL_ROWS_FIELD_NAME)) {
|
||||
int totalRows = fields.get(TOTAL_ROWS_FIELD_NAME);
|
||||
if (totalRows == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
result = new ArrayList(totalRows);
|
||||
} else {
|
||||
result = new ArrayList();
|
||||
}
|
||||
|
||||
ParseState state = new ParseState();
|
||||
|
||||
Object first = parseFirstRow(jp, state, clazz);
|
||||
if (first == null) {
|
||||
return Collections.emptyList();
|
||||
} else {
|
||||
result.add(first);
|
||||
}
|
||||
|
||||
while (jp.getCurrentToken() != null) {
|
||||
skipToField(jp, state.docFieldName, state);
|
||||
if (atEndOfRows(jp)) {
|
||||
return result;
|
||||
}
|
||||
result.add(jp.readValueAs(clazz));
|
||||
endRow(jp, state);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Object parseFirstRow(JsonParser jp, ParseState state, Class clazz)
|
||||
throws JsonParseException, IOException, JsonProcessingException,
|
||||
JsonMappingException {
|
||||
skipToField(jp, VALUE_FIELD_NAME, state);
|
||||
JsonNode value = null;
|
||||
if (atObjectStart(jp)) {
|
||||
value = jp.readValueAsTree();
|
||||
jp.nextToken();
|
||||
if (isEndOfRow(jp)) {
|
||||
state.docFieldName = VALUE_FIELD_NAME;
|
||||
Object doc = objectMapper.readValue(value, clazz);
|
||||
endRow(jp, state);
|
||||
return doc;
|
||||
}
|
||||
}
|
||||
skipToField(jp, INCLUDED_DOC_FIELD_NAME, state);
|
||||
if (atObjectStart(jp)) {
|
||||
state.docFieldName = INCLUDED_DOC_FIELD_NAME;
|
||||
Object doc = jp.readValueAs(clazz);
|
||||
endRow(jp, state);
|
||||
return doc;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private boolean isEndOfRow(JsonParser jp) {
|
||||
return jp.getCurrentToken() == JsonToken.END_OBJECT;
|
||||
}
|
||||
|
||||
private void endRow(JsonParser jp, ParseState state) throws IOException, JsonParseException {
|
||||
state.inRow = false;
|
||||
jp.nextToken();
|
||||
}
|
||||
|
||||
private boolean atObjectStart(JsonParser jp) {
|
||||
return jp.getCurrentToken() == JsonToken.START_OBJECT;
|
||||
}
|
||||
|
||||
private boolean atEndOfRows(JsonParser jp) {
|
||||
return jp.getCurrentToken() != JsonToken.START_OBJECT;
|
||||
}
|
||||
|
||||
private void skipToField(JsonParser jp, String fieldName, ParseState state) throws JsonParseException, IOException {
|
||||
String lastFieldName = null;
|
||||
while (jp.getCurrentToken() != null) {
|
||||
switch (jp.getCurrentToken()) {
|
||||
case FIELD_NAME:
|
||||
lastFieldName = jp.getCurrentName();
|
||||
jp.nextToken();
|
||||
break;
|
||||
case START_OBJECT:
|
||||
if (!state.inRow) {
|
||||
state.inRow = true;
|
||||
jp.nextToken();
|
||||
} else {
|
||||
if (isInField(fieldName, lastFieldName)) {
|
||||
return;
|
||||
} else {
|
||||
jp.skipChildren();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (isInField(fieldName, lastFieldName)) {
|
||||
jp.nextToken();
|
||||
return;
|
||||
}
|
||||
jp.nextToken();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isInField(String fieldName, String lastFieldName) {
|
||||
return lastFieldName != null && lastFieldName.equals(fieldName);
|
||||
}
|
||||
|
||||
|
||||
private Map<String, Integer> readHeaderFields(JsonParser jp)
|
||||
throws JsonParseException, IOException {
|
||||
Map<String, Integer> map = new HashMap<String, Integer>();
|
||||
jp.nextToken();
|
||||
String nextFieldName = jp.getCurrentName();
|
||||
while (!nextFieldName.equals(ROWS_FIELD_NAME)) {
|
||||
jp.nextToken();
|
||||
map.put(nextFieldName, Integer.valueOf(jp.getIntValue()));
|
||||
jp.nextToken();
|
||||
nextFieldName = jp.getCurrentName();
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeInternal(Object o, HttpOutputMessage outputMessage)
|
||||
throws IOException, HttpMessageNotWritableException {
|
||||
|
||||
JsonEncoding encoding = getEncoding(outputMessage.getHeaders()
|
||||
.getContentType());
|
||||
JsonGenerator jsonGenerator = this.objectMapper.getJsonFactory()
|
||||
.createJsonGenerator(outputMessage.getBody(), encoding);
|
||||
try {
|
||||
if (this.prefixJson) {
|
||||
jsonGenerator.writeRaw("{} && ");
|
||||
}
|
||||
this.objectMapper.writeValue(jsonGenerator, o);
|
||||
} catch (JsonGenerationException ex) {
|
||||
throw new HttpMessageNotWritableException("Could not write JSON: "
|
||||
+ ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private JsonEncoding getEncoding(MediaType contentType) {
|
||||
if (contentType != null && contentType.getCharSet() != null) {
|
||||
Charset charset = contentType.getCharSet();
|
||||
for (JsonEncoding encoding : JsonEncoding.values()) {
|
||||
if (charset.name().equals(encoding.getJavaName())) {
|
||||
return encoding;
|
||||
}
|
||||
}
|
||||
}
|
||||
return JsonEncoding.UTF8;
|
||||
}
|
||||
|
||||
private static class ParseState {
|
||||
boolean inRow;
|
||||
String docFieldName = "";
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.couchdb.monitor;
|
||||
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* Base class to encapsulate common configuration settings when connecting to a CouchDB database
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*/
|
||||
public abstract class AbstractMonitor {
|
||||
|
||||
|
||||
protected RestTemplate restTemplate;
|
||||
protected String databaseUrl;
|
||||
|
||||
/**
|
||||
* Gets the databaseUrl used to connect to CouchDB
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getDatabaseUrl() {
|
||||
return this.databaseUrl;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.couchdb.monitor;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.jmx.export.annotation.ManagedOperation;
|
||||
import org.springframework.jmx.export.annotation.ManagedResource;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* Expose basic server information via JMX
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*/
|
||||
@ManagedResource(description = "Server Information")
|
||||
public class ServerInfo extends AbstractMonitor {
|
||||
|
||||
|
||||
public ServerInfo(String databaseUrl) {
|
||||
this.databaseUrl = databaseUrl;
|
||||
this.restTemplate = new RestTemplate();
|
||||
}
|
||||
|
||||
|
||||
@ManagedOperation(description = "Server host name")
|
||||
public String getHostName() throws UnknownHostException {
|
||||
return InetAddress.getLocalHost().getHostName();
|
||||
}
|
||||
|
||||
|
||||
@ManagedOperation(description = "CouchDB Server Version")
|
||||
public String getVersion() {
|
||||
return (String) getRoot().get("version");
|
||||
}
|
||||
|
||||
@ManagedOperation(description = "Message of the day")
|
||||
public String getMotd() {
|
||||
return (String) getRoot().get("greeting");
|
||||
}
|
||||
|
||||
public Map getRoot() {
|
||||
Map map = restTemplate.getForObject(getDatabaseUrl(), Map.class);
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
/**
|
||||
* CouchDB specific JMX monitoring support.
|
||||
*/
|
||||
package org.springframework.data.document.couchdb.monitor;
|
||||
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Copyright 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.data.document.couchdb.support;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
|
||||
/**
|
||||
* Helper class featuring helper methods for internal CouchDB classes.
|
||||
* <p/>
|
||||
* <p>Mainly intended for internal use within the framework.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Tareq Abedrabbo
|
||||
* @since 1.0
|
||||
*/
|
||||
public abstract class CouchUtils {
|
||||
|
||||
/**
|
||||
* Convert the given runtime exception to an appropriate exception from the
|
||||
* <code>org.springframework.dao</code> hierarchy.
|
||||
* Return null if no translation is appropriate: any other exception may
|
||||
* have resulted from user code, and should not be translated.
|
||||
*
|
||||
* @param ex runtime exception that occurred
|
||||
* @return the corresponding DataAccessException instance,
|
||||
* or <code>null</code> if the exception should not be translated
|
||||
*/
|
||||
public static DataAccessException translateCouchExceptionIfPossible(RuntimeException ex) {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an id variable to a URL
|
||||
*
|
||||
* @param url the URL to modify
|
||||
* @return the modified URL
|
||||
*/
|
||||
public static String addId(String url) {
|
||||
return ensureTrailingSlash(url) + "{id}";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a 'changes since' variable to a URL
|
||||
*
|
||||
* @param url
|
||||
* @return
|
||||
*/
|
||||
public static String addChangesSince(String url) {
|
||||
return ensureTrailingSlash(url) + "_changes?since={seq}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that a URL ends with a slash.
|
||||
*
|
||||
* @param url the URL to modify
|
||||
* @return the modified URL
|
||||
*/
|
||||
public static String ensureTrailingSlash(String url) {
|
||||
if (!url.endsWith("/")) {
|
||||
url += "/";
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
http\://www.springframework.org/schema/data/couch=org.springframework.data.document.couchdb.config.CouchNamespaceHandler
|
||||
@@ -1,2 +0,0 @@
|
||||
http\://www.springframework.org/schema/data/couch/spring-couch-1.0.xsd=org/springframework/data/document/couchdb/config/spring-couch-1.0.xsd
|
||||
http\://www.springframework.org/schema/data/couch/spring-couch.xsd=org/springframework/data/document/couchdb/config/spring-couch-1.0.xsd
|
||||
@@ -1,4 +0,0 @@
|
||||
# Tooling related information for the Couch DB namespace
|
||||
http\://www.springframework.org/schema/data/couch@name=Couch Namespace
|
||||
http\://www.springframework.org/schema/data/couch@prefix=couch
|
||||
http\://www.springframework.org/schema/data/couch@icon=org/springframework/jdbc/config/spring-jdbc.gif
|
||||
@@ -1,33 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<xsd:schema xmlns="http://www.springframework.org/schema/data/couch"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:tool="http://www.springframework.org/schema/tool"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:repository="http://www.springframework.org/schema/data/repository"
|
||||
targetNamespace="http://www.springframework.org/schema/data/couch"
|
||||
elementFormDefault="qualified" attributeFormDefault="unqualified">
|
||||
|
||||
<xsd:import namespace="http://www.springframework.org/schema/tool"/>
|
||||
<xsd:import namespace="http://www.springframework.org/schema/context"
|
||||
schemaLocation="http://www.springframework.org/schema/context/spring-context.xsd"/>
|
||||
<xsd:import namespace="http://www.springframework.org/schema/data/repository"
|
||||
schemaLocation="http://www.springframework.org/schema/data/repository/spring-repository.xsd"/>
|
||||
|
||||
|
||||
<xsd:element name="jmx">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Defines a JMX Model MBeans for monitoring a CouchDB server'.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="database-url" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The database URL of the CouchDB]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
</xsd:schema>
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.document.couchdb;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
|
||||
|
||||
/**
|
||||
* @author Tareq Abedrabbo (tareq.abedrabbo@opencredo.com)
|
||||
* @since 13/01/2011
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class DummyDocument {
|
||||
|
||||
private String message;
|
||||
|
||||
private String timestamp = new Date().toString();
|
||||
|
||||
public DummyDocument() {
|
||||
}
|
||||
|
||||
public DummyDocument(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
DummyDocument document = (DummyDocument) o;
|
||||
|
||||
if (message != null ? !message.equals(document.message) : document.message != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return message != null ? message.hashCode() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DummyDocument{" +
|
||||
"message='" + message + '\'' +
|
||||
", timestamp=" + timestamp +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.document.couchdb;
|
||||
|
||||
import org.hamcrest.Description;
|
||||
import org.hamcrest.Factory;
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.TypeSafeMatcher;
|
||||
import org.springframework.http.HttpEntity;
|
||||
|
||||
/**
|
||||
* Matches the content of the body of an HttpEntity.
|
||||
*
|
||||
* @author Tareq Abedrabbo
|
||||
* @since 31/01/2011
|
||||
*/
|
||||
public class IsBodyEqual extends TypeSafeMatcher<HttpEntity> {
|
||||
|
||||
private Object object;
|
||||
|
||||
public IsBodyEqual(Object object) {
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matchesSafely(HttpEntity httpEntity) {
|
||||
return httpEntity.getBody().equals(object);
|
||||
}
|
||||
|
||||
public void describeTo(Description description) {
|
||||
description.appendText("body equals ").appendValue(object);
|
||||
}
|
||||
|
||||
@Factory
|
||||
public static Matcher<HttpEntity> bodyEqual(Object object) {
|
||||
return new IsBodyEqual(object);
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.couchdb.admin;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.document.couchdb.core.CouchConstants;
|
||||
|
||||
public class CouchAdminIntegrationTests {
|
||||
|
||||
@Test
|
||||
@Ignore("until CI has couch server running")
|
||||
public void dbLifecycle() {
|
||||
|
||||
CouchAdmin admin = new CouchAdmin(CouchConstants.COUCHDB_URL);
|
||||
admin.deleteDatabase("foo");
|
||||
List<String> dbs = admin.listDatabases();
|
||||
admin.createDatabase("foo");
|
||||
List<String> newDbs = admin.listDatabases();
|
||||
Assert.assertEquals(dbs.size() + 1, newDbs.size());
|
||||
}
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.document.couchdb.core;
|
||||
|
||||
import static org.junit.Assume.assumeNoException;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
import static org.springframework.http.HttpStatus.OK;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.web.client.DefaultResponseErrorHandler;
|
||||
import org.springframework.web.client.RestClientException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* Base class for CouchDB integration tests. Checks whether CouchDB is available before running each test,
|
||||
* in which case the test is executed. If CouchDB is not available, tests are ignored.
|
||||
*
|
||||
* @author Tareq Abedrabbo (tareq.abedrabbo@opencredo.com)
|
||||
* @since 13/01/2011
|
||||
*/
|
||||
|
||||
public abstract class AbstractCouchTemplateIntegrationTests {
|
||||
|
||||
|
||||
protected static final Log log = LogFactory.getLog(AbstractCouchTemplateIntegrationTests.class);
|
||||
|
||||
protected static final RestTemplate restTemplate = new RestTemplate();
|
||||
|
||||
/**
|
||||
* This methods ensures that the database is running. Otherwise, the test is ignored.
|
||||
*/
|
||||
@BeforeClass
|
||||
public static void assumeDatabaseIsUpAndRunning() {
|
||||
try {
|
||||
ResponseEntity<String> responseEntity = restTemplate.getForEntity(CouchConstants.COUCHDB_URL, String.class);
|
||||
assumeTrue(responseEntity.getStatusCode().equals(OK));
|
||||
log.debug("CouchDB is running on " + CouchConstants.COUCHDB_URL +
|
||||
" with status " + responseEntity.getStatusCode());
|
||||
} catch (RestClientException e) {
|
||||
log.debug("CouchDB is not running on " + CouchConstants.COUCHDB_URL);
|
||||
assumeNoException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUpTestDatabase() throws Exception {
|
||||
RestTemplate template = new RestTemplate();
|
||||
template.setErrorHandler(new DefaultResponseErrorHandler() {
|
||||
@Override
|
||||
public void handleError(ClientHttpResponse response) throws IOException {
|
||||
// do nothing, error status will be handled in the switch statement
|
||||
}
|
||||
});
|
||||
ResponseEntity<String> response = template.getForEntity(CouchConstants.TEST_DATABASE_URL, String.class);
|
||||
HttpStatus statusCode = response.getStatusCode();
|
||||
switch (statusCode) {
|
||||
case NOT_FOUND:
|
||||
createNewTestDatabase();
|
||||
break;
|
||||
case OK:
|
||||
deleteExisitingTestDatabase();
|
||||
createNewTestDatabase();
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unsupported http status [" + statusCode + "]");
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteExisitingTestDatabase() {
|
||||
restTemplate.delete(CouchConstants.TEST_DATABASE_URL);
|
||||
}
|
||||
|
||||
private void createNewTestDatabase() {
|
||||
restTemplate.put(CouchConstants.TEST_DATABASE_URL, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a CouchDB document and converts it to the expected type.
|
||||
*/
|
||||
protected <T> T getDocument(String id, Class<T> expectedType) {
|
||||
String url = CouchConstants.TEST_DATABASE_URL + "{id}";
|
||||
return restTemplate.getForObject(url, expectedType, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a CouchDB document
|
||||
*/
|
||||
protected String putDocument(Object document) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
HttpEntity request = new HttpEntity(document, headers);
|
||||
String id = UUID.randomUUID().toString();
|
||||
restTemplate.put(CouchConstants.TEST_DATABASE_URL + "{id}", request, id);
|
||||
return id;
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.couchdb.core;
|
||||
|
||||
public abstract class CouchConstants {
|
||||
|
||||
public static final String COUCHDB_URL = "http://127.0.0.1:5984/";
|
||||
public static final String TEST_DATABASE_URL = COUCHDB_URL + "si_couchdb_test/";
|
||||
|
||||
public CouchConstants() {
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.document.couchdb.core;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.document.couchdb.DummyDocument;
|
||||
|
||||
public class CouchTemplateIntegrationTests extends AbstractCouchTemplateIntegrationTests {
|
||||
|
||||
|
||||
@Test
|
||||
@Ignore("until CI has couch server running")
|
||||
public void saveAndFindTest() {
|
||||
CouchTemplate template = new CouchTemplate(CouchConstants.TEST_DATABASE_URL);
|
||||
DummyDocument document = new DummyDocument("hello");
|
||||
String id = UUID.randomUUID().toString();
|
||||
template.save(id, document);
|
||||
DummyDocument foundDocument = template.findOne(id, DummyDocument.class);
|
||||
Assert.assertEquals(document.getMessage(), foundDocument.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
log4j.rootCategory=INFO, stdout
|
||||
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
|
||||
|
||||
log4j.category.org.apache.activemq=ERROR
|
||||
log4j.category.org.springframework.batch=DEBUG
|
||||
log4j.category.org.springframework.transaction=INFO
|
||||
|
||||
log4j.category.org.hibernate.SQL=DEBUG
|
||||
# for debugging datasource initialization
|
||||
# log4j.category.test.jdbc=DEBUG
|
||||
@@ -1,24 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:p="http://www.springframework.org/schema/p"
|
||||
xmlns:couch="http://www.springframework.org/schema/data/couch"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/data/couch http://www.springframework.org/schema/data/couch/spring-couch-1.0.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
|
||||
|
||||
|
||||
<couch:jmx/>
|
||||
|
||||
<context:mbean-export/>
|
||||
|
||||
<bean id="registry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean"
|
||||
p:port="1099"/>
|
||||
|
||||
<!-- Expose JMX over RMI -->
|
||||
<bean id="serverConnector" class="org.springframework.jmx.support.ConnectorServerFactoryBean" depends-on="registry"
|
||||
p:objectName="connector:name=rmi"
|
||||
p:serviceUrl="service:jmx:rmi://localhost/jndi/rmi://localhost:1099/myconnector"/>
|
||||
|
||||
</beans>
|
||||
@@ -1,24 +0,0 @@
|
||||
Bundle-SymbolicName: org.springframework.data.couchdb
|
||||
Bundle-Name: Spring Data Couch DB Support
|
||||
Bundle-Vendor: SpringSource
|
||||
Bundle-ManifestVersion: 2
|
||||
Import-Package:
|
||||
sun.reflect;version="0";resolution:=optional
|
||||
Import-Template:
|
||||
org.springframework.beans.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.core.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.dao.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.http.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.web.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.util.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.context.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.jmx.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.remoting.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.data.core.*;version="[1.0.0, 2.0.0)",
|
||||
org.springframework.data.document.*;version="[1.0.0, 2.0.0)",
|
||||
org.codehaus.jackson.*;version="[1.0.0, 2.0.0)";resolution:=optional,
|
||||
org.aopalliance.*;version="[1.0.0, 2.0.0)";resolution:=optional,
|
||||
org.apache.commons.logging.*;version="[1.1.1, 2.0.0)",
|
||||
org.w3c.dom.*;version="0"
|
||||
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-document-parent</artifactId>
|
||||
<version>1.0.0.M2</version>
|
||||
<relativePath>../spring-data-document-parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-data-document-core</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Data Document Support</name>
|
||||
<dependencies>
|
||||
|
||||
<!-- Spring -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>jsr250-api</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- Dependencies for web analytics functionality - to me moved into spring framework -->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<version>2.5</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- Spring dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>${org.springframework.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<version>${org.springframework.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
<version>${org.springframework.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.springsource.bundlor</groupId>
|
||||
<artifactId>com.springsource.bundlor.maven</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,3 +0,0 @@
|
||||
Manifest-Version: 1.0
|
||||
Class-Path:
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
package org.springframework.data.document.analytics;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ControllerCounter {
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public double getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(double count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public Map<String, Double> getMethods() {
|
||||
return methods;
|
||||
}
|
||||
|
||||
|
||||
public void setMethods(Map<String, Double> methods) {
|
||||
this.methods = methods;
|
||||
}
|
||||
|
||||
private String name;
|
||||
|
||||
private double count;
|
||||
|
||||
private Map<String, Double> methods;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ControllerCounter [name=" + name + ", count=" + count
|
||||
+ ", methods=" + methods + "]";
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
package org.springframework.data.document.analytics;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class MvcEvent {
|
||||
|
||||
private String controller;
|
||||
|
||||
private String action;
|
||||
|
||||
private Parameters parameters;
|
||||
|
||||
private Date date;
|
||||
|
||||
private String requestUri;
|
||||
|
||||
private String requestAddress;
|
||||
|
||||
private String remoteUser;
|
||||
|
||||
private String view;
|
||||
|
||||
public String getController() {
|
||||
return controller;
|
||||
}
|
||||
|
||||
public void setController(String controller) {
|
||||
this.controller = controller;
|
||||
}
|
||||
|
||||
public String getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
public void setAction(String action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
public Parameters getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public void setParameters(Parameters parameters) {
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
public Date getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setDate(Date date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public String getRequestUri() {
|
||||
return requestUri;
|
||||
}
|
||||
|
||||
public void setRequestUri(String requestUri) {
|
||||
this.requestUri = requestUri;
|
||||
}
|
||||
|
||||
public String getRequestAddress() {
|
||||
return requestAddress;
|
||||
}
|
||||
|
||||
public void setRequestAddress(String requestAddress) {
|
||||
this.requestAddress = requestAddress;
|
||||
}
|
||||
|
||||
public String getRemoteUser() {
|
||||
return remoteUser;
|
||||
}
|
||||
|
||||
public void setRemoteUser(String remoteUser) {
|
||||
this.remoteUser = remoteUser;
|
||||
}
|
||||
|
||||
//TODO
|
||||
//Map sessionAttributes
|
||||
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package org.springframework.data.document.analytics;
|
||||
|
||||
public class Parameters {
|
||||
|
||||
private String p1;
|
||||
|
||||
private String p2;
|
||||
|
||||
private String p3;
|
||||
|
||||
public String getP1() {
|
||||
return p1;
|
||||
}
|
||||
|
||||
public void setP1(String p1) {
|
||||
this.p1 = p1;
|
||||
}
|
||||
|
||||
public String getP2() {
|
||||
return p2;
|
||||
}
|
||||
|
||||
public void setP2(String p2) {
|
||||
this.p2 = p2;
|
||||
}
|
||||
|
||||
public String getP3() {
|
||||
return p3;
|
||||
}
|
||||
|
||||
public void setP3(String p3) {
|
||||
this.p3 = p3;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,821 +0,0 @@
|
||||
/*
|
||||
* 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.data.document.web.bind.annotation.support;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.*;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.ui.ExtendedModelMap;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.util.*;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.web.HttpMediaTypeNotSupportedException;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.bind.annotation.support.HandlerMethodInvocationException;
|
||||
import org.springframework.web.bind.annotation.support.HandlerMethodResolver;
|
||||
import org.springframework.web.bind.support.*;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartRequest;
|
||||
|
||||
/**
|
||||
* Support class for invoking an annotated handler method. Operates on the introspection results of a {@link
|
||||
* HandlerMethodResolver} for a specific handler type.
|
||||
* <p/>
|
||||
* <p>Used by {@link org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter} and {@link
|
||||
* org.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Arjen Poutsma
|
||||
* @see #invokeHandlerMethod
|
||||
* @since 2.5.2
|
||||
*/
|
||||
public class HandlerMethodInvoker {
|
||||
|
||||
private static final String MODEL_KEY_PREFIX_STALE = SessionAttributeStore.class.getName() + ".STALE.";
|
||||
|
||||
/**
|
||||
* We'll create a lot of these objects, so we don't want a new logger every time.
|
||||
*/
|
||||
private static final Log logger = LogFactory.getLog(HandlerMethodInvoker.class);
|
||||
|
||||
private final HandlerMethodResolver methodResolver;
|
||||
|
||||
private final WebBindingInitializer bindingInitializer;
|
||||
|
||||
private final SessionAttributeStore sessionAttributeStore;
|
||||
|
||||
private final ParameterNameDiscoverer parameterNameDiscoverer;
|
||||
|
||||
private final WebArgumentResolver[] customArgumentResolvers;
|
||||
|
||||
private final HttpMessageConverter[] messageConverters;
|
||||
|
||||
private final SimpleSessionStatus sessionStatus = new SimpleSessionStatus();
|
||||
|
||||
|
||||
public HandlerMethodInvoker(HandlerMethodResolver methodResolver) {
|
||||
this(methodResolver, null);
|
||||
}
|
||||
|
||||
public HandlerMethodInvoker(HandlerMethodResolver methodResolver, WebBindingInitializer bindingInitializer) {
|
||||
this(methodResolver, bindingInitializer, new DefaultSessionAttributeStore(), null, null, null);
|
||||
}
|
||||
|
||||
public HandlerMethodInvoker(HandlerMethodResolver methodResolver, WebBindingInitializer bindingInitializer,
|
||||
SessionAttributeStore sessionAttributeStore, ParameterNameDiscoverer parameterNameDiscoverer,
|
||||
WebArgumentResolver[] customArgumentResolvers, HttpMessageConverter[] messageConverters) {
|
||||
|
||||
this.methodResolver = methodResolver;
|
||||
this.bindingInitializer = bindingInitializer;
|
||||
this.sessionAttributeStore = sessionAttributeStore;
|
||||
this.parameterNameDiscoverer = parameterNameDiscoverer;
|
||||
this.customArgumentResolvers = customArgumentResolvers;
|
||||
this.messageConverters = messageConverters;
|
||||
}
|
||||
|
||||
|
||||
public final Object invokeHandlerMethod(Method handlerMethod, Object handler,
|
||||
NativeWebRequest webRequest, ExtendedModelMap implicitModel) throws Exception {
|
||||
|
||||
Method handlerMethodToInvoke = BridgeMethodResolver.findBridgedMethod(handlerMethod);
|
||||
try {
|
||||
boolean debug = logger.isDebugEnabled();
|
||||
for (String attrName : this.methodResolver.getActualSessionAttributeNames()) {
|
||||
Object attrValue = this.sessionAttributeStore.retrieveAttribute(webRequest, attrName);
|
||||
if (attrValue != null) {
|
||||
implicitModel.addAttribute(attrName, attrValue);
|
||||
}
|
||||
}
|
||||
for (Method attributeMethod : this.methodResolver.getModelAttributeMethods()) {
|
||||
Method attributeMethodToInvoke = BridgeMethodResolver.findBridgedMethod(attributeMethod);
|
||||
Object[] args = resolveHandlerArguments(attributeMethodToInvoke, handler, webRequest, implicitModel);
|
||||
if (debug) {
|
||||
logger.debug("Invoking model attribute method: " + attributeMethodToInvoke);
|
||||
}
|
||||
String attrName = AnnotationUtils.findAnnotation(attributeMethod, ModelAttribute.class).value();
|
||||
if (!"".equals(attrName) && implicitModel.containsAttribute(attrName)) {
|
||||
continue;
|
||||
}
|
||||
ReflectionUtils.makeAccessible(attributeMethodToInvoke);
|
||||
Object attrValue = attributeMethodToInvoke.invoke(handler, args);
|
||||
if ("".equals(attrName)) {
|
||||
Class resolvedType = GenericTypeResolver.resolveReturnType(attributeMethodToInvoke, handler.getClass());
|
||||
attrName = Conventions.getVariableNameForReturnType(attributeMethodToInvoke, resolvedType, attrValue);
|
||||
}
|
||||
if (!implicitModel.containsAttribute(attrName)) {
|
||||
implicitModel.addAttribute(attrName, attrValue);
|
||||
}
|
||||
}
|
||||
Object[] args = resolveHandlerArguments(handlerMethodToInvoke, handler, webRequest, implicitModel);
|
||||
if (debug) {
|
||||
logger.debug("Invoking request handler method: " + handlerMethodToInvoke);
|
||||
}
|
||||
ReflectionUtils.makeAccessible(handlerMethodToInvoke);
|
||||
return handlerMethodToInvoke.invoke(handler, args);
|
||||
} catch (IllegalStateException ex) {
|
||||
// Internal assertion failed (e.g. invalid signature):
|
||||
// throw exception with full handler method context...
|
||||
throw new HandlerMethodInvocationException(handlerMethodToInvoke, ex);
|
||||
} catch (InvocationTargetException ex) {
|
||||
// User-defined @ModelAttribute/@InitBinder/@RequestMapping method threw an exception...
|
||||
ReflectionUtils.rethrowException(ex.getTargetException());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public final void updateModelAttributes(Object handler, Map<String, Object> mavModel,
|
||||
ExtendedModelMap implicitModel, NativeWebRequest webRequest) throws Exception {
|
||||
|
||||
if (this.methodResolver.hasSessionAttributes() && this.sessionStatus.isComplete()) {
|
||||
for (String attrName : this.methodResolver.getActualSessionAttributeNames()) {
|
||||
this.sessionAttributeStore.cleanupAttribute(webRequest, attrName);
|
||||
}
|
||||
}
|
||||
|
||||
// Expose model attributes as session attributes, if required.
|
||||
// Expose BindingResults for all attributes, making custom editors available.
|
||||
Map<String, Object> model = (mavModel != null ? mavModel : implicitModel);
|
||||
if (model != null) {
|
||||
try {
|
||||
String[] originalAttrNames = model.keySet().toArray(new String[model.size()]);
|
||||
for (String attrName : originalAttrNames) {
|
||||
Object attrValue = model.get(attrName);
|
||||
boolean isSessionAttr = this.methodResolver.isSessionAttribute(
|
||||
attrName, (attrValue != null ? attrValue.getClass() : null));
|
||||
if (isSessionAttr) {
|
||||
if (this.sessionStatus.isComplete()) {
|
||||
implicitModel.put(MODEL_KEY_PREFIX_STALE + attrName, Boolean.TRUE);
|
||||
} else if (!implicitModel.containsKey(MODEL_KEY_PREFIX_STALE + attrName)) {
|
||||
this.sessionAttributeStore.storeAttribute(webRequest, attrName, attrValue);
|
||||
}
|
||||
}
|
||||
if (!attrName.startsWith(BindingResult.MODEL_KEY_PREFIX) &&
|
||||
(isSessionAttr || isBindingCandidate(attrValue))) {
|
||||
String bindingResultKey = BindingResult.MODEL_KEY_PREFIX + attrName;
|
||||
if (mavModel != null && !model.containsKey(bindingResultKey)) {
|
||||
WebDataBinder binder = createBinder(webRequest, attrValue, attrName);
|
||||
initBinder(handler, attrName, binder, webRequest);
|
||||
mavModel.put(bindingResultKey, binder.getBindingResult());
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (InvocationTargetException ex) {
|
||||
// User-defined @InitBinder method threw an exception...
|
||||
ReflectionUtils.rethrowException(ex.getTargetException());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Object[] resolveHandlerArguments(Method handlerMethod, Object handler,
|
||||
NativeWebRequest webRequest, ExtendedModelMap implicitModel) throws Exception {
|
||||
|
||||
Class[] paramTypes = handlerMethod.getParameterTypes();
|
||||
Object[] args = new Object[paramTypes.length];
|
||||
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
MethodParameter methodParam = new MethodParameter(handlerMethod, i);
|
||||
methodParam.initParameterNameDiscovery(this.parameterNameDiscoverer);
|
||||
GenericTypeResolver.resolveParameterType(methodParam, handler.getClass());
|
||||
String paramName = null;
|
||||
String headerName = null;
|
||||
boolean requestBodyFound = false;
|
||||
String cookieName = null;
|
||||
String pathVarName = null;
|
||||
String attrName = null;
|
||||
boolean required = false;
|
||||
String defaultValue = null;
|
||||
boolean validate = false;
|
||||
int annotationsFound = 0;
|
||||
Annotation[] paramAnns = methodParam.getParameterAnnotations();
|
||||
|
||||
for (Annotation paramAnn : paramAnns) {
|
||||
if (RequestParam.class.isInstance(paramAnn)) {
|
||||
RequestParam requestParam = (RequestParam) paramAnn;
|
||||
paramName = requestParam.value();
|
||||
required = requestParam.required();
|
||||
defaultValue = parseDefaultValueAttribute(requestParam.defaultValue());
|
||||
annotationsFound++;
|
||||
} else if (RequestHeader.class.isInstance(paramAnn)) {
|
||||
RequestHeader requestHeader = (RequestHeader) paramAnn;
|
||||
headerName = requestHeader.value();
|
||||
required = requestHeader.required();
|
||||
defaultValue = parseDefaultValueAttribute(requestHeader.defaultValue());
|
||||
annotationsFound++;
|
||||
} else if (RequestBody.class.isInstance(paramAnn)) {
|
||||
requestBodyFound = true;
|
||||
annotationsFound++;
|
||||
} else if (CookieValue.class.isInstance(paramAnn)) {
|
||||
CookieValue cookieValue = (CookieValue) paramAnn;
|
||||
cookieName = cookieValue.value();
|
||||
required = cookieValue.required();
|
||||
defaultValue = parseDefaultValueAttribute(cookieValue.defaultValue());
|
||||
annotationsFound++;
|
||||
} else if (PathVariable.class.isInstance(paramAnn)) {
|
||||
PathVariable pathVar = (PathVariable) paramAnn;
|
||||
pathVarName = pathVar.value();
|
||||
annotationsFound++;
|
||||
} else if (ModelAttribute.class.isInstance(paramAnn)) {
|
||||
ModelAttribute attr = (ModelAttribute) paramAnn;
|
||||
attrName = attr.value();
|
||||
annotationsFound++;
|
||||
} else if (Value.class.isInstance(paramAnn)) {
|
||||
defaultValue = ((Value) paramAnn).value();
|
||||
} else if ("Valid".equals(paramAnn.annotationType().getSimpleName())) {
|
||||
validate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (annotationsFound > 1) {
|
||||
throw new IllegalStateException("Handler parameter annotations are exclusive choices - " +
|
||||
"do not specify more than one such annotation on the same parameter: " + handlerMethod);
|
||||
}
|
||||
|
||||
if (annotationsFound == 0) {
|
||||
Object argValue = resolveCommonArgument(methodParam, webRequest);
|
||||
if (argValue != WebArgumentResolver.UNRESOLVED) {
|
||||
args[i] = argValue;
|
||||
} else if (defaultValue != null) {
|
||||
args[i] = resolveDefaultValue(defaultValue);
|
||||
} else {
|
||||
Class paramType = methodParam.getParameterType();
|
||||
if (Model.class.isAssignableFrom(paramType) || Map.class.isAssignableFrom(paramType)) {
|
||||
args[i] = implicitModel;
|
||||
} else if (SessionStatus.class.isAssignableFrom(paramType)) {
|
||||
args[i] = this.sessionStatus;
|
||||
} else if (HttpEntity.class.isAssignableFrom(paramType)) {
|
||||
args[i] = resolveHttpEntityRequest(methodParam, webRequest);
|
||||
} else if (Errors.class.isAssignableFrom(paramType)) {
|
||||
throw new IllegalStateException("Errors/BindingResult argument declared " +
|
||||
"without preceding model attribute. Check your handler method signature!");
|
||||
} else if (BeanUtils.isSimpleProperty(paramType)) {
|
||||
paramName = "";
|
||||
} else {
|
||||
attrName = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (paramName != null) {
|
||||
args[i] = resolveRequestParam(paramName, required, defaultValue, methodParam, webRequest, handler);
|
||||
} else if (headerName != null) {
|
||||
args[i] = resolveRequestHeader(headerName, required, defaultValue, methodParam, webRequest, handler);
|
||||
} else if (requestBodyFound) {
|
||||
args[i] = resolveRequestBody(methodParam, webRequest, handler);
|
||||
} else if (cookieName != null) {
|
||||
args[i] = resolveCookieValue(cookieName, required, defaultValue, methodParam, webRequest, handler);
|
||||
} else if (pathVarName != null) {
|
||||
args[i] = resolvePathVariable(pathVarName, methodParam, webRequest, handler);
|
||||
} else if (attrName != null) {
|
||||
WebDataBinder binder =
|
||||
resolveModelAttribute(attrName, methodParam, implicitModel, webRequest, handler);
|
||||
boolean assignBindingResult = (args.length > i + 1 && Errors.class.isAssignableFrom(paramTypes[i + 1]));
|
||||
if (binder.getTarget() != null) {
|
||||
doBind(binder, webRequest, validate, !assignBindingResult);
|
||||
}
|
||||
args[i] = binder.getTarget();
|
||||
if (assignBindingResult) {
|
||||
args[i + 1] = binder.getBindingResult();
|
||||
i++;
|
||||
}
|
||||
implicitModel.putAll(binder.getBindingResult().getModel());
|
||||
}
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
protected void initBinder(Object handler, String attrName, WebDataBinder binder, NativeWebRequest webRequest)
|
||||
throws Exception {
|
||||
|
||||
if (this.bindingInitializer != null) {
|
||||
this.bindingInitializer.initBinder(binder, webRequest);
|
||||
}
|
||||
if (handler != null) {
|
||||
Set<Method> initBinderMethods = this.methodResolver.getInitBinderMethods();
|
||||
if (!initBinderMethods.isEmpty()) {
|
||||
boolean debug = logger.isDebugEnabled();
|
||||
for (Method initBinderMethod : initBinderMethods) {
|
||||
Method methodToInvoke = BridgeMethodResolver.findBridgedMethod(initBinderMethod);
|
||||
String[] targetNames = AnnotationUtils.findAnnotation(initBinderMethod, InitBinder.class).value();
|
||||
if (targetNames.length == 0 || Arrays.asList(targetNames).contains(attrName)) {
|
||||
Object[] initBinderArgs =
|
||||
resolveInitBinderArguments(handler, methodToInvoke, binder, webRequest);
|
||||
if (debug) {
|
||||
logger.debug("Invoking init-binder method: " + methodToInvoke);
|
||||
}
|
||||
ReflectionUtils.makeAccessible(methodToInvoke);
|
||||
Object returnValue = methodToInvoke.invoke(handler, initBinderArgs);
|
||||
if (returnValue != null) {
|
||||
throw new IllegalStateException(
|
||||
"InitBinder methods must not have a return value: " + methodToInvoke);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Object[] resolveInitBinderArguments(Object handler, Method initBinderMethod,
|
||||
WebDataBinder binder, NativeWebRequest webRequest) throws Exception {
|
||||
|
||||
Class[] initBinderParams = initBinderMethod.getParameterTypes();
|
||||
Object[] initBinderArgs = new Object[initBinderParams.length];
|
||||
|
||||
for (int i = 0; i < initBinderArgs.length; i++) {
|
||||
MethodParameter methodParam = new MethodParameter(initBinderMethod, i);
|
||||
methodParam.initParameterNameDiscovery(this.parameterNameDiscoverer);
|
||||
GenericTypeResolver.resolveParameterType(methodParam, handler.getClass());
|
||||
String paramName = null;
|
||||
boolean paramRequired = false;
|
||||
String paramDefaultValue = null;
|
||||
String pathVarName = null;
|
||||
Annotation[] paramAnns = methodParam.getParameterAnnotations();
|
||||
|
||||
for (Annotation paramAnn : paramAnns) {
|
||||
if (RequestParam.class.isInstance(paramAnn)) {
|
||||
RequestParam requestParam = (RequestParam) paramAnn;
|
||||
paramName = requestParam.value();
|
||||
paramRequired = requestParam.required();
|
||||
paramDefaultValue = parseDefaultValueAttribute(requestParam.defaultValue());
|
||||
break;
|
||||
} else if (ModelAttribute.class.isInstance(paramAnn)) {
|
||||
throw new IllegalStateException(
|
||||
"@ModelAttribute is not supported on @InitBinder methods: " + initBinderMethod);
|
||||
} else if (PathVariable.class.isInstance(paramAnn)) {
|
||||
PathVariable pathVar = (PathVariable) paramAnn;
|
||||
pathVarName = pathVar.value();
|
||||
}
|
||||
}
|
||||
|
||||
if (paramName == null && pathVarName == null) {
|
||||
Object argValue = resolveCommonArgument(methodParam, webRequest);
|
||||
if (argValue != WebArgumentResolver.UNRESOLVED) {
|
||||
initBinderArgs[i] = argValue;
|
||||
} else {
|
||||
Class paramType = initBinderParams[i];
|
||||
if (paramType.isInstance(binder)) {
|
||||
initBinderArgs[i] = binder;
|
||||
} else if (BeanUtils.isSimpleProperty(paramType)) {
|
||||
paramName = "";
|
||||
} else {
|
||||
throw new IllegalStateException("Unsupported argument [" + paramType.getName() +
|
||||
"] for @InitBinder method: " + initBinderMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (paramName != null) {
|
||||
initBinderArgs[i] =
|
||||
resolveRequestParam(paramName, paramRequired, paramDefaultValue, methodParam, webRequest, null);
|
||||
} else if (pathVarName != null) {
|
||||
initBinderArgs[i] = resolvePathVariable(pathVarName, methodParam, webRequest, null);
|
||||
}
|
||||
}
|
||||
|
||||
return initBinderArgs;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Object resolveRequestParam(String paramName, boolean required, String defaultValue,
|
||||
MethodParameter methodParam, NativeWebRequest webRequest, Object handlerForInitBinderCall)
|
||||
throws Exception {
|
||||
|
||||
Class<?> paramType = methodParam.getParameterType();
|
||||
if (Map.class.isAssignableFrom(paramType) && paramName.length() == 0) {
|
||||
return resolveRequestParamMap((Class<? extends Map>) paramType, webRequest);
|
||||
}
|
||||
if (paramName.length() == 0) {
|
||||
paramName = getRequiredParameterName(methodParam);
|
||||
}
|
||||
Object paramValue = null;
|
||||
MultipartRequest multipartRequest = webRequest.getNativeRequest(MultipartRequest.class);
|
||||
if (multipartRequest != null) {
|
||||
List<MultipartFile> files = multipartRequest.getFiles(paramName);
|
||||
if (!files.isEmpty()) {
|
||||
if (files.size() == 1 && !paramType.isArray() && !Collection.class.isAssignableFrom(paramType)) {
|
||||
paramValue = files.get(0);
|
||||
} else {
|
||||
paramValue = files;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (paramValue == null) {
|
||||
String[] paramValues = webRequest.getParameterValues(paramName);
|
||||
if (paramValues != null) {
|
||||
if (paramValues.length == 1 && !paramType.isArray() && !Collection.class.isAssignableFrom(paramType)) {
|
||||
paramValue = paramValues[0];
|
||||
} else {
|
||||
paramValue = paramValues;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (paramValue == null) {
|
||||
if (defaultValue != null) {
|
||||
paramValue = resolveDefaultValue(defaultValue);
|
||||
} else if (required) {
|
||||
raiseMissingParameterException(paramName, paramType);
|
||||
}
|
||||
paramValue = checkValue(paramName, paramValue, paramType);
|
||||
}
|
||||
WebDataBinder binder = createBinder(webRequest, null, paramName);
|
||||
initBinder(handlerForInitBinderCall, paramName, binder, webRequest);
|
||||
return binder.convertIfNecessary(paramValue, paramType, methodParam);
|
||||
}
|
||||
|
||||
private Map resolveRequestParamMap(Class<? extends Map> mapType, NativeWebRequest webRequest) {
|
||||
Map<String, String[]> parameterMap = webRequest.getParameterMap();
|
||||
if (MultiValueMap.class.isAssignableFrom(mapType)) {
|
||||
MultiValueMap<String, String> result = new LinkedMultiValueMap<String, String>(parameterMap.size());
|
||||
for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
|
||||
for (String value : entry.getValue()) {
|
||||
result.add(entry.getKey(), value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
Map<String, String> result = new LinkedHashMap<String, String>(parameterMap.size());
|
||||
for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
|
||||
if (entry.getValue().length > 0) {
|
||||
result.put(entry.getKey(), entry.getValue()[0]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Object resolveRequestHeader(String headerName, boolean required, String defaultValue,
|
||||
MethodParameter methodParam, NativeWebRequest webRequest, Object handlerForInitBinderCall)
|
||||
throws Exception {
|
||||
|
||||
Class<?> paramType = methodParam.getParameterType();
|
||||
if (Map.class.isAssignableFrom(paramType)) {
|
||||
return resolveRequestHeaderMap((Class<? extends Map>) paramType, webRequest);
|
||||
}
|
||||
if (headerName.length() == 0) {
|
||||
headerName = getRequiredParameterName(methodParam);
|
||||
}
|
||||
Object headerValue = null;
|
||||
String[] headerValues = webRequest.getHeaderValues(headerName);
|
||||
if (headerValues != null) {
|
||||
headerValue = (headerValues.length == 1 ? headerValues[0] : headerValues);
|
||||
}
|
||||
if (headerValue == null) {
|
||||
if (defaultValue != null) {
|
||||
headerValue = resolveDefaultValue(defaultValue);
|
||||
} else if (required) {
|
||||
raiseMissingHeaderException(headerName, paramType);
|
||||
}
|
||||
headerValue = checkValue(headerName, headerValue, paramType);
|
||||
}
|
||||
WebDataBinder binder = createBinder(webRequest, null, headerName);
|
||||
initBinder(handlerForInitBinderCall, headerName, binder, webRequest);
|
||||
return binder.convertIfNecessary(headerValue, paramType, methodParam);
|
||||
}
|
||||
|
||||
private Map resolveRequestHeaderMap(Class<? extends Map> mapType, NativeWebRequest webRequest) {
|
||||
if (MultiValueMap.class.isAssignableFrom(mapType)) {
|
||||
MultiValueMap<String, String> result;
|
||||
if (HttpHeaders.class.isAssignableFrom(mapType)) {
|
||||
result = new HttpHeaders();
|
||||
} else {
|
||||
result = new LinkedMultiValueMap<String, String>();
|
||||
}
|
||||
for (Iterator<String> iterator = webRequest.getHeaderNames(); iterator.hasNext();) {
|
||||
String headerName = iterator.next();
|
||||
for (String headerValue : webRequest.getHeaderValues(headerName)) {
|
||||
result.add(headerName, headerValue);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
Map<String, String> result = new LinkedHashMap<String, String>();
|
||||
for (Iterator<String> iterator = webRequest.getHeaderNames(); iterator.hasNext();) {
|
||||
String headerName = iterator.next();
|
||||
String headerValue = webRequest.getHeader(headerName);
|
||||
result.put(headerName, headerValue);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the given {@link RequestBody @RequestBody} annotation.
|
||||
*/
|
||||
protected Object resolveRequestBody(MethodParameter methodParam, NativeWebRequest webRequest, Object handler)
|
||||
throws Exception {
|
||||
|
||||
return readWithMessageConverters(methodParam, createHttpInputMessage(webRequest), methodParam.getParameterType());
|
||||
}
|
||||
|
||||
private HttpEntity resolveHttpEntityRequest(MethodParameter methodParam, NativeWebRequest webRequest)
|
||||
throws Exception {
|
||||
|
||||
HttpInputMessage inputMessage = createHttpInputMessage(webRequest);
|
||||
Class<?> paramType = getHttpEntityType(methodParam);
|
||||
Object body = readWithMessageConverters(methodParam, inputMessage, paramType);
|
||||
return new HttpEntity<Object>(body, inputMessage.getHeaders());
|
||||
}
|
||||
|
||||
private Object readWithMessageConverters(MethodParameter methodParam, HttpInputMessage inputMessage, Class paramType)
|
||||
throws Exception {
|
||||
|
||||
MediaType contentType = inputMessage.getHeaders().getContentType();
|
||||
if (contentType == null) {
|
||||
StringBuilder builder = new StringBuilder(ClassUtils.getShortName(methodParam.getParameterType()));
|
||||
String paramName = methodParam.getParameterName();
|
||||
if (paramName != null) {
|
||||
builder.append(' ');
|
||||
builder.append(paramName);
|
||||
}
|
||||
throw new HttpMediaTypeNotSupportedException(
|
||||
"Cannot extract parameter (" + builder.toString() + "): no Content-Type found");
|
||||
}
|
||||
|
||||
List<MediaType> allSupportedMediaTypes = new ArrayList<MediaType>();
|
||||
if (this.messageConverters != null) {
|
||||
for (HttpMessageConverter<?> messageConverter : this.messageConverters) {
|
||||
allSupportedMediaTypes.addAll(messageConverter.getSupportedMediaTypes());
|
||||
if (messageConverter.canRead(paramType, contentType)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Reading [" + paramType.getName() + "] as \"" + contentType
|
||||
+ "\" using [" + messageConverter + "]");
|
||||
}
|
||||
return messageConverter.read(paramType, inputMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new HttpMediaTypeNotSupportedException(contentType, allSupportedMediaTypes);
|
||||
}
|
||||
|
||||
private Class<?> getHttpEntityType(MethodParameter methodParam) {
|
||||
Assert.isAssignable(HttpEntity.class, methodParam.getParameterType());
|
||||
ParameterizedType type = (ParameterizedType) methodParam.getGenericParameterType();
|
||||
if (type.getActualTypeArguments().length == 1) {
|
||||
Type typeArgument = type.getActualTypeArguments()[0];
|
||||
if (typeArgument instanceof Class) {
|
||||
return (Class<?>) typeArgument;
|
||||
} else if (typeArgument instanceof GenericArrayType) {
|
||||
Type componentType = ((GenericArrayType) typeArgument).getGenericComponentType();
|
||||
if (componentType instanceof Class) {
|
||||
// Surely, there should be a nicer way to do this
|
||||
Object array = Array.newInstance((Class<?>) componentType, 0);
|
||||
return array.getClass();
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException(
|
||||
"HttpEntity parameter (" + methodParam.getParameterName() + ") is not parameterized");
|
||||
|
||||
}
|
||||
|
||||
private Object resolveCookieValue(String cookieName, boolean required, String defaultValue,
|
||||
MethodParameter methodParam, NativeWebRequest webRequest, Object handlerForInitBinderCall)
|
||||
throws Exception {
|
||||
|
||||
Class<?> paramType = methodParam.getParameterType();
|
||||
if (cookieName.length() == 0) {
|
||||
cookieName = getRequiredParameterName(methodParam);
|
||||
}
|
||||
Object cookieValue = resolveCookieValue(cookieName, paramType, webRequest);
|
||||
if (cookieValue == null) {
|
||||
if (defaultValue != null) {
|
||||
cookieValue = resolveDefaultValue(defaultValue);
|
||||
} else if (required) {
|
||||
raiseMissingCookieException(cookieName, paramType);
|
||||
}
|
||||
cookieValue = checkValue(cookieName, cookieValue, paramType);
|
||||
}
|
||||
WebDataBinder binder = createBinder(webRequest, null, cookieName);
|
||||
initBinder(handlerForInitBinderCall, cookieName, binder, webRequest);
|
||||
return binder.convertIfNecessary(cookieValue, paramType, methodParam);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the given {@link CookieValue @CookieValue} annotation.
|
||||
* <p>Throws an UnsupportedOperationException by default.
|
||||
*/
|
||||
protected Object resolveCookieValue(String cookieName, Class paramType, NativeWebRequest webRequest)
|
||||
throws Exception {
|
||||
|
||||
throw new UnsupportedOperationException("@CookieValue not supported");
|
||||
}
|
||||
|
||||
private Object resolvePathVariable(String pathVarName, MethodParameter methodParam,
|
||||
NativeWebRequest webRequest, Object handlerForInitBinderCall) throws Exception {
|
||||
|
||||
Class<?> paramType = methodParam.getParameterType();
|
||||
if (pathVarName.length() == 0) {
|
||||
pathVarName = getRequiredParameterName(methodParam);
|
||||
}
|
||||
String pathVarValue = resolvePathVariable(pathVarName, paramType, webRequest);
|
||||
WebDataBinder binder = createBinder(webRequest, null, pathVarName);
|
||||
initBinder(handlerForInitBinderCall, pathVarName, binder, webRequest);
|
||||
return binder.convertIfNecessary(pathVarValue, paramType, methodParam);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the given {@link PathVariable @PathVariable} annotation.
|
||||
* <p>Throws an UnsupportedOperationException by default.
|
||||
*/
|
||||
protected String resolvePathVariable(String pathVarName, Class paramType, NativeWebRequest webRequest)
|
||||
throws Exception {
|
||||
|
||||
throw new UnsupportedOperationException("@PathVariable not supported");
|
||||
}
|
||||
|
||||
private String getRequiredParameterName(MethodParameter methodParam) {
|
||||
String name = methodParam.getParameterName();
|
||||
if (name == null) {
|
||||
throw new IllegalStateException(
|
||||
"No parameter name specified for argument of type [" + methodParam.getParameterType().getName() +
|
||||
"], and no parameter name information found in class file either.");
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
private Object checkValue(String name, Object value, Class paramType) {
|
||||
if (value == null) {
|
||||
if (boolean.class.equals(paramType)) {
|
||||
return Boolean.FALSE;
|
||||
} else if (paramType.isPrimitive()) {
|
||||
throw new IllegalStateException("Optional " + paramType + " parameter '" + name +
|
||||
"' is not present but cannot be translated into a null value due to being declared as a " +
|
||||
"primitive type. Consider declaring it as object wrapper for the corresponding primitive type.");
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private WebDataBinder resolveModelAttribute(String attrName, MethodParameter methodParam,
|
||||
ExtendedModelMap implicitModel, NativeWebRequest webRequest, Object handler) throws Exception {
|
||||
|
||||
// Bind request parameter onto object...
|
||||
String name = attrName;
|
||||
if ("".equals(name)) {
|
||||
name = Conventions.getVariableNameForParameter(methodParam);
|
||||
}
|
||||
Class<?> paramType = methodParam.getParameterType();
|
||||
Object bindObject;
|
||||
if (implicitModel.containsKey(name)) {
|
||||
bindObject = implicitModel.get(name);
|
||||
} else if (this.methodResolver.isSessionAttribute(name, paramType)) {
|
||||
bindObject = this.sessionAttributeStore.retrieveAttribute(webRequest, name);
|
||||
if (bindObject == null) {
|
||||
raiseSessionRequiredException("Session attribute '" + name + "' required - not found in session");
|
||||
}
|
||||
} else {
|
||||
bindObject = BeanUtils.instantiateClass(paramType);
|
||||
}
|
||||
WebDataBinder binder = createBinder(webRequest, bindObject, name);
|
||||
initBinder(handler, name, binder, webRequest);
|
||||
return binder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine whether the given value qualifies as a "binding candidate", i.e. might potentially be subject to
|
||||
* bean-style data binding later on.
|
||||
*/
|
||||
protected boolean isBindingCandidate(Object value) {
|
||||
return (value != null && !value.getClass().isArray() && !(value instanceof Collection) &&
|
||||
!(value instanceof Map) && !BeanUtils.isSimpleValueType(value.getClass()));
|
||||
}
|
||||
|
||||
protected void raiseMissingParameterException(String paramName, Class paramType) throws Exception {
|
||||
throw new IllegalStateException("Missing parameter '" + paramName + "' of type [" + paramType.getName() + "]");
|
||||
}
|
||||
|
||||
protected void raiseMissingHeaderException(String headerName, Class paramType) throws Exception {
|
||||
throw new IllegalStateException("Missing header '" + headerName + "' of type [" + paramType.getName() + "]");
|
||||
}
|
||||
|
||||
protected void raiseMissingCookieException(String cookieName, Class paramType) throws Exception {
|
||||
throw new IllegalStateException(
|
||||
"Missing cookie value '" + cookieName + "' of type [" + paramType.getName() + "]");
|
||||
}
|
||||
|
||||
protected void raiseSessionRequiredException(String message) throws Exception {
|
||||
throw new IllegalStateException(message);
|
||||
}
|
||||
|
||||
protected WebDataBinder createBinder(NativeWebRequest webRequest, Object target, String objectName)
|
||||
throws Exception {
|
||||
|
||||
return new WebRequestDataBinder(target, objectName);
|
||||
}
|
||||
|
||||
private void doBind(WebDataBinder binder, NativeWebRequest webRequest, boolean validate, boolean failOnErrors)
|
||||
throws Exception {
|
||||
|
||||
doBind(binder, webRequest);
|
||||
if (validate) {
|
||||
binder.validate();
|
||||
}
|
||||
if (failOnErrors && binder.getBindingResult().hasErrors()) {
|
||||
throw new BindException(binder.getBindingResult());
|
||||
}
|
||||
}
|
||||
|
||||
protected void doBind(WebDataBinder binder, NativeWebRequest webRequest) throws Exception {
|
||||
((WebRequestDataBinder) binder).bind(webRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@link HttpInputMessage} for the given {@link NativeWebRequest}.
|
||||
* <p>Throws an UnsupportedOperation1Exception by default.
|
||||
*/
|
||||
protected HttpInputMessage createHttpInputMessage(NativeWebRequest webRequest) throws Exception {
|
||||
throw new UnsupportedOperationException("@RequestBody not supported");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@link HttpOutputMessage} for the given {@link NativeWebRequest}.
|
||||
* <p>Throws an UnsupportedOperationException by default.
|
||||
*/
|
||||
protected HttpOutputMessage createHttpOutputMessage(NativeWebRequest webRequest) throws Exception {
|
||||
throw new UnsupportedOperationException("@ResponseBody not supported");
|
||||
}
|
||||
|
||||
protected String parseDefaultValueAttribute(String value) {
|
||||
return (ValueConstants.DEFAULT_NONE.equals(value) ? null : value);
|
||||
}
|
||||
|
||||
protected Object resolveDefaultValue(String value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
protected Object resolveCommonArgument(MethodParameter methodParameter, NativeWebRequest webRequest)
|
||||
throws Exception {
|
||||
|
||||
// Invoke custom argument resolvers if present...
|
||||
if (this.customArgumentResolvers != null) {
|
||||
for (WebArgumentResolver argumentResolver : this.customArgumentResolvers) {
|
||||
Object value = argumentResolver.resolveArgument(methodParameter, webRequest);
|
||||
if (value != WebArgumentResolver.UNRESOLVED) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Resolution of standard parameter types...
|
||||
Class paramType = methodParameter.getParameterType();
|
||||
Object value = resolveStandardArgument(paramType, webRequest);
|
||||
if (value != WebArgumentResolver.UNRESOLVED && !ClassUtils.isAssignableValue(paramType, value)) {
|
||||
throw new IllegalStateException("Standard argument type [" + paramType.getName() +
|
||||
"] resolved to incompatible value of type [" + (value != null ? value.getClass() : null) +
|
||||
"]. Consider declaring the argument type in a less specific fashion.");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
protected Object resolveStandardArgument(Class<?> parameterType, NativeWebRequest webRequest) throws Exception {
|
||||
if (WebRequest.class.isAssignableFrom(parameterType)) {
|
||||
return webRequest;
|
||||
}
|
||||
return WebArgumentResolver.UNRESOLVED;
|
||||
}
|
||||
|
||||
protected final void addReturnValueAsModelAttribute(Method handlerMethod, Class handlerType,
|
||||
Object returnValue, ExtendedModelMap implicitModel) {
|
||||
|
||||
ModelAttribute attr = AnnotationUtils.findAnnotation(handlerMethod, ModelAttribute.class);
|
||||
String attrName = (attr != null ? attr.value() : "");
|
||||
if ("".equals(attrName)) {
|
||||
Class resolvedType = GenericTypeResolver.resolveReturnType(handlerMethod, handlerType);
|
||||
attrName = Conventions.getVariableNameForReturnType(handlerMethod, resolvedType, returnValue);
|
||||
}
|
||||
implicitModel.addAttribute(attrName, returnValue);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* 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.data.document.web.servlet;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
public class ActionExecutedContext extends ActionExecutingContext {
|
||||
|
||||
|
||||
private ModelAndView modelAndView;
|
||||
|
||||
private Exception exception;
|
||||
|
||||
public ActionExecutedContext(ActionExecutingContext actionExecutingContext, ModelAndView modelAndView, Exception exception) {
|
||||
super(actionExecutingContext.getServletWebRequest(), actionExecutingContext.getHandler(),
|
||||
actionExecutingContext.getHandlerMethod(), actionExecutingContext.getHandlerParameters(),
|
||||
actionExecutingContext.getImplicitModel());
|
||||
this.modelAndView = modelAndView;
|
||||
this.exception = exception;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ActionExecutedContext [handler=" + getHandler()
|
||||
+ ", servletWebRequest=" + getServletWebRequest()
|
||||
+ ", implicitModel=" + getImplicitModel() + ", handlerMethod="
|
||||
+ getHandlerMethod() + ", handlerParameters="
|
||||
+ Arrays.toString(getHandlerParameters()) + ",modelAndView=" + modelAndView
|
||||
+ ", exception=" + exception + "]";
|
||||
}
|
||||
|
||||
|
||||
public ModelAndView getModelAndView() {
|
||||
return modelAndView;
|
||||
}
|
||||
|
||||
|
||||
public Exception getException() {
|
||||
return exception;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* 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.data.document.web.servlet;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.ui.ExtendedModelMap;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
|
||||
public class ActionExecutingContext {
|
||||
|
||||
|
||||
private Object handler;
|
||||
|
||||
private ServletWebRequest servletWebRequest;
|
||||
|
||||
private ExtendedModelMap implicitModel;
|
||||
|
||||
private Method handlerMethod;
|
||||
|
||||
private Object[] handlerParameters;
|
||||
|
||||
|
||||
public ActionExecutingContext(ServletWebRequest servletWebRequest,
|
||||
Object handler, Method handlerMethod, Object[] handlerParameters,
|
||||
ExtendedModelMap implicitModel) {
|
||||
super();
|
||||
this.servletWebRequest = servletWebRequest;
|
||||
this.handler = handler;
|
||||
this.handlerMethod = handlerMethod;
|
||||
this.handlerParameters = handlerParameters;
|
||||
this.implicitModel = implicitModel;
|
||||
}
|
||||
|
||||
public HttpServletRequest getHttpServletRequest() {
|
||||
return servletWebRequest.getRequest();
|
||||
}
|
||||
|
||||
public HttpServletResponse getHttpServletResponse() {
|
||||
return servletWebRequest.getResponse();
|
||||
}
|
||||
|
||||
public Object getHandler() {
|
||||
return handler;
|
||||
}
|
||||
|
||||
public ServletWebRequest getServletWebRequest() {
|
||||
return servletWebRequest;
|
||||
}
|
||||
|
||||
public ExtendedModelMap getImplicitModel() {
|
||||
return implicitModel;
|
||||
}
|
||||
|
||||
public Method getHandlerMethod() {
|
||||
return handlerMethod;
|
||||
}
|
||||
|
||||
public Object[] getHandlerParameters() {
|
||||
return handlerParameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ActionExecutingContext [handler=" + handler
|
||||
+ ", servletWebRequest=" + servletWebRequest
|
||||
+ ", implicitModel=" + implicitModel + ", handlerMethod="
|
||||
+ handlerMethod + ", handlerParameters="
|
||||
+ Arrays.toString(handlerParameters) + "]";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,141 +0,0 @@
|
||||
/*
|
||||
* 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.data.document.web.servlet.mvc.annotation;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.util.WebUtils;
|
||||
|
||||
/**
|
||||
* Helper class for annotation-based request mapping.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Arjen Poutsma
|
||||
* @since 2.5.2
|
||||
*/
|
||||
abstract class ServletAnnotationMappingUtils {
|
||||
|
||||
/**
|
||||
* Check whether the given request matches the specified request methods.
|
||||
*
|
||||
* @param methods the HTTP request methods to check against
|
||||
* @param request the current HTTP request to check
|
||||
*/
|
||||
public static boolean checkRequestMethod(RequestMethod[] methods, HttpServletRequest request) {
|
||||
if (ObjectUtils.isEmpty(methods)) {
|
||||
return true;
|
||||
}
|
||||
for (RequestMethod method : methods) {
|
||||
if (method.name().equals(request.getMethod())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given request matches the specified parameter conditions.
|
||||
*
|
||||
* @param params the parameter conditions, following
|
||||
* {@link org.springframework.web.bind.annotation.RequestMapping#params() RequestMapping.#params()}
|
||||
* @param request the current HTTP request to check
|
||||
*/
|
||||
public static boolean checkParameters(String[] params, HttpServletRequest request) {
|
||||
if (!ObjectUtils.isEmpty(params)) {
|
||||
for (String param : params) {
|
||||
int separator = param.indexOf('=');
|
||||
if (separator == -1) {
|
||||
if (param.startsWith("!")) {
|
||||
if (WebUtils.hasSubmitParameter(request, param.substring(1))) {
|
||||
return false;
|
||||
}
|
||||
} else if (!WebUtils.hasSubmitParameter(request, param)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
boolean negated = separator > 0 && param.charAt(separator - 1) == '!';
|
||||
String key = !negated ? param.substring(0, separator) : param.substring(0, separator - 1);
|
||||
String value = param.substring(separator + 1);
|
||||
if (!value.equals(request.getParameter(key))) {
|
||||
return negated;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given request matches the specified header conditions.
|
||||
*
|
||||
* @param headers the header conditions, following
|
||||
* {@link org.springframework.web.bind.annotation.RequestMapping#headers() RequestMapping.headers()}
|
||||
* @param request the current HTTP request to check
|
||||
*/
|
||||
public static boolean checkHeaders(String[] headers, HttpServletRequest request) {
|
||||
if (!ObjectUtils.isEmpty(headers)) {
|
||||
for (String header : headers) {
|
||||
int separator = header.indexOf('=');
|
||||
if (separator == -1) {
|
||||
if (header.startsWith("!")) {
|
||||
if (request.getHeader(header.substring(1)) != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (request.getHeader(header) == null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
boolean negated = separator > 0 && header.charAt(separator - 1) == '!';
|
||||
String key = !negated ? header.substring(0, separator) : header.substring(0, separator - 1);
|
||||
String value = header.substring(separator + 1);
|
||||
if (isMediaTypeHeader(key)) {
|
||||
List<MediaType> requestMediaTypes = MediaType.parseMediaTypes(request.getHeader(key));
|
||||
List<MediaType> valueMediaTypes = MediaType.parseMediaTypes(value);
|
||||
boolean found = false;
|
||||
for (Iterator<MediaType> valIter = valueMediaTypes.iterator(); valIter.hasNext() && !found;) {
|
||||
MediaType valueMediaType = valIter.next();
|
||||
for (Iterator<MediaType> reqIter = requestMediaTypes.iterator();
|
||||
reqIter.hasNext() && !found;) {
|
||||
MediaType requestMediaType = reqIter.next();
|
||||
if (valueMediaType.includes(requestMediaType)) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (!found) {
|
||||
return negated;
|
||||
}
|
||||
} else if (!value.equals(request.getHeader(key))) {
|
||||
return negated;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isMediaTypeHeader(String headerName) {
|
||||
return "Accept".equalsIgnoreCase(headerName) || "Content-Type".equalsIgnoreCase(headerName);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,828 +0,0 @@
|
||||
/*
|
||||
* 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.data.document.web.servlet.mvc.annotation.support;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.*;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.data.document.web.servlet.ActionInterceptor;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.ui.ExtendedModelMap;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.util.*;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.web.HttpMediaTypeNotSupportedException;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.bind.annotation.support.HandlerMethodInvocationException;
|
||||
import org.springframework.web.bind.annotation.support.HandlerMethodResolver;
|
||||
import org.springframework.web.bind.support.*;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartRequest;
|
||||
|
||||
/**
|
||||
* Support class for invoking an annotated handler method. Operates on the introspection results of a {@link
|
||||
* HandlerMethodResolver} for a specific handler type.
|
||||
* <p/>
|
||||
* <p>Used by {@link org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter} and {@link
|
||||
* org.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Arjen Poutsma
|
||||
* @see #invokeHandlerMethod
|
||||
* @since 2.5.2
|
||||
*/
|
||||
public class InterceptingHandlerMethodInvoker {
|
||||
|
||||
private static final String MODEL_KEY_PREFIX_STALE = SessionAttributeStore.class.getName() + ".STALE.";
|
||||
|
||||
/**
|
||||
* We'll create a lot of these objects, so we don't want a new logger every time.
|
||||
*/
|
||||
private static final Log logger = LogFactory.getLog(InterceptingHandlerMethodInvoker.class);
|
||||
|
||||
protected final HandlerMethodResolver methodResolver;
|
||||
|
||||
private final WebBindingInitializer bindingInitializer;
|
||||
|
||||
protected final SessionAttributeStore sessionAttributeStore;
|
||||
|
||||
private final ParameterNameDiscoverer parameterNameDiscoverer;
|
||||
|
||||
private final WebArgumentResolver[] customArgumentResolvers;
|
||||
|
||||
private final HttpMessageConverter[] messageConverters;
|
||||
|
||||
private final ActionInterceptor[] actionInterceptors;
|
||||
|
||||
private final SimpleSessionStatus sessionStatus = new SimpleSessionStatus();
|
||||
|
||||
|
||||
public InterceptingHandlerMethodInvoker(HandlerMethodResolver methodResolver) {
|
||||
this(methodResolver, null);
|
||||
}
|
||||
|
||||
public InterceptingHandlerMethodInvoker(HandlerMethodResolver methodResolver, WebBindingInitializer bindingInitializer) {
|
||||
this(methodResolver, bindingInitializer, new DefaultSessionAttributeStore(), null, null, null, null);
|
||||
}
|
||||
|
||||
public InterceptingHandlerMethodInvoker(HandlerMethodResolver methodResolver, WebBindingInitializer bindingInitializer,
|
||||
SessionAttributeStore sessionAttributeStore, ParameterNameDiscoverer parameterNameDiscoverer,
|
||||
WebArgumentResolver[] customArgumentResolvers, HttpMessageConverter[] messageConverters, ActionInterceptor[] actionInterceptors) {
|
||||
|
||||
this.methodResolver = methodResolver;
|
||||
this.bindingInitializer = bindingInitializer;
|
||||
this.sessionAttributeStore = sessionAttributeStore;
|
||||
this.parameterNameDiscoverer = parameterNameDiscoverer;
|
||||
this.customArgumentResolvers = customArgumentResolvers;
|
||||
this.messageConverters = messageConverters;
|
||||
this.actionInterceptors = actionInterceptors;
|
||||
}
|
||||
|
||||
protected ActionInterceptor[] getActionInterceptors() {
|
||||
return actionInterceptors;
|
||||
}
|
||||
|
||||
|
||||
public final Object invokeHandlerMethod(Method handlerMethod, Object handler,
|
||||
NativeWebRequest webRequest, ExtendedModelMap implicitModel) throws Exception {
|
||||
|
||||
Method handlerMethodToInvoke = BridgeMethodResolver.findBridgedMethod(handlerMethod);
|
||||
try {
|
||||
boolean debug = logger.isDebugEnabled();
|
||||
for (String attrName : this.methodResolver.getActualSessionAttributeNames()) {
|
||||
Object attrValue = this.sessionAttributeStore.retrieveAttribute(webRequest, attrName);
|
||||
if (attrValue != null) {
|
||||
implicitModel.addAttribute(attrName, attrValue);
|
||||
}
|
||||
}
|
||||
for (Method attributeMethod : this.methodResolver.getModelAttributeMethods()) {
|
||||
Method attributeMethodToInvoke = BridgeMethodResolver.findBridgedMethod(attributeMethod);
|
||||
Object[] args = resolveHandlerArguments(attributeMethodToInvoke, handler, webRequest, implicitModel);
|
||||
if (debug) {
|
||||
logger.debug("Invoking model attribute method: " + attributeMethodToInvoke);
|
||||
}
|
||||
String attrName = AnnotationUtils.findAnnotation(attributeMethod, ModelAttribute.class).value();
|
||||
if (!"".equals(attrName) && implicitModel.containsAttribute(attrName)) {
|
||||
continue;
|
||||
}
|
||||
ReflectionUtils.makeAccessible(attributeMethodToInvoke);
|
||||
Object attrValue = attributeMethodToInvoke.invoke(handler, args);
|
||||
if ("".equals(attrName)) {
|
||||
Class resolvedType = GenericTypeResolver.resolveReturnType(attributeMethodToInvoke, handler.getClass());
|
||||
attrName = Conventions.getVariableNameForReturnType(attributeMethodToInvoke, resolvedType, attrValue);
|
||||
}
|
||||
if (!implicitModel.containsAttribute(attrName)) {
|
||||
implicitModel.addAttribute(attrName, attrValue);
|
||||
}
|
||||
}
|
||||
Object[] args = resolveHandlerArguments(handlerMethodToInvoke, handler, webRequest, implicitModel);
|
||||
if (debug) {
|
||||
logger.debug("Invoking request handler method: " + handlerMethodToInvoke);
|
||||
}
|
||||
ReflectionUtils.makeAccessible(handlerMethodToInvoke);
|
||||
return handlerMethodToInvoke.invoke(handler, args);
|
||||
} catch (IllegalStateException ex) {
|
||||
// Internal assertion failed (e.g. invalid signature):
|
||||
// throw exception with full handler method context...
|
||||
throw new HandlerMethodInvocationException(handlerMethodToInvoke, ex);
|
||||
} catch (InvocationTargetException ex) {
|
||||
// User-defined @ModelAttribute/@InitBinder/@RequestMapping method threw an exception...
|
||||
ReflectionUtils.rethrowException(ex.getTargetException());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public final void updateModelAttributes(Object handler, Map<String, Object> mavModel,
|
||||
ExtendedModelMap implicitModel, NativeWebRequest webRequest) throws Exception {
|
||||
|
||||
if (this.methodResolver.hasSessionAttributes() && this.sessionStatus.isComplete()) {
|
||||
for (String attrName : this.methodResolver.getActualSessionAttributeNames()) {
|
||||
this.sessionAttributeStore.cleanupAttribute(webRequest, attrName);
|
||||
}
|
||||
}
|
||||
|
||||
// Expose model attributes as session attributes, if required.
|
||||
// Expose BindingResults for all attributes, making custom editors available.
|
||||
Map<String, Object> model = (mavModel != null ? mavModel : implicitModel);
|
||||
if (model != null) {
|
||||
try {
|
||||
String[] originalAttrNames = model.keySet().toArray(new String[model.size()]);
|
||||
for (String attrName : originalAttrNames) {
|
||||
Object attrValue = model.get(attrName);
|
||||
boolean isSessionAttr = this.methodResolver.isSessionAttribute(
|
||||
attrName, (attrValue != null ? attrValue.getClass() : null));
|
||||
if (isSessionAttr) {
|
||||
if (this.sessionStatus.isComplete()) {
|
||||
implicitModel.put(MODEL_KEY_PREFIX_STALE + attrName, Boolean.TRUE);
|
||||
} else if (!implicitModel.containsKey(MODEL_KEY_PREFIX_STALE + attrName)) {
|
||||
this.sessionAttributeStore.storeAttribute(webRequest, attrName, attrValue);
|
||||
}
|
||||
}
|
||||
if (!attrName.startsWith(BindingResult.MODEL_KEY_PREFIX) &&
|
||||
(isSessionAttr || isBindingCandidate(attrValue))) {
|
||||
String bindingResultKey = BindingResult.MODEL_KEY_PREFIX + attrName;
|
||||
if (mavModel != null && !model.containsKey(bindingResultKey)) {
|
||||
WebDataBinder binder = createBinder(webRequest, attrValue, attrName);
|
||||
initBinder(handler, attrName, binder, webRequest);
|
||||
mavModel.put(bindingResultKey, binder.getBindingResult());
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (InvocationTargetException ex) {
|
||||
// User-defined @InitBinder method threw an exception...
|
||||
ReflectionUtils.rethrowException(ex.getTargetException());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected Object[] resolveHandlerArguments(Method handlerMethod, Object handler,
|
||||
NativeWebRequest webRequest, ExtendedModelMap implicitModel) throws Exception {
|
||||
|
||||
Class[] paramTypes = handlerMethod.getParameterTypes();
|
||||
Object[] args = new Object[paramTypes.length];
|
||||
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
MethodParameter methodParam = new MethodParameter(handlerMethod, i);
|
||||
methodParam.initParameterNameDiscovery(this.parameterNameDiscoverer);
|
||||
GenericTypeResolver.resolveParameterType(methodParam, handler.getClass());
|
||||
String paramName = null;
|
||||
String headerName = null;
|
||||
boolean requestBodyFound = false;
|
||||
String cookieName = null;
|
||||
String pathVarName = null;
|
||||
String attrName = null;
|
||||
boolean required = false;
|
||||
String defaultValue = null;
|
||||
boolean validate = false;
|
||||
int annotationsFound = 0;
|
||||
Annotation[] paramAnns = methodParam.getParameterAnnotations();
|
||||
|
||||
for (Annotation paramAnn : paramAnns) {
|
||||
if (RequestParam.class.isInstance(paramAnn)) {
|
||||
RequestParam requestParam = (RequestParam) paramAnn;
|
||||
paramName = requestParam.value();
|
||||
required = requestParam.required();
|
||||
defaultValue = parseDefaultValueAttribute(requestParam.defaultValue());
|
||||
annotationsFound++;
|
||||
} else if (RequestHeader.class.isInstance(paramAnn)) {
|
||||
RequestHeader requestHeader = (RequestHeader) paramAnn;
|
||||
headerName = requestHeader.value();
|
||||
required = requestHeader.required();
|
||||
defaultValue = parseDefaultValueAttribute(requestHeader.defaultValue());
|
||||
annotationsFound++;
|
||||
} else if (RequestBody.class.isInstance(paramAnn)) {
|
||||
requestBodyFound = true;
|
||||
annotationsFound++;
|
||||
} else if (CookieValue.class.isInstance(paramAnn)) {
|
||||
CookieValue cookieValue = (CookieValue) paramAnn;
|
||||
cookieName = cookieValue.value();
|
||||
required = cookieValue.required();
|
||||
defaultValue = parseDefaultValueAttribute(cookieValue.defaultValue());
|
||||
annotationsFound++;
|
||||
} else if (PathVariable.class.isInstance(paramAnn)) {
|
||||
PathVariable pathVar = (PathVariable) paramAnn;
|
||||
pathVarName = pathVar.value();
|
||||
annotationsFound++;
|
||||
} else if (ModelAttribute.class.isInstance(paramAnn)) {
|
||||
ModelAttribute attr = (ModelAttribute) paramAnn;
|
||||
attrName = attr.value();
|
||||
annotationsFound++;
|
||||
} else if (Value.class.isInstance(paramAnn)) {
|
||||
defaultValue = ((Value) paramAnn).value();
|
||||
} else if ("Valid".equals(paramAnn.annotationType().getSimpleName())) {
|
||||
validate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (annotationsFound > 1) {
|
||||
throw new IllegalStateException("Handler parameter annotations are exclusive choices - " +
|
||||
"do not specify more than one such annotation on the same parameter: " + handlerMethod);
|
||||
}
|
||||
|
||||
if (annotationsFound == 0) {
|
||||
Object argValue = resolveCommonArgument(methodParam, webRequest);
|
||||
if (argValue != WebArgumentResolver.UNRESOLVED) {
|
||||
args[i] = argValue;
|
||||
} else if (defaultValue != null) {
|
||||
args[i] = resolveDefaultValue(defaultValue);
|
||||
} else {
|
||||
Class paramType = methodParam.getParameterType();
|
||||
if (Model.class.isAssignableFrom(paramType) || Map.class.isAssignableFrom(paramType)) {
|
||||
args[i] = implicitModel;
|
||||
} else if (SessionStatus.class.isAssignableFrom(paramType)) {
|
||||
args[i] = this.sessionStatus;
|
||||
} else if (HttpEntity.class.isAssignableFrom(paramType)) {
|
||||
args[i] = resolveHttpEntityRequest(methodParam, webRequest);
|
||||
} else if (Errors.class.isAssignableFrom(paramType)) {
|
||||
throw new IllegalStateException("Errors/BindingResult argument declared " +
|
||||
"without preceding model attribute. Check your handler method signature!");
|
||||
} else if (BeanUtils.isSimpleProperty(paramType)) {
|
||||
paramName = "";
|
||||
} else {
|
||||
attrName = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (paramName != null) {
|
||||
args[i] = resolveRequestParam(paramName, required, defaultValue, methodParam, webRequest, handler);
|
||||
} else if (headerName != null) {
|
||||
args[i] = resolveRequestHeader(headerName, required, defaultValue, methodParam, webRequest, handler);
|
||||
} else if (requestBodyFound) {
|
||||
args[i] = resolveRequestBody(methodParam, webRequest, handler);
|
||||
} else if (cookieName != null) {
|
||||
args[i] = resolveCookieValue(cookieName, required, defaultValue, methodParam, webRequest, handler);
|
||||
} else if (pathVarName != null) {
|
||||
args[i] = resolvePathVariable(pathVarName, methodParam, webRequest, handler);
|
||||
} else if (attrName != null) {
|
||||
WebDataBinder binder =
|
||||
resolveModelAttribute(attrName, methodParam, implicitModel, webRequest, handler);
|
||||
boolean assignBindingResult = (args.length > i + 1 && Errors.class.isAssignableFrom(paramTypes[i + 1]));
|
||||
if (binder.getTarget() != null) {
|
||||
doBind(binder, webRequest, validate, !assignBindingResult);
|
||||
}
|
||||
args[i] = binder.getTarget();
|
||||
if (assignBindingResult) {
|
||||
args[i + 1] = binder.getBindingResult();
|
||||
i++;
|
||||
}
|
||||
implicitModel.putAll(binder.getBindingResult().getModel());
|
||||
}
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
protected void initBinder(Object handler, String attrName, WebDataBinder binder, NativeWebRequest webRequest)
|
||||
throws Exception {
|
||||
|
||||
if (this.bindingInitializer != null) {
|
||||
this.bindingInitializer.initBinder(binder, webRequest);
|
||||
}
|
||||
if (handler != null) {
|
||||
Set<Method> initBinderMethods = this.methodResolver.getInitBinderMethods();
|
||||
if (!initBinderMethods.isEmpty()) {
|
||||
boolean debug = logger.isDebugEnabled();
|
||||
for (Method initBinderMethod : initBinderMethods) {
|
||||
Method methodToInvoke = BridgeMethodResolver.findBridgedMethod(initBinderMethod);
|
||||
String[] targetNames = AnnotationUtils.findAnnotation(initBinderMethod, InitBinder.class).value();
|
||||
if (targetNames.length == 0 || Arrays.asList(targetNames).contains(attrName)) {
|
||||
Object[] initBinderArgs =
|
||||
resolveInitBinderArguments(handler, methodToInvoke, binder, webRequest);
|
||||
if (debug) {
|
||||
logger.debug("Invoking init-binder method: " + methodToInvoke);
|
||||
}
|
||||
ReflectionUtils.makeAccessible(methodToInvoke);
|
||||
Object returnValue = methodToInvoke.invoke(handler, initBinderArgs);
|
||||
if (returnValue != null) {
|
||||
throw new IllegalStateException(
|
||||
"InitBinder methods must not have a return value: " + methodToInvoke);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Object[] resolveInitBinderArguments(Object handler, Method initBinderMethod,
|
||||
WebDataBinder binder, NativeWebRequest webRequest) throws Exception {
|
||||
|
||||
Class[] initBinderParams = initBinderMethod.getParameterTypes();
|
||||
Object[] initBinderArgs = new Object[initBinderParams.length];
|
||||
|
||||
for (int i = 0; i < initBinderArgs.length; i++) {
|
||||
MethodParameter methodParam = new MethodParameter(initBinderMethod, i);
|
||||
methodParam.initParameterNameDiscovery(this.parameterNameDiscoverer);
|
||||
GenericTypeResolver.resolveParameterType(methodParam, handler.getClass());
|
||||
String paramName = null;
|
||||
boolean paramRequired = false;
|
||||
String paramDefaultValue = null;
|
||||
String pathVarName = null;
|
||||
Annotation[] paramAnns = methodParam.getParameterAnnotations();
|
||||
|
||||
for (Annotation paramAnn : paramAnns) {
|
||||
if (RequestParam.class.isInstance(paramAnn)) {
|
||||
RequestParam requestParam = (RequestParam) paramAnn;
|
||||
paramName = requestParam.value();
|
||||
paramRequired = requestParam.required();
|
||||
paramDefaultValue = parseDefaultValueAttribute(requestParam.defaultValue());
|
||||
break;
|
||||
} else if (ModelAttribute.class.isInstance(paramAnn)) {
|
||||
throw new IllegalStateException(
|
||||
"@ModelAttribute is not supported on @InitBinder methods: " + initBinderMethod);
|
||||
} else if (PathVariable.class.isInstance(paramAnn)) {
|
||||
PathVariable pathVar = (PathVariable) paramAnn;
|
||||
pathVarName = pathVar.value();
|
||||
}
|
||||
}
|
||||
|
||||
if (paramName == null && pathVarName == null) {
|
||||
Object argValue = resolveCommonArgument(methodParam, webRequest);
|
||||
if (argValue != WebArgumentResolver.UNRESOLVED) {
|
||||
initBinderArgs[i] = argValue;
|
||||
} else {
|
||||
Class paramType = initBinderParams[i];
|
||||
if (paramType.isInstance(binder)) {
|
||||
initBinderArgs[i] = binder;
|
||||
} else if (BeanUtils.isSimpleProperty(paramType)) {
|
||||
paramName = "";
|
||||
} else {
|
||||
throw new IllegalStateException("Unsupported argument [" + paramType.getName() +
|
||||
"] for @InitBinder method: " + initBinderMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (paramName != null) {
|
||||
initBinderArgs[i] =
|
||||
resolveRequestParam(paramName, paramRequired, paramDefaultValue, methodParam, webRequest, null);
|
||||
} else if (pathVarName != null) {
|
||||
initBinderArgs[i] = resolvePathVariable(pathVarName, methodParam, webRequest, null);
|
||||
}
|
||||
}
|
||||
|
||||
return initBinderArgs;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Object resolveRequestParam(String paramName, boolean required, String defaultValue,
|
||||
MethodParameter methodParam, NativeWebRequest webRequest, Object handlerForInitBinderCall)
|
||||
throws Exception {
|
||||
|
||||
Class<?> paramType = methodParam.getParameterType();
|
||||
if (Map.class.isAssignableFrom(paramType) && paramName.length() == 0) {
|
||||
return resolveRequestParamMap((Class<? extends Map>) paramType, webRequest);
|
||||
}
|
||||
if (paramName.length() == 0) {
|
||||
paramName = getRequiredParameterName(methodParam);
|
||||
}
|
||||
Object paramValue = null;
|
||||
MultipartRequest multipartRequest = webRequest.getNativeRequest(MultipartRequest.class);
|
||||
if (multipartRequest != null) {
|
||||
List<MultipartFile> files = multipartRequest.getFiles(paramName);
|
||||
if (!files.isEmpty()) {
|
||||
if (files.size() == 1 && !paramType.isArray() && !Collection.class.isAssignableFrom(paramType)) {
|
||||
paramValue = files.get(0);
|
||||
} else {
|
||||
paramValue = files;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (paramValue == null) {
|
||||
String[] paramValues = webRequest.getParameterValues(paramName);
|
||||
if (paramValues != null) {
|
||||
if (paramValues.length == 1 && !paramType.isArray() && !Collection.class.isAssignableFrom(paramType)) {
|
||||
paramValue = paramValues[0];
|
||||
} else {
|
||||
paramValue = paramValues;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (paramValue == null) {
|
||||
if (defaultValue != null) {
|
||||
paramValue = resolveDefaultValue(defaultValue);
|
||||
} else if (required) {
|
||||
raiseMissingParameterException(paramName, paramType);
|
||||
}
|
||||
paramValue = checkValue(paramName, paramValue, paramType);
|
||||
}
|
||||
WebDataBinder binder = createBinder(webRequest, null, paramName);
|
||||
initBinder(handlerForInitBinderCall, paramName, binder, webRequest);
|
||||
return binder.convertIfNecessary(paramValue, paramType, methodParam);
|
||||
}
|
||||
|
||||
private Map resolveRequestParamMap(Class<? extends Map> mapType, NativeWebRequest webRequest) {
|
||||
Map<String, String[]> parameterMap = webRequest.getParameterMap();
|
||||
if (MultiValueMap.class.isAssignableFrom(mapType)) {
|
||||
MultiValueMap<String, String> result = new LinkedMultiValueMap<String, String>(parameterMap.size());
|
||||
for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
|
||||
for (String value : entry.getValue()) {
|
||||
result.add(entry.getKey(), value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
Map<String, String> result = new LinkedHashMap<String, String>(parameterMap.size());
|
||||
for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
|
||||
if (entry.getValue().length > 0) {
|
||||
result.put(entry.getKey(), entry.getValue()[0]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Object resolveRequestHeader(String headerName, boolean required, String defaultValue,
|
||||
MethodParameter methodParam, NativeWebRequest webRequest, Object handlerForInitBinderCall)
|
||||
throws Exception {
|
||||
|
||||
Class<?> paramType = methodParam.getParameterType();
|
||||
if (Map.class.isAssignableFrom(paramType)) {
|
||||
return resolveRequestHeaderMap((Class<? extends Map>) paramType, webRequest);
|
||||
}
|
||||
if (headerName.length() == 0) {
|
||||
headerName = getRequiredParameterName(methodParam);
|
||||
}
|
||||
Object headerValue = null;
|
||||
String[] headerValues = webRequest.getHeaderValues(headerName);
|
||||
if (headerValues != null) {
|
||||
headerValue = (headerValues.length == 1 ? headerValues[0] : headerValues);
|
||||
}
|
||||
if (headerValue == null) {
|
||||
if (defaultValue != null) {
|
||||
headerValue = resolveDefaultValue(defaultValue);
|
||||
} else if (required) {
|
||||
raiseMissingHeaderException(headerName, paramType);
|
||||
}
|
||||
headerValue = checkValue(headerName, headerValue, paramType);
|
||||
}
|
||||
WebDataBinder binder = createBinder(webRequest, null, headerName);
|
||||
initBinder(handlerForInitBinderCall, headerName, binder, webRequest);
|
||||
return binder.convertIfNecessary(headerValue, paramType, methodParam);
|
||||
}
|
||||
|
||||
private Map resolveRequestHeaderMap(Class<? extends Map> mapType, NativeWebRequest webRequest) {
|
||||
if (MultiValueMap.class.isAssignableFrom(mapType)) {
|
||||
MultiValueMap<String, String> result;
|
||||
if (HttpHeaders.class.isAssignableFrom(mapType)) {
|
||||
result = new HttpHeaders();
|
||||
} else {
|
||||
result = new LinkedMultiValueMap<String, String>();
|
||||
}
|
||||
for (Iterator<String> iterator = webRequest.getHeaderNames(); iterator.hasNext();) {
|
||||
String headerName = iterator.next();
|
||||
for (String headerValue : webRequest.getHeaderValues(headerName)) {
|
||||
result.add(headerName, headerValue);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
Map<String, String> result = new LinkedHashMap<String, String>();
|
||||
for (Iterator<String> iterator = webRequest.getHeaderNames(); iterator.hasNext();) {
|
||||
String headerName = iterator.next();
|
||||
String headerValue = webRequest.getHeader(headerName);
|
||||
result.put(headerName, headerValue);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the given {@link RequestBody @RequestBody} annotation.
|
||||
*/
|
||||
protected Object resolveRequestBody(MethodParameter methodParam, NativeWebRequest webRequest, Object handler)
|
||||
throws Exception {
|
||||
|
||||
return readWithMessageConverters(methodParam, createHttpInputMessage(webRequest), methodParam.getParameterType());
|
||||
}
|
||||
|
||||
private HttpEntity resolveHttpEntityRequest(MethodParameter methodParam, NativeWebRequest webRequest)
|
||||
throws Exception {
|
||||
|
||||
HttpInputMessage inputMessage = createHttpInputMessage(webRequest);
|
||||
Class<?> paramType = getHttpEntityType(methodParam);
|
||||
Object body = readWithMessageConverters(methodParam, inputMessage, paramType);
|
||||
return new HttpEntity<Object>(body, inputMessage.getHeaders());
|
||||
}
|
||||
|
||||
private Object readWithMessageConverters(MethodParameter methodParam, HttpInputMessage inputMessage, Class paramType)
|
||||
throws Exception {
|
||||
|
||||
MediaType contentType = inputMessage.getHeaders().getContentType();
|
||||
if (contentType == null) {
|
||||
StringBuilder builder = new StringBuilder(ClassUtils.getShortName(methodParam.getParameterType()));
|
||||
String paramName = methodParam.getParameterName();
|
||||
if (paramName != null) {
|
||||
builder.append(' ');
|
||||
builder.append(paramName);
|
||||
}
|
||||
throw new HttpMediaTypeNotSupportedException(
|
||||
"Cannot extract parameter (" + builder.toString() + "): no Content-Type found");
|
||||
}
|
||||
|
||||
List<MediaType> allSupportedMediaTypes = new ArrayList<MediaType>();
|
||||
if (this.messageConverters != null) {
|
||||
for (HttpMessageConverter<?> messageConverter : this.messageConverters) {
|
||||
allSupportedMediaTypes.addAll(messageConverter.getSupportedMediaTypes());
|
||||
if (messageConverter.canRead(paramType, contentType)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Reading [" + paramType.getName() + "] as \"" + contentType
|
||||
+ "\" using [" + messageConverter + "]");
|
||||
}
|
||||
return messageConverter.read(paramType, inputMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new HttpMediaTypeNotSupportedException(contentType, allSupportedMediaTypes);
|
||||
}
|
||||
|
||||
private Class<?> getHttpEntityType(MethodParameter methodParam) {
|
||||
Assert.isAssignable(HttpEntity.class, methodParam.getParameterType());
|
||||
ParameterizedType type = (ParameterizedType) methodParam.getGenericParameterType();
|
||||
if (type.getActualTypeArguments().length == 1) {
|
||||
Type typeArgument = type.getActualTypeArguments()[0];
|
||||
if (typeArgument instanceof Class) {
|
||||
return (Class<?>) typeArgument;
|
||||
} else if (typeArgument instanceof GenericArrayType) {
|
||||
Type componentType = ((GenericArrayType) typeArgument).getGenericComponentType();
|
||||
if (componentType instanceof Class) {
|
||||
// Surely, there should be a nicer way to do this
|
||||
Object array = Array.newInstance((Class<?>) componentType, 0);
|
||||
return array.getClass();
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException(
|
||||
"HttpEntity parameter (" + methodParam.getParameterName() + ") is not parameterized");
|
||||
|
||||
}
|
||||
|
||||
private Object resolveCookieValue(String cookieName, boolean required, String defaultValue,
|
||||
MethodParameter methodParam, NativeWebRequest webRequest, Object handlerForInitBinderCall)
|
||||
throws Exception {
|
||||
|
||||
Class<?> paramType = methodParam.getParameterType();
|
||||
if (cookieName.length() == 0) {
|
||||
cookieName = getRequiredParameterName(methodParam);
|
||||
}
|
||||
Object cookieValue = resolveCookieValue(cookieName, paramType, webRequest);
|
||||
if (cookieValue == null) {
|
||||
if (defaultValue != null) {
|
||||
cookieValue = resolveDefaultValue(defaultValue);
|
||||
} else if (required) {
|
||||
raiseMissingCookieException(cookieName, paramType);
|
||||
}
|
||||
cookieValue = checkValue(cookieName, cookieValue, paramType);
|
||||
}
|
||||
WebDataBinder binder = createBinder(webRequest, null, cookieName);
|
||||
initBinder(handlerForInitBinderCall, cookieName, binder, webRequest);
|
||||
return binder.convertIfNecessary(cookieValue, paramType, methodParam);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the given {@link CookieValue @CookieValue} annotation.
|
||||
* <p>Throws an UnsupportedOperationException by default.
|
||||
*/
|
||||
protected Object resolveCookieValue(String cookieName, Class paramType, NativeWebRequest webRequest)
|
||||
throws Exception {
|
||||
|
||||
throw new UnsupportedOperationException("@CookieValue not supported");
|
||||
}
|
||||
|
||||
private Object resolvePathVariable(String pathVarName, MethodParameter methodParam,
|
||||
NativeWebRequest webRequest, Object handlerForInitBinderCall) throws Exception {
|
||||
|
||||
Class<?> paramType = methodParam.getParameterType();
|
||||
if (pathVarName.length() == 0) {
|
||||
pathVarName = getRequiredParameterName(methodParam);
|
||||
}
|
||||
String pathVarValue = resolvePathVariable(pathVarName, paramType, webRequest);
|
||||
WebDataBinder binder = createBinder(webRequest, null, pathVarName);
|
||||
initBinder(handlerForInitBinderCall, pathVarName, binder, webRequest);
|
||||
return binder.convertIfNecessary(pathVarValue, paramType, methodParam);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the given {@link PathVariable @PathVariable} annotation.
|
||||
* <p>Throws an UnsupportedOperationException by default.
|
||||
*/
|
||||
protected String resolvePathVariable(String pathVarName, Class paramType, NativeWebRequest webRequest)
|
||||
throws Exception {
|
||||
|
||||
throw new UnsupportedOperationException("@PathVariable not supported");
|
||||
}
|
||||
|
||||
private String getRequiredParameterName(MethodParameter methodParam) {
|
||||
String name = methodParam.getParameterName();
|
||||
if (name == null) {
|
||||
throw new IllegalStateException(
|
||||
"No parameter name specified for argument of type [" + methodParam.getParameterType().getName() +
|
||||
"], and no parameter name information found in class file either.");
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
private Object checkValue(String name, Object value, Class paramType) {
|
||||
if (value == null) {
|
||||
if (boolean.class.equals(paramType)) {
|
||||
return Boolean.FALSE;
|
||||
} else if (paramType.isPrimitive()) {
|
||||
throw new IllegalStateException("Optional " + paramType + " parameter '" + name +
|
||||
"' is not present but cannot be translated into a null value due to being declared as a " +
|
||||
"primitive type. Consider declaring it as object wrapper for the corresponding primitive type.");
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private WebDataBinder resolveModelAttribute(String attrName, MethodParameter methodParam,
|
||||
ExtendedModelMap implicitModel, NativeWebRequest webRequest, Object handler) throws Exception {
|
||||
|
||||
// Bind request parameter onto object...
|
||||
String name = attrName;
|
||||
if ("".equals(name)) {
|
||||
name = Conventions.getVariableNameForParameter(methodParam);
|
||||
}
|
||||
Class<?> paramType = methodParam.getParameterType();
|
||||
Object bindObject;
|
||||
if (implicitModel.containsKey(name)) {
|
||||
bindObject = implicitModel.get(name);
|
||||
} else if (this.methodResolver.isSessionAttribute(name, paramType)) {
|
||||
bindObject = this.sessionAttributeStore.retrieveAttribute(webRequest, name);
|
||||
if (bindObject == null) {
|
||||
raiseSessionRequiredException("Session attribute '" + name + "' required - not found in session");
|
||||
}
|
||||
} else {
|
||||
bindObject = BeanUtils.instantiateClass(paramType);
|
||||
}
|
||||
WebDataBinder binder = createBinder(webRequest, bindObject, name);
|
||||
initBinder(handler, name, binder, webRequest);
|
||||
return binder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine whether the given value qualifies as a "binding candidate", i.e. might potentially be subject to
|
||||
* bean-style data binding later on.
|
||||
*/
|
||||
protected boolean isBindingCandidate(Object value) {
|
||||
return (value != null && !value.getClass().isArray() && !(value instanceof Collection) &&
|
||||
!(value instanceof Map) && !BeanUtils.isSimpleValueType(value.getClass()));
|
||||
}
|
||||
|
||||
protected void raiseMissingParameterException(String paramName, Class paramType) throws Exception {
|
||||
throw new IllegalStateException("Missing parameter '" + paramName + "' of type [" + paramType.getName() + "]");
|
||||
}
|
||||
|
||||
protected void raiseMissingHeaderException(String headerName, Class paramType) throws Exception {
|
||||
throw new IllegalStateException("Missing header '" + headerName + "' of type [" + paramType.getName() + "]");
|
||||
}
|
||||
|
||||
protected void raiseMissingCookieException(String cookieName, Class paramType) throws Exception {
|
||||
throw new IllegalStateException(
|
||||
"Missing cookie value '" + cookieName + "' of type [" + paramType.getName() + "]");
|
||||
}
|
||||
|
||||
protected void raiseSessionRequiredException(String message) throws Exception {
|
||||
throw new IllegalStateException(message);
|
||||
}
|
||||
|
||||
protected WebDataBinder createBinder(NativeWebRequest webRequest, Object target, String objectName)
|
||||
throws Exception {
|
||||
|
||||
return new WebRequestDataBinder(target, objectName);
|
||||
}
|
||||
|
||||
private void doBind(WebDataBinder binder, NativeWebRequest webRequest, boolean validate, boolean failOnErrors)
|
||||
throws Exception {
|
||||
|
||||
doBind(binder, webRequest);
|
||||
if (validate) {
|
||||
binder.validate();
|
||||
}
|
||||
if (failOnErrors && binder.getBindingResult().hasErrors()) {
|
||||
throw new BindException(binder.getBindingResult());
|
||||
}
|
||||
}
|
||||
|
||||
protected void doBind(WebDataBinder binder, NativeWebRequest webRequest) throws Exception {
|
||||
((WebRequestDataBinder) binder).bind(webRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@link HttpInputMessage} for the given {@link NativeWebRequest}.
|
||||
* <p>Throws an UnsupportedOperation1Exception by default.
|
||||
*/
|
||||
protected HttpInputMessage createHttpInputMessage(NativeWebRequest webRequest) throws Exception {
|
||||
throw new UnsupportedOperationException("@RequestBody not supported");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@link HttpOutputMessage} for the given {@link NativeWebRequest}.
|
||||
* <p>Throws an UnsupportedOperationException by default.
|
||||
*/
|
||||
protected HttpOutputMessage createHttpOutputMessage(NativeWebRequest webRequest) throws Exception {
|
||||
throw new UnsupportedOperationException("@ResponseBody not supported");
|
||||
}
|
||||
|
||||
protected String parseDefaultValueAttribute(String value) {
|
||||
return (ValueConstants.DEFAULT_NONE.equals(value) ? null : value);
|
||||
}
|
||||
|
||||
protected Object resolveDefaultValue(String value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
protected Object resolveCommonArgument(MethodParameter methodParameter, NativeWebRequest webRequest)
|
||||
throws Exception {
|
||||
|
||||
// Invoke custom argument resolvers if present...
|
||||
if (this.customArgumentResolvers != null) {
|
||||
for (WebArgumentResolver argumentResolver : this.customArgumentResolvers) {
|
||||
Object value = argumentResolver.resolveArgument(methodParameter, webRequest);
|
||||
if (value != WebArgumentResolver.UNRESOLVED) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Resolution of standard parameter types...
|
||||
Class paramType = methodParameter.getParameterType();
|
||||
Object value = resolveStandardArgument(paramType, webRequest);
|
||||
if (value != WebArgumentResolver.UNRESOLVED && !ClassUtils.isAssignableValue(paramType, value)) {
|
||||
throw new IllegalStateException("Standard argument type [" + paramType.getName() +
|
||||
"] resolved to incompatible value of type [" + (value != null ? value.getClass() : null) +
|
||||
"]. Consider declaring the argument type in a less specific fashion.");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
protected Object resolveStandardArgument(Class<?> parameterType, NativeWebRequest webRequest) throws Exception {
|
||||
if (WebRequest.class.isAssignableFrom(parameterType)) {
|
||||
return webRequest;
|
||||
}
|
||||
return WebArgumentResolver.UNRESOLVED;
|
||||
}
|
||||
|
||||
protected final void addReturnValueAsModelAttribute(Method handlerMethod, Class handlerType,
|
||||
Object returnValue, ExtendedModelMap implicitModel) {
|
||||
|
||||
ModelAttribute attr = AnnotationUtils.findAnnotation(handlerMethod, ModelAttribute.class);
|
||||
String attrName = (attr != null ? attr.value() : "");
|
||||
if ("".equals(attrName)) {
|
||||
Class resolvedType = GenericTypeResolver.resolveReturnType(handlerMethod, handlerType);
|
||||
attrName = Conventions.getVariableNameForReturnType(handlerMethod, resolvedType, returnValue);
|
||||
}
|
||||
implicitModel.addAttribute(attrName, returnValue);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
Bundle-SymbolicName: org.springframework.data.document
|
||||
Bundle-Name: Spring Data Document
|
||||
Bundle-Vendor: SpringSource
|
||||
Bundle-ManifestVersion: 2
|
||||
Import-Package:
|
||||
sun.reflect;version="0";resolution:=optional
|
||||
Import-Template:
|
||||
javax.servlet;version="[2.4.0, 4.0.0)",
|
||||
javax.servlet.http;version="[2.4.0, 4.0.0)",
|
||||
org.springframework.http.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.http.converter.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.http.server*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.ui.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.web.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.web.bind.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.web.bind.annotation.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.web.bind.annotation.support.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.web.bind.support.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.web.context.request.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.web.util.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.validation.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.validation.support.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.beans.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.core.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.dao.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.util.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.expression.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.expression.common.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.expression.spel.standard.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.expression.spel.support.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.validation.*;version="[3.0.0, 4.0.0)",
|
||||
org.springframework.data.core.*;version="[1.0.0, 2.0.0)",
|
||||
org.aopalliance.*;version="[1.0.0, 2.0.0)";resolution:=optional,
|
||||
org.apache.commons.logging.*;version="[1.1.1, 2.0.0)",
|
||||
org.w3c.dom.*;version="0",
|
||||
javax.persistence.*;version="[1.0, 2.0)"
|
||||
|
||||
|
||||
@@ -1,415 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-document-parent</artifactId>
|
||||
<name>Spring Data Document Parent</name>
|
||||
<url>http://www.springsource.org/spring-data/data-document</url>
|
||||
<version>1.0.0.M2</version>
|
||||
<packaging>pom</packaging>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<!-- versions for commonly-used dependencies -->
|
||||
<junit.version>4.8.1</junit.version>
|
||||
<log4j.version>1.2.15</log4j.version>
|
||||
<org.mockito.version>1.8.4</org.mockito.version>
|
||||
<org.slf4j.version>1.5.10</org.slf4j.version>
|
||||
<org.codehaus.jackson.version>1.6.1</org.codehaus.jackson.version>
|
||||
<org.springframework.version>3.0.5.RELEASE</org.springframework.version>
|
||||
<data.commons.version>1.0.0.RC1</data.commons.version>
|
||||
<aspectj.version>1.6.11.RELEASE</aspectj.version>
|
||||
</properties>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>strict</id>
|
||||
<properties>
|
||||
<maven.test.failure.ignore>false</maven.test.failure.ignore>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>fast</id>
|
||||
<properties>
|
||||
<maven.test.skip>true</maven.test.skip>
|
||||
<maven.javadoc.skip>true</maven.javadoc.skip>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>staging</id>
|
||||
<distributionManagement>
|
||||
<site>
|
||||
<id>spring-site-staging</id>
|
||||
<url>file:///${java.io.tmpdir}/spring-data/data-document/docs</url>
|
||||
</site>
|
||||
<repository>
|
||||
<id>spring-milestone-staging</id>
|
||||
<url>file:///${java.io.tmpdir}/spring-data/data-document/milestone</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>spring-snapshot-staging</id>
|
||||
<url>file:///${java.io.tmpdir}/spring-data/data-document/snapshot</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>bootstrap</id>
|
||||
<!-- TODO: move the repositories in here before release -->
|
||||
</profile>
|
||||
</profiles>
|
||||
<distributionManagement>
|
||||
<!-- see 'staging' profile for dry-run deployment settings -->
|
||||
<downloadUrl>http://www.springsource.com/download/community
|
||||
</downloadUrl>
|
||||
<site>
|
||||
<id>static.springframework.org</id>
|
||||
<url>
|
||||
scp://static.springframework.org/var/www/domains/springframework.org/static/htdocs/spring-data/data-document/docs/${project.version}
|
||||
</url>
|
||||
</site>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<name>Spring Milestone Repository</name>
|
||||
<url>s3://maven.springframework.org/milestone</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>spring-snapshot</id>
|
||||
<name>Spring Snapshot Repository</name>
|
||||
<url>s3://maven.springframework.org/snapshot</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
<dependencyManagement>
|
||||
<!--
|
||||
inheritable <dependency> declarations for child poms. children still
|
||||
must explicitly declare the groupId/artifactId of these dependencies
|
||||
in order for them to show up on the classpath, but metadata like
|
||||
<version> and <scope> are inherited, which cuts down on verbosity.
|
||||
see
|
||||
http://www.sonatype.com/books/mvnref-book/reference/pom-relationships-sect-dep-manage.html
|
||||
-->
|
||||
<dependencies>
|
||||
|
||||
<!-- Spring -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
<version>${org.springframework.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<version>${org.springframework.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>${org.springframework.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<version>${org.springframework.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-orm</artifactId>
|
||||
<version>${org.springframework.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<version>${org.springframework.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-expression</artifactId>
|
||||
<version>${org.springframework.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>${org.springframework.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring Data -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-commons-core</artifactId>
|
||||
<version>${data.commons.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-commons-aspects</artifactId>
|
||||
<version>${data.commons.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-document-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-couchdb</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Logging -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>${org.slf4j.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>${org.slf4j.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<version>${org.slf4j.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>${log4j.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>javax.mail</groupId>
|
||||
<artifactId>mail</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>javax.jms</groupId>
|
||||
<artifactId>jms</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.sun.jdmk</groupId>
|
||||
<artifactId>jmxtools</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.sun.jmx</groupId>
|
||||
<artifactId>jmxri</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>jsr250-api</artifactId>
|
||||
<version>1.0</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<version>${org.mockito.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
<dependencies>
|
||||
<!--
|
||||
dependency definitions to be inherited by child poms. any
|
||||
<dependency> declarations here will automatically show up on child
|
||||
project classpaths. only items that are truly common across all
|
||||
projects (modules and samples) should go here. otherwise, consider
|
||||
<dependencyManagement> above
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>${log4j.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<extensions>
|
||||
<extension>
|
||||
<!--
|
||||
available only in the springframework maven repository. see
|
||||
<repositories> section below
|
||||
-->
|
||||
<groupId>org.springframework.build.aws</groupId>
|
||||
<artifactId>org.springframework.build.aws.maven</artifactId>
|
||||
<version>3.1.0.RELEASE</version>
|
||||
</extension>
|
||||
</extensions>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>${project.basedir}/src/main/java</directory>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>**/*.java</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>${project.basedir}/src/main/resources</directory>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
<testResources>
|
||||
<testResource>
|
||||
<directory>${project.basedir}/src/test/java</directory>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>**/*.java</exclude>
|
||||
</excludes>
|
||||
</testResource>
|
||||
<testResource>
|
||||
<directory>${project.basedir}/src/test/resources</directory>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>**/*.java</exclude>
|
||||
</excludes>
|
||||
</testResource>
|
||||
</testResources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.5</source>
|
||||
<target>1.5</target>
|
||||
<compilerArgument>-Xlint:all</compilerArgument>
|
||||
<showWarnings>true</showWarnings>
|
||||
<showDeprecation>false</showDeprecation>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.3.1</version>
|
||||
<configuration>
|
||||
<useDefaultManifestFile>true</useDefaultManifestFile>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<useFile>false</useFile>
|
||||
<includes>
|
||||
<include>**/*Tests.java</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>**/Abstract*.java</exclude>
|
||||
</excludes>
|
||||
<junitArtifactName>junit:junit</junitArtifactName>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<!--
|
||||
configures the springsource bundlor plugin, which generates
|
||||
OSGI-compatible MANIFEST.MF files during the 'compile' phase of
|
||||
the maven build. this plugin is declared within the
|
||||
pluginManagement section because not every module that inherits
|
||||
from this pom needs bundlor's services, e.g.:
|
||||
spring-integration-samples and all its children. for this reason,
|
||||
all modules that wish to use bundlor must declare it explicitly.
|
||||
it is not necessary to specify the <version> or <configuration>
|
||||
sections, but groupId and artifactId are required. see
|
||||
http://static.springsource.org/s2-bundlor/1.0.x/user-guide/html/ch04s03.html
|
||||
for more info
|
||||
-->
|
||||
<groupId>com.springsource.bundlor</groupId>
|
||||
<artifactId>com.springsource.bundlor.maven</artifactId>
|
||||
<version>1.0.0.RELEASE</version>
|
||||
<configuration>
|
||||
<failOnWarnings>true</failOnWarnings>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>bundlor</id>
|
||||
<goals>
|
||||
<goal>bundlor</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<!-- necessary for bundlor and utils -->
|
||||
<id>repository.plugin.springsource.release</id>
|
||||
<name>SpringSource Maven Repository</name>
|
||||
<url>http://repository.springsource.com/maven/bundles/release</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>repository.springframework.maven.release</id>
|
||||
<name>Spring Framework Maven Release Repository</name>
|
||||
<url>http://maven.springframework.org/release</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>repository.springframework.maven.milestone</id>
|
||||
<name>Spring Framework Maven Milestone Repository</name>
|
||||
<url>http://maven.springframework.org/milestone</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>repository.springframework.maven.snapshot</id>
|
||||
<name>Spring Framework Maven Snapshot Repository</name>
|
||||
<url>http://maven.springframework.org/snapshot</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<!--
|
||||
significantly speeds up the 'Dependencies' report during site
|
||||
creation see
|
||||
http://old.nabble.com/Skipping-dependency-report-during-Maven2-site-generation-td20116761.html
|
||||
-->
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-project-info-reports-plugin</artifactId>
|
||||
<version>2.1</version>
|
||||
<configuration>
|
||||
<dependencyLocationsEnabled>false</dependencyLocationsEnabled>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
</project>
|
||||
@@ -1,222 +1,145 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-document-parent</artifactId>
|
||||
<version>1.0.0.M2</version>
|
||||
<relativePath>../spring-data-document-parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-data-mongodb-cross-store</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Data MongoDB Cross-store Persistence Support</name>
|
||||
<dependencies>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<!-- Spring -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aspects</artifactId>
|
||||
<version>${org.springframework.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-orm</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.2.0.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>spring-data-mongodb-cross-store</artifactId>
|
||||
<name>Spring Data MongoDB - Cross-Store Persistence Support</name>
|
||||
|
||||
<properties>
|
||||
<jpa>1.0.0.Final</jpa>
|
||||
<hibernate>3.6.10.Final</hibernate>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- Spring Data -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-commons-core</artifactId>
|
||||
</dependency>
|
||||
<!-- <dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-commons-aspects</artifactId>
|
||||
</dependency> -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
</dependency>
|
||||
<!-- Spring -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<version>${spring}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<version>${spring}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aspects</artifactId>
|
||||
<version>${spring}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-orm</artifactId>
|
||||
<version>${spring}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring Data -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
<version>1.2.0.RELEASE</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Logging -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>javax.mail</groupId>
|
||||
<artifactId>mail</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>javax.jms</groupId>
|
||||
<artifactId>jms</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.sun.jdmk</groupId>
|
||||
<artifactId>jmxtools</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.sun.jmx</groupId>
|
||||
<artifactId>jmxri</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
<version>${aspectj}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cglib</groupId>
|
||||
<artifactId>cglib</artifactId>
|
||||
<version>2.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>jsr250-api</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<!-- JPA -->
|
||||
<dependency>
|
||||
<groupId>org.hibernate.javax.persistence</groupId>
|
||||
<artifactId>hibernate-jpa-2.0-api</artifactId>
|
||||
<version>${jpa}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- For Tests -->
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-entitymanager</artifactId>
|
||||
<version>${hibernate}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>hsqldb</groupId>
|
||||
<artifactId>hsqldb</artifactId>
|
||||
<version>1.8.0.10</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
<version>1.0.0.GA</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<version>4.0.2.GA</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
<version>${aspectj.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cglib</groupId>
|
||||
<artifactId>cglib</artifactId>
|
||||
<version>2.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- JPA -->
|
||||
<dependency>
|
||||
<groupId>org.hibernate.javax.persistence</groupId>
|
||||
<artifactId>hibernate-jpa-2.0-api</artifactId>
|
||||
<version>1.0.0.Final</version>
|
||||
</dependency>
|
||||
|
||||
<!-- For Tests -->
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-entitymanager</artifactId>
|
||||
<version>3.5.5-Final</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>hsqldb</groupId>
|
||||
<artifactId>hsqldb</artifactId>
|
||||
<version>1.8.0.10</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
<version>1.0.0.GA</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<version>4.0.2.GA</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jboss-repository</id>
|
||||
<name>JBoss Public Repository</name>
|
||||
<url>http://repository.jboss.org/nexus/content/groups/public-jboss</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-maven-snapshot</id>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
<name>Springframework Maven SNAPSHOT Repository</name>
|
||||
<url>http://maven.springframework.org/snapshot</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>spring-maven-milestones</id>
|
||||
<name>Springframework Maven Milestone Repository</name>
|
||||
<url>http://maven.springframework.org/milestone</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>aspectj-maven-plugin</artifactId>
|
||||
<version>1.2</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
<version>${aspectj.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjtools</artifactId>
|
||||
<version>${aspectj.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<outxml>true</outxml>
|
||||
<aspectLibraries>
|
||||
<aspectLibrary>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aspects</artifactId>
|
||||
</aspectLibrary>
|
||||
<!-- <aspectLibrary>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-commons-aspects</artifactId>
|
||||
</aspectLibrary> -->
|
||||
</aspectLibraries>
|
||||
<source>1.5</source>
|
||||
<target>1.5</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>aspectj-maven-plugin</artifactId>
|
||||
<version>1.4</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
<version>${aspectj}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjtools</artifactId>
|
||||
<version>${aspectj}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<outxml>true</outxml>
|
||||
<aspectLibraries>
|
||||
<aspectLibrary>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aspects</artifactId>
|
||||
</aspectLibrary>
|
||||
</aspectLibraries>
|
||||
<source>${source.level}</source>
|
||||
<target>${source.level}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -1,30 +1,22 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.document.couchdb.core;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for CouchTemplate with mocks
|
||||
*/
|
||||
public class CouchTemplateTests {
|
||||
|
||||
@Test
|
||||
public void foo() {
|
||||
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.crossstore;
|
||||
|
||||
import org.springframework.data.crossstore.ChangeSetBacked;
|
||||
|
||||
public interface DocumentBacked extends ChangeSetBacked {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.crossstore;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.data.crossstore.ChangeSet;
|
||||
import org.springframework.data.crossstore.ChangeSetBacked;
|
||||
import org.springframework.data.crossstore.ChangeSetPersister;
|
||||
import org.springframework.data.mongodb.core.CollectionCallback;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.MongoException;
|
||||
|
||||
public class MongoChangeSetPersister implements ChangeSetPersister<Object> {
|
||||
|
||||
private static final String ENTITY_CLASS = "_entity_class";
|
||||
|
||||
private static final String ENTITY_ID = "_entity_id";
|
||||
|
||||
private static final String ENTITY_FIELD_NAME = "_entity_field_name";
|
||||
|
||||
private static final String ENTITY_FIELD_CLASS = "_entity_field_class";
|
||||
|
||||
protected final Logger log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
private MongoTemplate mongoTemplate;
|
||||
|
||||
private EntityManagerFactory entityManagerFactory;
|
||||
|
||||
public void setMongoTemplate(MongoTemplate mongoTemplate) {
|
||||
this.mongoTemplate = mongoTemplate;
|
||||
}
|
||||
|
||||
public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
|
||||
this.entityManagerFactory = entityManagerFactory;
|
||||
}
|
||||
|
||||
public void getPersistentState(Class<? extends ChangeSetBacked> entityClass, Object id, final ChangeSet changeSet)
|
||||
throws DataAccessException, NotFoundException {
|
||||
|
||||
if (id == null) {
|
||||
log.debug("Unable to load MongoDB data for null id");
|
||||
return;
|
||||
}
|
||||
|
||||
String collName = getCollectionNameForEntity(entityClass);
|
||||
|
||||
final DBObject dbk = new BasicDBObject();
|
||||
dbk.put(ENTITY_ID, id);
|
||||
dbk.put(ENTITY_CLASS, entityClass.getName());
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Loading MongoDB data for " + dbk);
|
||||
}
|
||||
mongoTemplate.execute(collName, new CollectionCallback<Object>() {
|
||||
public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||
for (DBObject dbo : collection.find(dbk)) {
|
||||
String key = (String) dbo.get(ENTITY_FIELD_NAME);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Processing key: " + key);
|
||||
}
|
||||
if (!changeSet.getValues().containsKey(key)) {
|
||||
String className = (String) dbo.get(ENTITY_FIELD_CLASS);
|
||||
if (className == null) {
|
||||
throw new DataIntegrityViolationException("Unble to convert property " + key + ": Invalid metadata, "
|
||||
+ ENTITY_FIELD_CLASS + " not available");
|
||||
}
|
||||
Class<?> clazz = ClassUtils.resolveClassName(className, ClassUtils.getDefaultClassLoader());
|
||||
Object value = mongoTemplate.getConverter().read(clazz, dbo);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Adding to ChangeSet: " + key);
|
||||
}
|
||||
changeSet.set(key, value);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Object getPersistentId(ChangeSetBacked entity, ChangeSet cs) throws DataAccessException {
|
||||
log.debug("getPersistentId called on " + entity);
|
||||
if (entityManagerFactory == null) {
|
||||
throw new DataAccessResourceFailureException("EntityManagerFactory cannot be null");
|
||||
}
|
||||
Object o = entityManagerFactory.getPersistenceUnitUtil().getIdentifier(entity);
|
||||
return o;
|
||||
}
|
||||
|
||||
public Object persistState(ChangeSetBacked entity, ChangeSet cs) throws DataAccessException {
|
||||
if (cs == null) {
|
||||
log.debug("Flush: changeset was null, nothing to flush.");
|
||||
return 0L;
|
||||
}
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Flush: changeset: " + cs.getValues());
|
||||
}
|
||||
|
||||
String collName = getCollectionNameForEntity(entity.getClass());
|
||||
if (mongoTemplate.getCollection(collName) == null) {
|
||||
mongoTemplate.createCollection(collName);
|
||||
}
|
||||
|
||||
for (String key : cs.getValues().keySet()) {
|
||||
if (key != null && !key.startsWith("_") && !key.equals(ChangeSetPersister.ID_KEY)) {
|
||||
Object value = cs.getValues().get(key);
|
||||
final DBObject dbQuery = new BasicDBObject();
|
||||
dbQuery.put(ENTITY_ID, getPersistentId(entity, cs));
|
||||
dbQuery.put(ENTITY_CLASS, entity.getClass().getName());
|
||||
dbQuery.put(ENTITY_FIELD_NAME, key);
|
||||
DBObject dbId = mongoTemplate.execute(collName, new CollectionCallback<DBObject>() {
|
||||
public DBObject doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||
return collection.findOne(dbQuery);
|
||||
}
|
||||
});
|
||||
if (value == null) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Flush: removing: " + dbQuery);
|
||||
}
|
||||
mongoTemplate.execute(collName, new CollectionCallback<Object>() {
|
||||
public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||
collection.remove(dbQuery);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
final DBObject dbDoc = new BasicDBObject();
|
||||
dbDoc.putAll(dbQuery);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Flush: saving: " + dbQuery);
|
||||
}
|
||||
mongoTemplate.getConverter().write(value, dbDoc);
|
||||
dbDoc.put(ENTITY_FIELD_CLASS, value.getClass().getName());
|
||||
if (dbId != null) {
|
||||
dbDoc.put("_id", dbId.get("_id"));
|
||||
}
|
||||
mongoTemplate.execute(collName, new CollectionCallback<Object>() {
|
||||
public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||
collection.save(dbDoc);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
|
||||
private String getCollectionNameForEntity(Class<? extends ChangeSetBacked> entityClass) {
|
||||
return ClassUtils.getQualifiedName(entityClass);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.crossstore;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Transient;
|
||||
import javax.persistence.Entity;
|
||||
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.reflect.FieldSignature;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.mongodb.crossstore.RelatedDocument;
|
||||
import org.springframework.data.mongodb.crossstore.DocumentBacked;
|
||||
import org.springframework.data.crossstore.ChangeSetBackedTransactionSynchronization;
|
||||
import org.springframework.data.crossstore.ChangeSet;
|
||||
import org.springframework.data.crossstore.ChangeSetPersister;
|
||||
import org.springframework.data.crossstore.ChangeSetPersister.NotFoundException;
|
||||
import org.springframework.data.crossstore.HashMapChangeSet;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
/**
|
||||
* Aspect to turn an object annotated with @Document into a persistent document using Mongo.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
*/
|
||||
public aspect MongoDocumentBacking {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(MongoDocumentBacking.class);
|
||||
|
||||
// Aspect shared config
|
||||
private ChangeSetPersister<Object> changeSetPersister;
|
||||
|
||||
public void setChangeSetPersister(ChangeSetPersister<Object> changeSetPersister) {
|
||||
this.changeSetPersister = changeSetPersister;
|
||||
}
|
||||
|
||||
// ITD to introduce N state to Annotated objects
|
||||
declare parents : (@Entity *) implements DocumentBacked;
|
||||
|
||||
// The annotated fields that will be persisted in MongoDB rather than with JPA
|
||||
declare @field: @RelatedDocument * (@Entity+ *).*:@Transient;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Advise user-defined constructors of ChangeSetBacked objects to create a new
|
||||
// backing ChangeSet
|
||||
// -------------------------------------------------------------------------
|
||||
pointcut arbitraryUserConstructorOfChangeSetBackedObject(DocumentBacked entity) :
|
||||
execution((DocumentBacked+).new(..)) &&
|
||||
!execution((DocumentBacked+).new(ChangeSet)) &&
|
||||
this(entity);
|
||||
|
||||
pointcut finderConstructorOfChangeSetBackedObject(DocumentBacked entity, ChangeSet cs) :
|
||||
execution((DocumentBacked+).new(ChangeSet)) &&
|
||||
this(entity) &&
|
||||
args(cs);
|
||||
|
||||
protected pointcut entityFieldGet(DocumentBacked entity) :
|
||||
get(@RelatedDocument * DocumentBacked+.*) &&
|
||||
this(entity) &&
|
||||
!get(* DocumentBacked.*);
|
||||
|
||||
protected pointcut entityFieldSet(DocumentBacked entity, Object newVal) :
|
||||
set(@RelatedDocument * DocumentBacked+.*) &&
|
||||
this(entity) &&
|
||||
args(newVal) &&
|
||||
!set(* DocumentBacked.*);
|
||||
|
||||
// intercept EntityManager.merge calls
|
||||
public pointcut entityManagerMerge(EntityManager em, Object entity) :
|
||||
call(* EntityManager.merge(Object)) &&
|
||||
target(em) &&
|
||||
args(entity);
|
||||
|
||||
// intercept EntityManager.remove calls
|
||||
// public pointcut entityManagerRemove(EntityManager em, Object entity) :
|
||||
// call(* EntityManager.remove(Object)) &&
|
||||
// target(em) &&
|
||||
// args(entity);
|
||||
|
||||
// move changeSet from detached entity to the newly merged persistent object
|
||||
Object around(EntityManager em, Object entity) : entityManagerMerge(em, entity) {
|
||||
Object mergedEntity = proceed(em, entity);
|
||||
if (entity instanceof DocumentBacked && mergedEntity instanceof DocumentBacked) {
|
||||
((DocumentBacked) mergedEntity).changeSet = ((DocumentBacked) entity).getChangeSet();
|
||||
}
|
||||
return mergedEntity;
|
||||
}
|
||||
|
||||
// clear changeSet from removed entity
|
||||
// Object around(EntityManager em, Object entity) : entityManagerRemove(em, entity) {
|
||||
// if (entity instanceof DocumentBacked) {
|
||||
// removeChangeSetValues((DocumentBacked)entity);
|
||||
// }
|
||||
// return proceed(em, entity);
|
||||
// }
|
||||
|
||||
private static void removeChangeSetValues(DocumentBacked entity) {
|
||||
LOGGER.debug("Removing all change-set values for " + entity);
|
||||
ChangeSet nulledCs = new HashMapChangeSet();
|
||||
DocumentBacked documentEntity = (DocumentBacked) entity;
|
||||
@SuppressWarnings("unchecked")
|
||||
ChangeSetPersister<Object> changeSetPersister = (ChangeSetPersister<Object>) documentEntity.itdChangeSetPersister;
|
||||
try {
|
||||
changeSetPersister.getPersistentState(documentEntity.getClass(), documentEntity.get_persistent_id(),
|
||||
documentEntity.getChangeSet());
|
||||
} catch (DataAccessException e) {
|
||||
} catch (NotFoundException e) {
|
||||
}
|
||||
for (String key : entity.getChangeSet().getValues().keySet()) {
|
||||
nulledCs.set(key, null);
|
||||
}
|
||||
entity.setChangeSet(nulledCs);
|
||||
}
|
||||
|
||||
before(DocumentBacked entity) : arbitraryUserConstructorOfChangeSetBackedObject(entity) {
|
||||
LOGGER.debug("User-defined constructor called on DocumentBacked object of class " + entity.getClass());
|
||||
// Populate all ITD fields
|
||||
entity.setChangeSet(new HashMapChangeSet());
|
||||
entity.itdChangeSetPersister = changeSetPersister;
|
||||
entity.itdTransactionSynchronization = new ChangeSetBackedTransactionSynchronization(changeSetPersister, entity);
|
||||
// registerTransactionSynchronization(entity);
|
||||
}
|
||||
|
||||
private static void registerTransactionSynchronization(DocumentBacked entity) {
|
||||
if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||
if (!TransactionSynchronizationManager.getSynchronizations().contains(entity.itdTransactionSynchronization)) {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Adding transaction synchronization for " + entity);
|
||||
}
|
||||
TransactionSynchronizationManager.registerSynchronization(entity.itdTransactionSynchronization);
|
||||
} else {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Transaction synchronization already active for " + entity);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Transaction synchronization is not active for " + entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// ChangeSet-related mixins
|
||||
// -------------------------------------------------------------------------
|
||||
// Introduced field
|
||||
@Transient
|
||||
private ChangeSet DocumentBacked.changeSet;
|
||||
|
||||
@Transient
|
||||
private ChangeSetPersister<?> DocumentBacked.itdChangeSetPersister;
|
||||
|
||||
@Transient
|
||||
private ChangeSetBackedTransactionSynchronization DocumentBacked.itdTransactionSynchronization;
|
||||
|
||||
public void DocumentBacked.setChangeSet(ChangeSet cs) {
|
||||
this.changeSet = cs;
|
||||
}
|
||||
|
||||
public ChangeSet DocumentBacked.getChangeSet() {
|
||||
return changeSet;
|
||||
}
|
||||
|
||||
// Flush the entity state to the persistent store
|
||||
public void DocumentBacked.flush() {
|
||||
Object id = itdChangeSetPersister.getPersistentId(this, this.changeSet);
|
||||
itdChangeSetPersister.persistState(this, this.changeSet);
|
||||
}
|
||||
|
||||
public Object DocumentBacked.get_persistent_id() {
|
||||
return itdChangeSetPersister.getPersistentId(this, this.changeSet);
|
||||
}
|
||||
|
||||
// lifecycle methods
|
||||
@javax.persistence.PostPersist
|
||||
public void DocumentBacked.itdPostPersist() {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("JPA lifecycle event PrePersist: " + this.getClass().getName());
|
||||
}
|
||||
registerTransactionSynchronization(this);
|
||||
}
|
||||
|
||||
@javax.persistence.PreUpdate
|
||||
public void DocumentBacked.itdPreUpdate() {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("JPA lifecycle event PreUpdate: " + this.getClass().getName() + " :: " + this);
|
||||
}
|
||||
registerTransactionSynchronization(this);
|
||||
}
|
||||
|
||||
@javax.persistence.PostUpdate
|
||||
public void DocumentBacked.itdPostUpdate() {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("JPA lifecycle event PostUpdate: " + this.getClass().getName() + " :: " + this);
|
||||
}
|
||||
registerTransactionSynchronization(this);
|
||||
}
|
||||
|
||||
@javax.persistence.PostRemove
|
||||
public void DocumentBacked.itdPostRemove() {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("JPA lifecycle event PostRemove: " + this.getClass().getName() + " :: " + this);
|
||||
}
|
||||
registerTransactionSynchronization(this);
|
||||
removeChangeSetValues(this);
|
||||
}
|
||||
|
||||
@javax.persistence.PostLoad
|
||||
public void DocumentBacked.itdPostLoad() {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("JPA lifecycle event PostLoad: " + this.getClass().getName() + " :: " + this);
|
||||
}
|
||||
registerTransactionSynchronization(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* delegates field reads to the state accessors instance
|
||||
*/
|
||||
Object around(DocumentBacked entity): entityFieldGet(entity) {
|
||||
Field f = field(thisJoinPoint);
|
||||
String propName = f.getName();
|
||||
LOGGER.trace("GET " + f + " -> ChangeSet value property [" + propName + "] using: " + entity.getChangeSet());
|
||||
if (entity.getChangeSet().getValues().get(propName) == null) {
|
||||
try {
|
||||
this.changeSetPersister
|
||||
.getPersistentState(entity.getClass(), entity.get_persistent_id(), entity.getChangeSet());
|
||||
} catch (NotFoundException e) {
|
||||
}
|
||||
}
|
||||
Object fValue = entity.getChangeSet().getValues().get(propName);
|
||||
if (fValue != null) {
|
||||
return fValue;
|
||||
}
|
||||
return proceed(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* delegates field writes to the state accessors instance
|
||||
*/
|
||||
Object around(DocumentBacked entity, Object newVal) : entityFieldSet(entity, newVal) {
|
||||
Field f = field(thisJoinPoint);
|
||||
String propName = f.getName();
|
||||
LOGGER.trace("SET " + f + " -> ChangeSet number value property [" + propName + "] with value=[" + newVal + "]");
|
||||
entity.getChangeSet().set(propName, newVal);
|
||||
return proceed(entity, newVal);
|
||||
}
|
||||
|
||||
Field field(JoinPoint joinPoint) {
|
||||
FieldSignature fieldSignature = (FieldSignature) joinPoint.getSignature();
|
||||
return fieldSignature.getField();
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* 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,
|
||||
@@ -13,8 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.document.annotation;
|
||||
package org.springframework.data.mongodb.crossstore;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -25,11 +24,6 @@ import java.lang.annotation.Target;
|
||||
* @author Thomas Risberg
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({
|
||||
ElementType.FIELD
|
||||
})
|
||||
@Target({ ElementType.FIELD })
|
||||
public @interface RelatedDocument {
|
||||
|
||||
String collection() default "";
|
||||
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package org.springframework.data.persistence.document;
|
||||
|
||||
import org.springframework.data.persistence.ChangeSetBacked;
|
||||
|
||||
public interface DocumentBacked extends ChangeSetBacked {
|
||||
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
package org.springframework.data.persistence.document;
|
||||
|
||||
//public class DocumentBackedTransactionSynchronization {
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.data.persistence.ChangeSetBacked;
|
||||
import org.springframework.data.persistence.ChangeSetPersister;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
|
||||
public class DocumentBackedTransactionSynchronization implements TransactionSynchronization {
|
||||
|
||||
protected final Log log = LogFactory.getLog(getClass());
|
||||
|
||||
private ChangeSetPersister<Object> changeSetPersister;
|
||||
|
||||
private ChangeSetBacked entity;
|
||||
|
||||
private int changeSetTxStatus = -1;
|
||||
|
||||
public DocumentBackedTransactionSynchronization(ChangeSetPersister<Object> changeSetPersister, ChangeSetBacked entity) {
|
||||
this.changeSetPersister = changeSetPersister;
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
public void afterCommit() {
|
||||
log.debug("After Commit called for " + entity);
|
||||
changeSetPersister.persistState(entity, entity.getChangeSet());
|
||||
changeSetTxStatus = 0;
|
||||
}
|
||||
|
||||
public void afterCompletion(int status) {
|
||||
log.debug("After Completion called with status = " + status);
|
||||
if (changeSetTxStatus == 0) {
|
||||
if (status == STATUS_COMMITTED) {
|
||||
// this is good
|
||||
log.debug("ChangedSetBackedTransactionSynchronization completed successfully for " + this.entity);
|
||||
}
|
||||
else {
|
||||
// this could be bad - TODO: compensate
|
||||
log.error("ChangedSetBackedTransactionSynchronization failed for " + this.entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void beforeCommit(boolean readOnly) {
|
||||
}
|
||||
|
||||
public void beforeCompletion() {
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
throw new IllegalStateException("ChangedSetBackedTransactionSynchronization does not support transaction suspension currently.");
|
||||
}
|
||||
|
||||
public void suspend() {
|
||||
throw new IllegalStateException("ChangedSetBackedTransactionSynchronization does not support transaction suspension currently.");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,169 +0,0 @@
|
||||
package org.springframework.data.persistence.document.mongo;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.MongoException;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.data.document.mongodb.CollectionCallback;
|
||||
import org.springframework.data.document.mongodb.MongoTemplate;
|
||||
import org.springframework.data.persistence.ChangeSet;
|
||||
import org.springframework.data.persistence.ChangeSetBacked;
|
||||
import org.springframework.data.persistence.ChangeSetPersister;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
public class MongoChangeSetPersister implements ChangeSetPersister<Object> {
|
||||
|
||||
private static final String ENTITY_CLASS = "_entity_class";
|
||||
|
||||
private static final String ENTITY_ID = "_entity_id";
|
||||
|
||||
private static final String ENTITY_FIELD_NAME = "_entity_field_name";
|
||||
|
||||
private static final String ENTITY_FIELD_CLASS = "_entity_field_class";
|
||||
|
||||
protected final Log log = LogFactory.getLog(getClass());
|
||||
|
||||
private MongoTemplate mongoTemplate;
|
||||
|
||||
private EntityManagerFactory entityManagerFactory;
|
||||
|
||||
public void setMongoTemplate(MongoTemplate mongoTemplate) {
|
||||
this.mongoTemplate = mongoTemplate;
|
||||
}
|
||||
|
||||
public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
|
||||
this.entityManagerFactory = entityManagerFactory;
|
||||
}
|
||||
|
||||
|
||||
public void getPersistentState(Class<? extends ChangeSetBacked> entityClass,
|
||||
Object id, final ChangeSet changeSet)
|
||||
throws DataAccessException, NotFoundException {
|
||||
|
||||
if (id == null) {
|
||||
log.debug("Unable to load MongoDB data for null id");
|
||||
return;
|
||||
}
|
||||
|
||||
String collName = getCollectionNameForEntity(entityClass);
|
||||
|
||||
final DBObject dbk = new BasicDBObject();
|
||||
dbk.put(ENTITY_ID, id);
|
||||
dbk.put(ENTITY_CLASS, entityClass.getName());
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Loading MongoDB data for " + dbk);
|
||||
}
|
||||
mongoTemplate.execute(collName, new CollectionCallback<Object>() {
|
||||
public Object doInCollection(DBCollection collection)
|
||||
throws MongoException, DataAccessException {
|
||||
for (DBObject dbo : collection.find(dbk)) {
|
||||
String key = (String) dbo.get(ENTITY_FIELD_NAME);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Processing key: " + key);
|
||||
}
|
||||
if (!changeSet.getValues().containsKey(key)) {
|
||||
String className = (String) dbo.get(ENTITY_FIELD_CLASS);
|
||||
if (className == null) {
|
||||
throw new DataIntegrityViolationException(
|
||||
"Unble to convert property " + key
|
||||
+ ": Invalid metadata, " + ENTITY_FIELD_CLASS + " not available");
|
||||
}
|
||||
Class<?> clazz = ClassUtils.resolveClassName(className, ClassUtils.getDefaultClassLoader());
|
||||
Object value = mongoTemplate.getConverter().read(clazz, dbo);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Adding to ChangeSet: " + key);
|
||||
}
|
||||
changeSet.set(key, value);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Object getPersistentId(ChangeSetBacked entity, ChangeSet cs) throws DataAccessException {
|
||||
log.debug("getPersistentId called on " + entity);
|
||||
if (entityManagerFactory == null) {
|
||||
throw new DataAccessResourceFailureException("EntityManagerFactory cannot be null");
|
||||
}
|
||||
Object o = entityManagerFactory.getPersistenceUnitUtil().getIdentifier(entity);
|
||||
return o;
|
||||
}
|
||||
|
||||
public Object persistState(ChangeSetBacked entity, ChangeSet cs) throws DataAccessException {
|
||||
if (cs == null) {
|
||||
log.debug("Flush: changeset was null, nothing to flush.");
|
||||
return 0L;
|
||||
}
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Flush: changeset: " + cs.getValues());
|
||||
}
|
||||
|
||||
String collName = getCollectionNameForEntity(entity.getClass());
|
||||
DBCollection dbc = mongoTemplate.getCollection(collName);
|
||||
if (dbc == null) {
|
||||
dbc = mongoTemplate.createCollection(collName);
|
||||
}
|
||||
for (String key : cs.getValues().keySet()) {
|
||||
if (key != null && !key.startsWith("_") && !key.equals(ChangeSetPersister.ID_KEY)) {
|
||||
Object value = cs.getValues().get(key);
|
||||
final DBObject dbQuery = new BasicDBObject();
|
||||
dbQuery.put(ENTITY_ID, getPersistentId(entity, cs));
|
||||
dbQuery.put(ENTITY_CLASS, entity.getClass().getName());
|
||||
dbQuery.put(ENTITY_FIELD_NAME, key);
|
||||
DBObject dbId = mongoTemplate.execute(collName,
|
||||
new CollectionCallback<DBObject>() {
|
||||
public DBObject doInCollection(DBCollection collection)
|
||||
throws MongoException, DataAccessException {
|
||||
return collection.findOne(dbQuery);
|
||||
}
|
||||
});
|
||||
if (value == null) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Flush: removing: " + dbQuery);
|
||||
}
|
||||
mongoTemplate.execute(collName, new CollectionCallback<Object>() {
|
||||
public Object doInCollection(DBCollection collection)
|
||||
throws MongoException, DataAccessException {
|
||||
collection.remove(dbQuery);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
final DBObject dbDoc = new BasicDBObject();
|
||||
dbDoc.putAll(dbQuery);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Flush: saving: " + dbQuery);
|
||||
}
|
||||
mongoTemplate.getConverter().write(value, dbDoc);
|
||||
dbDoc.put(ENTITY_FIELD_CLASS, value.getClass().getName());
|
||||
if (dbId != null) {
|
||||
dbDoc.put("_id", dbId.get("_id"));
|
||||
}
|
||||
mongoTemplate.execute(collName, new CollectionCallback<Object>() {
|
||||
public Object doInCollection(DBCollection collection)
|
||||
throws MongoException, DataAccessException {
|
||||
collection.save(dbDoc);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
|
||||
private String getCollectionNameForEntity(Class<? extends ChangeSetBacked> entityClass) {
|
||||
return ClassUtils.getQualifiedName(entityClass);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,259 +0,0 @@
|
||||
package org.springframework.data.persistence.document.mongo;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Transient;
|
||||
import javax.persistence.Entity;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.reflect.FieldSignature;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.document.annotation.RelatedDocument;
|
||||
|
||||
import org.springframework.data.persistence.document.DocumentBacked;
|
||||
import org.springframework.data.persistence.document.DocumentBackedTransactionSynchronization;
|
||||
import org.springframework.data.persistence.ChangeSet;
|
||||
import org.springframework.data.persistence.ChangeSetBacked;
|
||||
import org.springframework.data.persistence.ChangeSetPersister;
|
||||
import org.springframework.data.persistence.ChangeSetPersister.NotFoundException;
|
||||
import org.springframework.data.persistence.HashMapChangeSet;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
/**
|
||||
* Aspect to turn an object annotated with @Document into a persistent document
|
||||
* using Mongo.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
*/
|
||||
public aspect MongoDocumentBacking {
|
||||
|
||||
private static final Log LOGGER = LogFactory
|
||||
.getLog(MongoDocumentBacking.class);
|
||||
|
||||
// Aspect shared config
|
||||
private ChangeSetPersister<Object> changeSetPersister;
|
||||
|
||||
public void setChangeSetPersister(
|
||||
ChangeSetPersister<Object> changeSetPersister) {
|
||||
this.changeSetPersister = changeSetPersister;
|
||||
}
|
||||
|
||||
// ITD to introduce N state to Annotated objects
|
||||
declare parents : (@Entity *) implements DocumentBacked;
|
||||
|
||||
// The annotated fields that will be persisted in MongoDB rather than with JPA
|
||||
declare @field: @RelatedDocument * (@Entity+ *).*:@Transient;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Advise user-defined constructors of ChangeSetBacked objects to create a new
|
||||
// backing ChangeSet
|
||||
// -------------------------------------------------------------------------
|
||||
pointcut arbitraryUserConstructorOfChangeSetBackedObject(DocumentBacked entity) :
|
||||
execution((DocumentBacked+).new(..)) &&
|
||||
!execution((DocumentBacked+).new(ChangeSet)) &&
|
||||
this(entity);
|
||||
|
||||
pointcut finderConstructorOfChangeSetBackedObject(DocumentBacked entity,
|
||||
ChangeSet cs) :
|
||||
execution((DocumentBacked+).new(ChangeSet)) &&
|
||||
this(entity) &&
|
||||
args(cs);
|
||||
|
||||
protected pointcut entityFieldGet(DocumentBacked entity) :
|
||||
get(@RelatedDocument * DocumentBacked+.*) &&
|
||||
this(entity) &&
|
||||
!get(* DocumentBacked.*);
|
||||
|
||||
protected pointcut entityFieldSet(DocumentBacked entity, Object newVal) :
|
||||
set(@RelatedDocument * DocumentBacked+.*) &&
|
||||
this(entity) &&
|
||||
args(newVal) &&
|
||||
!set(* DocumentBacked.*);
|
||||
|
||||
// intercept EntityManager.merge calls
|
||||
public pointcut entityManagerMerge(EntityManager em, Object entity) :
|
||||
call(* EntityManager.merge(Object)) &&
|
||||
target(em) &&
|
||||
args(entity);
|
||||
|
||||
// intercept EntityManager.remove calls
|
||||
// public pointcut entityManagerRemove(EntityManager em, Object entity) :
|
||||
// call(* EntityManager.remove(Object)) &&
|
||||
// target(em) &&
|
||||
// args(entity);
|
||||
|
||||
// move changeSet from detached entity to the newly merged persistent object
|
||||
Object around(EntityManager em, Object entity) : entityManagerMerge(em, entity) {
|
||||
Object mergedEntity = proceed(em, entity);
|
||||
if (entity instanceof DocumentBacked && mergedEntity instanceof DocumentBacked) {
|
||||
((DocumentBacked)mergedEntity).changeSet = ((DocumentBacked)entity).getChangeSet();
|
||||
}
|
||||
return mergedEntity;
|
||||
}
|
||||
|
||||
// clear changeSet from removed entity
|
||||
// Object around(EntityManager em, Object entity) : entityManagerRemove(em, entity) {
|
||||
// if (entity instanceof DocumentBacked) {
|
||||
// removeChangeSetValues((DocumentBacked)entity);
|
||||
// }
|
||||
// return proceed(em, entity);
|
||||
// }
|
||||
|
||||
private static void removeChangeSetValues(DocumentBacked entity) {
|
||||
LOGGER.debug("Removing all change-set values for " + entity);
|
||||
ChangeSet nulledCs = new HashMapChangeSet();
|
||||
DocumentBacked documentEntity = (DocumentBacked) entity;
|
||||
@SuppressWarnings("unchecked")
|
||||
ChangeSetPersister<Object> changeSetPersister = (ChangeSetPersister<Object>)documentEntity.itdChangeSetPersister;
|
||||
try {
|
||||
changeSetPersister.getPersistentState(
|
||||
documentEntity.getClass(),
|
||||
documentEntity.get_persistent_id(),
|
||||
documentEntity.getChangeSet());
|
||||
}
|
||||
catch (DataAccessException e) {}
|
||||
catch (NotFoundException e) {}
|
||||
for (String key :entity.getChangeSet().getValues().keySet()) {
|
||||
nulledCs.set(key, null);
|
||||
}
|
||||
entity.setChangeSet(nulledCs);
|
||||
}
|
||||
|
||||
before(DocumentBacked entity) : arbitraryUserConstructorOfChangeSetBackedObject(entity) {
|
||||
LOGGER
|
||||
.debug("User-defined constructor called on DocumentBacked object of class "
|
||||
+ entity.getClass());
|
||||
// Populate all ITD fields
|
||||
entity.setChangeSet(new HashMapChangeSet());
|
||||
entity.itdChangeSetPersister = changeSetPersister;
|
||||
entity.itdTransactionSynchronization =
|
||||
new DocumentBackedTransactionSynchronization(changeSetPersister, entity);
|
||||
//registerTransactionSynchronization(entity);
|
||||
}
|
||||
|
||||
private static void registerTransactionSynchronization(DocumentBacked entity) {
|
||||
if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||
if (!TransactionSynchronizationManager.getSynchronizations().contains(entity.itdTransactionSynchronization)) {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Adding transaction synchronization for " + entity);
|
||||
}
|
||||
TransactionSynchronizationManager.registerSynchronization(entity.itdTransactionSynchronization);
|
||||
}
|
||||
else {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Transaction synchronization already active for " + entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Transaction synchronization is not active for " + entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// ChangeSet-related mixins
|
||||
// -------------------------------------------------------------------------
|
||||
// Introduced field
|
||||
@Transient private ChangeSet DocumentBacked.changeSet;
|
||||
|
||||
@Transient private ChangeSetPersister<?> DocumentBacked.itdChangeSetPersister;
|
||||
|
||||
@Transient private DocumentBackedTransactionSynchronization DocumentBacked.itdTransactionSynchronization;
|
||||
|
||||
public void DocumentBacked.setChangeSet(ChangeSet cs) {
|
||||
this.changeSet = cs;
|
||||
}
|
||||
|
||||
public ChangeSet DocumentBacked.getChangeSet() {
|
||||
return changeSet;
|
||||
}
|
||||
|
||||
// Flush the entity state to the persistent store
|
||||
public void DocumentBacked.flush() {
|
||||
Object id = itdChangeSetPersister.getPersistentId(this, this.changeSet);
|
||||
itdChangeSetPersister.persistState(this, this.changeSet);
|
||||
}
|
||||
|
||||
public Object DocumentBacked.get_persistent_id() {
|
||||
return itdChangeSetPersister.getPersistentId(this, this.changeSet);
|
||||
}
|
||||
|
||||
// lifecycle methods
|
||||
@javax.persistence.PostPersist public void DocumentBacked.itdPostPersist() {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("JPA lifecycle event PrePersist: " + this.getClass().getName());
|
||||
}
|
||||
registerTransactionSynchronization(this);
|
||||
}
|
||||
@javax.persistence.PreUpdate public void DocumentBacked.itdPreUpdate() {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("JPA lifecycle event PreUpdate: " + this.getClass().getName() + " :: " + this);
|
||||
}
|
||||
registerTransactionSynchronization(this);
|
||||
}
|
||||
@javax.persistence.PostUpdate public void DocumentBacked.itdPostUpdate() {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("JPA lifecycle event PostUpdate: " + this.getClass().getName() + " :: " + this);
|
||||
}
|
||||
registerTransactionSynchronization(this);
|
||||
}
|
||||
@javax.persistence.PostRemove public void DocumentBacked.itdPostRemove() {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("JPA lifecycle event PostRemove: " + this.getClass().getName() + " :: " + this);
|
||||
}
|
||||
registerTransactionSynchronization(this);
|
||||
removeChangeSetValues(this);
|
||||
}
|
||||
@javax.persistence.PostLoad public void DocumentBacked.itdPostLoad() {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("JPA lifecycle event PostLoad: " + this.getClass().getName() + " :: " + this);
|
||||
}
|
||||
registerTransactionSynchronization(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* delegates field reads to the state accessors instance
|
||||
*/
|
||||
Object around(DocumentBacked entity): entityFieldGet(entity) {
|
||||
Field f = field(thisJoinPoint);
|
||||
String propName = f.getName();
|
||||
LOGGER.trace("GET " + f + " -> ChangeSet value property [" + propName
|
||||
+ "] using: " + entity.getChangeSet());
|
||||
if (entity.getChangeSet().getValues().get(propName) == null) {
|
||||
try {
|
||||
this.changeSetPersister.getPersistentState(entity.getClass(),
|
||||
entity.get_persistent_id(), entity.getChangeSet());
|
||||
} catch (NotFoundException e) {
|
||||
}
|
||||
}
|
||||
Object fValue = entity.getChangeSet().getValues().get(propName);
|
||||
if (fValue != null) {
|
||||
return fValue;
|
||||
}
|
||||
return proceed(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* delegates field writes to the state accessors instance
|
||||
*/
|
||||
Object around(DocumentBacked entity, Object newVal) : entityFieldSet(entity, newVal) {
|
||||
Field f = field(thisJoinPoint);
|
||||
String propName = f.getName();
|
||||
LOGGER.trace("SET " + f + " -> ChangeSet number value property [" + propName
|
||||
+ "] with value=[" + newVal + "]");
|
||||
entity.getChangeSet().set(propName, newVal);
|
||||
return proceed(entity, newVal);
|
||||
}
|
||||
|
||||
Field field(JoinPoint joinPoint) {
|
||||
FieldSignature fieldSignature = (FieldSignature) joinPoint.getSignature();
|
||||
return fieldSignature.getField();
|
||||
}
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
package org.springframework.data.document.persistence;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.document.mongodb.MongoTemplate;
|
||||
import org.springframework.data.document.persistence.test.Address;
|
||||
import org.springframework.data.document.persistence.test.Person;
|
||||
import org.springframework.data.document.persistence.test.Resume;
|
||||
import org.springframework.test.annotation.Rollback;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.TransactionCallback;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = "classpath:/META-INF/spring/applicationContext.xml")
|
||||
public class CrossStoreMongoTests {
|
||||
|
||||
@Autowired
|
||||
private MongoTemplate mongoTemplate;
|
||||
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Autowired
|
||||
private PlatformTransactionManager transactionManager;
|
||||
|
||||
@PersistenceContext
|
||||
public void setEntityManager(EntityManager entityManager) {
|
||||
this.entityManager = entityManager;
|
||||
}
|
||||
|
||||
private void clearData(String collectionName) {
|
||||
DBCollection col = this.mongoTemplate.getCollection(collectionName);
|
||||
if (col != null) {
|
||||
this.mongoTemplate.dropCollection(collectionName);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
@Rollback(false)
|
||||
public void testCreateJpaToMongoEntityRelationship() {
|
||||
clearData(Person.class.getName());
|
||||
Person p = new Person("Thomas", 20);
|
||||
Address a = new Address(12, "MAin St.", "Boston", "MA", "02101");
|
||||
p.setAddress(a);
|
||||
Resume r = new Resume();
|
||||
r.addEducation("Skanstulls High School, 1975");
|
||||
r.addEducation("Univ. of Stockholm, 1980");
|
||||
r.addJob("DiMark, DBA, 1990-2000");
|
||||
r.addJob("VMware, Developer, 2007-");
|
||||
p.setResume(r);
|
||||
p.setId(1L);
|
||||
entityManager.persist(p);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
@Rollback(false)
|
||||
public void testReadJpaToMongoEntityRelationship() {
|
||||
Person found = entityManager.find(Person.class, 1L);
|
||||
Assert.assertNotNull(found);
|
||||
Assert.assertEquals(Long.valueOf(1), found.getId());
|
||||
Assert.assertNotNull(found);
|
||||
Assert.assertEquals(Long.valueOf(1), found.getId());
|
||||
Assert.assertNotNull(found.getResume());
|
||||
Assert.assertEquals("DiMark, DBA, 1990-2000" + "; "
|
||||
+ "VMware, Developer, 2007-", found.getResume().getJobs());
|
||||
found.getResume().addJob("SpringDeveloper.com, Consultant, 2005-2006");
|
||||
found.setAge(44);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
@Rollback(false)
|
||||
public void testUpdatedJpaToMongoEntityRelationship() {
|
||||
Person found = entityManager.find(Person.class, 1L);
|
||||
Assert.assertNotNull(found);
|
||||
Assert.assertEquals(Long.valueOf(1), found.getId());
|
||||
Assert.assertNotNull(found);
|
||||
Assert.assertEquals(Long.valueOf(1), found.getId());
|
||||
Assert.assertNotNull(found.getResume());
|
||||
Assert.assertEquals("DiMark, DBA, 1990-2000" + "; "
|
||||
+ "VMware, Developer, 2007-" + "; "
|
||||
+ "SpringDeveloper.com, Consultant, 2005-2006", found.getResume().getJobs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMergeJpaEntityWithMongoDocument() {
|
||||
TransactionTemplate txTemplate = new TransactionTemplate(transactionManager);
|
||||
final Person detached = entityManager.find(Person.class, 1L);
|
||||
detached.getResume().addJob("TargetRx, Developer, 2000-2005");
|
||||
Person merged = txTemplate.execute(new TransactionCallback<Person>() {
|
||||
public Person doInTransaction(TransactionStatus status) {
|
||||
return entityManager.merge(detached);
|
||||
}
|
||||
});
|
||||
Assert.assertTrue(detached.getResume().getJobs().contains("TargetRx, Developer, 2000-2005"));
|
||||
Assert.assertTrue(merged.getResume().getJobs().contains("TargetRx, Developer, 2000-2005"));
|
||||
final Person updated = entityManager.find(Person.class, 1L);
|
||||
Assert.assertTrue(updated.getResume().getJobs().contains("TargetRx, Developer, 2000-2005"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveJpaEntityWithMongoDocument() {
|
||||
TransactionTemplate txTemplate = new TransactionTemplate(transactionManager);
|
||||
txTemplate.execute(new TransactionCallback<Person>() {
|
||||
public Person doInTransaction(TransactionStatus status) {
|
||||
Person p2 = new Person("Thomas", 20);
|
||||
Resume r2 = new Resume();
|
||||
r2.addEducation("Skanstulls High School, 1975");
|
||||
r2.addJob("DiMark, DBA, 1990-2000");
|
||||
p2.setResume(r2);
|
||||
p2.setId(2L);
|
||||
entityManager.persist(p2);
|
||||
Person p3 = new Person("Thomas", 20);
|
||||
Resume r3 = new Resume();
|
||||
r3.addEducation("Univ. of Stockholm, 1980");
|
||||
r3.addJob("VMware, Developer, 2007-");
|
||||
p3.setResume(r3);
|
||||
p3.setId(3L);
|
||||
entityManager.persist(p3);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
txTemplate.execute(new TransactionCallback<Person>() {
|
||||
public Person doInTransaction(TransactionStatus status) {
|
||||
final Person found2 = entityManager.find(Person.class, 2L);
|
||||
entityManager.remove(found2);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
boolean weFound3 = false;
|
||||
for (DBObject dbo : this.mongoTemplate.getCollection(Person.class.getName()).find()) {
|
||||
Assert.assertTrue(!dbo.get("_entity_id").equals(2L));
|
||||
if (dbo.get("_entity_id").equals(3L)) {
|
||||
weFound3 = true;
|
||||
}
|
||||
}
|
||||
Assert.assertTrue(weFound3);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
package org.springframework.data.document.persistence.test;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
import org.springframework.data.document.annotation.RelatedDocument;
|
||||
|
||||
@Entity
|
||||
public class Person {
|
||||
|
||||
@Id
|
||||
Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
private int age;
|
||||
|
||||
private java.util.Date birthDate;
|
||||
|
||||
@RelatedDocument
|
||||
private Address address;
|
||||
|
||||
@RelatedDocument
|
||||
private Resume resume;
|
||||
|
||||
public Person() {
|
||||
}
|
||||
|
||||
public Person(String name, int age) {
|
||||
this.name = name;
|
||||
this.age = age;
|
||||
this.birthDate = new java.util.Date();
|
||||
}
|
||||
|
||||
public void birthday() {
|
||||
++age;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public java.util.Date getBirthDate() {
|
||||
return birthDate;
|
||||
}
|
||||
|
||||
public void setBirthDate(java.util.Date birthDate) {
|
||||
this.birthDate = birthDate;
|
||||
}
|
||||
|
||||
public Resume getResume() {
|
||||
return resume;
|
||||
}
|
||||
|
||||
public void setResume(Resume resume) {
|
||||
this.resume = resume;
|
||||
}
|
||||
|
||||
public Address getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(Address address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
package org.springframework.data.document.persistence.test;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.document.mongodb.mapping.Document;
|
||||
|
||||
@Document
|
||||
public class Resume {
|
||||
|
||||
private static final Log LOGGER = LogFactory.getLog(Resume.class);
|
||||
|
||||
@Id
|
||||
private ObjectId id;
|
||||
|
||||
private String education = "";
|
||||
|
||||
private String jobs = "";
|
||||
|
||||
public String getId() {
|
||||
return id.toString();
|
||||
}
|
||||
|
||||
public String getEducation() {
|
||||
return education;
|
||||
}
|
||||
|
||||
public void addEducation(String education) {
|
||||
LOGGER.debug("Adding education " + education);
|
||||
this.education = this.education + (this.education.length() > 0 ? "; " : "") + education;
|
||||
}
|
||||
|
||||
public String getJobs() {
|
||||
return jobs;
|
||||
}
|
||||
|
||||
public void addJob(String job) {
|
||||
LOGGER.debug("Adding job " + job);
|
||||
this.jobs = this.jobs + (this.jobs.length() > 0 ? "; " : "") + job;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Resume [education=" + education + ", jobs=" + jobs + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright 2011-2013 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.data.mongodb.crossstore;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.crossstore.test.Address;
|
||||
import org.springframework.data.mongodb.crossstore.test.Person;
|
||||
import org.springframework.data.mongodb.crossstore.test.Resume;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.TransactionCallback;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration("classpath:/META-INF/spring/applicationContext.xml")
|
||||
public class CrossStoreMongoTests {
|
||||
|
||||
@Autowired
|
||||
MongoTemplate mongoTemplate;
|
||||
|
||||
@PersistenceContext
|
||||
EntityManager entityManager;
|
||||
|
||||
@Autowired
|
||||
PlatformTransactionManager transactionManager;
|
||||
TransactionTemplate txTemplate;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
txTemplate = new TransactionTemplate(transactionManager);
|
||||
|
||||
clearData(Person.class.getName());
|
||||
|
||||
Address address = new Address(12, "MAin St.", "Boston", "MA", "02101");
|
||||
|
||||
Resume resume = new Resume();
|
||||
resume.addEducation("Skanstulls High School, 1975");
|
||||
resume.addEducation("Univ. of Stockholm, 1980");
|
||||
resume.addJob("DiMark, DBA, 1990-2000");
|
||||
resume.addJob("VMware, Developer, 2007-");
|
||||
|
||||
final Person person = new Person("Thomas", 20);
|
||||
person.setAddress(address);
|
||||
person.setResume(resume);
|
||||
person.setId(1L);
|
||||
|
||||
txTemplate.execute(new TransactionCallback<Void>() {
|
||||
public Void doInTransaction(TransactionStatus status) {
|
||||
entityManager.persist(person);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
txTemplate.execute(new TransactionCallback<Void>() {
|
||||
public Void doInTransaction(TransactionStatus status) {
|
||||
entityManager.remove(entityManager.find(Person.class, 1L));
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void clearData(String collectionName) {
|
||||
DBCollection col = this.mongoTemplate.getCollection(collectionName);
|
||||
if (col != null) {
|
||||
this.mongoTemplate.dropCollection(collectionName);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void testReadJpaToMongoEntityRelationship() {
|
||||
|
||||
Person found = entityManager.find(Person.class, 1L);
|
||||
Assert.assertNotNull(found);
|
||||
Assert.assertEquals(Long.valueOf(1), found.getId());
|
||||
Assert.assertNotNull(found);
|
||||
Assert.assertEquals(Long.valueOf(1), found.getId());
|
||||
Assert.assertNotNull(found.getResume());
|
||||
Assert.assertEquals("DiMark, DBA, 1990-2000" + "; " + "VMware, Developer, 2007-", found.getResume().getJobs());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional
|
||||
public void testUpdatedJpaToMongoEntityRelationship() {
|
||||
|
||||
Person found = entityManager.find(Person.class, 1L);
|
||||
found.setAge(44);
|
||||
found.getResume().addJob("SpringDeveloper.com, Consultant, 2005-2006");
|
||||
|
||||
entityManager.merge(found);
|
||||
|
||||
Assert.assertNotNull(found);
|
||||
Assert.assertEquals(Long.valueOf(1), found.getId());
|
||||
Assert.assertNotNull(found);
|
||||
Assert.assertEquals(Long.valueOf(1), found.getId());
|
||||
Assert.assertNotNull(found.getResume());
|
||||
Assert.assertEquals("DiMark, DBA, 1990-2000" + "; " + "VMware, Developer, 2007-" + "; "
|
||||
+ "SpringDeveloper.com, Consultant, 2005-2006", found.getResume().getJobs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMergeJpaEntityWithMongoDocument() {
|
||||
|
||||
final Person detached = entityManager.find(Person.class, 1L);
|
||||
entityManager.detach(detached);
|
||||
detached.getResume().addJob("TargetRx, Developer, 2000-2005");
|
||||
|
||||
Person merged = txTemplate.execute(new TransactionCallback<Person>() {
|
||||
public Person doInTransaction(TransactionStatus status) {
|
||||
Person result = entityManager.merge(detached);
|
||||
entityManager.flush();
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
||||
Assert.assertTrue(detached.getResume().getJobs().contains("TargetRx, Developer, 2000-2005"));
|
||||
Assert.assertTrue(merged.getResume().getJobs().contains("TargetRx, Developer, 2000-2005"));
|
||||
final Person updated = entityManager.find(Person.class, 1L);
|
||||
Assert.assertTrue(updated.getResume().getJobs().contains("TargetRx, Developer, 2000-2005"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveJpaEntityWithMongoDocument() {
|
||||
|
||||
txTemplate.execute(new TransactionCallback<Person>() {
|
||||
public Person doInTransaction(TransactionStatus status) {
|
||||
Person p2 = new Person("Thomas", 20);
|
||||
Resume r2 = new Resume();
|
||||
r2.addEducation("Skanstulls High School, 1975");
|
||||
r2.addJob("DiMark, DBA, 1990-2000");
|
||||
p2.setResume(r2);
|
||||
p2.setId(2L);
|
||||
entityManager.persist(p2);
|
||||
Person p3 = new Person("Thomas", 20);
|
||||
Resume r3 = new Resume();
|
||||
r3.addEducation("Univ. of Stockholm, 1980");
|
||||
r3.addJob("VMware, Developer, 2007-");
|
||||
p3.setResume(r3);
|
||||
p3.setId(3L);
|
||||
entityManager.persist(p3);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
txTemplate.execute(new TransactionCallback<Person>() {
|
||||
public Person doInTransaction(TransactionStatus status) {
|
||||
final Person found2 = entityManager.find(Person.class, 2L);
|
||||
entityManager.remove(found2);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
boolean weFound3 = false;
|
||||
|
||||
for (DBObject dbo : this.mongoTemplate.getCollection(Person.class.getName()).find()) {
|
||||
Assert.assertTrue(!dbo.get("_entity_id").equals(2L));
|
||||
if (dbo.get("_entity_id").equals(3L)) {
|
||||
weFound3 = true;
|
||||
}
|
||||
}
|
||||
Assert.assertTrue(weFound3);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,15 +1,29 @@
|
||||
package org.springframework.data.document.persistence.test;
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.crossstore.test;
|
||||
|
||||
public class Address {
|
||||
|
||||
|
||||
private Integer streetNumber;
|
||||
private String streetName;
|
||||
private String city;
|
||||
private String state;
|
||||
private String zip;
|
||||
|
||||
public Address(Integer streetNumber, String streetName, String city,
|
||||
String state, String zip) {
|
||||
|
||||
public Address(Integer streetNumber, String streetName, String city, String state, String zip) {
|
||||
super();
|
||||
this.streetNumber = streetNumber;
|
||||
this.streetName = streetName;
|
||||
@@ -17,38 +31,45 @@ public class Address {
|
||||
this.state = state;
|
||||
this.zip = zip;
|
||||
}
|
||||
|
||||
|
||||
public Integer getStreetNumber() {
|
||||
return streetNumber;
|
||||
}
|
||||
|
||||
public void setStreetNumber(Integer streetNumber) {
|
||||
this.streetNumber = streetNumber;
|
||||
}
|
||||
|
||||
public String getStreetName() {
|
||||
return streetName;
|
||||
}
|
||||
|
||||
public void setStreetName(String streetName) {
|
||||
this.streetName = streetName;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public String getZip() {
|
||||
return zip;
|
||||
}
|
||||
|
||||
public void setZip(String zip) {
|
||||
this.zip = zip;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.crossstore.test;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
import org.springframework.data.mongodb.crossstore.RelatedDocument;
|
||||
|
||||
@Entity
|
||||
public class Person {
|
||||
|
||||
@Id
|
||||
Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
private int age;
|
||||
|
||||
private java.util.Date birthDate;
|
||||
|
||||
@RelatedDocument
|
||||
private Address address;
|
||||
|
||||
@RelatedDocument
|
||||
private Resume resume;
|
||||
|
||||
public Person() {
|
||||
}
|
||||
|
||||
public Person(String name, int age) {
|
||||
this.name = name;
|
||||
this.age = age;
|
||||
this.birthDate = new java.util.Date();
|
||||
}
|
||||
|
||||
public void birthday() {
|
||||
++age;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public java.util.Date getBirthDate() {
|
||||
return birthDate;
|
||||
}
|
||||
|
||||
public void setBirthDate(java.util.Date birthDate) {
|
||||
this.birthDate = birthDate;
|
||||
}
|
||||
|
||||
public Resume getResume() {
|
||||
return resume;
|
||||
}
|
||||
|
||||
public void setResume(Resume resume) {
|
||||
this.resume = resume;
|
||||
}
|
||||
|
||||
public Address getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(Address address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.crossstore.test;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
@Document
|
||||
public class Resume {
|
||||
|
||||
private static final Log LOGGER = LogFactory.getLog(Resume.class);
|
||||
|
||||
@Id
|
||||
private ObjectId id;
|
||||
|
||||
private String education = "";
|
||||
|
||||
private String jobs = "";
|
||||
|
||||
public String getId() {
|
||||
return id.toString();
|
||||
}
|
||||
|
||||
public String getEducation() {
|
||||
return education;
|
||||
}
|
||||
|
||||
public void addEducation(String education) {
|
||||
LOGGER.debug("Adding education " + education);
|
||||
this.education = this.education + (this.education.length() > 0 ? "; " : "") + education;
|
||||
}
|
||||
|
||||
public String getJobs() {
|
||||
return jobs;
|
||||
}
|
||||
|
||||
public void addJob(String job) {
|
||||
LOGGER.debug("Adding job " + job);
|
||||
this.jobs = this.jobs + (this.jobs.length() > 0 ? "; " : "") + job;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Resume [education=" + education + ", jobs=" + jobs + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
|
||||
<persistence-unit name="test" transaction-type="RESOURCE_LOCAL">
|
||||
<provider>org.hibernate.ejb.HibernatePersistence</provider>
|
||||
<class>org.springframework.data.document.persistence.test.Person</class>
|
||||
<class>org.springframework.data.mongodb.crossstore.test.Person</class>
|
||||
<properties>
|
||||
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
|
||||
<!--value='create' to build a new database on each run; value='update' to modify an existing database; value='create-drop' means the same as 'create' but also drops tables when Hibernate closes; value='validate' makes no changes to the database-->
|
||||
|
||||
@@ -13,34 +13,37 @@
|
||||
|
||||
<context:spring-configured/>
|
||||
|
||||
<context:component-scan base-package="org.springframework.persistence.test">
|
||||
<context:component-scan base-package="org.springframework.persistence.mongodb.test">
|
||||
<context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
|
||||
</context:component-scan>
|
||||
|
||||
<mongo:mapping-converter/>
|
||||
|
||||
<!-- Mongo config -->
|
||||
<bean id="mongo" class="org.springframework.data.document.mongodb.MongoFactoryBean">
|
||||
<bean id="mongo" class="org.springframework.data.mongodb.core.MongoFactoryBean">
|
||||
<property name="host" value="localhost"/>
|
||||
<property name="port" value="27017"/>
|
||||
</bean>
|
||||
|
||||
<bean id="mongoTemplate" class="org.springframework.data.document.mongodb.MongoTemplate">
|
||||
<constructor-arg name="mongo" ref="mongo"/>
|
||||
<constructor-arg name="databaseName" value="test"/>
|
||||
<constructor-arg name="defaultCollectionName" value="cross-store"/>
|
||||
<bean id="mongoDbFactory" class="org.springframework.data.mongodb.core.SimpleMongoDbFactory">
|
||||
<constructor-arg name="mongo" ref="mongo"/>
|
||||
<constructor-arg name="databaseName" value="database"/>
|
||||
</bean>
|
||||
|
||||
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
|
||||
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
|
||||
<constructor-arg name="mongoConverter" ref="mappingConverter"/>
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.data.document.mongodb.MongoExceptionTranslator"/>
|
||||
<bean class="org.springframework.data.mongodb.core.MongoExceptionTranslator"/>
|
||||
|
||||
<!-- Mongo aspect config -->
|
||||
<bean class="org.springframework.data.persistence.document.mongo.MongoDocumentBacking"
|
||||
<bean class="org.springframework.data.mongodb.crossstore.MongoDocumentBacking"
|
||||
factory-method="aspectOf">
|
||||
<property name="changeSetPersister" ref="mongoChangeSetPersister"/>
|
||||
</bean>
|
||||
<bean id="mongoChangeSetPersister"
|
||||
class="org.springframework.data.persistence.document.mongo.MongoChangeSetPersister">
|
||||
class="org.springframework.data.mongodb.crossstore.MongoChangeSetPersister">
|
||||
<property name="mongoTemplate" ref="mongoTemplate"/>
|
||||
<property name="entityManagerFactory" ref="entityManagerFactory"/>
|
||||
</bean>
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
log4j.rootCategory=INFO, stdout
|
||||
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
|
||||
|
||||
log4j.category.org.springframework=INFO
|
||||
log4j.category.org.springframework.data=TRACE
|
||||
|
||||
log4j.category.org.hibernate.SQL=DEBUG
|
||||
# for debugging datasource initialization
|
||||
# log4j.category.test.jdbc=DEBUG
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d %5p %40.40c:%4L - %m%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!--
|
||||
<logger name="org.springframework" level="debug" />
|
||||
-->
|
||||
|
||||
<root level="error">
|
||||
<appender-ref ref="console" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
18
spring-data-mongodb-cross-store/template.mf
Normal file
18
spring-data-mongodb-cross-store/template.mf
Normal file
@@ -0,0 +1,18 @@
|
||||
Bundle-SymbolicName: org.springframework.data.mongodb.crossstore
|
||||
Bundle-Name: Spring Data MongoDB Cross Store Support
|
||||
Bundle-Vendor: SpringSource
|
||||
Bundle-ManifestVersion: 2
|
||||
Import-Package:
|
||||
sun.reflect;version="0";resolution:=optional
|
||||
Export-Template:
|
||||
org.springframework.data.mongodb.crossstore.*;version="${project.version}"
|
||||
Import-Template:
|
||||
com.mongodb.*;version="0",
|
||||
javax.persistence.*;version="${jpa:[=.=.=,+1.0.0)}",
|
||||
org.aspectj.*;version="${aspectj:[1.0.0, 2.0.0)}",
|
||||
org.bson.*;version="0",
|
||||
org.slf4j.*;version="${slf4j:[=.=.=,+1.0.0)}",
|
||||
org.springframework.*;version="${spring30:[=.=.=.=,+1.0.0)}",
|
||||
org.springframework.data.*;version="${springdata.commons:[=.=.=.=,+1.0.0)}",
|
||||
org.springframework.data.mongodb.*;version="${project.version:[=.=.=.=,+1.0.0)}",
|
||||
org.w3c.dom.*;version="0"
|
||||
39
spring-data-mongodb-distribution/pom.xml
Normal file
39
spring-data-mongodb-distribution/pom.xml
Normal file
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-data-mongodb-distribution</artifactId>
|
||||
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Spring Data MongoDB - Distribution</name>
|
||||
<description>Distribution build for Spring Data MongoDB</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.2.0.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.root>${basedir}/..</project.root>
|
||||
<dist.id>spring-data-mongodb</dist.id>
|
||||
<dist.key>SDMONGO</dist.key>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>wagon-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -5,7 +5,7 @@ and connects directly to the MongoDB server using the driver. It has no dependen
|
||||
|
||||
To use it, configure a host, port, (optionally) applicationId, and database property in your Log4J configuration:
|
||||
|
||||
log4j.appender.stdout=org.springframework.data.document.mongodb.log4j.MongoLog4jAppender
|
||||
log4j.appender.stdout=org.springframework.data.mongodb.log4j.MongoLog4jAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
|
||||
log4j.appender.stdout.host = localhost
|
||||
@@ -32,7 +32,7 @@ An example log entry might look like:
|
||||
{
|
||||
"_id" : ObjectId("4d89341a8ef397e06940d5cd"),
|
||||
"applicationId" : "my.application",
|
||||
"name" : "org.springframework.data.document.mongodb.log4j.AppenderTest",
|
||||
"name" : "org.springframework.data.mongodb.log4j.AppenderTest",
|
||||
"level" : "DEBUG",
|
||||
"timestamp" : ISODate("2011-03-23T16:53:46.778Z"),
|
||||
"properties" : {
|
||||
|
||||
@@ -1,84 +1,30 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-document-parent</artifactId>
|
||||
<version>1.0.0.M2</version>
|
||||
<relativePath>../spring-data-document-parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-data-mongodb-log4j</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Data MongoDB Log4J Appender</name>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.2.0.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<mongo.version>2.3</mongo.version>
|
||||
</properties>
|
||||
<artifactId>spring-data-mongodb-log4j</artifactId>
|
||||
<name>Spring Data MongoDB - Log4J Appender</name>
|
||||
|
||||
<dependencies>
|
||||
<properties>
|
||||
<log4j>1.2.16</log4j>
|
||||
</properties>
|
||||
|
||||
<!-- MongoDB -->
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongo-java-driver</artifactId>
|
||||
<version>${mongo.version}</version>
|
||||
</dependency>
|
||||
<dependencies>
|
||||
|
||||
<!-- Logging -->
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>javax.mail</groupId>
|
||||
<artifactId>mail</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>javax.jms</groupId>
|
||||
<artifactId>jms</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.sun.jdmk</groupId>
|
||||
<artifactId>jmxtools</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.sun.jmx</groupId>
|
||||
<artifactId>jmxri</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- Logging -->
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>${log4j}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Test dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-all</artifactId>
|
||||
<version>1.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.springsource.bundlor</groupId>
|
||||
<artifactId>com.springsource.bundlor.maven</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.document.mongodb.log4j;
|
||||
package org.springframework.data.mongodb.log4j;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Arrays;
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.document.mongodb.log4j;
|
||||
package org.springframework.data.mongodb.log4j;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
@@ -1,6 +1,6 @@
|
||||
log4j.rootCategory=INFO, stdout
|
||||
|
||||
log4j.appender.stdout=org.springframework.data.document.mongodb.log4j.MongoLog4jAppender
|
||||
log4j.appender.stdout=org.springframework.data.mongodb.log4j.MongoLog4jAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
|
||||
log4j.appender.stdout.host = localhost
|
||||
|
||||
@@ -5,6 +5,5 @@ Bundle-ManifestVersion: 2
|
||||
Import-Package:
|
||||
sun.reflect;version="0";resolution:=optional
|
||||
Import-Template:
|
||||
com.mongodb.*;version="${mongo.version:[=.=,+1.0.0)}",
|
||||
org.apache.log4j.*;version="[1.2.15, 2.0.0)",
|
||||
org.apache.log4j.spi.*;version="[1.2.15, 2.0.0)"
|
||||
com.mongodb.*;version="${mongo:[=.=,+1.0.0)}",
|
||||
org.apache.log4j.*;version="${log4j:[=.=.=,+1.0.0)}"
|
||||
|
||||
146
spring-data-mongodb/Spring Data MongoDB.sonargraph
Normal file
146
spring-data-mongodb/Spring Data MongoDB.sonargraph
Normal file
@@ -0,0 +1,146 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<context version="7.0.3.1152">
|
||||
<scope name="spring-data-mongodb" type="Project">
|
||||
<element name="Filter" type="TypeFilterReferenceOverridden">
|
||||
<element name="org.springframework.data.mongodb.**" type="IncludeTypePattern"/>
|
||||
</element>
|
||||
<architecture>
|
||||
<element name="Config" type="Layer">
|
||||
<element name="Assignment" type="TypeFilter">
|
||||
<element name="**.config.**" type="WeakTypePattern"/>
|
||||
</element>
|
||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Core"/>
|
||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Monitoring"/>
|
||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Repositories"/>
|
||||
</element>
|
||||
<element name="Repositories" type="Layer">
|
||||
<element name="Assignment" type="TypeFilter">
|
||||
<element name="**.repository.**" type="IncludeTypePattern"/>
|
||||
</element>
|
||||
<element name="API" type="Subsystem">
|
||||
<element name="Assignment" type="TypeFilter">
|
||||
<element name="**.repository.*" type="IncludeTypePattern"/>
|
||||
</element>
|
||||
</element>
|
||||
<element name="Query" type="Subsystem">
|
||||
<element name="Assignment" type="TypeFilter">
|
||||
<element name="**.query.**" type="IncludeTypePattern"/>
|
||||
</element>
|
||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Repositories::Subsystem|API"/>
|
||||
</element>
|
||||
<element name="Implementation" type="Subsystem">
|
||||
<element name="Assignment" type="TypeFilter">
|
||||
<element name="**.support.**" type="IncludeTypePattern"/>
|
||||
</element>
|
||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Repositories::Subsystem|API"/>
|
||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Repositories::Subsystem|Query"/>
|
||||
</element>
|
||||
<element name="Config" type="Subsystem">
|
||||
<element name="Assignment" type="TypeFilter">
|
||||
<element name="**.config.**" type="IncludeTypePattern"/>
|
||||
</element>
|
||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Repositories::Subsystem|Implementation"/>
|
||||
</element>
|
||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Core"/>
|
||||
</element>
|
||||
<element name="Monitoring" type="Layer">
|
||||
<element name="Assignment" type="TypeFilter">
|
||||
<element name="**.monitor.**" type="IncludeTypePattern"/>
|
||||
</element>
|
||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Core"/>
|
||||
</element>
|
||||
<element name="GridFS" type="Layer">
|
||||
<element name="Assignment" type="TypeFilter">
|
||||
<element name="**.gridfs.**" type="IncludeTypePattern"/>
|
||||
</element>
|
||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Core"/>
|
||||
</element>
|
||||
<element name="Core" type="Layer">
|
||||
<element name="Assignment" type="TypeFilter">
|
||||
<element name="**.core.**" type="IncludeTypePattern"/>
|
||||
</element>
|
||||
<element name="Mapping" type="Subsystem">
|
||||
<element name="Assignment" type="TypeFilter">
|
||||
<element name="**.mapping.**" type="IncludeTypePattern"/>
|
||||
</element>
|
||||
</element>
|
||||
<element name="Geospatial" type="Subsystem">
|
||||
<element name="Assignment" type="TypeFilter">
|
||||
<element name="**.geo.**" type="IncludeTypePattern"/>
|
||||
</element>
|
||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Mapping"/>
|
||||
</element>
|
||||
<element name="Query" type="Subsystem">
|
||||
<element name="Assignment" type="TypeFilter">
|
||||
<element name="**.query.**" type="IncludeTypePattern"/>
|
||||
</element>
|
||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Geospatial"/>
|
||||
</element>
|
||||
<element name="Index" type="Subsystem">
|
||||
<element name="Assignment" type="TypeFilter">
|
||||
<element name="**.index.**" type="IncludeTypePattern"/>
|
||||
</element>
|
||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Mapping"/>
|
||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Query"/>
|
||||
</element>
|
||||
<element name="Core" type="Subsystem">
|
||||
<element name="Assignment" type="TypeFilter">
|
||||
<element name="**.core.**" type="WeakTypePattern"/>
|
||||
</element>
|
||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Geospatial"/>
|
||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Index"/>
|
||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Mapping"/>
|
||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Query"/>
|
||||
</element>
|
||||
</element>
|
||||
</architecture>
|
||||
<workspace>
|
||||
<element name="src/main/java" type="JavaRootDirectory">
|
||||
<reference name="Project|spring-data-mongodb::BuildUnit|spring-data-mongodb"/>
|
||||
</element>
|
||||
<element name="target/classes" type="JavaRootDirectory">
|
||||
<reference name="Project|spring-data-mongodb::BuildUnit|spring-data-mongodb"/>
|
||||
</element>
|
||||
</workspace>
|
||||
<physical>
|
||||
<element name="spring-data-mongodb" type="BuildUnit"/>
|
||||
</physical>
|
||||
</scope>
|
||||
<scope name="External" type="External">
|
||||
<element name="Filter" type="TypeFilter">
|
||||
<element name="**" type="IncludeTypePattern"/>
|
||||
<element name="java.**" type="ExcludeTypePattern"/>
|
||||
<element name="javax.**" type="ExcludeTypePattern"/>
|
||||
</element>
|
||||
<architecture>
|
||||
<element name="Spring" type="Subsystem">
|
||||
<element name="Assignment" type="TypeFilter">
|
||||
<element name="org.springframework.**" type="IncludeTypePattern"/>
|
||||
<element name="org.springframework.data.**" type="ExcludeTypePattern"/>
|
||||
</element>
|
||||
</element>
|
||||
<element name="Spring Data Core" type="Subsystem">
|
||||
<element name="Assignment" type="TypeFilter">
|
||||
<element name="org.springframework.data.**" type="IncludeTypePattern"/>
|
||||
</element>
|
||||
</element>
|
||||
<element name="Mongo Java Driver" type="Subsystem">
|
||||
<element name="Assignment" type="TypeFilter">
|
||||
<element name="com.mongodb.**" type="IncludeTypePattern"/>
|
||||
<element name="org.bson.**" type="IncludeTypePattern"/>
|
||||
</element>
|
||||
</element>
|
||||
<element name="Querydsl" type="Subsystem">
|
||||
<element name="Assignment" type="TypeFilter">
|
||||
<element name="com.mysema.query.**" type="IncludeTypePattern"/>
|
||||
</element>
|
||||
</element>
|
||||
</architecture>
|
||||
</scope>
|
||||
<scope name="Global" type="Global">
|
||||
<element name="Configuration" type="Configuration"/>
|
||||
<element name="Filter" type="TypeFilter">
|
||||
<element name="**" type="IncludeTypePattern"/>
|
||||
</element>
|
||||
</scope>
|
||||
</context>
|
||||
291
spring-data-mongodb/etc/eclipse-formatter.xml
Normal file
291
spring-data-mongodb/etc/eclipse-formatter.xml
Normal file
@@ -0,0 +1,291 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<profiles version="12">
|
||||
<profile kind="CodeFormatterProfile" name="Spring Data" version="12">
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.source" value="1.7"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="120"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="2"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="tab"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="2"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.7"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="120"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.7"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
|
||||
</profile>
|
||||
</profiles>
|
||||
@@ -1,167 +1,155 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
|
||||
<name>Spring Data MongoDB - Core</name>
|
||||
<description>MongoDB support for Spring Data</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-document-parent</artifactId>
|
||||
<version>1.0.0.M2</version>
|
||||
<relativePath>../spring-data-document-parent/pom.xml</relativePath>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.2.0.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Data MongoDB Support</name>
|
||||
|
||||
<properties>
|
||||
<mongo.version>2.4</mongo.version>
|
||||
<validation>1.0.0.GA</validation>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
|
||||
<!-- Spring -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<version>${spring}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${spring}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<version>${spring}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>${spring}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-expression</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<scope>test</scope>
|
||||
<version>${spring}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring Data -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-document-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-commons-core</artifactId>
|
||||
<version>${data.commons.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- MongoDB -->
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongo-java-driver</artifactId>
|
||||
<version>${mongo.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>javax.persistence</groupId>
|
||||
<artifactId>persistence-api</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>spring-data-commons</artifactId>
|
||||
<version>${springdata.commons}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-mongodb</artifactId>
|
||||
<version>2.1.1</version>
|
||||
<version>${querydsl}</version>
|
||||
<optional>true</optional>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.google.code.morphia</groupId>
|
||||
<artifactId>morphia</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-apt</artifactId>
|
||||
<version>2.1.1</version>
|
||||
<version>${querydsl}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>jsr250-api</artifactId>
|
||||
<version>1.0</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- CDI -->
|
||||
<dependency>
|
||||
<groupId>javax.enterprise</groupId>
|
||||
<artifactId>cdi-api</artifactId>
|
||||
<version>${cdi}</version>
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.el</groupId>
|
||||
<artifactId>el-api</artifactId>
|
||||
<version>${cdi}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.openwebbeans.test</groupId>
|
||||
<artifactId>cditest-owb</artifactId>
|
||||
<version>${webbeans}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<version>2.5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- JSR 303 Validation -->
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
<version>${validation}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>jsr250-api</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!--
|
||||
<dependency>
|
||||
<groupId>javax.persistence</groupId>
|
||||
<artifactId>persistence-api</artifactId>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
-->
|
||||
|
||||
<!-- Test dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<version>4.2.0.Final</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-all</artifactId>
|
||||
<version>1.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>1.6</version>
|
||||
<version>${jodatime}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.springsource.bundlor</groupId>
|
||||
<artifactId>com.springsource.bundlor.maven</artifactId>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.mysema.maven</groupId>
|
||||
<artifactId>maven-apt-plugin</artifactId>
|
||||
<version>1.0</version>
|
||||
<version>1.0.4</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.mysema.querydsl</groupId>
|
||||
<artifactId>querydsl-apt</artifactId>
|
||||
<version>${querydsl}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>generate-test-sources</phase>
|
||||
@@ -169,23 +157,31 @@
|
||||
<goal>test-process</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>target/generated-sources/test-annotations</outputDirectory>
|
||||
<processor>org.springframework.data.document.mongodb.repository.MongoAnnotationProcessor</processor>
|
||||
<outputDirectory>target/generated-test-sources</outputDirectory>
|
||||
<processor>org.springframework.data.mongodb.repository.support.MongoAnnotationProcessor</processor>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.12</version>
|
||||
<configuration>
|
||||
<useFile>false</useFile>
|
||||
<includes>
|
||||
<include>**/*Tests.java</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>**/PerformanceTests.java</exclude>
|
||||
</excludes>
|
||||
<systemPropertyVariables>
|
||||
<java.util.logging.config.file>src/test/resources/logging.properties</java.util.logging.config.file>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>querydsl</id>
|
||||
<name>Mysema QueryDsl</name>
|
||||
<url>http://source.mysema.com/maven2/releases</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
</project>
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.mongodb;
|
||||
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
|
||||
public class CannotGetMongoDbConnectionException extends DataAccessResourceFailureException {
|
||||
|
||||
private String username;
|
||||
|
||||
private char[] password;
|
||||
|
||||
private String database;
|
||||
|
||||
private static final long serialVersionUID = 1172099106475265589L;
|
||||
|
||||
public CannotGetMongoDbConnectionException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
||||
public CannotGetMongoDbConnectionException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public CannotGetMongoDbConnectionException(String msg, String database, String username, char[] password2) {
|
||||
super(msg);
|
||||
this.username = username;
|
||||
this.password = password2;
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public char[] getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public String getDatabase() {
|
||||
return database;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.mongodb;
|
||||
|
||||
/**
|
||||
* Provides a simple wrapper to encapsulate the variety of settings you can use when creating a collection.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
*/
|
||||
public class CollectionOptions {
|
||||
|
||||
private Integer maxDocuments;
|
||||
|
||||
private Integer size;
|
||||
|
||||
private Boolean capped;
|
||||
|
||||
/**
|
||||
* Constructs a new <code>CollectionOptions</code> instance.
|
||||
*
|
||||
* @param size the collection size in bytes, this data space is preallocated
|
||||
* @param maxDocuments the maximum number of documents in the collection.
|
||||
* @param capped true to created a "capped" collection (fixed size with auto-FIFO behavior
|
||||
* based on insertion order), false otherwise.
|
||||
*/
|
||||
public CollectionOptions(Integer size, Integer maxDocuments, Boolean capped) {
|
||||
super();
|
||||
this.maxDocuments = maxDocuments;
|
||||
this.size = size;
|
||||
this.capped = capped;
|
||||
}
|
||||
|
||||
public Integer getMaxDocuments() {
|
||||
return maxDocuments;
|
||||
}
|
||||
|
||||
public void setMaxDocuments(Integer maxDocuments) {
|
||||
this.maxDocuments = maxDocuments;
|
||||
}
|
||||
|
||||
public Integer getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(Integer size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public Boolean getCapped() {
|
||||
return capped;
|
||||
}
|
||||
|
||||
public void setCapped(Boolean capped) {
|
||||
this.capped = capped;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
package org.springframework.data.document.mongodb;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.mongodb.DB;
|
||||
import org.springframework.transaction.support.ResourceHolderSupport;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
class DbHolder extends ResourceHolderSupport {
|
||||
private static final Object DEFAULT_KEY = new Object();
|
||||
|
||||
private final Map<Object, DB> dbMap = new ConcurrentHashMap<Object, DB>();
|
||||
|
||||
|
||||
public DbHolder(DB db) {
|
||||
addDB(db);
|
||||
}
|
||||
|
||||
public DbHolder(Object key, DB db) {
|
||||
addDB(key, db);
|
||||
}
|
||||
|
||||
|
||||
public DB getDB() {
|
||||
return getDB(DEFAULT_KEY);
|
||||
}
|
||||
|
||||
public DB getDB(Object key) {
|
||||
return this.dbMap.get(key);
|
||||
}
|
||||
|
||||
|
||||
public DB getAnyDB() {
|
||||
if (!this.dbMap.isEmpty()) {
|
||||
return this.dbMap.values().iterator().next();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addDB(DB session) {
|
||||
addDB(DEFAULT_KEY, session);
|
||||
}
|
||||
|
||||
public void addDB(Object key, DB session) {
|
||||
Assert.notNull(key, "Key must not be null");
|
||||
Assert.notNull(session, "DB must not be null");
|
||||
this.dbMap.put(key, session);
|
||||
}
|
||||
|
||||
public DB removeDB(Object key) {
|
||||
return this.dbMap.remove(key);
|
||||
}
|
||||
|
||||
public boolean containsDB(DB session) {
|
||||
return this.dbMap.containsValue(session);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this.dbMap.isEmpty();
|
||||
}
|
||||
|
||||
public boolean doesNotHoldNonDefaultDB() {
|
||||
synchronized (this.dbMap) {
|
||||
return this.dbMap.isEmpty() ||
|
||||
(this.dbMap.size() == 1 && this.dbMap.containsKey(DEFAULT_KEY));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.mongodb;
|
||||
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.Mongo;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.jmx.export.annotation.ManagedOperation;
|
||||
import org.springframework.jmx.export.annotation.ManagedResource;
|
||||
|
||||
/**
|
||||
* Mongo server administration exposed via JMX annotations
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*/
|
||||
|
||||
@ManagedResource(description = "Mongo Admin Operations")
|
||||
public class MongoAdmin implements MongoAdminOperations {
|
||||
|
||||
/**
|
||||
* Logger available to subclasses
|
||||
*/
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private Mongo mongo;
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
public MongoAdmin(Mongo mongo) {
|
||||
this.mongo = mongo;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.MongoAdminOperations#dropDatabase(java.lang.String)
|
||||
*/
|
||||
@ManagedOperation
|
||||
public void dropDatabase(String databaseName) {
|
||||
getDB(databaseName).dropDatabase();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.MongoAdminOperations#createDatabase(java.lang.String)
|
||||
*/
|
||||
@ManagedOperation
|
||||
public void createDatabase(String databaseName) {
|
||||
getDB(databaseName);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.MongoAdminOperations#getDatabaseStats(java.lang.String)
|
||||
*/
|
||||
@ManagedOperation
|
||||
public String getDatabaseStats(String databaseName) {
|
||||
return getDB(databaseName).getStats().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the username to use to connect to the Mongo database
|
||||
*
|
||||
* @param username The username to use
|
||||
*/
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the password to use to authenticate with the Mongo database.
|
||||
*
|
||||
* @param password The password to use
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
|
||||
DB getDB(String databaseName) {
|
||||
return MongoDbUtils.getDB(mongo, databaseName, username, password == null ? null : password.toCharArray());
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package org.springframework.data.document.mongodb;
|
||||
|
||||
import org.springframework.jmx.export.annotation.ManagedOperation;
|
||||
|
||||
public interface MongoAdminOperations {
|
||||
|
||||
@ManagedOperation
|
||||
public abstract void dropDatabase(String databaseName);
|
||||
|
||||
@ManagedOperation
|
||||
public abstract void createDatabase(String databaseName);
|
||||
|
||||
@ManagedOperation
|
||||
public abstract String getDatabaseStats(String databaseName);
|
||||
|
||||
}
|
||||
@@ -1,168 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.document.mongodb;
|
||||
|
||||
import com.mongodb.CommandResult;
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.Mongo;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Helper class featuring helper methods for internal MongoDb classes.
|
||||
* <p/>
|
||||
* <p>Mainly intended for internal use within the framework.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Graeme Rocher
|
||||
* @author Oliver Gierke
|
||||
* @since 1.0
|
||||
*/
|
||||
public abstract class MongoDbUtils {
|
||||
|
||||
private static final Log LOGGER = LogFactory.getLog(MongoDbUtils.class);
|
||||
|
||||
/**
|
||||
* Private constructor to prevent instantiation.
|
||||
*/
|
||||
private MongoDbUtils() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains a {@link DB} connection for the given {@link Mongo} instance and database name
|
||||
*
|
||||
* @param mongo The {@link Mongo} instance
|
||||
* @param databaseName The database name
|
||||
* @return The {@link DB} connection
|
||||
*/
|
||||
public static DB getDB(Mongo mongo, String databaseName) {
|
||||
return doGetDB(mongo, databaseName, null, null, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains a {@link DB} connection for the given {@link Mongo} instance and database name
|
||||
*
|
||||
* @param mongo The {@link Mongo} instance
|
||||
* @param databaseName The database name
|
||||
* @param username The username to authenticate with
|
||||
* @param password The password to authenticate with
|
||||
* @return The {@link DB} connection
|
||||
*/
|
||||
public static DB getDB(Mongo mongo, String databaseName, String username, char[] password) {
|
||||
return doGetDB(mongo, databaseName, username, password, true);
|
||||
}
|
||||
|
||||
public static DB doGetDB(Mongo mongo, String databaseName, String username, char[] password, boolean allowCreate) {
|
||||
Assert.notNull(mongo, "No Mongo instance specified");
|
||||
|
||||
DbHolder dbHolder = (DbHolder) TransactionSynchronizationManager.getResource(mongo);
|
||||
if (dbHolder != null && !dbHolder.isEmpty()) {
|
||||
// pre-bound Mongo DB
|
||||
DB db = null;
|
||||
if (TransactionSynchronizationManager.isSynchronizationActive() &&
|
||||
dbHolder.doesNotHoldNonDefaultDB()) {
|
||||
// Spring transaction management is active ->
|
||||
db = dbHolder.getDB();
|
||||
if (db != null && !dbHolder.isSynchronizedWithTransaction()) {
|
||||
LOGGER.debug("Registering Spring transaction synchronization for existing Mongo DB");
|
||||
TransactionSynchronizationManager.registerSynchronization(new MongoSynchronization(dbHolder, mongo));
|
||||
dbHolder.setSynchronizedWithTransaction(true);
|
||||
}
|
||||
}
|
||||
if (db != null) {
|
||||
return db;
|
||||
}
|
||||
}
|
||||
|
||||
LOGGER.trace("Getting Mongo Database name=["+databaseName+"]");
|
||||
DB db = mongo.getDB(databaseName);
|
||||
|
||||
boolean credentialsGiven = username != null && password != null;
|
||||
if (credentialsGiven && !db.isAuthenticated()) {
|
||||
//Note, can only authenticate once against the same com.mongodb.DB object.
|
||||
if (!db.authenticate(username, password)) {
|
||||
throw new CannotGetMongoDbConnectionException("Failed to authenticate to database [" + databaseName +
|
||||
"], username = [" + username + "], password = [" + new String(password) + "]", databaseName, username, password );
|
||||
}
|
||||
}
|
||||
|
||||
// Use same Session for further Mongo actions within the transaction.
|
||||
// Thread object will get removed by synchronization at transaction completion.
|
||||
if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||
// We're within a Spring-managed transaction, possibly from JtaTransactionManager.
|
||||
LOGGER.debug("Registering Spring transaction synchronization for new Hibernate Session");
|
||||
DbHolder holderToUse = dbHolder;
|
||||
if (holderToUse == null) {
|
||||
holderToUse = new DbHolder(db);
|
||||
} else {
|
||||
holderToUse.addDB(db);
|
||||
}
|
||||
TransactionSynchronizationManager.registerSynchronization(new MongoSynchronization(holderToUse, mongo));
|
||||
holderToUse.setSynchronizedWithTransaction(true);
|
||||
if (holderToUse != dbHolder) {
|
||||
TransactionSynchronizationManager.bindResource(mongo, holderToUse);
|
||||
}
|
||||
}
|
||||
|
||||
// Check whether we are allowed to return the DB.
|
||||
if (!allowCreate && !isDBTransactional(db, mongo)) {
|
||||
throw new IllegalStateException("No Mongo DB bound to thread, " +
|
||||
"and configuration does not allow creation of non-transactional one here");
|
||||
}
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return whether the given DB instance is transactional, that is,
|
||||
* bound to the current thread by Spring's transaction facilities.
|
||||
*
|
||||
* @param db the DB to check
|
||||
* @param mongo the Mongo instance that the DB was created with
|
||||
* (may be <code>null</code>)
|
||||
* @return whether the DB is transactional
|
||||
*/
|
||||
public static boolean isDBTransactional(DB db, Mongo mongo) {
|
||||
if (mongo == null) {
|
||||
return false;
|
||||
}
|
||||
DbHolder dbHolder =
|
||||
(DbHolder) TransactionSynchronizationManager.getResource(mongo);
|
||||
return (dbHolder != null && dbHolder.containsDB(db));
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform actual closing of the Mongo DB object,
|
||||
* catching and logging any cleanup exceptions thrown.
|
||||
*
|
||||
* @param db the DB to close (may be <code>null</code>)
|
||||
*/
|
||||
public static void closeDB(DB db) {
|
||||
if (db != null) {
|
||||
LOGGER.debug("Closing Mongo DB object");
|
||||
try {
|
||||
db.requestDone();
|
||||
} catch (Throwable ex) {
|
||||
LOGGER.debug("Unexpected exception on closing Mongo DB object", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.mongodb;
|
||||
|
||||
import com.mongodb.MongoException;
|
||||
import com.mongodb.MongoException.CursorNotFound;
|
||||
import com.mongodb.MongoException.DuplicateKey;
|
||||
import com.mongodb.MongoException.Network;
|
||||
import com.mongodb.MongoInternalException;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.dao.InvalidDataAccessResourceUsageException;
|
||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||
import org.springframework.data.document.UncategorizedDocumentStoreException;
|
||||
|
||||
/**
|
||||
* Simple {@link PersistenceExceptionTranslator} for Mongo. Convert the given runtime exception to an appropriate
|
||||
* exception from the {@code org.springframework.dao} hierarchy. Return {@literal null} if no translation is
|
||||
* appropriate: any other exception may have resulted from user code, and should not be translated.
|
||||
*
|
||||
* @param ex runtime exception that occurred
|
||||
* @author Oliver Gierke
|
||||
* @return the corresponding DataAccessException instance, or {@literal null} if the exception should not be translated
|
||||
*/
|
||||
public class MongoExceptionTranslator implements PersistenceExceptionTranslator {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.dao.support.PersistenceExceptionTranslator#
|
||||
* translateExceptionIfPossible(java.lang.RuntimeException)
|
||||
*/
|
||||
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
|
||||
|
||||
// Check for well-known MongoException subclasses.
|
||||
|
||||
// All other MongoExceptions
|
||||
if (ex instanceof DuplicateKey) {
|
||||
return new DuplicateKeyException(ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof Network) {
|
||||
return new DataAccessResourceFailureException(ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof CursorNotFound) {
|
||||
return new DataAccessResourceFailureException(ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof MongoException) {
|
||||
int code = ((MongoException)ex).getCode();
|
||||
if (code == 11000 || code == 11001) {
|
||||
throw new DuplicateKeyException(ex.getMessage(), ex);
|
||||
} else if (code == 12000 || code == 13440) {
|
||||
throw new DataAccessResourceFailureException(ex.getMessage(), ex);
|
||||
} else if (code == 10003 || code == 12001 || code == 12010 || code == 12011 || code == 12012 ) {
|
||||
throw new InvalidDataAccessApiUsageException(ex.getMessage(), ex);
|
||||
}
|
||||
return new UncategorizedDocumentStoreException(ex.getMessage(), ex);
|
||||
}
|
||||
if (ex instanceof MongoInternalException) {
|
||||
return new InvalidDataAccessResourceUsageException(ex.getMessage(), ex);
|
||||
}
|
||||
|
||||
// If we get here, we have an exception that resulted from user code,
|
||||
// rather than the persistence provider, so we return null to indicate
|
||||
// that translation should not occur.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.document.mongodb;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.MongoOptions;
|
||||
import com.mongodb.ServerAddress;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Convenient factory for configuring MongoDB.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Graeme Rocher
|
||||
* @since 1.0
|
||||
*/
|
||||
public class MongoFactoryBean implements FactoryBean<Mongo>, InitializingBean, PersistenceExceptionTranslator {
|
||||
|
||||
|
||||
/**
|
||||
* Logger, available to subclasses.
|
||||
*/
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private Mongo mongo;
|
||||
private MongoOptions mongoOptions;
|
||||
private String host;
|
||||
private Integer port;
|
||||
private List<ServerAddress> replicaSetSeeds;
|
||||
private List<ServerAddress> replicaPair;
|
||||
|
||||
private PersistenceExceptionTranslator exceptionTranslator = new MongoExceptionTranslator();
|
||||
|
||||
public void setMongoOptions(MongoOptions mongoOptions) {
|
||||
this.mongoOptions = mongoOptions;
|
||||
}
|
||||
|
||||
public void setReplicaSetSeeds(List<ServerAddress> replicaSetSeeds) {
|
||||
this.replicaSetSeeds = replicaSetSeeds;
|
||||
}
|
||||
|
||||
public void setReplicaPair(List<ServerAddress> replicaPair) {
|
||||
this.replicaPair = replicaPair;
|
||||
}
|
||||
|
||||
public void setHost(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public PersistenceExceptionTranslator getExceptionTranslator() {
|
||||
return exceptionTranslator;
|
||||
}
|
||||
|
||||
public void setExceptionTranslator(
|
||||
PersistenceExceptionTranslator exceptionTranslator) {
|
||||
this.exceptionTranslator = exceptionTranslator;
|
||||
}
|
||||
|
||||
public Mongo getObject() throws Exception {
|
||||
Assert.notNull(mongo, "Mongo must not be null");
|
||||
return mongo;
|
||||
}
|
||||
|
||||
public Class<? extends Mongo> getObjectType() {
|
||||
return Mongo.class;
|
||||
}
|
||||
|
||||
public boolean isSingleton() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
// apply defaults - convenient when used to configure for tests
|
||||
// in an application context
|
||||
if (mongo == null) {
|
||||
|
||||
if (host == null) {
|
||||
logger.warn("Property host not specified. Using default configuration");
|
||||
mongo = new Mongo();
|
||||
} else {
|
||||
ServerAddress defaultOptions = new ServerAddress();
|
||||
if (mongoOptions == null) mongoOptions = new MongoOptions();
|
||||
if (replicaPair != null) {
|
||||
if (replicaPair.size() < 2) {
|
||||
throw new CannotGetMongoDbConnectionException("A replica pair must have two server entries");
|
||||
}
|
||||
mongo = new Mongo(replicaPair.get(0), replicaPair.get(1), mongoOptions);
|
||||
} else if (replicaSetSeeds != null) {
|
||||
mongo = new Mongo(replicaSetSeeds, mongoOptions);
|
||||
} else {
|
||||
String mongoHost = host != null ? host : defaultOptions.getHost();
|
||||
if (port != null) {
|
||||
mongo = new Mongo(new ServerAddress(mongoHost, port), mongoOptions);
|
||||
} else {
|
||||
mongo = new Mongo(mongoHost, mongoOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
|
||||
return exceptionTranslator.translateExceptionIfPossible(ex);
|
||||
}
|
||||
}
|
||||
@@ -1,735 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.mongodb;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.mongodb.CommandResult;
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.WriteResult;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
import org.springframework.data.document.mongodb.index.IndexDefinition;
|
||||
import org.springframework.data.document.mongodb.query.Query;
|
||||
import org.springframework.data.document.mongodb.query.Update;
|
||||
|
||||
/**
|
||||
* Interface that specifies a basic set of MongoDB operations. Implemented by {@link MongoTemplate}.
|
||||
* Not often used but a useful option for extensibility and testability (as it can be easily mocked, stubbed, or be
|
||||
* the target of a JDK proxy).
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Mark Pollack
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface MongoOperations {
|
||||
|
||||
/**
|
||||
* The default collection name used by this template.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getDefaultCollectionName();
|
||||
|
||||
/**
|
||||
* The default collection used by this template.
|
||||
*
|
||||
* @return The default collection used by this template
|
||||
*/
|
||||
DBCollection getDefaultCollection();
|
||||
|
||||
/**
|
||||
* Execute the a MongoDB command expressed as a JSON string. This will call the method
|
||||
* JSON.parse that is part of the MongoDB driver to convert the JSON string to a DBObject.
|
||||
* Any errors that result from executing this command will be converted into Spring's DAO
|
||||
* exception hierarchy.
|
||||
*
|
||||
* @param jsonCommand a MongoDB command expressed as a JSON string.
|
||||
*/
|
||||
CommandResult executeCommand(String jsonCommand);
|
||||
|
||||
/**
|
||||
* Execute a MongoDB command. Any errors that result from executing this command will be converted
|
||||
* into Spring's DAO exception hierarchy.
|
||||
*
|
||||
* @param command a MongoDB command
|
||||
*/
|
||||
CommandResult executeCommand(DBObject command);
|
||||
|
||||
/**
|
||||
* Executes a {@link DbCallback} translating any exceptions as necessary.
|
||||
* <p/>
|
||||
* Allows for returning a result object, that is a domain object or a collection of domain objects.
|
||||
*
|
||||
* @param <T> return type
|
||||
* @param action callback object that specifies the MongoDB actions to perform on the passed in DB instance.
|
||||
* @return a result object returned by the action or <tt>null</tt>
|
||||
*/
|
||||
<T> T execute(DbCallback<T> action);
|
||||
|
||||
/**
|
||||
* Executes the given {@link CollectionCallback} on the default collection.
|
||||
* <p/>
|
||||
* Allows for returning a result object, that is a domain object or a collection of domain objects.
|
||||
*
|
||||
* @param <T> return type
|
||||
* @param action callback object that specifies the MongoDB action
|
||||
* @return a result object returned by the action or <tt>null</tt>
|
||||
*/
|
||||
<T> T execute(CollectionCallback<T> action);
|
||||
|
||||
/**
|
||||
* Executes the given {@link CollectionCallback} on the collection of the given name.
|
||||
* <p/>
|
||||
* Allows for returning a result object, that is a domain object or a collection of domain objects.
|
||||
*
|
||||
* @param <T> return type
|
||||
* @param collectionName the name of the collection that specifies which DBCollection instance will be passed into
|
||||
* @param action callback object that specifies the MongoDB action
|
||||
* the callback action.
|
||||
* @return a result object returned by the action or <tt>null</tt>
|
||||
*/
|
||||
<T> T execute(String collectionName, CollectionCallback<T> action);
|
||||
|
||||
/**
|
||||
* Executes the given {@link DbCallback} within the same connection to the database so as to ensure
|
||||
* consistency in a write heavy environment where you may read the data that you wrote. See the
|
||||
* comments on {@see <a href=http://www.mongodb.org/display/DOCS/Java+Driver+Concurrency>Java Driver Concurrency</a>}
|
||||
* <p/>
|
||||
* Allows for returning a result object, that is a domain object or a collection of domain objects.
|
||||
*
|
||||
* @param <T> return type
|
||||
* @param action callback that specified the MongoDB actions to perform on the DB instance
|
||||
* @return a result object returned by the action or <tt>null</tt>
|
||||
*/
|
||||
<T> T executeInSession(DbCallback<T> action);
|
||||
|
||||
/**
|
||||
* Create an uncapped collection with the provided name.
|
||||
*
|
||||
* @param collectionName name of the collection
|
||||
* @return the created collection
|
||||
*/
|
||||
DBCollection createCollection(String collectionName);
|
||||
|
||||
/**
|
||||
* Create a collect with the provided name and options.
|
||||
*
|
||||
* @param collectionName name of the collection
|
||||
* @param collectionOptions options to use when creating the collection.
|
||||
* @return the created collection
|
||||
*/
|
||||
DBCollection createCollection(String collectionName, CollectionOptions collectionOptions);
|
||||
|
||||
/**
|
||||
* A set of collection names.
|
||||
*
|
||||
* @return list of collection names
|
||||
*/
|
||||
Set<String> getCollectionNames();
|
||||
|
||||
/**
|
||||
* Get a collection by name, creating it if it doesn't exist.
|
||||
* <p/>
|
||||
* Translate any exceptions as necessary.
|
||||
*
|
||||
* @param collectionName name of the collection
|
||||
* @return an existing collection or a newly created one.
|
||||
*/
|
||||
DBCollection getCollection(String collectionName);
|
||||
|
||||
/**
|
||||
* Check to see if a collection with a given name exists.
|
||||
* <p/>
|
||||
* Translate any exceptions as necessary.
|
||||
*
|
||||
* @param collectionName name of the collection
|
||||
* @return true if a collection with the given name is found, false otherwise.
|
||||
*/
|
||||
boolean collectionExists(String collectionName);
|
||||
|
||||
/**
|
||||
* Drop the collection with the given name.
|
||||
* <p/>
|
||||
* Translate any exceptions as necessary.
|
||||
*
|
||||
* @param collectionName name of the collection to drop/delete.
|
||||
*/
|
||||
void dropCollection(String collectionName);
|
||||
|
||||
/**
|
||||
* Query for a list of objects of type T from the default collection.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* If your collection does not contain a homogeneous collection of types, this operation will not be an efficient
|
||||
* way to map objects since the test for class type is done in the client and not on the server.
|
||||
*
|
||||
* @param targetClass the parameterized type of the returned list
|
||||
* @return the converted collection
|
||||
*/
|
||||
<T> List<T> getCollection(Class<T> targetClass);
|
||||
|
||||
/**
|
||||
* Query for a list of objects of type T from the specified collection.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* If your collection does not contain a homogeneous collection of types, this operation will not be an efficient
|
||||
* way to map objects since the test for class type is done in the client and not on the server.
|
||||
*
|
||||
* @param collectionName name of the collection to retrieve the objects from
|
||||
* @param targetClass the parameterized type of the returned list.
|
||||
* @return the converted collection
|
||||
*/
|
||||
<T> List<T> getCollection(String collectionName, Class<T> targetClass);
|
||||
|
||||
/**
|
||||
* Query for a list of objects of type T from the specified collection, mapping the DBObject using
|
||||
* the provided MongoReader.
|
||||
*
|
||||
* @param collectionName name of the collection to retrieve the objects from
|
||||
* @param targetClass the parameterized type of the returned list.
|
||||
* @param reader the MongoReader to convert from DBObject to an object.
|
||||
* @return the converted collection
|
||||
*/
|
||||
<T> List<T> getCollection(String collectionName, Class<T> targetClass,
|
||||
MongoReader<T> reader);
|
||||
|
||||
/**
|
||||
* Ensure that an index for the provided {@link IndexDefinition} exists for the default collection.
|
||||
* If not it will be created.
|
||||
*
|
||||
* @param index
|
||||
*/
|
||||
void ensureIndex(IndexDefinition indexDefinition);
|
||||
|
||||
/**
|
||||
* Ensure that an index for the provided {@link IndexDefinition} exists. If not it will be
|
||||
* created.
|
||||
*
|
||||
* @param collectionName
|
||||
* @param index
|
||||
*/
|
||||
void ensureIndex(String collectionName, IndexDefinition indexDefinition);
|
||||
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the default MongoDB collection to a single instance of an object
|
||||
* of the specified type.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
*
|
||||
* @param query the query class that specifies the criteria used to find a record and also an optional fields specification
|
||||
* @param targetClass the parameterized type of the returned list.
|
||||
* @return the converted object
|
||||
*/
|
||||
<T> T findOne(Query query, Class<T> targetClass);
|
||||
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the default MongoDB collection to a single instance of an object
|
||||
* of the specified type.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
*
|
||||
* @param query the query class that specifies the criteria used to find a record and also an optional fields specification
|
||||
* @param targetClass the parameterized type of the returned list.
|
||||
* @param reader the MongoReader to convert from DBObject to an object.
|
||||
* @return the converted object
|
||||
*/
|
||||
<T> T findOne(Query query, Class<T> targetClass,
|
||||
MongoReader<T> reader);
|
||||
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the specified collection to a single instance of an object
|
||||
* of the specified type.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
*
|
||||
* @param collectionName name of the collection to retrieve the objects from
|
||||
* @param query the query class that specifies the criteria used to find a record and also an optional fields specification
|
||||
* @param targetClass the parameterized type of the returned list.
|
||||
* @return the converted object
|
||||
*/
|
||||
<T> T findOne(String collectionName, Query query,
|
||||
Class<T> targetClass);
|
||||
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the specified collection to a single instance of an object
|
||||
* of the specified type.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
*
|
||||
* @param collectionName name of the collection to retrieve the objects from
|
||||
* @param query the query class that specifies the criteria used to find a record and also an optional fields specification
|
||||
* @param targetClass the parameterized type of the returned list.
|
||||
* @param reader the MongoReader to convert from DBObject to an object.
|
||||
* @return the converted object
|
||||
*/
|
||||
<T> T findOne(String collectionName, Query query,
|
||||
Class<T> targetClass, MongoReader<T> reader);
|
||||
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the default MongoDB collection to a List of the specified type.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
*
|
||||
* @param query the query class that specifies the criteria used to find a record and also an optional fields specification
|
||||
* @param targetClass the parameterized type of the returned list.
|
||||
* @return the List of converted objects
|
||||
*/
|
||||
<T> List<T> find(Query query, Class<T> targetClass);
|
||||
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the default MongoDB collection to a List of the specified type.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
*
|
||||
* @param query the query class that specifies the criteria used to find a record and also an optional fields specification
|
||||
* @param targetClass the parameterized type of the returned list.
|
||||
* @param reader the MongoReader to convert from DBObject to an object.
|
||||
* @return the List of converted objects
|
||||
*/
|
||||
<T> List<T> find(Query query, Class<T> targetClass,
|
||||
MongoReader<T> reader);
|
||||
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the specified collection to a List of the specified type.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
*
|
||||
* @param collectionName name of the collection to retrieve the objects from
|
||||
* @param query the query class that specifies the criteria used to find a record and also an optional fields specification
|
||||
* @param targetClass the parameterized type of the returned list.
|
||||
* @return the List of converted objects
|
||||
*/
|
||||
<T> List<T> find(String collectionName, Query query,
|
||||
Class<T> targetClass);
|
||||
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the specified collection to a List of the specified type.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
*
|
||||
* @param collectionName name of the collection to retrieve the objects from
|
||||
* @param query the query class that specifies the criteria used to find a record and also an optional fields specification
|
||||
* @param targetClass the parameterized type of the returned list.
|
||||
* @param reader the MongoReader to convert from DBObject to an object.
|
||||
* @return the List of converted objects
|
||||
*/
|
||||
<T> List<T> find(String collectionName, Query query,
|
||||
Class<T> targetClass, MongoReader<T> reader);
|
||||
|
||||
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the specified collection to a List of the specified type.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
*
|
||||
* @param collectionName name of the collection to retrieve the objects from
|
||||
* @param query the query class that specifies the criteria used to find a record and also an optional fields specification
|
||||
* @param targetClass the parameterized type of the returned list.
|
||||
* @param preparer allows for customization of the DBCursor used when iterating over the result set,
|
||||
* (apply limits, skips and so on).
|
||||
* @return the List of converted objects.
|
||||
*/
|
||||
<T> List<T> find(String collectionName, Query query, Class<T> targetClass, CursorPreparer preparer);
|
||||
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the default MongoDB collection to a single instance of an object
|
||||
* of the specified type. The first document that matches the query is returned and also removed from the
|
||||
* collection in the database.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
*
|
||||
* @param query the query class that specifies the criteria used to find a record and also an optional fields specification
|
||||
* @param targetClass the parameterized type of the returned list.
|
||||
* @return the converted object
|
||||
*/
|
||||
<T> T findAndRemove(Query query, Class<T> targetClass);
|
||||
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the default MongoDB collection to a single instance of an object
|
||||
* of the specified type. The first document that matches the query is returned and also removed from the
|
||||
* collection in the database.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
*
|
||||
* @param query the query class that specifies the criteria used to find a record and also an optional fields specification
|
||||
* @param targetClass the parameterized type of the returned list.
|
||||
* @param reader the MongoReader to convert from DBObject to an object.
|
||||
* @return the converted object
|
||||
*/
|
||||
<T> T findAndRemove(Query query, Class<T> targetClass,
|
||||
MongoReader<T> reader);
|
||||
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the specified collection to a single instance of an object
|
||||
* of the specified type. The first document that matches the query is returned and also removed from the
|
||||
* collection in the database.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
*
|
||||
* @param collectionName name of the collection to retrieve the objects from
|
||||
* @param query the query class that specifies the criteria used to find a record and also an optional fields specification
|
||||
* @param targetClass the parameterized type of the returned list.
|
||||
* @return the converted object
|
||||
*/
|
||||
<T> T findAndRemove(String collectionName, Query query,
|
||||
Class<T> targetClass);
|
||||
|
||||
/**
|
||||
* Map the results of an ad-hoc query on the specified collection to a single instance of an object
|
||||
* of the specified type. The first document that matches the query is returned and also removed from the
|
||||
* collection in the database.
|
||||
* <p/>
|
||||
* The object is converted from the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
|
||||
* feature rich {@link Query}.
|
||||
*
|
||||
* @param collectionName name of the collection to retrieve the objects from
|
||||
* @param query the query class that specifies the criteria used to find a record and also an optional fields specification
|
||||
* @param targetClass the parameterized type of the returned list.
|
||||
* @param reader the MongoReader to convert from DBObject to an object.
|
||||
* @return the converted object
|
||||
*/
|
||||
<T> T findAndRemove(String collectionName, Query query,
|
||||
Class<T> targetClass, MongoReader<T> reader);
|
||||
|
||||
/**
|
||||
* Insert the object into the default collection.
|
||||
* <p/>
|
||||
* The object is converted to the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* If you object has an "Id' property, it will be set with the generated Id from MongoDB. If your Id property
|
||||
* is a String then MongoDB ObjectId will be used to populate that string. Otherwise, the conversion from
|
||||
* ObjectId to your property type will be handled by Spring's BeanWrapper class that leverages Spring 3.0's
|
||||
* new Type Conversion API.
|
||||
* See <a href="http://static.springsource.org/spring/docs/3.0.x/reference/validation.html#core-convert">Spring 3 Type Conversion"</a>
|
||||
* for more details.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* Insert is used to initially store the object into the database.
|
||||
* To update an existing object use the save method.
|
||||
*
|
||||
* @param objectToSave the object to store in the collection.
|
||||
*/
|
||||
void insert(Object objectToSave);
|
||||
|
||||
/**
|
||||
* Insert the object into the specified collection.
|
||||
* <p/>
|
||||
* The object is converted to the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* Insert is used to initially store the object into the
|
||||
* database. To update an existing object use the save method.
|
||||
*
|
||||
* @param collectionName name of the collection to store the object in
|
||||
* @param objectToSave the object to store in the collection
|
||||
*/
|
||||
void insert(String collectionName, Object objectToSave);
|
||||
|
||||
/**
|
||||
* Insert the object into the default collection.
|
||||
* <p/>
|
||||
* The object is converted to the MongoDB native representation using an instance of
|
||||
* {@see MongoWriter}
|
||||
* <p/>
|
||||
* Insert is used to initially store the object into the
|
||||
* database. To update an existing object use the save method.
|
||||
*
|
||||
* @param <T> the type of the object to insert
|
||||
* @param objectToSave the object to store in the collection
|
||||
* @param writer the writer to convert the object to save into a DBObject
|
||||
*/
|
||||
<T> void insert(T objectToSave, MongoWriter<T> writer);
|
||||
|
||||
/**
|
||||
* Insert the object into the specified collection.
|
||||
* <p/>
|
||||
* The object is converted to the MongoDB native representation using an instance of
|
||||
* {@see MongoWriter}
|
||||
* <p/>
|
||||
* Insert is used to initially store the object into the
|
||||
* database. To update an existing object use the save method.
|
||||
*
|
||||
* @param <T> the type of the object to insert
|
||||
* @param collectionName name of the collection to store the object in
|
||||
* @param objectToSave the object to store in the collection
|
||||
* @param writer the writer to convert the object to save into a DBObject
|
||||
*/
|
||||
<T> void insert(String collectionName, T objectToSave, MongoWriter<T> writer);
|
||||
|
||||
/**
|
||||
* Insert a list of objects into the default collection in a single batch write to the database.
|
||||
*
|
||||
* @param listToSave the list of objects to save.
|
||||
*/
|
||||
void insertList(List<? extends Object> listToSave);
|
||||
|
||||
/**
|
||||
* Insert a list of objects into the specified collection in a single batch write to the database.
|
||||
*
|
||||
* @param collectionName name of the collection to store the object in
|
||||
* @param listToSave the list of objects to save.
|
||||
*/
|
||||
void insertList(String collectionName, List<? extends Object> listToSave);
|
||||
|
||||
/**
|
||||
* Insert a list of objects into the default collection using the provided MongoWriter instance
|
||||
*
|
||||
* @param <T> the type of object being saved
|
||||
* @param listToSave the list of objects to save.
|
||||
* @param writer the writer to convert the object to save into a DBObject
|
||||
*/
|
||||
<T> void insertList(List<? extends T> listToSave, MongoWriter<T> writer);
|
||||
|
||||
/**
|
||||
* Insert a list of objects into the specified collection using the provided MongoWriter instance
|
||||
*
|
||||
* @param <T> the type of object being saved
|
||||
* @param collectionName name of the collection to store the object in
|
||||
* @param listToSave the list of objects to save.
|
||||
* @param writer the writer to convert the object to save into a DBObject
|
||||
*/
|
||||
<T> void insertList(String collectionName, List<? extends T> listToSave, MongoWriter<T> writer);
|
||||
|
||||
/**
|
||||
* Save the object to the default collection. This will perform an insert if the object is not already
|
||||
* present, that is an 'upsert'.
|
||||
* <p/>
|
||||
* The object is converted to the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* If you object has an "Id' property, it will be set with the generated Id from MongoDB. If your Id property
|
||||
* is a String then MongoDB ObjectId will be used to populate that string. Otherwise, the conversion from
|
||||
* ObjectId to your property type will be handled by Spring's BeanWrapper class that leverages Spring 3.0's
|
||||
* new Type Conversion API.
|
||||
* See <a href="http://static.springsource.org/spring/docs/3.0.x/reference/validation.html#core-convert">Spring 3 Type Conversion"</a>
|
||||
* for more details.
|
||||
*
|
||||
* @param objectToSave the object to store in the collection
|
||||
*/
|
||||
void save(Object objectToSave);
|
||||
|
||||
/**
|
||||
* Save the object to the specified collection. This will perform an insert if the object is not already
|
||||
* present, that is an 'upsert'.
|
||||
* <p/>
|
||||
* The object is converted to the MongoDB native representation using an instance of
|
||||
* {@see MongoConverter}. Unless configured otherwise, an
|
||||
* instance of SimpleMongoConverter will be used.
|
||||
* <p/>
|
||||
* If you object has an "Id' property, it will be set with the generated Id from MongoDB. If your Id property
|
||||
* is a String then MongoDB ObjectId will be used to populate that string. Otherwise, the conversion from
|
||||
* ObjectId to your property type will be handled by Spring's BeanWrapper class that leverages Spring 3.0's
|
||||
* new Type Cobnversion API.
|
||||
* See <a href="http://static.springsource.org/spring/docs/3.0.x/reference/validation.html#core-convert">Spring 3 Type Conversion"</a>
|
||||
* for more details.
|
||||
*
|
||||
* @param collectionName name of the collection to store the object in
|
||||
* @param objectToSave the object to store in the collection
|
||||
*/
|
||||
void save(String collectionName, Object objectToSave);
|
||||
|
||||
/**
|
||||
* Save the object into the default collection using the provided writer.
|
||||
* This will perform an insert if the object is not already
|
||||
* present, that is an 'upsert'.
|
||||
* <p/>
|
||||
* The object is converted to the MongoDB native representation using an instance of
|
||||
* {@see MongoWriter}
|
||||
*
|
||||
* @param <T> the type of the object to insert
|
||||
* @param objectToSave the object to store in the collection
|
||||
* @param writer the writer to convert the object to save into a DBObject
|
||||
*/
|
||||
<T> void save(T objectToSave, MongoWriter<T> writer);
|
||||
|
||||
/**
|
||||
* Save the object into the specified collection using the provided writer.
|
||||
* This will perform an insert if the object is not already
|
||||
* present, that is an 'upsert'.
|
||||
* <p/>
|
||||
* The object is converted to the MongoDB native representation using an instance of
|
||||
* {@see MongoWriter}
|
||||
*
|
||||
* @param <T> the type of the object to insert
|
||||
* @param collectionName name of the collection to store the object in
|
||||
* @param objectToSave the object to store in the collection
|
||||
* @param writer the writer to convert the object to save into a DBObject
|
||||
*/
|
||||
<T> void save(String collectionName, T objectToSave, MongoWriter<T> writer);
|
||||
|
||||
/**
|
||||
* Updates the first object that is found in the default collection that matches the query document
|
||||
* with the provided updated document.
|
||||
*
|
||||
* @param queryDoc the query document that specifies the criteria used to select a record to be updated
|
||||
* @param updateDoc the update document that contains the updated object or $ operators to manipulate the
|
||||
* existing object.
|
||||
*/
|
||||
WriteResult updateFirst(Query query, Update update);
|
||||
|
||||
/**
|
||||
* Updates the first object that is found in the specified collection that matches the query document criteria
|
||||
* with the provided updated document.
|
||||
*
|
||||
* @param collectionName name of the collection to update the object in
|
||||
* @param queryDoc the query document that specifies the criteria used to select a record to be updated
|
||||
* @param updateDoc the update document that contains the updated object or $ operators to manipulate the
|
||||
* existing object.
|
||||
*/
|
||||
WriteResult updateFirst(String collectionName, Query query,
|
||||
Update update);
|
||||
|
||||
/**
|
||||
* Updates all objects that are found in the default collection that matches the query document criteria
|
||||
* with the provided updated document.
|
||||
*
|
||||
* @param queryDoc the query document that specifies the criteria used to select a record to be updated
|
||||
* @param updateDoc the update document that contains the updated object or $ operators to manipulate the
|
||||
* existing object.
|
||||
*/
|
||||
WriteResult updateMulti(Query query, Update update);
|
||||
|
||||
/**
|
||||
* Updates all objects that are found in the specified collection that matches the query document criteria
|
||||
* with the provided updated document.
|
||||
*
|
||||
* @param collectionName name of the collection to update the object in
|
||||
* @param queryDoc the query document that specifies the criteria used to select a record to be updated
|
||||
* @param updateDoc the update document that contains the updated object or $ operators to manipulate the
|
||||
* existing object.
|
||||
*/
|
||||
WriteResult updateMulti(String collectionName, Query query,
|
||||
Update update);
|
||||
|
||||
/**
|
||||
* Remove the given object from the collection by Id
|
||||
* @param object
|
||||
*/
|
||||
void remove(Object object);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Remove all documents from the default collection that match the provided query document criteria.
|
||||
*
|
||||
* @param queryDoc the query document that specifies the criteria used to remove a record
|
||||
*/
|
||||
void remove(Query query);
|
||||
|
||||
/**
|
||||
* Remove all documents from the default collection that match the provided query document criteria. The
|
||||
* Class parameter is used to help convert the Id of the object if it is present in the query.
|
||||
* @param <T>
|
||||
* @param query
|
||||
* @param targetClass
|
||||
*/
|
||||
<T> void remove(Query query, Class<T> targetClass);
|
||||
|
||||
/**
|
||||
* Remove all documents from the specified collection that match the provided query document criteria.
|
||||
*
|
||||
* @param collectionName name of the collection where the objects will removed
|
||||
* @param queryDoc the query document that specifies the criteria used to remove a record
|
||||
*/
|
||||
void remove(String collectionName, Query query);
|
||||
|
||||
/**
|
||||
* Remove all documents from the specified collection that match the provided query document criteria.
|
||||
* The Class parameter is used to help convert the Id of the object if it is present in the query.
|
||||
* @param collectionName
|
||||
* @param query
|
||||
* @param targetClass
|
||||
*/
|
||||
<T> void remove(String collectionName, Query query, Class<T> targetClass);
|
||||
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.mongodb;
|
||||
|
||||
import com.mongodb.MongoOptions;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
/**
|
||||
* A factory bean for consruction a MongoOptions instance
|
||||
*
|
||||
* @author Graeme Rocher
|
||||
*/
|
||||
public class MongoOptionsFactoryBean implements FactoryBean<MongoOptions>, InitializingBean {
|
||||
|
||||
private static final MongoOptions MONGO_OPTIONS = new MongoOptions();
|
||||
/**
|
||||
* number of connections allowed per host
|
||||
* will block if run out
|
||||
*/
|
||||
private int connectionsPerHost = MONGO_OPTIONS.connectionsPerHost;
|
||||
|
||||
/**
|
||||
* multiplier for connectionsPerHost for # of threads that can block
|
||||
* if connectionsPerHost is 10, and threadsAllowedToBlockForConnectionMultiplier is 5,
|
||||
* then 50 threads can block
|
||||
* more than that and an exception will be throw
|
||||
*/
|
||||
private int threadsAllowedToBlockForConnectionMultiplier = MONGO_OPTIONS.threadsAllowedToBlockForConnectionMultiplier;
|
||||
|
||||
/**
|
||||
* max wait time of a blocking thread for a connection
|
||||
*/
|
||||
private int maxWaitTime = MONGO_OPTIONS.maxWaitTime;
|
||||
|
||||
/**
|
||||
* connect timeout in milliseconds. 0 is default and infinite
|
||||
*/
|
||||
private int connectTimeout = MONGO_OPTIONS.connectTimeout;
|
||||
|
||||
/**
|
||||
* socket timeout. 0 is default and infinite
|
||||
*/
|
||||
private int socketTimeout = MONGO_OPTIONS.socketTimeout;
|
||||
|
||||
/**
|
||||
* this controls whether or not on a connect, the system retries automatically
|
||||
*/
|
||||
private boolean autoConnectRetry = MONGO_OPTIONS.autoConnectRetry;
|
||||
|
||||
|
||||
/**
|
||||
* number of connections allowed per host
|
||||
* will block if run out
|
||||
*/
|
||||
public void setConnectionsPerHost(int connectionsPerHost) {
|
||||
this.connectionsPerHost = connectionsPerHost;
|
||||
}
|
||||
|
||||
/**
|
||||
* multiplier for connectionsPerHost for # of threads that can block
|
||||
* if connectionsPerHost is 10, and threadsAllowedToBlockForConnectionMultiplier is 5,
|
||||
* then 50 threads can block
|
||||
* more than that and an exception will be throw
|
||||
*/
|
||||
public void setThreadsAllowedToBlockForConnectionMultiplier(
|
||||
int threadsAllowedToBlockForConnectionMultiplier) {
|
||||
this.threadsAllowedToBlockForConnectionMultiplier = threadsAllowedToBlockForConnectionMultiplier;
|
||||
}
|
||||
|
||||
/**
|
||||
* max wait time of a blocking thread for a connection
|
||||
*/
|
||||
public void setMaxWaitTime(int maxWaitTime) {
|
||||
this.maxWaitTime = maxWaitTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* connect timeout in milliseconds. 0 is default and infinite
|
||||
*/
|
||||
public void setConnectTimeout(int connectTimeout) {
|
||||
this.connectTimeout = connectTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* socket timeout. 0 is default and infinite
|
||||
*/
|
||||
public void setSocketTimeout(int socketTimeout) {
|
||||
this.socketTimeout = socketTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* this controls whether or not on a connect, the system retries automatically
|
||||
*/
|
||||
public void setAutoConnectRetry(boolean autoConnectRetry) {
|
||||
this.autoConnectRetry = autoConnectRetry;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() {
|
||||
MONGO_OPTIONS.connectionsPerHost = connectionsPerHost;
|
||||
MONGO_OPTIONS.threadsAllowedToBlockForConnectionMultiplier = threadsAllowedToBlockForConnectionMultiplier;
|
||||
MONGO_OPTIONS.maxWaitTime = maxWaitTime;
|
||||
MONGO_OPTIONS.connectTimeout = connectTimeout;
|
||||
MONGO_OPTIONS.socketTimeout = socketTimeout;
|
||||
MONGO_OPTIONS.autoConnectRetry = autoConnectRetry;
|
||||
|
||||
}
|
||||
|
||||
public MongoOptions getObject() {
|
||||
return MONGO_OPTIONS;
|
||||
}
|
||||
|
||||
public Class<?> getObjectType() {
|
||||
return MongoOptions.class;
|
||||
}
|
||||
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,245 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.mongodb;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigInteger;
|
||||
import java.util.*;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* An iterable of {@link MongoPropertyDescriptor}s that allows dedicated access to the {@link MongoPropertyDescriptor}
|
||||
* that captures the id-property.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MongoPropertyDescriptors implements Iterable<MongoPropertyDescriptors.MongoPropertyDescriptor> {
|
||||
|
||||
private final Collection<MongoPropertyDescriptors.MongoPropertyDescriptor> descriptors;
|
||||
private final MongoPropertyDescriptors.MongoPropertyDescriptor idDescriptor;
|
||||
|
||||
/**
|
||||
* Creates the {@link MongoPropertyDescriptors} for the given type.
|
||||
*
|
||||
* @param type
|
||||
*/
|
||||
public MongoPropertyDescriptors(Class<?> type) {
|
||||
|
||||
Assert.notNull(type);
|
||||
Set<MongoPropertyDescriptors.MongoPropertyDescriptor> descriptors = new HashSet<MongoPropertyDescriptors.MongoPropertyDescriptor>();
|
||||
MongoPropertyDescriptors.MongoPropertyDescriptor idDesciptor = null;
|
||||
|
||||
for (PropertyDescriptor candidates : BeanUtils.getPropertyDescriptors(type)) {
|
||||
MongoPropertyDescriptor descriptor = new MongoPropertyDescriptors.MongoPropertyDescriptor(candidates, type);
|
||||
descriptors.add(descriptor);
|
||||
if (descriptor.isIdProperty()) {
|
||||
idDesciptor = descriptor;
|
||||
}
|
||||
}
|
||||
|
||||
this.descriptors = Collections.unmodifiableSet(descriptors);
|
||||
this.idDescriptor = idDesciptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link MongoPropertyDescriptor} for the id property.
|
||||
*
|
||||
* @return the idDescriptor
|
||||
*/
|
||||
public MongoPropertyDescriptors.MongoPropertyDescriptor getIdDescriptor() {
|
||||
return idDescriptor;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Iterable#iterator()
|
||||
*/
|
||||
public Iterator<MongoPropertyDescriptors.MongoPropertyDescriptor> iterator() {
|
||||
return descriptors.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple value object to have a more suitable abstraction for MongoDB specific property handling.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public static class MongoPropertyDescriptor {
|
||||
|
||||
public static Collection<Class<?>> SUPPORTED_ID_CLASSES;
|
||||
|
||||
static {
|
||||
Set<Class<?>> classes = new HashSet<Class<?>>();
|
||||
classes.add(ObjectId.class);
|
||||
classes.add(String.class);
|
||||
classes.add(BigInteger.class);
|
||||
SUPPORTED_ID_CLASSES = Collections.unmodifiableCollection(classes);
|
||||
}
|
||||
|
||||
private static final String ID_PROPERTY = "id";
|
||||
static final String ID_KEY = "_id";
|
||||
|
||||
private final PropertyDescriptor delegate;
|
||||
private final Class<?> owningType;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MongoPropertyDescriptor} for the given {@link PropertyDescriptor}.
|
||||
*
|
||||
* @param descriptor
|
||||
* @param owningType
|
||||
*/
|
||||
public MongoPropertyDescriptor(PropertyDescriptor descriptor, Class<?> owningType) {
|
||||
Assert.notNull(descriptor);
|
||||
this.delegate = descriptor;
|
||||
this.owningType = owningType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the property is the id-property. Will be identified by name for now ({@value #ID_PROPERTY}).
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isIdProperty() {
|
||||
return ID_PROPERTY.equals(delegate.getName()) || ID_KEY.equals(delegate.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the property is of one of the supported id types. Currently we support {@link String},
|
||||
* {@link ObjectId} and {@link BigInteger}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isOfIdType() {
|
||||
return SUPPORTED_ID_CLASSES.contains(delegate.getPropertyType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key that shall be used for mapping. Will return {@value #ID_KEY} for the id property and the
|
||||
* plain name for all other ones.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getKeyToMap() {
|
||||
return isIdProperty() ? ID_KEY : delegate.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the property.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getName() {
|
||||
return delegate.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the underlying property is actually mappable. By default this will exclude the
|
||||
* {@literal class} property and only include properties with a getter.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isMappable() {
|
||||
|
||||
boolean isNotClassAttribute = !delegate.getName().equals("class");
|
||||
boolean hasGetter = delegate.getReadMethod() != null;
|
||||
boolean hasField = ReflectionUtils.findField(owningType, delegate.getName()) != null;
|
||||
|
||||
return isNotClassAttribute && hasGetter && hasField;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the plain property type.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Class<?> getPropertyType() {
|
||||
return delegate.getPropertyType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type type to be set. Will return the setter method's type and fall back to the getter method's
|
||||
* return type in case no setter is available. Useful for further (generics) inspection.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Type getTypeToSet() {
|
||||
|
||||
Method method = delegate.getWriteMethod();
|
||||
return method == null ? delegate.getReadMethod().getGenericReturnType()
|
||||
: method.getGenericParameterTypes()[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whther we describe a {@link Map}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isMap() {
|
||||
return Map.class.isAssignableFrom(getPropertyType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the descriptor is for a collection.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isCollection() {
|
||||
return Collection.class.isAssignableFrom(getPropertyType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the descriptor is for an {@link Enum}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isEnum() {
|
||||
return Enum.class.isAssignableFrom(getPropertyType());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || !getClass().equals(obj.getClass())) {
|
||||
return false;
|
||||
}
|
||||
MongoPropertyDescriptor that = (MongoPropertyDescriptor) obj;
|
||||
return that.delegate.equals(this.delegate);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return delegate.hashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.mongodb;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* A MongoWriter is responsible for converting a native MongoDB DBObject to an object of type T.
|
||||
*
|
||||
* @param <T> the type of the object to convert from a DBObject
|
||||
* @author Mark Pollack
|
||||
* @author Thomas Risberg
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface MongoReader<T> {
|
||||
|
||||
/**
|
||||
* Ready from the native MongoDB DBObject representation to an instance of the class T. The given type has to be the
|
||||
* starting point for marshalling the {@link DBObject} into it. So in case there's no real valid data inside
|
||||
* {@link DBObject} for the given type, just return an empty instance of the given type.
|
||||
*
|
||||
* @param clazz the type of the return value
|
||||
* @param dbo theDBObject
|
||||
* @return the converted object
|
||||
*/
|
||||
<S extends T> S read(Class<S> clazz, DBObject dbo);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.mongodb;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* A MongoWriter is responsible for converting an object of type T to the native MongoDB representation DBObject.
|
||||
*
|
||||
* @param <T> the type of the object to convert to a DBObject
|
||||
* @author Mark Pollack
|
||||
* @author Thomas Risberg
|
||||
*/
|
||||
public interface MongoWriter<T> {
|
||||
|
||||
/**
|
||||
* Write the given object of type T to the native MongoDB object representation DBObject.
|
||||
*
|
||||
* @param t The object to convert to a DBObject
|
||||
* @param dbo The DBObject to use for writing.
|
||||
*/
|
||||
void write(T t, DBObject dbo);
|
||||
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package org.springframework.data.document.mongodb;
|
||||
|
||||
public enum WriteResultChecking {
|
||||
NONE, LOG, EXCEPTION
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.mongodb.config;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.type.filter.AnnotationTypeFilter;
|
||||
import org.springframework.data.annotation.Persistent;
|
||||
import org.springframework.data.document.mongodb.MongoTemplate;
|
||||
import org.springframework.data.document.mongodb.convert.MappingMongoConverter;
|
||||
import org.springframework.data.document.mongodb.mapping.Document;
|
||||
import org.springframework.data.document.mongodb.mapping.MongoMappingContext;
|
||||
import org.springframework.data.document.mongodb.mapping.MongoPersistentEntityIndexCreator;
|
||||
import org.springframework.data.document.mongodb.mapping.event.LoggingEventListener;
|
||||
import org.springframework.data.document.mongodb.mapping.event.MongoMappingEvent;
|
||||
import org.springframework.data.mapping.context.MappingContextAwareBeanPostProcessor;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.mongodb.Mongo;
|
||||
|
||||
@Configuration
|
||||
public abstract class AbstractMongoConfiguration {
|
||||
|
||||
|
||||
@Bean
|
||||
public abstract Mongo mongo() throws Exception;
|
||||
|
||||
@Bean
|
||||
public abstract MongoTemplate mongoTemplate() throws Exception;
|
||||
|
||||
public String getMappingBasePackage() {
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public MongoMappingContext mongoMappingContext() throws ClassNotFoundException, LinkageError {
|
||||
MongoMappingContext mappingContext = new MongoMappingContext();
|
||||
String basePackage = getMappingBasePackage();
|
||||
if (StringUtils.hasText(basePackage)) {
|
||||
ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider(false);
|
||||
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Document.class));
|
||||
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Persistent.class));
|
||||
|
||||
Set<Class<?>> initialEntitySet = new HashSet<Class<?>>();
|
||||
for (BeanDefinition candidate : componentProvider.findCandidateComponents(basePackage)) {
|
||||
initialEntitySet.add(ClassUtils.forName(candidate.getBeanClassName(), mappingContext.getClass().getClassLoader()));
|
||||
}
|
||||
mappingContext.setInitialEntitySet(initialEntitySet);
|
||||
}
|
||||
return mappingContext;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MappingMongoConverter mappingMongoConverter() throws Exception {
|
||||
MappingMongoConverter converter = new MappingMongoConverter(mongoMappingContext());
|
||||
converter.setMongo(mongo());
|
||||
afterMappingMongoConverterCreation(converter);
|
||||
return converter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook that allows post-processing after the MappingMongoConverter has been
|
||||
* successfully created.
|
||||
* @param converter
|
||||
*/
|
||||
protected void afterMappingMongoConverterCreation(MappingMongoConverter converter) {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MappingContextAwareBeanPostProcessor mappingContextAwareBeanPostProcessor() {
|
||||
MappingContextAwareBeanPostProcessor bpp = new MappingContextAwareBeanPostProcessor();
|
||||
bpp.setMappingContextBeanName("mongoMappingContext");
|
||||
return bpp;
|
||||
}
|
||||
|
||||
@Bean MongoPersistentEntityIndexCreator mongoPersistentEntityIndexCreator() throws Exception {
|
||||
MongoPersistentEntityIndexCreator indexCreator = new MongoPersistentEntityIndexCreator(mongoMappingContext(), mongoTemplate() );
|
||||
return indexCreator;
|
||||
}
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* 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.data.document.mongodb.config;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.ManagedSet;
|
||||
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
||||
import org.springframework.core.type.filter.AnnotationTypeFilter;
|
||||
import org.springframework.data.annotation.Persistent;
|
||||
import org.springframework.data.document.mongodb.convert.MappingMongoConverter;
|
||||
import org.springframework.data.document.mongodb.mapping.Document;
|
||||
import org.springframework.data.document.mongodb.mapping.MongoMappingContext;
|
||||
import org.springframework.data.document.mongodb.mapping.MongoPersistentEntityIndexCreator;
|
||||
import org.springframework.data.mapping.context.MappingContextAwareBeanPostProcessor;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MappingMongoConverterParser extends AbstractBeanDefinitionParser {
|
||||
|
||||
static final String MAPPING_CONTEXT = "mappingContext";
|
||||
|
||||
private static final String INDEX_HELPER = "indexCreationHelper";
|
||||
private static final String TEMPLATE = "mongoTemplate";
|
||||
private static final String POST_PROCESSOR = "mappingContextAwareBeanPostProcessor";
|
||||
|
||||
private static final String BASE_PACKAGE = "base-package";
|
||||
|
||||
@Override
|
||||
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) throws BeanDefinitionStoreException {
|
||||
String id = super.resolveId(element, definition, parserContext);
|
||||
return StringUtils.hasText(id) ? id : "mappingConverter";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
|
||||
BeanDefinitionRegistry registry = parserContext.getRegistry();
|
||||
|
||||
String ctxRef = element.getAttribute("mapping-context-ref");
|
||||
if (!StringUtils.hasText(ctxRef)) {
|
||||
BeanDefinitionBuilder mappingContextBuilder = BeanDefinitionBuilder.genericBeanDefinition(MongoMappingContext.class);
|
||||
|
||||
Set<String> classesToAdd = getInititalEntityClasses(element, mappingContextBuilder);
|
||||
if (classesToAdd != null) {
|
||||
mappingContextBuilder.addPropertyValue("initialEntitySet", classesToAdd);
|
||||
}
|
||||
|
||||
registry.registerBeanDefinition(MAPPING_CONTEXT, mappingContextBuilder.getBeanDefinition());
|
||||
ctxRef = MAPPING_CONTEXT;
|
||||
}
|
||||
|
||||
try {
|
||||
registry.getBeanDefinition(POST_PROCESSOR);
|
||||
} catch (NoSuchBeanDefinitionException ignored) {
|
||||
BeanDefinitionBuilder postProcBuilder = BeanDefinitionBuilder.genericBeanDefinition(MappingContextAwareBeanPostProcessor.class);
|
||||
postProcBuilder.addPropertyValue("mappingContextBeanName", ctxRef);
|
||||
registry.registerBeanDefinition(POST_PROCESSOR, postProcBuilder.getBeanDefinition());
|
||||
}
|
||||
|
||||
BeanDefinitionBuilder converterBuilder = BeanDefinitionBuilder.genericBeanDefinition(MappingMongoConverter.class);
|
||||
converterBuilder.addConstructorArgReference(ctxRef);
|
||||
|
||||
// Need a reference to a Mongo instance
|
||||
String mongoRef = element.getAttribute("mongo-ref");
|
||||
converterBuilder.addPropertyReference("mongo", StringUtils.hasText(mongoRef) ? mongoRef : "mongo");
|
||||
|
||||
try {
|
||||
registry.getBeanDefinition(INDEX_HELPER);
|
||||
} catch (NoSuchBeanDefinitionException ignored) {
|
||||
String templateRef = element.getAttribute("mongo-template-ref");
|
||||
BeanDefinitionBuilder indexHelperBuilder = BeanDefinitionBuilder.genericBeanDefinition(MongoPersistentEntityIndexCreator.class);
|
||||
indexHelperBuilder.addConstructorArgValue(new RuntimeBeanReference(ctxRef));
|
||||
indexHelperBuilder.addConstructorArgValue(new RuntimeBeanReference(StringUtils.hasText(templateRef) ? templateRef : TEMPLATE));
|
||||
registry.registerBeanDefinition(INDEX_HELPER, indexHelperBuilder.getBeanDefinition());
|
||||
}
|
||||
|
||||
return converterBuilder.getBeanDefinition();
|
||||
}
|
||||
|
||||
|
||||
public Set<String> getInititalEntityClasses(Element element, BeanDefinitionBuilder builder) {
|
||||
|
||||
String basePackage = element.getAttribute(BASE_PACKAGE);
|
||||
|
||||
if (!StringUtils.hasText(basePackage)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider(false);
|
||||
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Document.class));
|
||||
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Persistent.class));
|
||||
|
||||
Set<String> classes = new ManagedSet<String>();
|
||||
for (BeanDefinition candidate : componentProvider.findCandidateComponents(basePackage)) {
|
||||
classes.add(candidate.getBeanClassName());
|
||||
}
|
||||
|
||||
return classes;
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.mongodb.config;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
|
||||
import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.data.document.mongodb.MongoAdmin;
|
||||
import org.springframework.data.document.mongodb.monitor.*;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
public class MongoJmxParser implements BeanDefinitionParser {
|
||||
|
||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||
String name = element.getAttribute("mongo-ref");
|
||||
if (!StringUtils.hasText(name)) {
|
||||
name = "mongo";
|
||||
}
|
||||
registerJmxComponents(name, element, parserContext);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void registerJmxComponents(String mongoRefName, Element element, ParserContext parserContext) {
|
||||
Object eleSource = parserContext.extractSource(element);
|
||||
|
||||
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
|
||||
|
||||
createBeanDefEntry(AssertMetrics.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(BackgroundFlushingMetrics.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(BtreeIndexCounters.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(ConnectionMetrics.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(GlobalLockMetrics.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(MemoryMetrics.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(OperationCounters.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(ServerInfo.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
createBeanDefEntry(MongoAdmin.class, compositeDef, mongoRefName, eleSource, parserContext);
|
||||
|
||||
|
||||
parserContext.registerComponent(compositeDef);
|
||||
|
||||
}
|
||||
|
||||
protected void createBeanDefEntry(Class<?> clazz, CompositeComponentDefinition compositeDef, String mongoRefName, Object eleSource, ParserContext parserContext) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
|
||||
builder.getRawBeanDefinition().setSource(eleSource);
|
||||
builder.addConstructorArgReference(mongoRefName);
|
||||
BeanDefinition assertDef = builder.getBeanDefinition();
|
||||
String assertName = parserContext.getReaderContext().registerWithGeneratedName(assertDef);
|
||||
compositeDef.addNestedComponent(new BeanComponentDefinition(assertDef, assertName));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.document.mongodb.config;
|
||||
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.data.document.mongodb.MongoFactoryBean;
|
||||
import org.springframework.data.document.mongodb.MongoOptionsFactoryBean;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Parser for <mongo;gt; definitions. If no name
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*/
|
||||
public class MongoParser extends AbstractSingleBeanDefinitionParser {
|
||||
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
return MongoFactoryBean.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
super.doParse(element, builder);
|
||||
|
||||
setPropertyValue(element, builder, "port", "port");
|
||||
setPropertyValue(element, builder, "host", "host");
|
||||
|
||||
parseOptions(parserContext, element, builder);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the options sub-element. Populates the given attribute factory with the proper attributes.
|
||||
*
|
||||
* @param element
|
||||
* @param attrBuilder
|
||||
* @return true if parsing actually occured, false otherwise
|
||||
*/
|
||||
private boolean parseOptions(ParserContext parserContext, Element element,
|
||||
BeanDefinitionBuilder mongoBuilder) {
|
||||
Element optionsElement = DomUtils.getChildElementByTagName(element, "options");
|
||||
if (optionsElement == null)
|
||||
return false;
|
||||
|
||||
BeanDefinitionBuilder optionsDefBuilder = BeanDefinitionBuilder.genericBeanDefinition(MongoOptionsFactoryBean.class);
|
||||
|
||||
setPropertyValue(optionsElement, optionsDefBuilder, "connectionsPerHost", "connectionsPerHost");
|
||||
setPropertyValue(optionsElement, optionsDefBuilder, "threadsAllowedToBlockForConnectionMultiplier", "threadsAllowedToBlockForConnectionMultiplier");
|
||||
setPropertyValue(optionsElement, optionsDefBuilder, "maxWaitTime", "maxWaitTime");
|
||||
setPropertyValue(optionsElement, optionsDefBuilder, "connectTimeout", "connectTimeout");
|
||||
setPropertyValue(optionsElement, optionsDefBuilder, "socketTimeout", "socketTimeout");
|
||||
setPropertyValue(optionsElement, optionsDefBuilder, "autoConnectRetry", "autoConnectRetry");
|
||||
|
||||
mongoBuilder.addPropertyValue("mongoOptions", optionsDefBuilder.getBeanDefinition());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
|
||||
throws BeanDefinitionStoreException {
|
||||
String name = super.resolveId(element, definition, parserContext);
|
||||
if (!StringUtils.hasText(name)) {
|
||||
name = "mongo";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
private void setPropertyValue(Element element, BeanDefinitionBuilder builder, String attrName, String propertyName) {
|
||||
String attr = element.getAttribute(attrName);
|
||||
if (StringUtils.hasText(attr)) {
|
||||
builder.addPropertyValue(propertyName, attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.mongodb.config;
|
||||
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.data.document.mongodb.config.SimpleMongoRepositoryConfiguration.MongoRepositoryConfiguration;
|
||||
import org.springframework.data.mapping.model.MappingContext;
|
||||
import org.springframework.data.repository.config.AbstractRepositoryConfigDefinitionParser;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
|
||||
/**
|
||||
* {@link org.springframework.beans.factory.xml.BeanDefinitionParser} to create
|
||||
* Mongo DB repositories from classpath scanning or manual definition.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MongoRepositoryConfigParser
|
||||
extends
|
||||
AbstractRepositoryConfigDefinitionParser<SimpleMongoRepositoryConfiguration, MongoRepositoryConfiguration> {
|
||||
|
||||
private static final String MAPPING_CONTEXT_DEFAULT = MappingMongoConverterParser.MAPPING_CONTEXT;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.config.
|
||||
* AbstractRepositoryConfigDefinitionParser
|
||||
* #getGlobalRepositoryConfigInformation(org.w3c.dom.Element)
|
||||
*/
|
||||
@Override
|
||||
protected SimpleMongoRepositoryConfiguration getGlobalRepositoryConfigInformation(
|
||||
Element element) {
|
||||
|
||||
return new SimpleMongoRepositoryConfiguration(element);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.config.AbstractRepositoryConfigDefinitionParser#postProcessBeanDefinition(org.springframework.data.repository.config.SingleRepositoryConfigInformation, org.springframework.beans.factory.support.BeanDefinitionBuilder, org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
protected void postProcessBeanDefinition(
|
||||
MongoRepositoryConfiguration context,
|
||||
BeanDefinitionBuilder builder, BeanDefinitionRegistry registry, Object beanSource) {
|
||||
|
||||
builder.addPropertyReference("template", context.getMongoTemplateRef());
|
||||
|
||||
String mappingContextRef = getMappingContextReference(context, registry);
|
||||
if (mappingContextRef != null) {
|
||||
builder.addPropertyReference("mappingContext", mappingContextRef);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bean name of a {@link MappingContext} to be wired. Will inspect the namespace attribute first and if no
|
||||
* config is found in that place it will try to lookup the default one. Will return {@literal null} if neither one is
|
||||
* available.
|
||||
*
|
||||
* @param config
|
||||
* @param registry
|
||||
* @return
|
||||
*/
|
||||
private String getMappingContextReference(MongoRepositoryConfiguration config, BeanDefinitionRegistry registry) {
|
||||
|
||||
String contextRef = config.getMappingContextRef();
|
||||
|
||||
if (contextRef != null) {
|
||||
return contextRef;
|
||||
}
|
||||
|
||||
try {
|
||||
registry.getBeanDefinition(MAPPING_CONTEXT_DEFAULT);
|
||||
return MAPPING_CONTEXT_DEFAULT;
|
||||
} catch(NoSuchBeanDefinitionException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.mongodb.config;
|
||||
|
||||
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
|
||||
|
||||
|
||||
/**
|
||||
* {@link org.springframework.beans.factory.xml.NamespaceHandler} for Mongo DB
|
||||
* based repositories.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MongoRepositoryNamespaceHandler extends NamespaceHandlerSupport {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.beans.factory.xml.NamespaceHandler#init()
|
||||
*/
|
||||
public void init() {
|
||||
|
||||
registerBeanDefinitionParser("repositories", new MongoRepositoryConfigParser());
|
||||
registerBeanDefinitionParser("mapping-converter", new MappingMongoConverterParser());
|
||||
registerBeanDefinitionParser("mongo", new MongoParser());
|
||||
registerBeanDefinitionParser("jmx", new MongoJmxParser());
|
||||
}
|
||||
}
|
||||
@@ -1,216 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.document.mongodb.config;
|
||||
|
||||
import org.springframework.data.document.mongodb.repository.MongoRepository;
|
||||
import org.springframework.data.document.mongodb.repository.MongoRepositoryFactoryBean;
|
||||
import org.springframework.data.repository.config.AutomaticRepositoryConfigInformation;
|
||||
import org.springframework.data.repository.config.ManualRepositoryConfigInformation;
|
||||
import org.springframework.data.repository.config.RepositoryConfig;
|
||||
import org.springframework.data.repository.config.SingleRepositoryConfigInformation;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
|
||||
/**
|
||||
* {@link RepositoryConfig} implementation to create
|
||||
* {@link MongoRepositoryConfiguration} instances for both automatic and manual
|
||||
* configuration.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class SimpleMongoRepositoryConfiguration extends RepositoryConfig<SimpleMongoRepositoryConfiguration.MongoRepositoryConfiguration, SimpleMongoRepositoryConfiguration> {
|
||||
|
||||
private static final String MONGO_TEMPLATE_REF = "mongo-template-ref";
|
||||
private static final String DEFAULT_MONGO_TEMPLATE_REF = "mongoTemplate";
|
||||
|
||||
private static final String MAPPING_CONTEXT_REF = "mongo-mapping-context-ref";
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new {@link SimpleMongoRepositoryConfiguration} for the given
|
||||
* {@link Element}.
|
||||
*
|
||||
* @param repositoriesElement
|
||||
*/
|
||||
protected SimpleMongoRepositoryConfiguration(Element repositoriesElement) {
|
||||
|
||||
super(repositoriesElement, MongoRepositoryFactoryBean.class.getName());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the bean name of the {@link org.springframework.data.document.mongodb.MongoTemplate} to be referenced.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getMongoTemplateRef() {
|
||||
|
||||
String templateRef = getSource().getAttribute(MONGO_TEMPLATE_REF);
|
||||
return StringUtils.hasText(templateRef) ? templateRef
|
||||
: DEFAULT_MONGO_TEMPLATE_REF;
|
||||
}
|
||||
|
||||
public String getMappingContextRef() {
|
||||
|
||||
String attribute = getSource().getAttribute(MAPPING_CONTEXT_REF);
|
||||
return StringUtils.hasText(attribute) ? attribute : null;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.config.GlobalRepositoryConfigInformation
|
||||
* #getAutoconfigRepositoryInformation(java.lang.String)
|
||||
*/
|
||||
public MongoRepositoryConfiguration getAutoconfigRepositoryInformation(
|
||||
String interfaceName) {
|
||||
|
||||
return new AutomaticMongoRepositoryConfiguration(interfaceName, this);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.data.repository.config.GlobalRepositoryConfigInformation
|
||||
* #getRepositoryBaseInterface()
|
||||
*/
|
||||
public Class<?> getRepositoryBaseInterface() {
|
||||
|
||||
return MongoRepository.class;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.repository.config.RepositoryConfig#
|
||||
* createSingleRepositoryConfigInformationFor(org.w3c.dom.Element)
|
||||
*/
|
||||
@Override
|
||||
protected MongoRepositoryConfiguration createSingleRepositoryConfigInformationFor(
|
||||
Element element) {
|
||||
|
||||
return new ManualMongoRepositoryConfiguration(element, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple interface for configuration values specific to Mongo repositories.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface MongoRepositoryConfiguration
|
||||
extends
|
||||
SingleRepositoryConfigInformation<SimpleMongoRepositoryConfiguration> {
|
||||
|
||||
String getMongoTemplateRef();
|
||||
|
||||
String getMappingContextRef();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements manual lookup of the additional attributes.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private static class ManualMongoRepositoryConfiguration
|
||||
extends
|
||||
ManualRepositoryConfigInformation<SimpleMongoRepositoryConfiguration>
|
||||
implements MongoRepositoryConfiguration {
|
||||
|
||||
/**
|
||||
* Creates a new {@link ManualMongoRepositoryConfiguration} for the
|
||||
* given {@link Element} and parent.
|
||||
*
|
||||
* @param element
|
||||
* @param parent
|
||||
*/
|
||||
public ManualMongoRepositoryConfiguration(Element element,
|
||||
SimpleMongoRepositoryConfiguration parent) {
|
||||
|
||||
super(element, parent);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.document.mongodb.repository.config.
|
||||
* SimpleMongoRepositoryConfiguration
|
||||
* .MongoRepositoryConfiguration#getMongoTemplateRef()
|
||||
*/
|
||||
public String getMongoTemplateRef() {
|
||||
|
||||
return getAttribute(MONGO_TEMPLATE_REF);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.config.SimpleMongoRepositoryConfiguration.MongoRepositoryConfiguration#getMappingContextRef()
|
||||
*/
|
||||
public String getMappingContextRef() {
|
||||
return getAttribute(MAPPING_CONTEXT_REF);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the lookup of the additional attributes during automatic
|
||||
* configuration.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private static class AutomaticMongoRepositoryConfiguration
|
||||
extends
|
||||
AutomaticRepositoryConfigInformation<SimpleMongoRepositoryConfiguration>
|
||||
implements MongoRepositoryConfiguration {
|
||||
|
||||
/**
|
||||
* Creates a new {@link AutomaticMongoRepositoryConfiguration} for the
|
||||
* given interface and parent.
|
||||
*
|
||||
* @param interfaceName
|
||||
* @param parent
|
||||
*/
|
||||
public AutomaticMongoRepositoryConfiguration(String interfaceName,
|
||||
SimpleMongoRepositoryConfiguration parent) {
|
||||
|
||||
super(interfaceName, parent);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.document.mongodb.repository.config.
|
||||
* SimpleMongoRepositoryConfiguration
|
||||
* .MongoRepositoryConfiguration#getMongoTemplateRef()
|
||||
*/
|
||||
public String getMongoTemplateRef() {
|
||||
|
||||
return getParent().getMongoTemplateRef();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.document.mongodb.config.SimpleMongoRepositoryConfiguration.MongoRepositoryConfiguration#getMappingContextRef()
|
||||
*/
|
||||
public String getMappingContextRef() {
|
||||
return getParent().getMappingContextRef();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,636 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
*
|
||||
* 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.data.document.mongodb.convert;
|
||||
|
||||
import static org.springframework.data.document.mongodb.convert.ObjectIdConverters.*;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.mongodb.BasicDBList;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.DBRef;
|
||||
import com.mongodb.Mongo;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.expression.BeanFactoryResolver;
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.converter.ConverterFactory;
|
||||
import org.springframework.core.convert.support.ConversionServiceFactory;
|
||||
import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.data.mapping.AssociationHandler;
|
||||
import org.springframework.data.mapping.MappingBeanHelper;
|
||||
import org.springframework.data.mapping.PropertyHandler;
|
||||
import org.springframework.data.mapping.model.Association;
|
||||
import org.springframework.data.mapping.model.MappingContext;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.data.mapping.model.PersistentEntity;
|
||||
import org.springframework.data.mapping.model.PersistentProperty;
|
||||
import org.springframework.data.mapping.model.PreferredConstructor;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
|
||||
/**
|
||||
* {@link MongoConverter} that uses a {@link MappingContext} to do sophisticated mapping of domain objects to
|
||||
* {@link DBObject}.
|
||||
*
|
||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MappingMongoConverter implements MongoConverter, ApplicationContextAware, InitializingBean {
|
||||
|
||||
private static final String CUSTOM_TYPE_KEY = "_class";
|
||||
@SuppressWarnings({"unchecked"})
|
||||
private static final List<Class<?>> MONGO_TYPES = Arrays.asList(Number.class, Date.class, String.class, DBObject.class);
|
||||
private static final List<Class<?>> VALID_ID_TYPES = Arrays.asList(new Class<?>[]{ObjectId.class, String.class, BigInteger.class, byte[].class});
|
||||
protected static final Log log = LogFactory.getLog(MappingMongoConverter.class);
|
||||
|
||||
protected final GenericConversionService conversionService = ConversionServiceFactory.createDefaultConversionService();
|
||||
protected final Map<Class<?>, Class<?>> customTypeMapping = new HashMap<Class<?>, Class<?>>();
|
||||
protected final MappingContext mappingContext;
|
||||
protected SpelExpressionParser spelExpressionParser = new SpelExpressionParser();
|
||||
protected ApplicationContext applicationContext;
|
||||
protected boolean useFieldAccessOnly = true;
|
||||
protected Mongo mongo;
|
||||
protected String defaultDatabase;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MappingMongoConverter} with the given {@link MappingContext}.
|
||||
*
|
||||
* @param mappingContext
|
||||
*/
|
||||
public MappingMongoConverter(MappingContext mappingContext) {
|
||||
this.mappingContext = mappingContext;
|
||||
this.conversionService.removeConvertible(Object.class, String.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add custom {@link Converter} or {@link ConverterFactory} instances to be used that will take presidence over
|
||||
* metadata driven conversion between of objects to/from DBObject
|
||||
*
|
||||
* @param converters
|
||||
*/
|
||||
public void setConverters(List<Converter<?, ?>> converters) {
|
||||
if (null != converters) {
|
||||
for (Converter<?, ?> c : converters) {
|
||||
registerConverter(c);
|
||||
conversionService.addConverter(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inspects the given {@link Converter} for the types it can convert and registers the pair for custom type conversion
|
||||
* in case the target type is a Mongo basic type.
|
||||
*
|
||||
* @param converter
|
||||
*/
|
||||
private void registerConverter(Converter<?, ?> converter) {
|
||||
Class<?>[] arguments = GenericTypeResolver.resolveTypeArguments(converter.getClass(), Converter.class);
|
||||
if (MONGO_TYPES.contains(arguments[1])) {
|
||||
customTypeMapping.put(arguments[0], arguments[1]);
|
||||
}
|
||||
}
|
||||
|
||||
public MappingContext getMappingContext() {
|
||||
return mappingContext;
|
||||
}
|
||||
|
||||
public Mongo getMongo() {
|
||||
return mongo;
|
||||
}
|
||||
|
||||
public void setMongo(Mongo mongo) {
|
||||
this.mongo = mongo;
|
||||
}
|
||||
|
||||
public String getDefaultDatabase() {
|
||||
return defaultDatabase;
|
||||
}
|
||||
|
||||
public void setDefaultDatabase(String defaultDatabase) {
|
||||
this.defaultDatabase = defaultDatabase;
|
||||
}
|
||||
|
||||
public boolean isUseFieldAccessOnly() {
|
||||
return useFieldAccessOnly;
|
||||
}
|
||||
|
||||
public void setUseFieldAccessOnly(boolean useFieldAccessOnly) {
|
||||
this.useFieldAccessOnly = useFieldAccessOnly;
|
||||
}
|
||||
|
||||
public <T> T convertObjectId(ObjectId id, Class<T> targetType) {
|
||||
return conversionService.convert(id, targetType);
|
||||
}
|
||||
|
||||
public ObjectId convertObjectId(Object id) {
|
||||
return conversionService.convert(id, ObjectId.class);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public <S extends Object> S read(Class<S> clazz, final DBObject dbo) {
|
||||
if (null == dbo) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ((clazz.isArray()
|
||||
|| (clazz.isAssignableFrom(Collection.class)
|
||||
|| clazz.isAssignableFrom(List.class)))
|
||||
&& dbo instanceof BasicDBList) {
|
||||
List l = new ArrayList<S>();
|
||||
BasicDBList dbList = (BasicDBList) dbo;
|
||||
for (Object o : dbList) {
|
||||
if (o instanceof DBObject) {
|
||||
Object newObj = read(clazz.getComponentType(), (DBObject) o);
|
||||
if (newObj.getClass().isAssignableFrom(clazz.getComponentType())) {
|
||||
l.add(newObj);
|
||||
} else {
|
||||
l.add(conversionService.convert(newObj, clazz.getComponentType()));
|
||||
}
|
||||
} else {
|
||||
l.add(o);
|
||||
}
|
||||
}
|
||||
return conversionService.convert(l, clazz);
|
||||
}
|
||||
|
||||
// Retrieve persistent entity info
|
||||
PersistentEntity<S> persistentEntity = mappingContext.getPersistentEntity(clazz);
|
||||
if (persistentEntity == null) {
|
||||
persistentEntity = mappingContext.addPersistentEntity(clazz);
|
||||
}
|
||||
|
||||
return read(persistentEntity, dbo);
|
||||
}
|
||||
|
||||
private <S extends Object> S read(PersistentEntity<S> entity, final DBObject dbo) {
|
||||
|
||||
final StandardEvaluationContext spelCtx = new StandardEvaluationContext();
|
||||
if (null != applicationContext) {
|
||||
spelCtx.setBeanResolver(new BeanFactoryResolver(applicationContext));
|
||||
}
|
||||
String[] keySet = dbo.keySet().toArray(new String[]{});
|
||||
for (String key : keySet) {
|
||||
spelCtx.setVariable(key, dbo.get(key));
|
||||
}
|
||||
|
||||
final List<String> ctorParamNames = new ArrayList<String>();
|
||||
final S instance = MappingBeanHelper.constructInstance(entity, new PreferredConstructor.ParameterValueProvider() {
|
||||
public Object getParameterValue(PreferredConstructor.Parameter parameter) {
|
||||
String name = parameter.getName();
|
||||
Class<?> type = parameter.getType();
|
||||
Object obj = dbo.get(name);
|
||||
if (obj instanceof DBRef) {
|
||||
ctorParamNames.add(name);
|
||||
return read(type, ((DBRef) obj).fetch());
|
||||
} else if (obj instanceof DBObject) {
|
||||
ctorParamNames.add(name);
|
||||
return read(type, ((DBObject) obj));
|
||||
} else if (null != obj && obj.getClass().isAssignableFrom(type)) {
|
||||
ctorParamNames.add(name);
|
||||
return obj;
|
||||
} else if (null != obj) {
|
||||
ctorParamNames.add(name);
|
||||
return conversionService.convert(obj, type);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}, spelCtx);
|
||||
|
||||
// Set the ID
|
||||
PersistentProperty idProperty = entity.getIdProperty();
|
||||
if (dbo.containsField("_id") && null != idProperty) {
|
||||
Object idObj = dbo.get("_id");
|
||||
try {
|
||||
MappingBeanHelper.setProperty(instance, idProperty, idObj, useFieldAccessOnly);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new MappingException(e.getMessage(), e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new MappingException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
// Set properties not already set in the constructor
|
||||
entity.doWithProperties(new PropertyHandler() {
|
||||
public void doWithPersistentProperty(PersistentProperty prop) {
|
||||
if (ctorParamNames.contains(prop.getName())) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object obj = getValueInternal(prop, dbo, spelCtx, prop.getValueAnnotation());
|
||||
try {
|
||||
MappingBeanHelper.setProperty(instance, prop, obj, useFieldAccessOnly);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new MappingException(e.getMessage(), e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new MappingException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Handle associations
|
||||
entity.doWithAssociations(new AssociationHandler() {
|
||||
public void doWithAssociation(Association association) {
|
||||
PersistentProperty inverseProp = association.getInverse();
|
||||
Object obj = getValueInternal(inverseProp, dbo, spelCtx, inverseProp.getValueAnnotation());
|
||||
try {
|
||||
MappingBeanHelper.setProperty(instance, inverseProp, obj);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new MappingException(e.getMessage(), e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new MappingException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void write(final Object obj, final DBObject dbo) {
|
||||
if (null == obj) {
|
||||
return;
|
||||
}
|
||||
|
||||
PersistentEntity<?> entity = mappingContext.getPersistentEntity(obj.getClass());
|
||||
write(obj, dbo, entity);
|
||||
}
|
||||
|
||||
protected void write(final Object obj, final DBObject dbo, PersistentEntity<?> entity) {
|
||||
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (null == entity) {
|
||||
// Must not have explictly added this entity yet
|
||||
entity = mappingContext.addPersistentEntity(obj.getClass());
|
||||
if (null == entity) {
|
||||
// We can't map this entity for some reason
|
||||
throw new MappingException("Unable to map entity " + obj);
|
||||
}
|
||||
}
|
||||
|
||||
// Write the ID
|
||||
final PersistentProperty idProperty = entity.getIdProperty();
|
||||
if (!dbo.containsField("_id") && null != idProperty) {
|
||||
Object idObj = null;
|
||||
try {
|
||||
idObj = MappingBeanHelper.getProperty(obj, idProperty, Object.class, useFieldAccessOnly);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new MappingException(e.getMessage(), e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new MappingException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
if (null != idObj) {
|
||||
dbo.put("_id", idObj);
|
||||
} else {
|
||||
if (!VALID_ID_TYPES.contains(idProperty.getType())) {
|
||||
throw new MappingException("Invalid data type " + idProperty.getType().getName() + " for Id property. Should be one of " + VALID_ID_TYPES);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write the properties
|
||||
entity.doWithProperties(new PropertyHandler() {
|
||||
public void doWithPersistentProperty(PersistentProperty prop) {
|
||||
String name = prop.getName();
|
||||
Class<?> type = prop.getType();
|
||||
Object propertyObj = null;
|
||||
try {
|
||||
propertyObj = MappingBeanHelper.getProperty(obj, prop, type, useFieldAccessOnly);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new MappingException(e.getMessage(), e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new MappingException(e.getMessage(), e);
|
||||
}
|
||||
if (null != propertyObj) {
|
||||
if (!MappingBeanHelper.isSimpleType(propertyObj.getClass())) {
|
||||
writePropertyInternal(prop, propertyObj, dbo);
|
||||
} else {
|
||||
dbo.put(name, propertyObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
entity.doWithAssociations(new AssociationHandler() {
|
||||
public void doWithAssociation(Association association) {
|
||||
PersistentProperty inverseProp = association.getInverse();
|
||||
Class<?> type = inverseProp.getType();
|
||||
Object propertyObj = null;
|
||||
try {
|
||||
propertyObj = MappingBeanHelper.getProperty(obj, inverseProp, type, useFieldAccessOnly);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new MappingException(e.getMessage(), e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new MappingException(e.getMessage(), e);
|
||||
}
|
||||
if (null != propertyObj) {
|
||||
writePropertyInternal(inverseProp, propertyObj, dbo);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers converters for {@link ObjectId} handling, removes plain {@link #toString()} converter and promotes the
|
||||
* configured {@link ConversionService} to {@link MappingBeanHelper}.
|
||||
*/
|
||||
private void initializeConverters() {
|
||||
|
||||
if (!conversionService.canConvert(ObjectId.class, String.class)) {
|
||||
conversionService.addConverter(ObjectIdToStringConverter.INSTANCE);
|
||||
}
|
||||
if (!conversionService.canConvert(String.class, ObjectId.class)) {
|
||||
conversionService.addConverter(StringToObjectIdConverter.INSTANCE);
|
||||
}
|
||||
if (!conversionService.canConvert(ObjectId.class, BigInteger.class)) {
|
||||
conversionService.addConverter(ObjectIdToBigIntegerConverter.INSTANCE);
|
||||
}
|
||||
if (!conversionService.canConvert(BigInteger.class, ObjectId.class)) {
|
||||
conversionService.addConverter(BigIntegerToObjectIdConverter.INSTANCE);
|
||||
}
|
||||
|
||||
MappingBeanHelper.setConversionService(conversionService);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
protected void writePropertyInternal(PersistentProperty prop, Object obj, DBObject dbo) {
|
||||
org.springframework.data.document.mongodb.mapping.DBRef dbref = prop.getField()
|
||||
.getAnnotation(org.springframework.data.document.mongodb.mapping.DBRef.class);
|
||||
|
||||
String name = prop.getName();
|
||||
Class<?> type = prop.getType();
|
||||
if (prop.isCollection()) {
|
||||
BasicDBList dbList = new BasicDBList();
|
||||
Collection<?> coll;
|
||||
if (type.isArray()) {
|
||||
coll = new ArrayList<Object>();
|
||||
for (Object o : (Object[]) obj) {
|
||||
((List) coll).add(o);
|
||||
}
|
||||
} else {
|
||||
coll = (Collection<?>) obj;
|
||||
}
|
||||
for (Object propObjItem : coll) {
|
||||
if (null != dbref) {
|
||||
DBRef dbRef = createDBRef(propObjItem, dbref);
|
||||
dbList.add(dbRef);
|
||||
} else if (type.isArray() && MappingBeanHelper.isSimpleType(type.getComponentType())) {
|
||||
dbList.add(propObjItem);
|
||||
} else if (MappingBeanHelper.isSimpleType(propObjItem.getClass())) {
|
||||
dbList.add(propObjItem);
|
||||
} else {
|
||||
BasicDBObject propDbObj = new BasicDBObject();
|
||||
write(propObjItem, propDbObj, mappingContext.getPersistentEntity(prop.getTypeInformation()));
|
||||
dbList.add(propDbObj);
|
||||
}
|
||||
}
|
||||
dbo.put(name, dbList);
|
||||
return;
|
||||
}
|
||||
|
||||
if (null != obj && obj instanceof Map) {
|
||||
BasicDBObject mapDbObj = new BasicDBObject();
|
||||
writeMapInternal((Map<Object, Object>) obj, mapDbObj);
|
||||
dbo.put(name, mapDbObj);
|
||||
return;
|
||||
}
|
||||
|
||||
if (null != dbref) {
|
||||
DBRef dbRefObj = createDBRef(obj, dbref);
|
||||
if (null != dbRefObj) {
|
||||
dbo.put(name, dbRefObj);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Lookup potential custom target type
|
||||
Class<?> basicTargetType = customTypeMapping.get(obj.getClass());
|
||||
|
||||
if (basicTargetType != null) {
|
||||
dbo.put(name, conversionService.convert(obj, basicTargetType));
|
||||
return;
|
||||
}
|
||||
|
||||
BasicDBObject propDbObj = new BasicDBObject();
|
||||
write(obj, propDbObj, mappingContext.getPersistentEntity(prop.getTypeInformation()));
|
||||
dbo.put(name, propDbObj);
|
||||
|
||||
}
|
||||
|
||||
protected void writeMapInternal(Map<Object, Object> obj, DBObject dbo) {
|
||||
for (Map.Entry<Object, Object> entry : obj.entrySet()) {
|
||||
Object key = entry.getKey();
|
||||
Object val = entry.getValue();
|
||||
if (MappingBeanHelper.isSimpleType(key.getClass())) {
|
||||
String simpleKey = conversionService.convert(key, String.class);
|
||||
if (MappingBeanHelper.isSimpleType(val.getClass())) {
|
||||
dbo.put(simpleKey, val);
|
||||
} else {
|
||||
DBObject newDbo = new BasicDBObject();
|
||||
Class<?> componentType = val.getClass();
|
||||
if (componentType.isArray()
|
||||
|| componentType.isAssignableFrom(Collection.class)
|
||||
|| componentType.isAssignableFrom(List.class)) {
|
||||
Class<?> ctype = val.getClass().getComponentType();
|
||||
dbo.put("_class", (null != ctype ? ctype.getName() : componentType.getName()));
|
||||
} else {
|
||||
dbo.put("_class", componentType.getName());
|
||||
}
|
||||
write(val, newDbo);
|
||||
dbo.put(simpleKey, newDbo);
|
||||
}
|
||||
} else {
|
||||
throw new MappingException("Cannot use a complex object as a key value.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected DBRef createDBRef(Object target, org.springframework.data.document.mongodb.mapping.DBRef dbref) {
|
||||
PersistentEntity<?> targetEntity = mappingContext.getPersistentEntity(target.getClass());
|
||||
if (null == targetEntity || null == targetEntity.getIdProperty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
PersistentProperty idProperty = targetEntity.getIdProperty();
|
||||
ObjectId id = null;
|
||||
try {
|
||||
id = MappingBeanHelper.getProperty(target, idProperty, ObjectId.class, useFieldAccessOnly);
|
||||
if (null == id) {
|
||||
throw new MappingException("Cannot create a reference to an object with a NULL id.");
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new MappingException(e.getMessage(), e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new MappingException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
String collection = dbref.collection();
|
||||
if ("".equals(collection)) {
|
||||
collection = targetEntity.getType().getSimpleName().toLowerCase();
|
||||
}
|
||||
|
||||
String dbname = dbref.db();
|
||||
if ("".equals(dbname)) {
|
||||
dbname = defaultDatabase;
|
||||
}
|
||||
|
||||
DB db = mongo.getDB(dbname);
|
||||
return new DBRef(db, collection, id);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
protected Object getValueInternal(PersistentProperty prop, DBObject dbo, StandardEvaluationContext ctx, Value spelExpr) {
|
||||
String name = prop.getName();
|
||||
Object o;
|
||||
if (null != spelExpr) {
|
||||
Expression x = spelExpressionParser.parseExpression(spelExpr.value());
|
||||
o = x.getValue(ctx);
|
||||
} else {
|
||||
DBObject from = dbo;
|
||||
if (dbo instanceof DBRef) {
|
||||
from = ((DBRef) dbo).fetch();
|
||||
}
|
||||
Object dbObj = from.get(name);
|
||||
if (dbObj instanceof DBObject) {
|
||||
if (prop.isMap() && dbObj instanceof DBObject) {
|
||||
|
||||
// We have to find a potentially stored class to be used first.
|
||||
Class<?> toType = findTypeToBeUsed((DBObject) dbObj);
|
||||
Map<String, Object> m = new LinkedHashMap<String, Object>();
|
||||
|
||||
for (Map.Entry<String, Object> entry : ((Map<String, Object>) ((DBObject) dbObj).toMap()).entrySet()) {
|
||||
if (entry.getKey().equals(CUSTOM_TYPE_KEY)) {
|
||||
continue;
|
||||
}
|
||||
if (null != entry.getValue() && entry.getValue() instanceof DBObject) {
|
||||
m.put(entry.getKey(), read((null != toType ? toType : prop.getMapValueType()), (DBObject) entry.getValue()));
|
||||
} else {
|
||||
m.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
return m;
|
||||
} else if (prop.isArray() && dbObj instanceof BasicDBObject && ((DBObject) dbObj).keySet().size() == 0) {
|
||||
// It's empty
|
||||
return Array.newInstance(prop.getComponentType(), 0);
|
||||
} else if (prop.isCollection() && dbObj instanceof BasicDBList) {
|
||||
BasicDBList dbObjList = (BasicDBList) dbObj;
|
||||
Object[] items = (Object[]) Array.newInstance(prop.getComponentType(), dbObjList.size());
|
||||
for (int i = 0; i < dbObjList.size(); i++) {
|
||||
Object dbObjItem = dbObjList.get(i);
|
||||
if (dbObjItem instanceof DBRef) {
|
||||
items[i] = read(prop.getComponentType(), ((DBRef) dbObjItem).fetch());
|
||||
} else if (dbObjItem instanceof DBObject) {
|
||||
items[i] = read(prop.getComponentType(), (DBObject) dbObjItem);
|
||||
} else {
|
||||
items[i] = dbObjItem;
|
||||
}
|
||||
}
|
||||
List<Object> itemsToReturn = new LinkedList<Object>();
|
||||
for (Object obj : items) {
|
||||
itemsToReturn.add(obj);
|
||||
}
|
||||
return itemsToReturn;
|
||||
}
|
||||
|
||||
Class<?> toType = findTypeToBeUsed((DBObject) dbObj);
|
||||
|
||||
// It's a complex object, have to read it in
|
||||
if (toType != null) {
|
||||
dbo.removeField(CUSTOM_TYPE_KEY);
|
||||
o = read(toType, (DBObject) dbObj);
|
||||
} else {
|
||||
o = read(mappingContext.getPersistentEntity(prop.getTypeInformation()), (DBObject) dbObj);
|
||||
}
|
||||
} else {
|
||||
o = dbObj;
|
||||
}
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type to be used to convert the DBObject given to.
|
||||
*
|
||||
* @param dbObject
|
||||
* @return
|
||||
*/
|
||||
protected Class<?> findTypeToBeUsed(DBObject dbObject) {
|
||||
Object classToBeUsed = dbObject.get(CUSTOM_TYPE_KEY);
|
||||
|
||||
if (classToBeUsed == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return Class.forName(classToBeUsed.toString());
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new MappingException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() {
|
||||
initializeConverters();
|
||||
}
|
||||
|
||||
protected class PersistentPropertyWrapper {
|
||||
private final PersistentProperty property;
|
||||
private final DBObject target;
|
||||
|
||||
public PersistentPropertyWrapper(PersistentProperty property, DBObject target) {
|
||||
this.property = property;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public PersistentProperty getProperty() {
|
||||
return property;
|
||||
}
|
||||
|
||||
public DBObject getTarget() {
|
||||
return target;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user