Compare commits
1051 Commits
1.0.0.M4-M
...
2.0.0.M1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
909fda2076 | ||
|
|
3b5d231529 | ||
|
|
e90fe70ae1 | ||
|
|
27d379ba71 | ||
|
|
e987a853ac | ||
|
|
3c16b4db7f | ||
|
|
070d784be3 | ||
|
|
af4f0e0913 | ||
|
|
474af92075 | ||
|
|
99838c02fd | ||
|
|
8060ebae6a | ||
|
|
9e9495ee54 | ||
|
|
098aae41b7 | ||
|
|
df859d0f3a | ||
|
|
e0f371f648 | ||
|
|
2145e212ca | ||
|
|
c814073441 | ||
|
|
59573b10e6 | ||
|
|
054274392e | ||
|
|
2d3efdc0b4 | ||
|
|
2461575c52 | ||
|
|
4371760272 | ||
|
|
da5289fc18 | ||
|
|
ea9b402547 | ||
|
|
255d32513c | ||
|
|
6a9823fd24 | ||
|
|
2ae75a4ff9 | ||
|
|
9c20da3e8f | ||
|
|
f782338581 | ||
|
|
cb90bfc6a6 | ||
|
|
189d4dd1b7 | ||
|
|
10208001f8 | ||
|
|
98dca5a65e | ||
|
|
b6bc0ea316 | ||
|
|
b67c551e19 | ||
|
|
e0bc1e0f20 | ||
|
|
fcb436dd30 | ||
|
|
0e57dd473c | ||
|
|
8d36e42b1b | ||
|
|
b66bfae105 | ||
|
|
eb3d55e0bd | ||
|
|
84dbfdfd5e | ||
|
|
1813b1aea0 | ||
|
|
69241737b7 | ||
|
|
f053bed447 | ||
|
|
1a1cd9ef14 | ||
|
|
7effc0e10f | ||
|
|
395bb1faa4 | ||
|
|
eb1392cc1a | ||
|
|
ace01e4e6d | ||
|
|
116dda63c2 | ||
|
|
4649872394 | ||
|
|
ecc6f3fc4e | ||
|
|
512f68a611 | ||
|
|
fbcd4ba367 | ||
|
|
760d7d6a32 | ||
|
|
29a6688e8c | ||
|
|
b6e7683202 | ||
|
|
286a977575 | ||
|
|
d7f70e219b | ||
|
|
728cc390f6 | ||
|
|
ddcc3914ff | ||
|
|
9a385599af | ||
|
|
c14c42fb0c | ||
|
|
5a8e4f3dae | ||
|
|
5d50155d81 | ||
|
|
babab54ffd | ||
|
|
1ba137b98a | ||
|
|
353b836a77 | ||
|
|
325bcd11b9 | ||
|
|
9db2dde19b | ||
|
|
318ba53e2f | ||
|
|
3db30bd4a6 | ||
|
|
dd1fbfeb66 | ||
|
|
3fa17272bb | ||
|
|
9361fc3c71 | ||
|
|
ac55f5e77f | ||
|
|
116baf9a92 | ||
|
|
026dce2612 | ||
|
|
eae32be568 | ||
|
|
9d51ea4c01 | ||
|
|
f4a5482005 | ||
|
|
0db36aff8f | ||
|
|
ba8ece334a | ||
|
|
a5394074c5 | ||
|
|
fe5bb515b7 | ||
|
|
c84bfbccf4 | ||
|
|
d147f80a39 | ||
|
|
7b8dadeb74 | ||
|
|
d1251c42ca | ||
|
|
4140dd573f | ||
|
|
0e60630393 | ||
|
|
9bc35512fd | ||
|
|
b626c2f82b | ||
|
|
c3e894ee8d | ||
|
|
2f713bede5 | ||
|
|
e03520d2fb | ||
|
|
3829d58dc2 | ||
|
|
7b87fa9509 | ||
|
|
b2b9f3406a | ||
|
|
d610761019 | ||
|
|
8983bd26ce | ||
|
|
5485f2fcd4 | ||
|
|
f8681fec66 | ||
|
|
0dd904894d | ||
|
|
7d70a8677e | ||
|
|
13a52b5ac9 | ||
|
|
f5cfcda673 | ||
|
|
cf44a7105f | ||
|
|
0228255d2b | ||
|
|
50e37355d4 | ||
|
|
a15dababfa | ||
|
|
9942451017 | ||
|
|
e144c29316 | ||
|
|
64d4880983 | ||
|
|
47c348e03a | ||
|
|
dea86535c1 | ||
|
|
eee6b62589 | ||
|
|
771ca8d84c | ||
|
|
8f5b334951 | ||
|
|
0dc6169282 | ||
|
|
abe78f0428 | ||
|
|
9930ec2d19 | ||
|
|
83d7f4477e | ||
|
|
18c3704c2e | ||
|
|
bef581caa5 | ||
|
|
2f0abe0604 | ||
|
|
4235b44c47 | ||
|
|
f318185ad0 | ||
|
|
43b496287c | ||
|
|
9d0c8ecdc3 | ||
|
|
5a78d99af0 | ||
|
|
693f5ddf6e | ||
|
|
ece655f67d | ||
|
|
119692c979 | ||
|
|
6068f3243a | ||
|
|
a7cda2e793 | ||
|
|
2687cb85f0 | ||
|
|
b2ce1700d2 | ||
|
|
0b634f8340 | ||
|
|
9a078b743f | ||
|
|
65b6576cfc | ||
|
|
78e99e6df2 | ||
|
|
bb0a42733d | ||
|
|
a2ae08e263 | ||
|
|
eaa9d6c7e6 | ||
|
|
8900695153 | ||
|
|
bfe548d573 | ||
|
|
7ab4002771 | ||
|
|
6eace856aa | ||
|
|
f10e5a19c5 | ||
|
|
90a4a63776 | ||
|
|
0f14e35ba3 | ||
|
|
ad0c4207d6 | ||
|
|
97da43645a | ||
|
|
42b7c42617 | ||
|
|
bd81e25e6b | ||
|
|
debe6aa649 | ||
|
|
6f433902f0 | ||
|
|
ba902e7f8e | ||
|
|
7e8ec21684 | ||
|
|
b7131b7efc | ||
|
|
ace99c3464 | ||
|
|
83fc5bc113 | ||
|
|
160de0adf6 | ||
|
|
b4753f3a83 | ||
|
|
bce6e2c78c | ||
|
|
b5ea0eccd2 | ||
|
|
87865b9761 | ||
|
|
13fa4703c0 | ||
|
|
5a21e00322 | ||
|
|
3feed2bc5a | ||
|
|
501b9501e0 | ||
|
|
727271e68c | ||
|
|
63a619dddf | ||
|
|
113566a6ab | ||
|
|
7862841b48 | ||
|
|
fe6cbaa03d | ||
|
|
9ef1fc7304 | ||
|
|
cf3a9d3ced | ||
|
|
1d1c80db7b | ||
|
|
eeb37e9104 | ||
|
|
18bf0daee7 | ||
|
|
1e9189aee7 | ||
|
|
95f6dfafdd | ||
|
|
bedaae8a90 | ||
|
|
7bfa3fe7fd | ||
|
|
143b0b73b9 | ||
|
|
cbfc46270e | ||
|
|
b31efb46ec | ||
|
|
ef3477098f | ||
|
|
9dce117555 | ||
|
|
e66e1e0502 | ||
|
|
19e1e9daeb | ||
|
|
ec8a948f3f | ||
|
|
38fc7641a0 | ||
|
|
ddc3925659 | ||
|
|
f8416edf8f | ||
|
|
4f94f37ce8 | ||
|
|
528de58418 | ||
|
|
e6ea34aed8 | ||
|
|
f171938b00 | ||
|
|
7b27368d2d | ||
|
|
f754df51bc | ||
|
|
77dce53c7a | ||
|
|
73f268e7c4 | ||
|
|
075d7d8131 | ||
|
|
206337044a | ||
|
|
55b44ff7aa | ||
|
|
ae48639ae9 | ||
|
|
6b5e78f810 | ||
|
|
3e485e0a88 | ||
|
|
335c78f908 | ||
|
|
b103e4eaf6 | ||
|
|
c4a6c63d23 | ||
|
|
4a4f10f97b | ||
|
|
a5712daab7 | ||
|
|
28cb1ef106 | ||
|
|
0d99a3e527 | ||
|
|
9da43263ce | ||
|
|
784e199068 | ||
|
|
1ffee802c0 | ||
|
|
6f0ac7f0c2 | ||
|
|
941d4d8985 | ||
|
|
44c76d8ffb | ||
|
|
df9a9f5fb6 | ||
|
|
bebd0fa0e6 | ||
|
|
594e90789d | ||
|
|
f2ab42cb80 | ||
|
|
3224fa8ce7 | ||
|
|
ce156c1344 | ||
|
|
434e553022 | ||
|
|
de5b5ee4b0 | ||
|
|
60636bf56d | ||
|
|
1ca71f93e9 | ||
|
|
63ff39bed6 | ||
|
|
cb0b9604d4 | ||
|
|
1dbe3b62d7 | ||
|
|
5c0707d221 | ||
|
|
c4ffc37dd5 | ||
|
|
aaf93b0f6f | ||
|
|
23eab1e84f | ||
|
|
218f32e552 | ||
|
|
62fbe4d08c | ||
|
|
41ffd00619 | ||
|
|
98b9a604cf | ||
|
|
01468b640a | ||
|
|
4d96b036a2 | ||
|
|
2d1ac15e24 | ||
|
|
2c27e8576f | ||
|
|
67f638d953 | ||
|
|
ea5bd5f7d3 | ||
|
|
394f695416 | ||
|
|
e4db466ab9 | ||
|
|
ee04c014c9 | ||
|
|
ea84f08de8 | ||
|
|
7d8a2b2d56 | ||
|
|
995d1e5aac | ||
|
|
3b918492ae | ||
|
|
66b419163c | ||
|
|
52bff39c22 | ||
|
|
d151a13e87 | ||
|
|
5e7e7d3598 | ||
|
|
356248bd05 | ||
|
|
73a60153f6 | ||
|
|
67cf0e62a7 | ||
|
|
21fbcc3e67 | ||
|
|
0d63ff92a0 | ||
|
|
983645e222 | ||
|
|
d2805bfa47 | ||
|
|
3f16b30631 | ||
|
|
8ebcbe3c5c | ||
|
|
363bed5c37 | ||
|
|
1547a646dd | ||
|
|
1408d51065 | ||
|
|
f5c319f18f | ||
|
|
a3c29054d0 | ||
|
|
01533ca34c | ||
|
|
a1f6dc6db4 | ||
|
|
37d53d936d | ||
|
|
bc0a2df653 | ||
|
|
7e50fd8273 | ||
|
|
ba560ffbad | ||
|
|
50ca32c8b9 | ||
|
|
bdfe3af505 | ||
|
|
798b56055d | ||
|
|
ce68e4a070 | ||
|
|
5da3130d26 | ||
|
|
6687cdc101 | ||
|
|
7e74ec6b62 | ||
|
|
b887fa70a5 | ||
|
|
1c6ab25253 | ||
|
|
1c43a3d1ee | ||
|
|
60ca1b3509 | ||
|
|
39d9312005 | ||
|
|
a0e42f5dfe | ||
|
|
7a3aff12a5 | ||
|
|
d4f1ef8704 | ||
|
|
a86d704bec | ||
|
|
57ab27aa5b | ||
|
|
909cc8b5d3 | ||
|
|
b7acbc4347 | ||
|
|
d276306ddc | ||
|
|
25b98b7ad2 | ||
|
|
819b424142 | ||
|
|
5d0328ba4b | ||
|
|
b219cff29c | ||
|
|
409eeaf962 | ||
|
|
4e5e8bd026 | ||
|
|
b91ec53ae0 | ||
|
|
ce0624b8b0 | ||
|
|
b4de2769cf | ||
|
|
3f7b0f1eb6 | ||
|
|
4055365c57 | ||
|
|
db7f782ca6 | ||
|
|
cde9d8d23a | ||
|
|
3dd9b0a2b6 | ||
|
|
59e54cecd2 | ||
|
|
5ed7e8efc2 | ||
|
|
fa85adfe0b | ||
|
|
a3e4f44a64 | ||
|
|
4a7a485e62 | ||
|
|
c353e02b3e | ||
|
|
1c2964cab4 | ||
|
|
47e083280a | ||
|
|
7db003100b | ||
|
|
f814b1ef47 | ||
|
|
f3d2ae366e | ||
|
|
b6ecce3aa2 | ||
|
|
c5235be9a7 | ||
|
|
23300de9d4 | ||
|
|
41dc57c84f | ||
|
|
85d1fe1ce6 | ||
|
|
ac6067ad53 | ||
|
|
173a62b5ce | ||
|
|
cbbafce73d | ||
|
|
2e74c19995 | ||
|
|
a212b7566c | ||
|
|
08faa52ef4 | ||
|
|
33bc4fffd9 | ||
|
|
eca2108e15 | ||
|
|
dab6034eb9 | ||
|
|
461e7d05d7 | ||
|
|
10c37b101d | ||
|
|
81f2c910f7 | ||
|
|
1fd97713c1 | ||
|
|
2d3eeed9ec | ||
|
|
b22eb6f12f | ||
|
|
dfb0a2a368 | ||
|
|
03bcc56429 | ||
|
|
457fda3fc3 | ||
|
|
54cee64610 | ||
|
|
477499248a | ||
|
|
3b70b6aeee | ||
|
|
163762e99e | ||
|
|
b99833df75 | ||
|
|
4be6231426 | ||
|
|
4673e3d511 | ||
|
|
00e48cc424 | ||
|
|
f8453825fb | ||
|
|
6cda9ab939 | ||
|
|
831d667896 | ||
|
|
17c342895a | ||
|
|
6ef518e6a0 | ||
|
|
ddee2fbb12 | ||
|
|
6512c2cdfb | ||
|
|
0eee05adaa | ||
|
|
17e0154ff3 | ||
|
|
2780f60c65 | ||
|
|
7dd3450362 | ||
|
|
ca4b2a61b8 | ||
|
|
d2ecd65ca5 | ||
|
|
03bd49f6c8 | ||
|
|
51607c5ed8 | ||
|
|
e2cbd3ee28 | ||
|
|
5944e6b57e | ||
|
|
efd46498ef | ||
|
|
3d705a737f | ||
|
|
996c57bccf | ||
|
|
a31e72ff06 | ||
|
|
f07d8fca8c | ||
|
|
69dbdee01f | ||
|
|
dedb9f3dc0 | ||
|
|
7d69b840fe | ||
|
|
4eaef300cb | ||
|
|
ec1a6b5edd | ||
|
|
adc5485c09 | ||
|
|
f622b2916d | ||
|
|
26be0cf948 | ||
|
|
e27c01fe5b | ||
|
|
d639e58fb9 | ||
|
|
0195c2cb48 | ||
|
|
068e2ec49b | ||
|
|
a9306b99ec | ||
|
|
3597194742 | ||
|
|
6f06ccec8e | ||
|
|
6fe7f220f9 | ||
|
|
45e70d493d | ||
|
|
ce71ab83f2 | ||
|
|
bf85d8facd | ||
|
|
c5ff7cdb2b | ||
|
|
f9ccf4f532 | ||
|
|
ab731f40a7 | ||
|
|
d8434fffa8 | ||
|
|
151b1d4510 | ||
|
|
168cf3e1f6 | ||
|
|
52dab0fa20 | ||
|
|
9257bab06e | ||
|
|
27f0a6f27a | ||
|
|
5bedbef2f2 | ||
|
|
51e7be8aa0 | ||
|
|
6c85bb39a3 | ||
|
|
07f7247707 | ||
|
|
f669711670 | ||
|
|
5f3671f349 | ||
|
|
1335cb699b | ||
|
|
84414b87c0 | ||
|
|
a1ecd4a501 | ||
|
|
d7e6f2ee41 | ||
|
|
04870fb8b3 | ||
|
|
9d196b78f7 | ||
|
|
4229525928 | ||
|
|
d861fecdb8 | ||
|
|
f280e23095 | ||
|
|
ed0e1d92c0 | ||
|
|
d82fc22659 | ||
|
|
6616d6788c | ||
|
|
322a7cf033 | ||
|
|
0f487c10ba | ||
|
|
11417144bd | ||
|
|
dafc59b163 | ||
|
|
566f9a80c4 | ||
|
|
89a42c5648 | ||
|
|
83ffbb00e8 | ||
|
|
84913cecab | ||
|
|
998bb09a92 | ||
|
|
cd68a8db54 | ||
|
|
df8477d180 | ||
|
|
244fbae0ce | ||
|
|
19e08a52c0 | ||
|
|
6389b1bb73 | ||
|
|
cadcbf6106 | ||
|
|
118f007ca6 | ||
|
|
cbb32bd29d | ||
|
|
9858dcd740 | ||
|
|
1fb76d135b | ||
|
|
bb62c8b2f1 | ||
|
|
2cbe7bf885 | ||
|
|
6043f6b74d | ||
|
|
ef1366592a | ||
|
|
01cf9fb8f3 | ||
|
|
285c406d5d | ||
|
|
ad29e52a57 | ||
|
|
3cfe207c83 | ||
|
|
c7e65cbc40 | ||
|
|
b8e02efb04 | ||
|
|
c7f20fb836 | ||
|
|
28a0202ef4 | ||
|
|
164e947045 | ||
|
|
7e65c0c87d | ||
|
|
9c1f753f17 | ||
|
|
0f821eb52d | ||
|
|
e3aadd63ab | ||
|
|
aa06d520df | ||
|
|
4fa1d4ba97 | ||
|
|
ba9f11b345 | ||
|
|
4777dd2e5e | ||
|
|
64b4591b72 | ||
|
|
bac5961fd8 | ||
|
|
b3cac862d8 | ||
|
|
b8ab2ad539 | ||
|
|
618d5bd5e9 | ||
|
|
096c3278b3 | ||
|
|
c9d9976c22 | ||
|
|
65497f93d4 | ||
|
|
af8a53bef6 | ||
|
|
916b856e97 | ||
|
|
7848da63f2 | ||
|
|
f359a1d31a | ||
|
|
72d645feae | ||
|
|
72fe382bba | ||
|
|
d25e840cf5 | ||
|
|
df1775572a | ||
|
|
86670cd49f | ||
|
|
31a4bf906e | ||
|
|
599291e8b7 | ||
|
|
f5a04fb9fb | ||
|
|
88558b67c3 | ||
|
|
d52cb255e0 | ||
|
|
6c214cbc37 | ||
|
|
01012c1448 | ||
|
|
4c7befb910 | ||
|
|
b62669ec8f | ||
|
|
0fb74caf9b | ||
|
|
9623dac01f | ||
|
|
695b27968c | ||
|
|
22933e4493 | ||
|
|
40aa6bbdd5 | ||
|
|
5e43f5846a | ||
|
|
2cfd4781bc | ||
|
|
031ab0c07b | ||
|
|
10f69f6623 | ||
|
|
d7b03915a7 | ||
|
|
ed55d48a53 | ||
|
|
d5ed4e0ac2 | ||
|
|
75194730e9 | ||
|
|
a09183d2eb | ||
|
|
45dd3cd988 | ||
|
|
b24e34c360 | ||
|
|
fa9b5efdab | ||
|
|
8f2ced8ada | ||
|
|
ff92cf1429 | ||
|
|
ba48290a3e | ||
|
|
70e5efd0d9 | ||
|
|
4eae229bff | ||
|
|
47f0607c49 | ||
|
|
753e794194 | ||
|
|
d27bec8ed5 | ||
|
|
c63f7f75dc | ||
|
|
84040518cf | ||
|
|
c66b9a538c | ||
|
|
a0c6b9aa64 | ||
|
|
9370c1ee01 | ||
|
|
2839e9491f | ||
|
|
6963f9e07a | ||
|
|
8dd08a36a0 | ||
|
|
a908e89ef7 | ||
|
|
5ace4032ed | ||
|
|
621b299f6f | ||
|
|
a2628d1b74 | ||
|
|
294616432d | ||
|
|
47dd512f95 | ||
|
|
f16e8d85e5 | ||
|
|
eb03ae61f2 | ||
|
|
5be66a3fee | ||
|
|
d88e4c0e3e | ||
|
|
57d1449008 | ||
|
|
8d00a0d926 | ||
|
|
e3fa844488 | ||
|
|
58bee75a6b | ||
|
|
a402395f5c | ||
|
|
9d5f8f3ba0 | ||
|
|
7ebf953063 | ||
|
|
617ebe0ca7 | ||
|
|
7f76789664 | ||
|
|
81e5919ace | ||
|
|
efd74956dc | ||
|
|
49eee40f7e | ||
|
|
8e93b844c7 | ||
|
|
3e64432f1a | ||
|
|
88c968ad36 | ||
|
|
99eefe0773 | ||
|
|
3d4569be14 | ||
|
|
57455c4a26 | ||
|
|
f9e20d12b2 | ||
|
|
4d6152c65e | ||
|
|
d81cc53c12 | ||
|
|
af4b84ea43 | ||
|
|
f9110828bc | ||
|
|
f301837be5 | ||
|
|
4d29d937eb | ||
|
|
86c11bc614 | ||
|
|
be34b4e503 | ||
|
|
ebfa2c5689 | ||
|
|
b245ef2d9e | ||
|
|
5ef40d54bc | ||
|
|
c679dba438 | ||
|
|
fd6e4000b5 | ||
|
|
c12a27a8f8 | ||
|
|
df2184f204 | ||
|
|
e9c8644d23 | ||
|
|
c730b8f479 | ||
|
|
f3b31fc467 | ||
|
|
f778b2554c | ||
|
|
9d292f64b9 | ||
|
|
8ab038f83c | ||
|
|
689552c28e | ||
|
|
9ea9912b23 | ||
|
|
a952ce5d2b | ||
|
|
b88d960893 | ||
|
|
e44d1f5f9a | ||
|
|
2b5e2361a8 | ||
|
|
5737f2d19d | ||
|
|
60494a6904 | ||
|
|
ceb561e3e4 | ||
|
|
e2d0220cea | ||
|
|
ea33e8b8c6 | ||
|
|
506b6a2e85 | ||
|
|
7c0eee9e09 | ||
|
|
332e5eb715 | ||
|
|
39ee9b56e2 | ||
|
|
8fb390ee88 | ||
|
|
df1c4496dc | ||
|
|
b808fd3003 | ||
|
|
ed12298271 | ||
|
|
682798325b | ||
|
|
0e69021486 | ||
|
|
ae7e24f1b6 | ||
|
|
94d4fa613c | ||
|
|
39c9593b39 | ||
|
|
6e5f3661a8 | ||
|
|
2bd78e0bf0 | ||
|
|
dd59cdc59a | ||
|
|
7e471e2301 | ||
|
|
0871a43831 | ||
|
|
710e77dabe | ||
|
|
9c996617e8 | ||
|
|
eebd49ab8d | ||
|
|
fb979b1734 | ||
|
|
b5c88938e0 | ||
|
|
4027770701 | ||
|
|
a120ce2bb1 | ||
|
|
a5d40a049d | ||
|
|
f0f12d5296 | ||
|
|
24e06cf219 | ||
|
|
1b83ff0382 | ||
|
|
fe41202f96 | ||
|
|
78235b4799 | ||
|
|
51ece4353b | ||
|
|
51bab838b0 | ||
|
|
361f9daa45 | ||
|
|
56b23a6dbe | ||
|
|
9e15c17e26 | ||
|
|
a3c77a43b6 | ||
|
|
55169e2e11 | ||
|
|
24672e6bdd | ||
|
|
1a46abfbb9 | ||
|
|
61284228dd | ||
|
|
8cb92de1ee | ||
|
|
5d3cc3fa04 | ||
|
|
c0b99740dc | ||
|
|
595bbd3aa7 | ||
|
|
5d2fc31164 | ||
|
|
a9dc0fae69 | ||
|
|
0605c7b753 | ||
|
|
21352a8829 | ||
|
|
58e1d2dbd9 | ||
|
|
4f7821e3c2 | ||
|
|
9dd866e34a | ||
|
|
def6079795 | ||
|
|
f3f537c1a6 | ||
|
|
ad44db386b | ||
|
|
bcc3bf61b6 | ||
|
|
1a28a294d1 | ||
|
|
14623a3655 | ||
|
|
6dcaa31897 | ||
|
|
e57fe346c0 | ||
|
|
7dd94949d5 | ||
|
|
966f971bee | ||
|
|
aa23c579e8 | ||
|
|
6b634d08ce | ||
|
|
b7b61405f9 | ||
|
|
4d65aa7207 | ||
|
|
c129c706a3 | ||
|
|
7823385ac7 | ||
|
|
21fcfe11c2 | ||
|
|
bfe33a446c | ||
|
|
9be50316c3 | ||
|
|
30513267af | ||
|
|
d3d480e79b | ||
|
|
c39ad1bbc4 | ||
|
|
fcdc29df49 | ||
|
|
de7120d8dd | ||
|
|
84df02ae38 | ||
|
|
d6c5907940 | ||
|
|
b2fe54c0a1 | ||
|
|
47a198c688 | ||
|
|
5d9dbda03b | ||
|
|
36d52862bc | ||
|
|
0afbf6fe19 | ||
|
|
b0bf8cb718 | ||
|
|
567a8d9d5b | ||
|
|
ceef18d7a4 | ||
|
|
4f57712f12 | ||
|
|
478396c503 | ||
|
|
aa80d1ad0a | ||
|
|
fd28ab4d33 | ||
|
|
187c80dfcc | ||
|
|
389a3ac066 | ||
|
|
297bd3e3dd | ||
|
|
b11fba3321 | ||
|
|
3c68671d86 | ||
|
|
b171f4192d | ||
|
|
21a1ce985c | ||
|
|
97caba50bf | ||
|
|
818f739d5a | ||
|
|
a44c1fdd2d | ||
|
|
6b35ca80d4 | ||
|
|
23b276745c | ||
|
|
be0092d3f5 | ||
|
|
f36792d419 | ||
|
|
31393db6ff | ||
|
|
8b50af07ce | ||
|
|
0eb315a758 | ||
|
|
976f5dd0e3 | ||
|
|
f614364918 | ||
|
|
38a86033be | ||
|
|
d11c20d548 | ||
|
|
3e2387ae6b | ||
|
|
e8a1caec53 | ||
|
|
44c0b14018 | ||
|
|
3daf3fc95b | ||
|
|
bd3aac8342 | ||
|
|
94f697da10 | ||
|
|
0cdec56a27 | ||
|
|
9d83331f9f | ||
|
|
071cd1647f | ||
|
|
92af5aa345 | ||
|
|
c07ad0fdf6 | ||
|
|
04e0f5c4a7 | ||
|
|
133975fb44 | ||
|
|
9a372a57e0 | ||
|
|
e67644094a | ||
|
|
c5a99b5b5e | ||
|
|
9564bcb280 | ||
|
|
f1e961a1ee | ||
|
|
0c69c87787 | ||
|
|
48b4a88a6a | ||
|
|
d0c0866f88 | ||
|
|
ab18bb5b96 | ||
|
|
509be3d681 | ||
|
|
8e01f95b29 | ||
|
|
4dcec1f6e2 | ||
|
|
d3bf6c0a19 | ||
|
|
3410a0589c | ||
|
|
7a64766496 | ||
|
|
e56a8597b8 | ||
|
|
e13208b4b3 | ||
|
|
6139e83d8d | ||
|
|
f33790013f | ||
|
|
bf81d95d21 | ||
|
|
158e4f033c | ||
|
|
81097061ad | ||
|
|
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 |
9
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
9
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Thank you for proposing a pull request. This template will guide you through the essential steps necessary for a pull request.
|
||||||
|
Make sure that:
|
||||||
|
|
||||||
|
- [ ] You have read the [Spring Data contribution guidelines](https://github.com/spring-projects/spring-data-build/blob/master/CONTRIBUTING.adoc).
|
||||||
|
- [ ] There is a ticket in the bug tracker for the project in our [JIRA](https://jira.spring.io/browse/DATAMONGO).
|
||||||
|
- [ ] You use the code formatters provided [here](https://github.com/spring-projects/spring-data-build/tree/master/etc/ide) and have them applied to your changes. Don’t submit any formatting related changes.
|
||||||
|
- [ ] You submit test cases (unit or integration tests) that back your changes.
|
||||||
|
- [ ] You added yourself as author in the headers of the classes you touched. Amend the date range in the Apache license header if needed. For new types, add the license header (copy from another file and set the current year only).
|
||||||
|
- [ ] You provide your full name and an email address registered with your GitHub account. If you’re a first-time submitter, make sure you have completed the [Contributor’s License Agreement form](https://support.springsource.com/spring_committer_signup).
|
||||||
37
.travis.yml
Normal file
37
.travis.yml
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
language: java
|
||||||
|
|
||||||
|
jdk:
|
||||||
|
- oraclejdk8
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- mongod --version
|
||||||
|
|
||||||
|
env:
|
||||||
|
matrix:
|
||||||
|
- PROFILE=ci
|
||||||
|
- PROFILE=mongo3
|
||||||
|
- PROFILE=mongo3-next
|
||||||
|
- PROFILE=mongo31
|
||||||
|
- PROFILE=mongo32
|
||||||
|
- PROFILE=mongo33
|
||||||
|
- PROFILE=mongo34-next
|
||||||
|
|
||||||
|
# Current MongoDB version is 2.4.2 as of 2016-04, see https://github.com/travis-ci/travis-ci/issues/3694
|
||||||
|
# apt-get starts a MongoDB instance so it's not started using before_script
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources:
|
||||||
|
- mongodb-3.2-precise
|
||||||
|
packages:
|
||||||
|
- mongodb-org-server
|
||||||
|
- mongodb-org-shell
|
||||||
|
|
||||||
|
sudo: false
|
||||||
|
|
||||||
|
cache:
|
||||||
|
directories:
|
||||||
|
- $HOME/.m2
|
||||||
|
|
||||||
|
install: true
|
||||||
|
|
||||||
|
script: "mvn clean dependency:list test -P${PROFILE} -Dsort"
|
||||||
27
CODE_OF_CONDUCT.adoc
Normal file
27
CODE_OF_CONDUCT.adoc
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
= Contributor Code of Conduct
|
||||||
|
|
||||||
|
As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
||||||
|
|
||||||
|
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
|
||||||
|
|
||||||
|
Examples of unacceptable behavior by participants include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery
|
||||||
|
* Personal attacks
|
||||||
|
* Trolling or insulting/derogatory comments
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing other's private information, such as physical or electronic addresses,
|
||||||
|
without explicit permission
|
||||||
|
* Other unethical or unprofessional conduct
|
||||||
|
|
||||||
|
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||||
|
|
||||||
|
By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
|
||||||
|
|
||||||
|
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting a project maintainer at spring-code-of-conduct@pivotal.io.
|
||||||
|
All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances.
|
||||||
|
Maintainers are obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the http://contributor-covenant.org[Contributor Covenant], version 1.3.0, available at http://contributor-covenant.org/version/1/3/0/[contributor-covenant.org/version/1/3/0/].
|
||||||
3
CONTRIBUTING.adoc
Normal file
3
CONTRIBUTING.adoc
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
= Spring Data contribution guidelines
|
||||||
|
|
||||||
|
You find the contribution guidelines for Spring Data projects https://github.com/spring-projects/spring-data-build/blob/master/CONTRIBUTING.adoc[here].
|
||||||
213
README.md
213
README.md
@@ -1,155 +1,150 @@
|
|||||||
Spring Data - Document
|
[](http://projects.spring.io/spring-data-mongodb#quick-start)
|
||||||
======================
|
[](http://projects.spring.io/spring-data-mongodb#quick-start)
|
||||||
|
|
||||||
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.
|
# Spring Data MongoDB
|
||||||
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/).
|
|
||||||
|
|
||||||
Getting Help
|
The primary goal of the [Spring Data](http://projects.spring.io/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.
|
||||||
------------
|
|
||||||
|
|
||||||
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).
|
The Spring Data MongoDB project aims to provide a familiar and consistent Spring-based programming model 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.
|
||||||
|
|
||||||
The [User Guide](http://static.springsource.org/spring-data/data-document/docs/1.0.0.BUILD-SNAPSHOT/reference/html/) (A work in progress).
|
## Getting Help
|
||||||
|
|
||||||
|
For a comprehensive treatment of all the Spring Data MongoDB features, please refer to:
|
||||||
|
|
||||||
|
* the [User Guide](http://docs.spring.io/spring-data/mongodb/docs/current/reference/html/)
|
||||||
|
* the [JavaDocs](http://docs.spring.io/spring-data/mongodb/docs/current/api/) have extensive comments in them as well.
|
||||||
|
* the home page of [Spring Data MongoDB](http://projects.spring.io/spring-data-mongodb) contains links to articles and other resources.
|
||||||
|
* for more detailed questions, use [Spring Data Mongodb on Stackoverflow](http://stackoverflow.com/questions/tagged/spring-data-mongodb).
|
||||||
|
|
||||||
|
If you are new to Spring as well as to Spring Data, look for information about [Spring projects](http://projects.spring.io/).
|
||||||
|
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
Quick Start
|
### Maven configuration
|
||||||
-----------
|
|
||||||
|
|
||||||
## MongoDB
|
Add the Maven dependency:
|
||||||
|
|
||||||
For those in a hurry:
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.data</groupId>
|
||||||
|
<artifactId>spring-data-mongodb</artifactId>
|
||||||
|
<version>${version}.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
If you'd rather like the latest snapshots of the upcoming major version, use our Maven snapshot repository and declare the appropriate dependency version.
|
||||||
|
|
||||||
* Download the jar through Maven:
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.data</groupId>
|
||||||
|
<artifactId>spring-data-mongodb</artifactId>
|
||||||
|
<version>${version}.BUILD-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<repository>
|
||||||
<groupId>org.springframework.data</groupId>
|
<id>spring-libs-snapshot</id>
|
||||||
<artifactId>spring-data-mongodb</artifactId>
|
<name>Spring Snapshot Repository</name>
|
||||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
<url>http://repo.spring.io/libs-snapshot</url>
|
||||||
</dependency>
|
</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
|
||||||
MongoTemplate is the central support class for Mongo database operations. It provides
|
|
||||||
|
MongoTemplate is the central support class for Mongo database operations. It provides:
|
||||||
|
|
||||||
* Basic POJO mapping support to and from BSON
|
* Basic POJO mapping support to and from BSON
|
||||||
* Connection Affinity callback
|
* Convenience methods to interact with the store (insert object, update objects) and MongoDB specific ones (geo-spatial operations, upserts, map-reduce etc.)
|
||||||
* Exception translation into Spring's [technology agnostic DAO exception hierarchy](http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/dao.html#dao-exceptions).
|
* Connection affinity callback
|
||||||
|
* Exception translation into Spring's [technology agnostic DAO exception hierarchy](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/dao.html#dao-exceptions).
|
||||||
|
|
||||||
Future plans are to support optional logging and/or exception throwing based on WriteResult return value, common map-reduce operations, GridFS operations. A simple API for partial document updates is also planned.
|
### Spring Data repositories
|
||||||
|
|
||||||
### Easy Data Repository generation
|
To simplify the creation of data repositories Spring Data MongoDB provides a generic repository programming model. It will automatically create a repository proxy for you that adds implementations of finder methods you specify on an interface.
|
||||||
|
|
||||||
To simplify the creation of Data Repositories a generic Repository interface and default implementation is provided. Furthermore, Spring will automatically create a Repository implementation for you that adds implementations of finder methods you specify on an interface.
|
For example, given a `Person` class with first and last name properties, a `PersonRepository` interface that can query for `Person` by last name and when the first name matches a like expression is shown below:
|
||||||
|
|
||||||
The Repository interface is
|
```java
|
||||||
|
public interface PersonRepository extends CrudRepository<Person, Long> {
|
||||||
|
|
||||||
public interface Repository<T, ID extends Serializable> {
|
List<Person> findByLastname(String lastname);
|
||||||
|
|
||||||
T save(T entity);
|
List<Person> findByFirstnameLike(String firstname);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
List<T> save(Iterable<? extends T> entities);
|
The queries issued on execution will be derived from the method name. Extending `CrudRepository` causes CRUD methods being pulled into the interface so that you can easily save and find single entities and collections of them.
|
||||||
|
|
||||||
T findById(ID id);
|
You can have Spring automatically create a proxy for the interface by using the following JavaConfig:
|
||||||
|
|
||||||
boolean exists(ID id);
|
```java
|
||||||
|
@Configuration
|
||||||
|
@EnableMongoRepositories
|
||||||
|
class ApplicationConfig extends AbstractMongoConfiguration {
|
||||||
|
|
||||||
List<T> findAll();
|
@Override
|
||||||
|
public Mongo mongo() throws Exception {
|
||||||
|
return new MongoClient();
|
||||||
|
}
|
||||||
|
|
||||||
Long count();
|
@Override
|
||||||
|
protected String getDatabaseName() {
|
||||||
|
return "springdata";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
void delete(T entity);
|
This sets up a connection to a local MongoDB instance and enables the detection of Spring Data repositories (through `@EnableMongoRepositories`). The same configuration would look like this in XML:
|
||||||
|
|
||||||
void delete(Iterable<? extends T> entities);
|
```xml
|
||||||
|
<bean id="template" class="org.springframework.data.mongodb.core.MongoTemplate">
|
||||||
|
<constructor-arg>
|
||||||
|
<bean class="com.mongodb.MongoClient">
|
||||||
|
<constructor-arg value="localhost" />
|
||||||
|
<constructor-arg value="27017" />
|
||||||
|
</bean>
|
||||||
|
</constructor-arg>
|
||||||
|
<constructor-arg value="database" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
void deleteAll();
|
<mongo:repositories base-package="com.acme.repository" />
|
||||||
}
|
```
|
||||||
|
|
||||||
|
This will find the repository interface and register a proxy object in the container. You can use it as shown below:
|
||||||
|
|
||||||
The MongoRepository extends Repository and will in future add more Mongo specific methods.
|
```java
|
||||||
|
@Service
|
||||||
|
public class MyService {
|
||||||
|
|
||||||
public interface MongoRepository<T, ID extends Serializable> extends
|
private final PersonRepository repository;
|
||||||
Repository<T, ID> {
|
|
||||||
}
|
|
||||||
|
|
||||||
SimpleMongoRepository is the out of the box implementation of the MongoRepository you can use for basid CRUD operations.
|
@Autowired
|
||||||
|
public MyService(PersonRepository repository) {
|
||||||
|
this.repository = repository;
|
||||||
|
}
|
||||||
|
|
||||||
To go beyond basic CRUD, extend the MongoRepository interface and supply your own finder methods that follow simple naming conventions such that they can be easily converted into queries.
|
public void doWork() {
|
||||||
|
|
||||||
For example, given a Person class with first and last name properties, a PersonRepository interface that can query for Person by last name and when the first name matches a regular expression is shown below
|
repository.deleteAll();
|
||||||
|
|
||||||
public interface PersonRepository extends MongoRepository<Person, Long> {
|
Person person = new Person();
|
||||||
|
person.setFirstname("Oliver");
|
||||||
|
person.setLastname("Gierke");
|
||||||
|
person = repository.save(person);
|
||||||
|
|
||||||
List<Person> findByLastname(String lastname);
|
List<Person> lastNameResults = repository.findByLastname("Gierke");
|
||||||
|
List<Person> firstNameResults = repository.findByFirstnameLike("Oli*");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
List<Person> findByFirstnameLike(String firstname);
|
## Contributing to Spring Data
|
||||||
}
|
|
||||||
|
|
||||||
You can have Spring automatically generate the implemention as shown below
|
|
||||||
|
|
||||||
<bean id="template" class="org.springframework.data.document.mongodb.MongoTemplate">
|
|
||||||
<constructor-arg>
|
|
||||||
<bean class="com.mongodb.Mongo">
|
|
||||||
<constructor-arg value="localhost" />
|
|
||||||
<constructor-arg value="27017" />
|
|
||||||
</bean>
|
|
||||||
</constructor-arg>
|
|
||||||
<constructor-arg value="database" />
|
|
||||||
<property name="defaultCollectionName" value="springdata" />
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean class="org.springframework.data.document.mongodb.repository.MongoRepositoryFactoryBean">
|
|
||||||
<property name="template" ref="template" />
|
|
||||||
<property name="repositoryInterface" value="org.springframework.data.document.mongodb.repository.PersonRepository" />
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
This will register an object in the container named PersonRepository. You can use it as shown below
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class MyService {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
PersonRepository repository;
|
|
||||||
|
|
||||||
|
|
||||||
public void doWork() {
|
|
||||||
|
|
||||||
repository.deleteAll();
|
|
||||||
|
|
||||||
Person person = new Person();
|
|
||||||
person.setFirstname("Oliver");
|
|
||||||
person.setLastname("Gierke");
|
|
||||||
person = repository.save(person);
|
|
||||||
|
|
||||||
List<Person> lastNameResults = repository.findByLastname("Gierke");
|
|
||||||
|
|
||||||
List<Person> firstNameResults = repository.findByFirstnameLike("Oli*");
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
## CouchDB
|
|
||||||
|
|
||||||
TBD
|
|
||||||
|
|
||||||
|
|
||||||
Contributing to Spring Data
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
Here are some ways for you to get involved in the community:
|
Here are some ways for you to get involved in the community:
|
||||||
|
|
||||||
* Get involved with the Spring community on the Spring Community Forums. Please help out on the [forum](http://forum.springsource.org/forumdisplay.php?f=80) by responding to questions and joining the debate.
|
* Get involved with the Spring community on Stackoverflow and help out on the [spring-data-mongodb](http://stackoverflow.com/questions/tagged/spring-data-mongodb) tag by responding to questions and joining the debate.
|
||||||
* Create [JIRA](https://jira.springframework.org/browse/DATADOC) tickets for bugs and new features and comment and vote on the ones that you are interested in.
|
* Create [JIRA](https://jira.springframework.org/browse/DATADOC) tickets for bugs and new features and comment and vote on the ones that you are interested in.
|
||||||
* Github is for social coding: if you want to write code, we encourage contributions through pull requests from [forks of this repository](http://help.github.com/forking/). If you want to contribute code this way, please reference a JIRA ticket as well covering the specific issue you are addressing.
|
* Github is for social coding: if you want to write code, we encourage contributions through pull requests from [forks of this repository](http://help.github.com/forking/). If you want to contribute code this way, please reference a JIRA ticket as well covering the specific issue you are addressing.
|
||||||
* Watch for upcoming articles on Spring by [subscribing](http://www.springsource.org/node/feed) to springframework.org
|
* Watch for upcoming articles on Spring by [subscribing](http://spring.io/blog) to spring.io.
|
||||||
|
|
||||||
Before we accept a non-trivial patch or pull request we will need you to sign the [contributor's agreement](https://support.springsource.com/spring_committer_signup). Signing the contributor's agreement does not grant anyone commit rights to the main repository, but it does mean that we can accept your contributions, and you will get an author credit if we do. Active contributors might be asked to join the core team, and given the ability to merge pull requests.
|
Before we accept a non-trivial patch or pull request we will need you to sign the [contributor's agreement](https://support.springsource.com/spring_committer_signup). Signing the contributor's agreement does not grant anyone commit rights to the main repository, but it does mean that we can accept your contributions, and you will get an author credit if we do. Active contributors might be asked to join the core team, and given the ability to merge pull requests.
|
||||||
|
|||||||
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="do not 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="do not 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="true"/>
|
||||||
|
<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="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
|
||||||
|
<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="do not 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="true"/>
|
||||||
|
<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="do not 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="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="do not 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="16"/>
|
||||||
|
<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="do not 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>
|
||||||
505
pom.xml
505
pom.xml
@@ -1,301 +1,230 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<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">
|
||||||
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.M4</version>
|
|
||||||
<packaging>pom</packaging>
|
|
||||||
<modules>
|
|
||||||
<module>spring-data-document-parent</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>
|
|
||||||
|
|
||||||
<developers>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<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>
|
|
||||||
|
|
||||||
<licenses>
|
<groupId>org.springframework.data</groupId>
|
||||||
<license>
|
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||||
<name>Apache License, Version 2.0</name>
|
<version>2.0.0.M1</version>
|
||||||
<url>http://www.apache.org/licenses/LICENSE-2.0</url>
|
<packaging>pom</packaging>
|
||||||
<comments>
|
|
||||||
Copyright 2010 the original author or authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
<name>Spring Data MongoDB</name>
|
||||||
you may not use this file except in compliance with the License.
|
<description>MongoDB support for Spring Data</description>
|
||||||
You may obtain a copy of the License at
|
<url>http://projects.spring.io/spring-data-mongodb</url>
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
<parent>
|
||||||
|
<groupId>org.springframework.data.build</groupId>
|
||||||
|
<artifactId>spring-data-parent</artifactId>
|
||||||
|
<version>2.0.0.M1</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
<modules>
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
<module>spring-data-mongodb</module>
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
<module>spring-data-mongodb-cross-store</module>
|
||||||
implied.
|
<module>spring-data-mongodb-log4j</module>
|
||||||
See the License for the specific language governing permissions and
|
<module>spring-data-mongodb-distribution</module>
|
||||||
limitations under the License.
|
</modules>
|
||||||
</comments>
|
|
||||||
</license>
|
|
||||||
</licenses>
|
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.type>multi</project.type>
|
||||||
<!-- dist.* properties are used by the antrun tasks below -->
|
<dist.id>spring-data-mongodb</dist.id>
|
||||||
<dist.id>spring-data-document</dist.id>
|
<springdata.commons>2.0.0.M1</springdata.commons>
|
||||||
<dist.name>Spring Data Mongo</dist.name>
|
<mongo>3.2.2</mongo>
|
||||||
<dist.key>SDMONGO</dist.key>
|
<mongo.reactivestreams>1.2.0</mongo.reactivestreams>
|
||||||
<dist.version>${project.version}</dist.version>
|
</properties>
|
||||||
<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>
|
<developers>
|
||||||
<extensions>
|
<developer>
|
||||||
<extension>
|
<id>ogierke</id>
|
||||||
<groupId>org.springframework.build.aws</groupId>
|
<name>Oliver Gierke</name>
|
||||||
<artifactId>org.springframework.build.aws.maven</artifactId>
|
<email>ogierke at gopivotal.com</email>
|
||||||
<version>3.1.0.RELEASE</version>
|
<organization>Pivotal</organization>
|
||||||
</extension>
|
<organizationUrl>http://www.gopivotal.com</organizationUrl>
|
||||||
</extensions>
|
<roles>
|
||||||
|
<role>Project Lead</role>
|
||||||
|
</roles>
|
||||||
|
<timezone>+1</timezone>
|
||||||
|
</developer>
|
||||||
|
<developer>
|
||||||
|
<id>trisberg</id>
|
||||||
|
<name>Thomas Risberg</name>
|
||||||
|
<email>trisberg at vmware.com</email>
|
||||||
|
<organization>Pivotal</organization>
|
||||||
|
<organizationUrl>http://www.gopivotal.com</organizationUrl>
|
||||||
|
<roles>
|
||||||
|
<role>Developer</role>
|
||||||
|
</roles>
|
||||||
|
<timezone>-5</timezone>
|
||||||
|
</developer>
|
||||||
|
<developer>
|
||||||
|
<id>mpollack</id>
|
||||||
|
<name>Mark Pollack</name>
|
||||||
|
<email>mpollack at gopivotal.com</email>
|
||||||
|
<organization>Pivotal</organization>
|
||||||
|
<organizationUrl>http://www.gopivotal.com</organizationUrl>
|
||||||
|
<roles>
|
||||||
|
<role>Developer</role>
|
||||||
|
</roles>
|
||||||
|
<timezone>-5</timezone>
|
||||||
|
</developer>
|
||||||
|
<developer>
|
||||||
|
<id>jbrisbin</id>
|
||||||
|
<name>Jon Brisbin</name>
|
||||||
|
<email>jbrisbin at gopivotal.com</email>
|
||||||
|
<organization>Pivotal</organization>
|
||||||
|
<organizationUrl>http://www.gopivotal.com</organizationUrl>
|
||||||
|
<roles>
|
||||||
|
<role>Developer</role>
|
||||||
|
</roles>
|
||||||
|
<timezone>-6</timezone>
|
||||||
|
</developer>
|
||||||
|
<developer>
|
||||||
|
<id>tdarimont</id>
|
||||||
|
<name>Thomas Darimont</name>
|
||||||
|
<email>tdarimont at gopivotal.com</email>
|
||||||
|
<organization>Pivotal</organization>
|
||||||
|
<organizationUrl>http://www.gopivotal.com</organizationUrl>
|
||||||
|
<roles>
|
||||||
|
<role>Developer</role>
|
||||||
|
</roles>
|
||||||
|
<timezone>+1</timezone>
|
||||||
|
</developer>
|
||||||
|
<developer>
|
||||||
|
<id>cstrobl</id>
|
||||||
|
<name>Christoph Strobl</name>
|
||||||
|
<email>cstrobl at gopivotal.com</email>
|
||||||
|
<organization>Pivotal</organization>
|
||||||
|
<organizationUrl>http://www.gopivotal.com</organizationUrl>
|
||||||
|
<roles>
|
||||||
|
<role>Developer</role>
|
||||||
|
</roles>
|
||||||
|
<timezone>+1</timezone>
|
||||||
|
</developer>
|
||||||
|
<developer>
|
||||||
|
<id>mpaluch</id>
|
||||||
|
<name>Mark Paluch</name>
|
||||||
|
<email>mpaluch at pivotal.io</email>
|
||||||
|
<organization>Pivotal</organization>
|
||||||
|
<organizationUrl>http://www.pivotal.io</organizationUrl>
|
||||||
|
<roles>
|
||||||
|
<role>Developer</role>
|
||||||
|
</roles>
|
||||||
|
<timezone>+1</timezone>
|
||||||
|
</developer>
|
||||||
|
</developers>
|
||||||
|
|
||||||
<plugins>
|
<profiles>
|
||||||
<plugin>
|
<profile>
|
||||||
<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>
|
<id>mongo3</id>
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
<properties>
|
||||||
<version>2.5</version>
|
<mongo>3.0.4</mongo>
|
||||||
<configuration>
|
</properties>
|
||||||
<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>
|
|
||||||
|
|
||||||
<pluginRepositories>
|
</profile>
|
||||||
<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>
|
|
||||||
<pluginRepository>
|
|
||||||
<id>repository.springframework.maven.release</id>
|
|
||||||
<name>Spring Framework Maven Release Repository</name>
|
|
||||||
<url>http://maven.springframework.org/release</url>
|
|
||||||
</pluginRepository>
|
|
||||||
</pluginRepositories>
|
|
||||||
|
|
||||||
<distributionManagement>
|
<profile>
|
||||||
<!-- see 'staging' profile for dry-run deployment settings -->
|
|
||||||
<downloadUrl>http://www.springsource.com/spring-data</downloadUrl>
|
<id>mongo3-next</id>
|
||||||
<site>
|
<properties>
|
||||||
<id>static.springframework.org</id>
|
<mongo>3.0.5-SNAPSHOT</mongo>
|
||||||
<url>
|
</properties>
|
||||||
scp://static.springframework.org/var/www/domains/springframework.org/static/htdocs/spring-data/data-document/snapshot-site/
|
|
||||||
</url>
|
<repositories>
|
||||||
</site>
|
<repository>
|
||||||
<repository>
|
<id>mongo-snapshots</id>
|
||||||
<id>spring-milestone</id>
|
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||||
<name>Spring Milestone Repository</name>
|
</repository>
|
||||||
<url>s3://maven.springframework.org/milestone</url>
|
</repositories>
|
||||||
</repository>
|
|
||||||
<snapshotRepository>
|
</profile>
|
||||||
<id>spring-snapshot</id>
|
|
||||||
<name>Spring Snapshot Repository</name>
|
<profile>
|
||||||
<url>s3://maven.springframework.org/snapshot</url>
|
|
||||||
</snapshotRepository>
|
<id>mongo31</id>
|
||||||
</distributionManagement>
|
<properties>
|
||||||
|
<mongo>3.1.1</mongo>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</profile>
|
||||||
|
|
||||||
|
<profile>
|
||||||
|
|
||||||
|
<id>mongo32</id>
|
||||||
|
<properties>
|
||||||
|
<mongo>3.2.2</mongo>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</profile>
|
||||||
|
|
||||||
|
<profile>
|
||||||
|
|
||||||
|
<id>mongo33</id>
|
||||||
|
<properties>
|
||||||
|
<mongo>3.3.0</mongo>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>mongo-snapshots</id>
|
||||||
|
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
</profile>
|
||||||
|
|
||||||
|
<profile>
|
||||||
|
|
||||||
|
<id>mongo34-next</id>
|
||||||
|
<properties>
|
||||||
|
<mongo>3.4.0-SNAPSHOT</mongo>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>mongo-snapshots</id>
|
||||||
|
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
</profile>
|
||||||
|
|
||||||
|
<profile>
|
||||||
|
<id>release</id>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jfrog.buildinfo</groupId>
|
||||||
|
<artifactId>artifactory-maven-plugin</artifactId>
|
||||||
|
<inherited>false</inherited>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
|
||||||
|
</profiles>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- MongoDB -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mongodb</groupId>
|
||||||
|
<artifactId>mongo-java-driver</artifactId>
|
||||||
|
<version>${mongo}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>spring-libs-milestone</id>
|
||||||
|
<url>https://repo.spring.io/libs-milestone</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<pluginRepositories>
|
||||||
|
<pluginRepository>
|
||||||
|
<id>spring-plugins-release</id>
|
||||||
|
<url>https://repo.spring.io/plugins-release</url>
|
||||||
|
</pluginRepository>
|
||||||
|
</pluginRepositories>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -1,156 +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-commons-core</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>
|
|
||||||
<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>
|
|
||||||
|
|
||||||
<!-- 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,35 +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.DataRetrievalFailureException;
|
|
||||||
|
|
||||||
public class DocumentRetrievalFailureException extends
|
|
||||||
DataRetrievalFailureException {
|
|
||||||
|
|
||||||
private String documentPath;
|
|
||||||
|
|
||||||
public DocumentRetrievalFailureException(String documentPath) {
|
|
||||||
super("Could not find document at path = " + documentPath);
|
|
||||||
this.documentPath = documentPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDocumentPath() {
|
|
||||||
return documentPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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,43 +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.xml.NamespaceHandlerSupport;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link org.springframework.beans.factory.xml.NamespaceHandler} for Couch DB
|
|
||||||
* based repositories.
|
|
||||||
*
|
|
||||||
* @author Oliver Gierke
|
|
||||||
*/
|
|
||||||
public class CouchNamespaceHandler extends NamespaceHandlerSupport {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see org.springframework.beans.factory.xml.NamespaceHandler#init()
|
|
||||||
*/
|
|
||||||
public void init() {
|
|
||||||
|
|
||||||
/*
|
|
||||||
registerBeanDefinitionParser("repositories",
|
|
||||||
new MongoRepositoryConfigDefinitionParser());
|
|
||||||
*/
|
|
||||||
|
|
||||||
registerBeanDefinitionParser("jmx", new CouchJmxParser());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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,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.M4</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.6.RELEASE</org.springframework.version>
|
|
||||||
<data.commons.version>1.2.0.M1</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-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:-path</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>
|
|
||||||
<pluginRepository>
|
|
||||||
<id>repository.springframework.maven.release</id>
|
|
||||||
<name>Spring Framework Maven Release Repository</name>
|
|
||||||
<url>http://maven.springframework.org/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>
|
|
||||||
7
spring-data-mongodb-cross-store/aop.xml
Normal file
7
spring-data-mongodb-cross-store/aop.xml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<aspectj>
|
||||||
|
<aspects>
|
||||||
|
<aspect name="org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect" />
|
||||||
|
<aspect name="org.springframework.data.mongodb.crossstore.MongoDocumentBacking" />
|
||||||
|
</aspects>
|
||||||
|
</aspectj>
|
||||||
@@ -1,219 +1,147 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
<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.M4</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>
|
|
||||||
|
|
||||||
<!-- Spring -->
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<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>
|
|
||||||
|
|
||||||
<!-- Spring Data -->
|
<parent>
|
||||||
<dependency>
|
<groupId>org.springframework.data</groupId>
|
||||||
<groupId>org.springframework.data</groupId>
|
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||||
<artifactId>spring-data-commons-core</artifactId>
|
<version>2.0.0.M1</version>
|
||||||
</dependency>
|
<relativePath>../pom.xml</relativePath>
|
||||||
<!-- <dependency>
|
</parent>
|
||||||
<groupId>org.springframework.data</groupId>
|
|
||||||
<artifactId>spring-data-commons-aspects</artifactId>
|
|
||||||
</dependency> -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.data</groupId>
|
|
||||||
<artifactId>spring-data-mongodb</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
|
<artifactId>spring-data-mongodb-cross-store</artifactId>
|
||||||
|
<name>Spring Data MongoDB - Cross-Store Support</name>
|
||||||
|
|
||||||
<!-- Logging -->
|
<properties>
|
||||||
<dependency>
|
<jpa>2.1.1</jpa>
|
||||||
<groupId>org.slf4j</groupId>
|
<hibernate>5.2.1.Final</hibernate>
|
||||||
<artifactId>slf4j-api</artifactId>
|
</properties>
|
||||||
</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>
|
<dependencies>
|
||||||
<groupId>javax.annotation</groupId>
|
|
||||||
<artifactId>jsr250-api</artifactId>
|
|
||||||
<optional>true</optional>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<!-- Spring -->
|
||||||
<groupId>org.mockito</groupId>
|
<dependency>
|
||||||
<artifactId>mockito-all</artifactId>
|
<groupId>org.springframework</groupId>
|
||||||
<scope>test</scope>
|
<artifactId>spring-beans</artifactId>
|
||||||
</dependency>
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>commons-logging</groupId>
|
||||||
|
<artifactId>commons-logging</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-tx</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-aspects</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-orm</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<!-- Spring Data -->
|
||||||
<groupId>junit</groupId>
|
<dependency>
|
||||||
<artifactId>junit</artifactId>
|
<groupId>org.springframework.data</groupId>
|
||||||
</dependency>
|
<artifactId>spring-data-mongodb</artifactId>
|
||||||
|
<version>2.0.0.M1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<!-- reactive -->
|
||||||
<groupId>org.aspectj</groupId>
|
<dependency>
|
||||||
<artifactId>aspectjrt</artifactId>
|
<groupId>io.projectreactor</groupId>
|
||||||
<version>${aspectj.version}</version>
|
<artifactId>reactor-core</artifactId>
|
||||||
</dependency>
|
<version>${reactor}</version>
|
||||||
<dependency>
|
<optional>true</optional>
|
||||||
<groupId>cglib</groupId>
|
</dependency>
|
||||||
<artifactId>cglib</artifactId>
|
|
||||||
<version>2.2</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- JPA -->
|
<dependency>
|
||||||
<dependency>
|
<groupId>org.aspectj</groupId>
|
||||||
<groupId>org.hibernate.javax.persistence</groupId>
|
<artifactId>aspectjrt</artifactId>
|
||||||
<artifactId>hibernate-jpa-2.0-api</artifactId>
|
<version>${aspectj}</version>
|
||||||
<version>1.0.0.Final</version>
|
</dependency>
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- For Tests -->
|
<!-- JPA -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.hibernate</groupId>
|
<groupId>org.eclipse.persistence</groupId>
|
||||||
<artifactId>hibernate-entitymanager</artifactId>
|
<artifactId>javax.persistence</artifactId>
|
||||||
<version>3.5.5-Final</version>
|
<version>${jpa}</version>
|
||||||
<scope>test</scope>
|
<optional>true</optional>
|
||||||
</dependency>
|
</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>
|
<!-- For Tests -->
|
||||||
<repositories>
|
<dependency>
|
||||||
<repository>
|
<groupId>org.hibernate</groupId>
|
||||||
<id>jboss-repository</id>
|
<artifactId>hibernate-entitymanager</artifactId>
|
||||||
<name>JBoss Public Repository</name>
|
<version>${hibernate}</version>
|
||||||
<url>http://repository.jboss.org/nexus/content/groups/public-jboss</url>
|
<scope>test</scope>
|
||||||
</repository>
|
</dependency>
|
||||||
</repositories>
|
<dependency>
|
||||||
<pluginRepositories>
|
<groupId>hsqldb</groupId>
|
||||||
<pluginRepository>
|
<artifactId>hsqldb</artifactId>
|
||||||
<id>spring-maven-milestones</id>
|
<version>1.8.0.10</version>
|
||||||
<name>Springframework Maven Milestone Repository</name>
|
<scope>test</scope>
|
||||||
<url>http://maven.springframework.org/milestone</url>
|
</dependency>
|
||||||
</pluginRepository>
|
<dependency>
|
||||||
<pluginRepository>
|
<groupId>javax.validation</groupId>
|
||||||
<id>spring-maven-release</id>
|
<artifactId>validation-api</artifactId>
|
||||||
<name>Springframework Maven Release Repository</name>
|
<version>${validation}</version>
|
||||||
<url>http://maven.springframework.org/release</url>
|
<scope>test</scope>
|
||||||
</pluginRepository>
|
</dependency>
|
||||||
</pluginRepositories>
|
<dependency>
|
||||||
<build>
|
<groupId>org.hibernate</groupId>
|
||||||
<plugins>
|
<artifactId>hibernate-validator</artifactId>
|
||||||
<plugin>
|
<version>5.2.4.Final</version>
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
<scope>test</scope>
|
||||||
<artifactId>aspectj-maven-plugin</artifactId>
|
</dependency>
|
||||||
<version>1.2</version>
|
|
||||||
<dependencies>
|
</dependencies>
|
||||||
<dependency>
|
|
||||||
<groupId>org.aspectj</groupId>
|
<build>
|
||||||
<artifactId>aspectjrt</artifactId>
|
<plugins>
|
||||||
<version>${aspectj.version}</version>
|
<plugin>
|
||||||
</dependency>
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
<dependency>
|
<artifactId>aspectj-maven-plugin</artifactId>
|
||||||
<groupId>org.aspectj</groupId>
|
<version>1.6</version>
|
||||||
<artifactId>aspectjtools</artifactId>
|
<dependencies>
|
||||||
<version>${aspectj.version}</version>
|
<dependency>
|
||||||
</dependency>
|
<groupId>org.aspectj</groupId>
|
||||||
</dependencies>
|
<artifactId>aspectjrt</artifactId>
|
||||||
<executions>
|
<version>${aspectj}</version>
|
||||||
<execution>
|
</dependency>
|
||||||
<goals>
|
<dependency>
|
||||||
<goal>compile</goal>
|
<groupId>org.aspectj</groupId>
|
||||||
<goal>test-compile</goal>
|
<artifactId>aspectjtools</artifactId>
|
||||||
</goals>
|
<version>${aspectj}</version>
|
||||||
</execution>
|
</dependency>
|
||||||
</executions>
|
</dependencies>
|
||||||
<configuration>
|
<executions>
|
||||||
<outxml>true</outxml>
|
<execution>
|
||||||
<aspectLibraries>
|
<goals>
|
||||||
<aspectLibrary>
|
<goal>compile</goal>
|
||||||
<groupId>org.springframework</groupId>
|
<goal>test-compile</goal>
|
||||||
<artifactId>spring-aspects</artifactId>
|
</goals>
|
||||||
</aspectLibrary>
|
</execution>
|
||||||
<!-- <aspectLibrary>
|
</executions>
|
||||||
<groupId>org.springframework.data</groupId>
|
<configuration>
|
||||||
<artifactId>spring-data-commons-aspects</artifactId>
|
<outxml>true</outxml>
|
||||||
</aspectLibrary> -->
|
<aspectLibraries>
|
||||||
</aspectLibraries>
|
<aspectLibrary>
|
||||||
<source>1.5</source>
|
<groupId>org.springframework</groupId>
|
||||||
<target>1.5</target>
|
<artifactId>spring-aspects</artifactId>
|
||||||
</configuration>
|
</aspectLibrary>
|
||||||
</plugin>
|
</aspectLibraries>
|
||||||
</plugins>
|
<complianceLevel>${source.level}</complianceLevel>
|
||||||
</build>
|
<source>${source.level}</source>
|
||||||
|
<target>${source.level}</target>
|
||||||
|
<xmlConfigured>aop.xml</xmlConfigured>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -13,18 +13,10 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
package org.springframework.data.mongodb.crossstore;
|
||||||
|
|
||||||
package org.springframework.data.document.couchdb.core;
|
import org.springframework.data.crossstore.ChangeSetBacked;
|
||||||
|
|
||||||
import org.junit.Test;
|
public interface DocumentBacked extends ChangeSetBacked {
|
||||||
|
|
||||||
/**
|
|
||||||
* Unit tests for CouchTemplate with mocks
|
|
||||||
*/
|
|
||||||
public class CouchTemplateTests {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void foo() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,212 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011-2016 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.bson.Document;
|
||||||
|
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.MongoException;
|
||||||
|
import com.mongodb.client.MongoCollection;
|
||||||
|
import com.mongodb.client.model.Filters;
|
||||||
|
import com.mongodb.client.result.DeleteResult;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Thomas Risberg
|
||||||
|
* @author Oliver Gierke
|
||||||
|
* @author Alex Vengrovsk
|
||||||
|
* @author Mark Paluch
|
||||||
|
*/
|
||||||
|
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";
|
||||||
|
|
||||||
|
private 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.crossstore.ChangeSetPersister#getPersistentState(java.lang.Class, java.lang.Object, org.springframework.data.crossstore.ChangeSet)
|
||||||
|
*/
|
||||||
|
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 Document dbk = new Document();
|
||||||
|
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(MongoCollection<Document> collection) throws MongoException, DataAccessException {
|
||||||
|
for (Document 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;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.crossstore.ChangeSetPersister#getPersistentId(org.springframework.data.crossstore.ChangeSetBacked, org.springframework.data.crossstore.ChangeSet)
|
||||||
|
*/
|
||||||
|
public Object getPersistentId(ChangeSetBacked entity, ChangeSet cs) throws DataAccessException {
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("getPersistentId called on {}", entity);
|
||||||
|
}
|
||||||
|
if (entityManagerFactory == null) {
|
||||||
|
throw new DataAccessResourceFailureException("EntityManagerFactory cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
return entityManagerFactory.getPersistenceUnitUtil().getIdentifier(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.crossstore.ChangeSetPersister#persistState(org.springframework.data.crossstore.ChangeSetBacked, org.springframework.data.crossstore.ChangeSet)
|
||||||
|
*/
|
||||||
|
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 Document dbQuery = new Document();
|
||||||
|
dbQuery.put(ENTITY_ID, getPersistentId(entity, cs));
|
||||||
|
dbQuery.put(ENTITY_CLASS, entity.getClass().getName());
|
||||||
|
dbQuery.put(ENTITY_FIELD_NAME, key);
|
||||||
|
final Document dbId = mongoTemplate.execute(collName, new CollectionCallback<Document>() {
|
||||||
|
public Document doInCollection(MongoCollection<Document> collection)
|
||||||
|
throws MongoException, DataAccessException {
|
||||||
|
Document id = collection.find(dbQuery).first();
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (value == null) {
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("Flush: removing: {}", dbQuery);
|
||||||
|
}
|
||||||
|
mongoTemplate.execute(collName, new CollectionCallback<Object>() {
|
||||||
|
public Object doInCollection(MongoCollection<Document> collection)
|
||||||
|
throws MongoException, DataAccessException {
|
||||||
|
DeleteResult dr = collection.deleteMany(dbQuery);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
final Document dbDoc = new Document();
|
||||||
|
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(MongoCollection<Document> collection)
|
||||||
|
throws MongoException, DataAccessException {
|
||||||
|
|
||||||
|
if (dbId != null) {
|
||||||
|
collection.replaceOne(Filters.eq("_id", dbId.get("_id")), dbDoc);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (dbDoc.containsKey("_id") && dbDoc.get("_id") == null) {
|
||||||
|
dbDoc.remove("_id");
|
||||||
|
}
|
||||||
|
collection.insertOne(dbDoc);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the collection the given entity type shall be persisted to.
|
||||||
|
*
|
||||||
|
* @param entityClass must not be {@literal null}.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String getCollectionNameForEntity(Class<? extends ChangeSetBacked> entityClass) {
|
||||||
|
return mongoTemplate.getCollectionName(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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* 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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
package org.springframework.data.mongodb.crossstore;
|
||||||
package org.springframework.data.persistence.document;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
@@ -25,8 +24,6 @@ import java.lang.annotation.Target;
|
|||||||
* @author Thomas Risberg
|
* @author Thomas Risberg
|
||||||
*/
|
*/
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target({
|
@Target({ ElementType.FIELD })
|
||||||
ElementType.FIELD
|
|
||||||
})
|
|
||||||
public @interface RelatedDocument {
|
public @interface RelatedDocument {
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
/**
|
||||||
|
* Infrastructure for Spring Data's MongoDB cross store support.
|
||||||
|
*/
|
||||||
|
package org.springframework.data.mongodb.crossstore;
|
||||||
|
|
||||||
@@ -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.mongodb;
|
|
||||||
|
|
||||||
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.mongodb.core.CollectionCallback;
|
|
||||||
import org.springframework.data.mongodb.core.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,257 +0,0 @@
|
|||||||
package org.springframework.data.persistence.document.mongodb;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
|
|
||||||
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.persistence.document.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.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.persistence.test.Address;
|
|
||||||
import org.springframework.data.document.persistence.test.Person;
|
|
||||||
import org.springframework.data.document.persistence.test.Resume;
|
|
||||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
|
||||||
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.persistence.document.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.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 + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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.bson.Document;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integration tests for MongoDB cross-store persistence (mainly {@link MongoChangeSetPersister}).
|
||||||
|
*
|
||||||
|
* @author Thomas Risberg
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
|
@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);
|
||||||
|
|
||||||
|
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(Class<?> domainType) {
|
||||||
|
|
||||||
|
String collectionName = mongoTemplate.getCollectionName(domainType);
|
||||||
|
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 (Document dbo : this.mongoTemplate.getCollection(mongoTemplate.getCollectionName(Person.class)).find()) {
|
||||||
|
Assert.assertTrue(!dbo.get("_entity_id").equals(2L));
|
||||||
|
if (dbo.get("_entity_id").equals(3L)) {
|
||||||
|
weFound3 = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Assert.assertTrue(weFound3);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,4 +1,19 @@
|
|||||||
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 {
|
public class Address {
|
||||||
|
|
||||||
@@ -8,8 +23,7 @@ public class Address {
|
|||||||
private String state;
|
private String state;
|
||||||
private String zip;
|
private String zip;
|
||||||
|
|
||||||
public Address(Integer streetNumber, String streetName, String city,
|
public Address(Integer streetNumber, String streetName, String city, String state, String zip) {
|
||||||
String state, String zip) {
|
|
||||||
super();
|
super();
|
||||||
this.streetNumber = streetNumber;
|
this.streetNumber = streetNumber;
|
||||||
this.streetName = streetName;
|
this.streetName = streetName;
|
||||||
@@ -21,34 +35,41 @@ public class Address {
|
|||||||
public Integer getStreetNumber() {
|
public Integer getStreetNumber() {
|
||||||
return streetNumber;
|
return streetNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStreetNumber(Integer streetNumber) {
|
public void setStreetNumber(Integer streetNumber) {
|
||||||
this.streetNumber = streetNumber;
|
this.streetNumber = streetNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getStreetName() {
|
public String getStreetName() {
|
||||||
return streetName;
|
return streetName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStreetName(String streetName) {
|
public void setStreetName(String streetName) {
|
||||||
this.streetName = streetName;
|
this.streetName = streetName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCity() {
|
public String getCity() {
|
||||||
return city;
|
return city;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCity(String city) {
|
public void setCity(String city) {
|
||||||
this.city = city;
|
this.city = city;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getState() {
|
public String getState() {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setState(String state) {
|
public void setState(String state) {
|
||||||
this.state = state;
|
this.state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getZip() {
|
public String getZip() {
|
||||||
return zip;
|
return zip;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setZip(String zip) {
|
public void setZip(String zip) {
|
||||||
this.zip = 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">
|
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">
|
<persistence-unit name="test" transaction-type="RESOURCE_LOCAL">
|
||||||
<provider>org.hibernate.ejb.HibernatePersistence</provider>
|
<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>
|
<properties>
|
||||||
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
|
<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-->
|
<!--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,14 +13,14 @@
|
|||||||
|
|
||||||
<context:spring-configured/>
|
<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:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
|
||||||
</context:component-scan>
|
</context:component-scan>
|
||||||
|
|
||||||
<mongo:mapping-converter/>
|
<mongo:mapping-converter/>
|
||||||
|
|
||||||
<!-- Mongo config -->
|
<!-- Mongo config -->
|
||||||
<bean id="mongo" class="org.springframework.data.mongodb.core.MongoFactoryBean">
|
<bean id="mongo" class="org.springframework.data.mongodb.core.MongoClientFactoryBean">
|
||||||
<property name="host" value="localhost"/>
|
<property name="host" value="localhost"/>
|
||||||
<property name="port" value="27017"/>
|
<property name="port" value="27017"/>
|
||||||
</bean>
|
</bean>
|
||||||
@@ -38,12 +38,12 @@
|
|||||||
<bean class="org.springframework.data.mongodb.core.MongoExceptionTranslator"/>
|
<bean class="org.springframework.data.mongodb.core.MongoExceptionTranslator"/>
|
||||||
|
|
||||||
<!-- Mongo aspect config -->
|
<!-- Mongo aspect config -->
|
||||||
<bean class="org.springframework.data.persistence.document.mongodb.MongoDocumentBacking"
|
<bean class="org.springframework.data.mongodb.crossstore.MongoDocumentBacking"
|
||||||
factory-method="aspectOf">
|
factory-method="aspectOf">
|
||||||
<property name="changeSetPersister" ref="mongoChangeSetPersister"/>
|
<property name="changeSetPersister" ref="mongoChangeSetPersister"/>
|
||||||
</bean>
|
</bean>
|
||||||
<bean id="mongoChangeSetPersister"
|
<bean id="mongoChangeSetPersister"
|
||||||
class="org.springframework.data.persistence.document.mongodb.MongoChangeSetPersister">
|
class="org.springframework.data.mongodb.crossstore.MongoChangeSetPersister">
|
||||||
<property name="mongoTemplate" ref="mongoTemplate"/>
|
<property name="mongoTemplate" ref="mongoTemplate"/>
|
||||||
<property name="entityManagerFactory" ref="entityManagerFactory"/>
|
<property name="entityManagerFactory" ref="entityManagerFactory"/>
|
||||||
</bean>
|
</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>
|
||||||
42
spring-data-mongodb-distribution/pom.xml
Normal file
42
spring-data-mongodb-distribution/pom.xml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?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>2.0.0.M1</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.root>${basedir}/..</project.root>
|
||||||
|
<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>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.asciidoctor</groupId>
|
||||||
|
<artifactId>asciidoctor-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:
|
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=org.apache.log4j.PatternLayout
|
||||||
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
|
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
|
||||||
log4j.appender.stdout.host = localhost
|
log4j.appender.stdout.host = localhost
|
||||||
@@ -32,7 +32,7 @@ An example log entry might look like:
|
|||||||
{
|
{
|
||||||
"_id" : ObjectId("4d89341a8ef397e06940d5cd"),
|
"_id" : ObjectId("4d89341a8ef397e06940d5cd"),
|
||||||
"applicationId" : "my.application",
|
"applicationId" : "my.application",
|
||||||
"name" : "org.springframework.data.document.mongodb.log4j.AppenderTest",
|
"name" : "org.springframework.data.mongodb.log4j.MongoLog4jAppenderIntegrationTests",
|
||||||
"level" : "DEBUG",
|
"level" : "DEBUG",
|
||||||
"timestamp" : ISODate("2011-03-23T16:53:46.778Z"),
|
"timestamp" : ISODate("2011-03-23T16:53:46.778Z"),
|
||||||
"properties" : {
|
"properties" : {
|
||||||
|
|||||||
@@ -1,84 +1,30 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<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">
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<groupId>org.springframework.data</groupId>
|
|
||||||
<artifactId>spring-data-document-parent</artifactId>
|
|
||||||
<version>1.0.0.M4</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>
|
|
||||||
|
|
||||||
<properties>
|
<parent>
|
||||||
<mongo.version>2.3</mongo.version>
|
<groupId>org.springframework.data</groupId>
|
||||||
</properties>
|
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||||
|
<version>2.0.0.M1</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<artifactId>spring-data-mongodb-log4j</artifactId>
|
||||||
|
<name>Spring Data MongoDB - Log4J Appender</name>
|
||||||
|
|
||||||
<!-- MongoDB -->
|
<properties>
|
||||||
<dependency>
|
<log4j>1.2.16</log4j>
|
||||||
<groupId>org.mongodb</groupId>
|
</properties>
|
||||||
<artifactId>mongo-java-driver</artifactId>
|
|
||||||
<version>${mongo.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Logging -->
|
<dependencies>
|
||||||
<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>
|
|
||||||
|
|
||||||
<!-- Test dependencies -->
|
<!-- Logging -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mockito</groupId>
|
<groupId>log4j</groupId>
|
||||||
<artifactId>mockito-all</artifactId>
|
<artifactId>log4j</artifactId>
|
||||||
<scope>test</scope>
|
<version>${log4j}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
</dependencies>
|
||||||
<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>
|
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -1,208 +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.log4j;
|
|
||||||
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import com.mongodb.BasicDBList;
|
|
||||||
import com.mongodb.BasicDBObject;
|
|
||||||
import com.mongodb.DB;
|
|
||||||
import com.mongodb.Mongo;
|
|
||||||
import com.mongodb.WriteConcern;
|
|
||||||
import org.apache.log4j.AppenderSkeleton;
|
|
||||||
import org.apache.log4j.Level;
|
|
||||||
import org.apache.log4j.MDC;
|
|
||||||
import org.apache.log4j.PatternLayout;
|
|
||||||
import org.apache.log4j.spi.LoggingEvent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
|
||||||
*/
|
|
||||||
public class MongoLog4jAppender extends AppenderSkeleton {
|
|
||||||
|
|
||||||
public static final String LEVEL = "level";
|
|
||||||
public static final String NAME = "name";
|
|
||||||
public static final String APP_ID = "applicationId";
|
|
||||||
public static final String TIMESTAMP = "timestamp";
|
|
||||||
public static final String PROPERTIES = "properties";
|
|
||||||
public static final String TRACEBACK = "traceback";
|
|
||||||
public static final String MESSAGE = "message";
|
|
||||||
public static final String YEAR = "year";
|
|
||||||
public static final String MONTH = "month";
|
|
||||||
public static final String DAY = "day";
|
|
||||||
public static final String HOUR = "hour";
|
|
||||||
|
|
||||||
protected String host = "localhost";
|
|
||||||
protected int port = 27017;
|
|
||||||
protected String database = "logs";
|
|
||||||
protected String collectionPattern = "%c";
|
|
||||||
protected PatternLayout collectionLayout = new PatternLayout(collectionPattern);
|
|
||||||
protected String applicationId = System.getProperty("APPLICATION_ID", null);
|
|
||||||
protected WriteConcern warnOrHigherWriteConcern = WriteConcern.SAFE;
|
|
||||||
protected WriteConcern infoOrLowerWriteConcern = WriteConcern.NORMAL;
|
|
||||||
protected Mongo mongo;
|
|
||||||
protected DB db;
|
|
||||||
|
|
||||||
public MongoLog4jAppender() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public MongoLog4jAppender(boolean isActive) {
|
|
||||||
super(isActive);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHost() {
|
|
||||||
return host;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHost(String host) {
|
|
||||||
this.host = host;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPort() {
|
|
||||||
return port;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPort(int port) {
|
|
||||||
this.port = port;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDatabase() {
|
|
||||||
return database;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDatabase(String database) {
|
|
||||||
this.database = database;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCollectionPattern() {
|
|
||||||
return collectionPattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCollectionPattern(String collectionPattern) {
|
|
||||||
this.collectionPattern = collectionPattern;
|
|
||||||
this.collectionLayout = new PatternLayout(collectionPattern);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getApplicationId() {
|
|
||||||
return applicationId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setApplicationId(String applicationId) {
|
|
||||||
this.applicationId = applicationId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setWarnOrHigherWriteConcern(String wc) {
|
|
||||||
this.warnOrHigherWriteConcern = WriteConcern.valueOf(wc);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getWarnOrHigherWriteConcern() {
|
|
||||||
return warnOrHigherWriteConcern.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getInfoOrLowerWriteConcern() {
|
|
||||||
return infoOrLowerWriteConcern.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setInfoOrLowerWriteConcern(String wc) {
|
|
||||||
this.infoOrLowerWriteConcern = WriteConcern.valueOf(wc);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void connectToMongo() throws UnknownHostException {
|
|
||||||
this.mongo = new Mongo(host, port);
|
|
||||||
this.db = mongo.getDB(database);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked"})
|
|
||||||
@Override
|
|
||||||
protected void append(final LoggingEvent event) {
|
|
||||||
if (null == db) {
|
|
||||||
try {
|
|
||||||
connectToMongo();
|
|
||||||
} catch (UnknownHostException e) {
|
|
||||||
throw new RuntimeException(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BasicDBObject dbo = new BasicDBObject();
|
|
||||||
if (null != applicationId) {
|
|
||||||
dbo.put(APP_ID, applicationId);
|
|
||||||
MDC.put(APP_ID, applicationId);
|
|
||||||
}
|
|
||||||
dbo.put(NAME, event.getLogger().getName());
|
|
||||||
dbo.put(LEVEL, event.getLevel().toString());
|
|
||||||
Calendar tstamp = Calendar.getInstance();
|
|
||||||
tstamp.setTimeInMillis(event.getTimeStamp());
|
|
||||||
dbo.put(TIMESTAMP, tstamp.getTime());
|
|
||||||
|
|
||||||
// Copy properties into document
|
|
||||||
Map<Object, Object> props = event.getProperties();
|
|
||||||
if (null != props && props.size() > 0) {
|
|
||||||
BasicDBObject propsDbo = new BasicDBObject();
|
|
||||||
for (Map.Entry<Object, Object> entry : props.entrySet()) {
|
|
||||||
propsDbo.put(entry.getKey().toString(), entry.getValue().toString());
|
|
||||||
}
|
|
||||||
dbo.put(PROPERTIES, propsDbo);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy traceback info (if there is any) into the document
|
|
||||||
String[] traceback = event.getThrowableStrRep();
|
|
||||||
if (null != traceback && traceback.length > 0) {
|
|
||||||
BasicDBList tbDbo = new BasicDBList();
|
|
||||||
tbDbo.addAll(Arrays.asList(traceback));
|
|
||||||
dbo.put(TRACEBACK, tbDbo);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Put the rendered message into the document
|
|
||||||
dbo.put(MESSAGE, event.getRenderedMessage());
|
|
||||||
|
|
||||||
// Insert the document
|
|
||||||
Calendar now = Calendar.getInstance();
|
|
||||||
MDC.put(YEAR, now.get(Calendar.YEAR));
|
|
||||||
MDC.put(MONTH, String.format("%1$02d", now.get(Calendar.MONTH) + 1));
|
|
||||||
MDC.put(DAY, String.format("%1$02d", now.get(Calendar.DAY_OF_MONTH)));
|
|
||||||
MDC.put(HOUR, String.format("%1$02d", now.get(Calendar.HOUR_OF_DAY)));
|
|
||||||
|
|
||||||
String coll = collectionLayout.format(event);
|
|
||||||
|
|
||||||
MDC.remove(YEAR);
|
|
||||||
MDC.remove(MONTH);
|
|
||||||
MDC.remove(DAY);
|
|
||||||
MDC.remove(HOUR);
|
|
||||||
if (null != applicationId) {
|
|
||||||
MDC.remove(APP_ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
WriteConcern wc;
|
|
||||||
if (event.getLevel().isGreaterOrEqual(Level.WARN)) {
|
|
||||||
wc = warnOrHigherWriteConcern;
|
|
||||||
} else {
|
|
||||||
wc = infoOrLowerWriteConcern;
|
|
||||||
}
|
|
||||||
db.getCollection(coll).insert(dbo, wc);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void close() {
|
|
||||||
mongo.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean requiresLayout() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,228 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011-2016 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.log4j;
|
||||||
|
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.log4j.AppenderSkeleton;
|
||||||
|
import org.apache.log4j.Level;
|
||||||
|
import org.apache.log4j.MDC;
|
||||||
|
import org.apache.log4j.PatternLayout;
|
||||||
|
import org.apache.log4j.spi.LoggingEvent;
|
||||||
|
|
||||||
|
import com.mongodb.BasicDBList;
|
||||||
|
import com.mongodb.BasicDBObject;
|
||||||
|
import com.mongodb.DB;
|
||||||
|
import com.mongodb.Mongo;
|
||||||
|
import com.mongodb.MongoClient;
|
||||||
|
import com.mongodb.WriteConcern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log4j appender writing log entries into a MongoDB instance.
|
||||||
|
*
|
||||||
|
* @author Jon Brisbin
|
||||||
|
* @author Oliver Gierke
|
||||||
|
* @auhtor Christoph Strobl
|
||||||
|
*/
|
||||||
|
public class MongoLog4jAppender extends AppenderSkeleton {
|
||||||
|
|
||||||
|
public static final String LEVEL = "level";
|
||||||
|
public static final String NAME = "name";
|
||||||
|
public static final String APP_ID = "applicationId";
|
||||||
|
public static final String TIMESTAMP = "timestamp";
|
||||||
|
public static final String PROPERTIES = "properties";
|
||||||
|
public static final String TRACEBACK = "traceback";
|
||||||
|
public static final String MESSAGE = "message";
|
||||||
|
public static final String YEAR = "year";
|
||||||
|
public static final String MONTH = "month";
|
||||||
|
public static final String DAY = "day";
|
||||||
|
public static final String HOUR = "hour";
|
||||||
|
|
||||||
|
protected String host = "localhost";
|
||||||
|
protected int port = 27017;
|
||||||
|
protected String database = "logs";
|
||||||
|
protected String collectionPattern = "%c";
|
||||||
|
protected PatternLayout collectionLayout = new PatternLayout(collectionPattern);
|
||||||
|
protected String applicationId = System.getProperty("APPLICATION_ID", null);
|
||||||
|
protected WriteConcern warnOrHigherWriteConcern = WriteConcern.ACKNOWLEDGED;
|
||||||
|
protected WriteConcern infoOrLowerWriteConcern = WriteConcern.UNACKNOWLEDGED;
|
||||||
|
protected Mongo mongo;
|
||||||
|
protected DB db;
|
||||||
|
|
||||||
|
public MongoLog4jAppender() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public MongoLog4jAppender(boolean isActive) {
|
||||||
|
super(isActive);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHost() {
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHost(String host) {
|
||||||
|
this.host = host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPort() {
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPort(int port) {
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDatabase() {
|
||||||
|
return database;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDatabase(String database) {
|
||||||
|
this.database = database;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCollectionPattern() {
|
||||||
|
return collectionPattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCollectionPattern(String collectionPattern) {
|
||||||
|
this.collectionPattern = collectionPattern;
|
||||||
|
this.collectionLayout = new PatternLayout(collectionPattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getApplicationId() {
|
||||||
|
return applicationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApplicationId(String applicationId) {
|
||||||
|
this.applicationId = applicationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWarnOrHigherWriteConcern(String wc) {
|
||||||
|
this.warnOrHigherWriteConcern = WriteConcern.valueOf(wc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getWarnOrHigherWriteConcern() {
|
||||||
|
return warnOrHigherWriteConcern.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInfoOrLowerWriteConcern() {
|
||||||
|
return infoOrLowerWriteConcern.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInfoOrLowerWriteConcern(String wc) {
|
||||||
|
this.infoOrLowerWriteConcern = WriteConcern.valueOf(wc);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void connectToMongo() throws UnknownHostException {
|
||||||
|
this.mongo = new MongoClient(host, port);
|
||||||
|
this.db = mongo.getDB(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.apache.log4j.AppenderSkeleton#append(org.apache.log4j.spi.LoggingEvent)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings({ "unchecked" })
|
||||||
|
protected void append(final LoggingEvent event) {
|
||||||
|
if (null == db) {
|
||||||
|
try {
|
||||||
|
connectToMongo();
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
throw new RuntimeException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BasicDBObject dbo = new BasicDBObject();
|
||||||
|
if (null != applicationId) {
|
||||||
|
dbo.put(APP_ID, applicationId);
|
||||||
|
MDC.put(APP_ID, applicationId);
|
||||||
|
}
|
||||||
|
dbo.put(NAME, event.getLogger().getName());
|
||||||
|
dbo.put(LEVEL, event.getLevel().toString());
|
||||||
|
Calendar tstamp = Calendar.getInstance();
|
||||||
|
tstamp.setTimeInMillis(event.getTimeStamp());
|
||||||
|
dbo.put(TIMESTAMP, tstamp.getTime());
|
||||||
|
|
||||||
|
// Copy properties into document
|
||||||
|
Map<Object, Object> props = event.getProperties();
|
||||||
|
if (null != props && !props.isEmpty()) {
|
||||||
|
BasicDBObject propsDbo = new BasicDBObject();
|
||||||
|
for (Map.Entry<Object, Object> entry : props.entrySet()) {
|
||||||
|
propsDbo.put(entry.getKey().toString(), entry.getValue().toString());
|
||||||
|
}
|
||||||
|
dbo.put(PROPERTIES, propsDbo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy traceback info (if there is any) into the document
|
||||||
|
String[] traceback = event.getThrowableStrRep();
|
||||||
|
if (null != traceback && traceback.length > 0) {
|
||||||
|
BasicDBList tbDbo = new BasicDBList();
|
||||||
|
tbDbo.addAll(Arrays.asList(traceback));
|
||||||
|
dbo.put(TRACEBACK, tbDbo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put the rendered message into the document
|
||||||
|
dbo.put(MESSAGE, event.getRenderedMessage());
|
||||||
|
|
||||||
|
// Insert the document
|
||||||
|
Calendar now = Calendar.getInstance();
|
||||||
|
MDC.put(YEAR, now.get(Calendar.YEAR));
|
||||||
|
MDC.put(MONTH, String.format("%1$02d", now.get(Calendar.MONTH) + 1));
|
||||||
|
MDC.put(DAY, String.format("%1$02d", now.get(Calendar.DAY_OF_MONTH)));
|
||||||
|
MDC.put(HOUR, String.format("%1$02d", now.get(Calendar.HOUR_OF_DAY)));
|
||||||
|
|
||||||
|
String coll = collectionLayout.format(event);
|
||||||
|
|
||||||
|
MDC.remove(YEAR);
|
||||||
|
MDC.remove(MONTH);
|
||||||
|
MDC.remove(DAY);
|
||||||
|
MDC.remove(HOUR);
|
||||||
|
if (null != applicationId) {
|
||||||
|
MDC.remove(APP_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteConcern wc;
|
||||||
|
if (event.getLevel().isGreaterOrEqual(Level.WARN)) {
|
||||||
|
wc = warnOrHigherWriteConcern;
|
||||||
|
} else {
|
||||||
|
wc = infoOrLowerWriteConcern;
|
||||||
|
}
|
||||||
|
db.getCollection(coll).insert(dbo, wc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.apache.log4j.AppenderSkeleton#close()
|
||||||
|
*/
|
||||||
|
public void close() {
|
||||||
|
|
||||||
|
if (mongo != null) {
|
||||||
|
mongo.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.apache.log4j.AppenderSkeleton#requiresLayout()
|
||||||
|
*/
|
||||||
|
public boolean requiresLayout() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
/**
|
||||||
|
* Infrastructure for to use MongoDB as a logging sink.
|
||||||
|
*/
|
||||||
|
package org.springframework.data.mongodb.log4j;
|
||||||
|
|
||||||
@@ -1,75 +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.log4j;
|
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.*;
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import java.util.Calendar;
|
|
||||||
|
|
||||||
import com.mongodb.DB;
|
|
||||||
import com.mongodb.DBCursor;
|
|
||||||
import com.mongodb.Mongo;
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
import org.apache.log4j.MDC;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
|
||||||
*/
|
|
||||||
public class AppenderTest {
|
|
||||||
|
|
||||||
private static final String NAME = AppenderTest.class.getName();
|
|
||||||
private Logger log = Logger.getLogger(NAME);
|
|
||||||
private Mongo mongo;
|
|
||||||
private DB db;
|
|
||||||
private String collection;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setup() {
|
|
||||||
try {
|
|
||||||
mongo = new Mongo("localhost", 27017);
|
|
||||||
db = mongo.getDB("logs");
|
|
||||||
Calendar now = Calendar.getInstance();
|
|
||||||
collection = String.valueOf(now.get(Calendar.YEAR)) + String.format("%1$02d", now.get(Calendar.MONTH) + 1);
|
|
||||||
db.getCollection(collection).drop();
|
|
||||||
} catch (UnknownHostException e) {
|
|
||||||
throw new RuntimeException(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testLogging() {
|
|
||||||
log.debug("DEBUG message");
|
|
||||||
log.info("INFO message");
|
|
||||||
log.warn("WARN message");
|
|
||||||
log.error("ERROR message");
|
|
||||||
|
|
||||||
DBCursor msgs = db.getCollection(collection).find();
|
|
||||||
assertThat(msgs.count(), is(4));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testProperties() {
|
|
||||||
MDC.put("property", "one");
|
|
||||||
log.debug("DEBUG message");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011-2016 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.log4j;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.apache.log4j.MDC;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.mongodb.BasicDBObject;
|
||||||
|
import com.mongodb.DB;
|
||||||
|
import com.mongodb.DBCursor;
|
||||||
|
import com.mongodb.MongoClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integration tests for {@link MongoLog4jAppender}.
|
||||||
|
*
|
||||||
|
* @author Jon Brisbin
|
||||||
|
* @author Oliver Gierke
|
||||||
|
* @author Christoph Strobl
|
||||||
|
*/
|
||||||
|
public class MongoLog4jAppenderIntegrationTests {
|
||||||
|
|
||||||
|
static final String NAME = MongoLog4jAppenderIntegrationTests.class.getName();
|
||||||
|
|
||||||
|
private static final Logger log = Logger.getLogger(NAME);
|
||||||
|
MongoClient mongo;
|
||||||
|
DB db;
|
||||||
|
String collection;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
|
||||||
|
mongo = new MongoClient("localhost", 27017);
|
||||||
|
db = mongo.getDB("logs");
|
||||||
|
|
||||||
|
Calendar now = Calendar.getInstance();
|
||||||
|
collection = String.valueOf(now.get(Calendar.YEAR)) + String.format("%1$02d", now.get(Calendar.MONTH) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
db.getCollection(collection).remove(new BasicDBObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLogging() {
|
||||||
|
|
||||||
|
log.debug("DEBUG message");
|
||||||
|
log.info("INFO message");
|
||||||
|
log.warn("WARN message");
|
||||||
|
log.error("ERROR message");
|
||||||
|
|
||||||
|
DBCursor msgs = db.getCollection(collection).find();
|
||||||
|
assertThat(msgs.count(), is(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testProperties() {
|
||||||
|
|
||||||
|
MDC.put("property", "one");
|
||||||
|
log.debug("DEBUG message");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 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.log4j;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for {@link MongoLog4jAppender}.
|
||||||
|
*
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
|
public class MongoLog4jAppenderUnitTests {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see DATAMONGO-641
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void closesWithoutMongoInstancePresent() {
|
||||||
|
new MongoLog4jAppender().close();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
log4j.rootCategory=INFO, stdout
|
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=org.apache.log4j.PatternLayout
|
||||||
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
|
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
|
||||||
log4j.appender.stdout.host = localhost
|
log4j.appender.stdout.host = localhost
|
||||||
@@ -10,11 +10,4 @@ log4j.appender.stdout.collectionPattern = %X{year}%X{month}
|
|||||||
log4j.appender.stdout.applicationId = my.application
|
log4j.appender.stdout.applicationId = my.application
|
||||||
log4j.appender.stdout.warnOrHigherWriteConcern = FSYNC_SAFE
|
log4j.appender.stdout.warnOrHigherWriteConcern = FSYNC_SAFE
|
||||||
|
|
||||||
log4j.category.org.apache.activemq=ERROR
|
log4j.category.org.springframework.data.mongodb=DEBUG
|
||||||
log4j.category.org.springframework.batch=DEBUG
|
|
||||||
log4j.category.org.springframework.data.document.mongodb=DEBUG
|
|
||||||
log4j.category.org.springframework.transaction=INFO
|
|
||||||
|
|
||||||
log4j.category.org.hibernate.SQL=DEBUG
|
|
||||||
# for debugging datasource initialization
|
|
||||||
# log4j.category.test.jdbc=DEBUG
|
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
Bundle-SymbolicName: org.springframework.data.mongodb.log4j
|
|
||||||
Bundle-Name: Spring Data Mongo DB Log4J Appender
|
|
||||||
Bundle-Vendor: SpringSource
|
|
||||||
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)"
|
|
||||||
@@ -1,116 +1,227 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
<context version="7.0.3.1152">
|
<context version="7.2.2.230">
|
||||||
<scope name="spring-data-mongodb" type="Project">
|
<scope type="Project" name="spring-data-mongodb">
|
||||||
<element name="Filter" type="TypeFilterReferenceOverridden">
|
<element type="TypeFilterReferenceOverridden" name="Filter">
|
||||||
<element name="org.springframework.data.mongodb.**" type="IncludeTypePattern"/>
|
<element type="IncludeTypePattern" name="org.springframework.data.mongodb.**"/>
|
||||||
</element>
|
</element>
|
||||||
<architecture>
|
<architecture>
|
||||||
<element name="Config" type="Layer">
|
<element type="Layer" name="Repositories">
|
||||||
<element name="Assignment" type="TypeFilter">
|
<element type="TypeFilter" name="Assignment">
|
||||||
<element name="**.config.**" type="IncludeTypePattern"/>
|
<element type="IncludeTypePattern" name="**.repository.**"/>
|
||||||
</element>
|
</element>
|
||||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Core"/>
|
<element type="Subsystem" name="API">
|
||||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Monitoring"/>
|
<element type="TypeFilter" name="Assignment">
|
||||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Repositories"/>
|
<element type="IncludeTypePattern" name="**.repository.*"/>
|
||||||
|
</element>
|
||||||
|
</element>
|
||||||
|
<element type="Subsystem" name="Query">
|
||||||
|
<element type="TypeFilter" name="Assignment">
|
||||||
|
<element type="IncludeTypePattern" name="**.query.**"/>
|
||||||
|
</element>
|
||||||
|
<dependency toName="Project|spring-data-mongodb::Layer|Repositories::Subsystem|API" type="AllowedDependency"/>
|
||||||
|
</element>
|
||||||
|
<element type="Subsystem" name="Implementation">
|
||||||
|
<element type="TypeFilter" name="Assignment">
|
||||||
|
<element type="IncludeTypePattern" name="**.support.**"/>
|
||||||
|
</element>
|
||||||
|
<dependency toName="Project|spring-data-mongodb::Layer|Repositories::Subsystem|API" type="AllowedDependency"/>
|
||||||
|
<dependency toName="Project|spring-data-mongodb::Layer|Repositories::Subsystem|Query" type="AllowedDependency"/>
|
||||||
|
</element>
|
||||||
|
<element type="Subsystem" name="Config">
|
||||||
|
<element type="TypeFilter" name="Assignment">
|
||||||
|
<element type="IncludeTypePattern" name="**.config.**"/>
|
||||||
|
</element>
|
||||||
|
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Mapping" type="AllowedDependency"/>
|
||||||
|
<dependency toName="Project|spring-data-mongodb::Layer|Repositories::Subsystem|API" type="AllowedDependency"/>
|
||||||
|
<dependency toName="Project|spring-data-mongodb::Layer|Repositories::Subsystem|Implementation" type="AllowedDependency"/>
|
||||||
|
</element>
|
||||||
|
<element type="Subsystem" name="CDI">
|
||||||
|
<element type="TypeFilter" name="Assignment">
|
||||||
|
<element type="IncludeTypePattern" name="**.cdi.**"/>
|
||||||
|
</element>
|
||||||
|
<stereotype name="Unrestricted"/>
|
||||||
|
</element>
|
||||||
|
<dependency toName="Project|spring-data-mongodb::Layer|Config" type="AllowedDependency"/>
|
||||||
|
<dependency toName="Project|spring-data-mongodb::Layer|Core" type="AllowedDependency"/>
|
||||||
</element>
|
</element>
|
||||||
<element name="Repositories" type="Layer">
|
<element type="Layer" name="Config">
|
||||||
<element name="Assignment" type="TypeFilter">
|
<element type="TypeFilter" name="Assignment">
|
||||||
<element name="**.repository.**" type="IncludeTypePattern"/>
|
<element type="WeakTypePattern" name="**.config.**"/>
|
||||||
</element>
|
</element>
|
||||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Core"/>
|
<dependency toName="Project|spring-data-mongodb::Layer|Core" type="AllowedDependency"/>
|
||||||
|
<dependency toName="Project|spring-data-mongodb::Layer|GridFS" type="AllowedDependency"/>
|
||||||
|
<dependency toName="Project|spring-data-mongodb::Layer|Monitoring" type="AllowedDependency"/>
|
||||||
</element>
|
</element>
|
||||||
<element name="Monitoring" type="Layer">
|
<element type="Layer" name="Monitoring">
|
||||||
<element name="Assignment" type="TypeFilter">
|
<element type="TypeFilter" name="Assignment">
|
||||||
<element name="**.monitor.**" type="IncludeTypePattern"/>
|
<element type="IncludeTypePattern" name="**.monitor.**"/>
|
||||||
</element>
|
</element>
|
||||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Core"/>
|
<dependency toName="Project|spring-data-mongodb::Layer|Core" type="AllowedDependency"/>
|
||||||
</element>
|
</element>
|
||||||
<element name="Core" type="Layer">
|
<element type="Layer" name="GridFS">
|
||||||
<element name="Assignment" type="TypeFilter">
|
<element type="TypeFilter" name="Assignment">
|
||||||
<element name="**.core.**" type="IncludeTypePattern"/>
|
<element type="IncludeTypePattern" name="**.gridfs.**"/>
|
||||||
</element>
|
</element>
|
||||||
<element name="Mapping" type="Subsystem">
|
<dependency toName="Project|spring-data-mongodb::Layer|Core" type="AllowedDependency"/>
|
||||||
<element name="Assignment" type="TypeFilter">
|
</element>
|
||||||
<element name="**.mapping.**" type="IncludeTypePattern"/>
|
<element type="Layer" name="Core">
|
||||||
|
<element type="TypeFilter" name="Assignment"/>
|
||||||
|
<element type="Subsystem" name="Mapping">
|
||||||
|
<element type="TypeFilter" name="Assignment">
|
||||||
|
<element type="IncludeTypePattern" name="**.core.mapping.**"/>
|
||||||
</element>
|
</element>
|
||||||
</element>
|
</element>
|
||||||
<element name="Geospatial" type="Subsystem">
|
<element type="Subsystem" name="Geospatial">
|
||||||
<element name="Assignment" type="TypeFilter">
|
<element type="TypeFilter" name="Assignment">
|
||||||
<element name="**.geo.**" type="IncludeTypePattern"/>
|
<element type="IncludeTypePattern" name="**.core.geo.**"/>
|
||||||
</element>
|
</element>
|
||||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Mapping"/>
|
|
||||||
</element>
|
</element>
|
||||||
<element name="Query" type="Subsystem">
|
<element type="Subsystem" name="Query">
|
||||||
<element name="Assignment" type="TypeFilter">
|
<element type="TypeFilter" name="Assignment">
|
||||||
<element name="**.query.**" type="IncludeTypePattern"/>
|
<element type="IncludeTypePattern" name="**.core.query.**"/>
|
||||||
</element>
|
</element>
|
||||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Geospatial"/>
|
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Geospatial" type="AllowedDependency"/>
|
||||||
</element>
|
</element>
|
||||||
<element name="Index" type="Subsystem">
|
<element type="Subsystem" name="Script">
|
||||||
<element name="Assignment" type="TypeFilter">
|
<element type="TypeFilter" name="Assignment">
|
||||||
<element name="**.index.**" type="IncludeTypePattern"/>
|
<element type="IncludeTypePattern" name="**.script.**"/>
|
||||||
</element>
|
</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>
|
||||||
<element name="Core" type="Subsystem">
|
<element type="Subsystem" name="Conversion">
|
||||||
<element name="Assignment" type="TypeFilter">
|
<element type="TypeFilter" name="Assignment">
|
||||||
<element name="**.core.**" type="WeakTypePattern"/>
|
<element type="IncludeTypePattern" name="**.core.convert.**"/>
|
||||||
</element>
|
</element>
|
||||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Geospatial"/>
|
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Geospatial" type="AllowedDependency"/>
|
||||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Index"/>
|
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Mapping" type="AllowedDependency"/>
|
||||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Mapping"/>
|
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Query" type="AllowedDependency"/>
|
||||||
<dependency type="AllowedDependency" toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Query"/>
|
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Script" type="AllowedDependency"/>
|
||||||
</element>
|
</element>
|
||||||
|
<element type="Subsystem" name="SpEL">
|
||||||
|
<element type="TypeFilter" name="Assignment">
|
||||||
|
<element type="IncludeTypePattern" name="**.core.spel.**"/>
|
||||||
|
</element>
|
||||||
|
</element>
|
||||||
|
<element type="Subsystem" name="Aggregation">
|
||||||
|
<element type="TypeFilter" name="Assignment">
|
||||||
|
<element type="IncludeTypePattern" name="**.core.aggregation.**"/>
|
||||||
|
</element>
|
||||||
|
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Conversion" type="AllowedDependency"/>
|
||||||
|
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Mapping" type="AllowedDependency"/>
|
||||||
|
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Query" type="AllowedDependency"/>
|
||||||
|
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|SpEL" type="AllowedDependency"/>
|
||||||
|
</element>
|
||||||
|
<element type="Subsystem" name="Index">
|
||||||
|
<element type="TypeFilter" name="Assignment">
|
||||||
|
<element type="IncludeTypePattern" name="**.core.index.**"/>
|
||||||
|
</element>
|
||||||
|
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Mapping" type="AllowedDependency"/>
|
||||||
|
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Query" type="AllowedDependency"/>
|
||||||
|
</element>
|
||||||
|
<element type="Subsystem" name="MapReduce">
|
||||||
|
<element type="TypeFilter" name="Assignment">
|
||||||
|
<element type="IncludeTypePattern" name="**.mapreduce.**"/>
|
||||||
|
</element>
|
||||||
|
</element>
|
||||||
|
<element type="Subsystem" name="Core">
|
||||||
|
<element type="TypeFilter" name="Assignment">
|
||||||
|
<element type="WeakTypePattern" name="**.core.**"/>
|
||||||
|
</element>
|
||||||
|
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Aggregation" type="AllowedDependency"/>
|
||||||
|
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Conversion" type="AllowedDependency"/>
|
||||||
|
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Geospatial" type="AllowedDependency"/>
|
||||||
|
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Index" type="AllowedDependency"/>
|
||||||
|
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|MapReduce" type="AllowedDependency"/>
|
||||||
|
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Mapping" type="AllowedDependency"/>
|
||||||
|
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Query" type="AllowedDependency"/>
|
||||||
|
<dependency toName="Project|spring-data-mongodb::Layer|Core::Subsystem|Script" type="AllowedDependency"/>
|
||||||
|
</element>
|
||||||
|
<element type="Subsystem" name="Util">
|
||||||
|
<element type="TypeFilter" name="Assignment">
|
||||||
|
<element type="IncludeTypePattern" name="**.util.**"/>
|
||||||
|
</element>
|
||||||
|
<stereotype name="Unrestricted"/>
|
||||||
|
<stereotype name="Public"/>
|
||||||
|
</element>
|
||||||
|
</element>
|
||||||
|
<element type="Subsystem" name="API">
|
||||||
|
<element type="TypeFilter" name="Assignment">
|
||||||
|
<element type="IncludeTypePattern" name="org.springframework.data.mongodb.*"/>
|
||||||
|
</element>
|
||||||
|
<stereotype name="Public"/>
|
||||||
</element>
|
</element>
|
||||||
</architecture>
|
</architecture>
|
||||||
<workspace>
|
<workspace>
|
||||||
<element name="src/main/java" type="JavaRootDirectory">
|
<element type="JavaRootDirectory" name="src/main/java">
|
||||||
<reference name="Project|spring-data-mongodb::BuildUnit|spring-data-mongodb"/>
|
<reference name="Project|spring-data-mongodb::BuildUnit|spring-data-mongodb"/>
|
||||||
</element>
|
</element>
|
||||||
<element name="target/classes" type="JavaRootDirectory">
|
<element type="JavaRootDirectory" name="target/classes">
|
||||||
<reference name="Project|spring-data-mongodb::BuildUnit|spring-data-mongodb"/>
|
<reference name="Project|spring-data-mongodb::BuildUnit|spring-data-mongodb"/>
|
||||||
</element>
|
</element>
|
||||||
</workspace>
|
</workspace>
|
||||||
<physical>
|
<physical>
|
||||||
<element name="spring-data-mongodb" type="BuildUnit"/>
|
<element type="BuildUnit" name="spring-data-mongodb"/>
|
||||||
</physical>
|
</physical>
|
||||||
</scope>
|
</scope>
|
||||||
<scope name="External" type="External">
|
<scope type="External" name="External">
|
||||||
<element name="Filter" type="TypeFilter">
|
<element type="TypeFilter" name="Filter">
|
||||||
<element name="**" type="IncludeTypePattern"/>
|
<element type="IncludeTypePattern" name="**"/>
|
||||||
<element name="java.**" type="ExcludeTypePattern"/>
|
<element type="ExcludeTypePattern" name="java.**"/>
|
||||||
<element name="javax.**" type="ExcludeTypePattern"/>
|
<element type="ExcludeTypePattern" name="javax.**"/>
|
||||||
</element>
|
</element>
|
||||||
<architecture>
|
<architecture>
|
||||||
<element name="Spring" type="Subsystem">
|
<element type="Subsystem" name="Spring">
|
||||||
<element name="Assignment" type="TypeFilter">
|
<element type="TypeFilter" name="Assignment">
|
||||||
<element name="org.springframework.**" type="IncludeTypePattern"/>
|
<element type="IncludeTypePattern" name="org.springframework.**"/>
|
||||||
<element name="org.springframework.data.**" type="ExcludeTypePattern"/>
|
<element type="ExcludeTypePattern" name="org.springframework.data.**"/>
|
||||||
</element>
|
</element>
|
||||||
</element>
|
</element>
|
||||||
<element name="Spring Data Core" type="Subsystem">
|
<element type="Subsystem" name="Spring Data Core">
|
||||||
<element name="Assignment" type="TypeFilter">
|
<element type="TypeFilter" name="Assignment">
|
||||||
<element name="org.springframework.data.**" type="IncludeTypePattern"/>
|
<element type="IncludeTypePattern" name="org.springframework.data.**"/>
|
||||||
</element>
|
</element>
|
||||||
</element>
|
</element>
|
||||||
<element name="Mongo Java Driver" type="Subsystem">
|
<element type="Subsystem" name="Mongo Java Driver">
|
||||||
<element name="Assignment" type="TypeFilter">
|
<element type="TypeFilter" name="Assignment">
|
||||||
<element name="com.mongodb.**" type="IncludeTypePattern"/>
|
<element type="IncludeTypePattern" name="com.mongodb.**"/>
|
||||||
<element name="org.bson.**" type="IncludeTypePattern"/>
|
<element type="IncludeTypePattern" name="org.bson.**"/>
|
||||||
</element>
|
</element>
|
||||||
</element>
|
</element>
|
||||||
<element name="Querydsl" type="Subsystem">
|
<element type="Subsystem" name="Querydsl">
|
||||||
<element name="Assignment" type="TypeFilter">
|
<element type="TypeFilter" name="Assignment">
|
||||||
<element name="com.mysema.query.**" type="IncludeTypePattern"/>
|
<element type="IncludeTypePattern" name="com.querydsl.**"/>
|
||||||
|
</element>
|
||||||
|
</element>
|
||||||
|
<element type="Subsystem" name="Slf4j">
|
||||||
|
<element type="TypeFilter" name="Assignment">
|
||||||
|
<element type="IncludeTypePattern" name="org.slf4j.**"/>
|
||||||
|
</element>
|
||||||
|
</element>
|
||||||
|
<element type="Subsystem" name="Jackson">
|
||||||
|
<element type="TypeFilter" name="Assignment">
|
||||||
|
<element type="IncludeTypePattern" name="com.fasterxml.jackson.**"/>
|
||||||
|
</element>
|
||||||
|
</element>
|
||||||
|
<element type="Subsystem" name="DOM">
|
||||||
|
<element type="TypeFilter" name="Assignment">
|
||||||
|
<element type="IncludeTypePattern" name="org.w3c.dom.**"/>
|
||||||
|
</element>
|
||||||
|
</element>
|
||||||
|
<element type="Subsystem" name="AOP Alliance">
|
||||||
|
<element type="TypeFilter" name="Assignment">
|
||||||
|
<element type="IncludeTypePattern" name="org.aopalliance.**"/>
|
||||||
|
</element>
|
||||||
|
</element>
|
||||||
|
<element type="Subsystem" name="Guava">
|
||||||
|
<element type="TypeFilter" name="Assignment">
|
||||||
|
<element type="IncludeTypePattern" name="com.google.common.**"/>
|
||||||
</element>
|
</element>
|
||||||
</element>
|
</element>
|
||||||
</architecture>
|
</architecture>
|
||||||
</scope>
|
</scope>
|
||||||
<scope name="Global" type="Global">
|
<scope type="Global" name="Global">
|
||||||
<element name="Configuration" type="Configuration"/>
|
<element type="Configuration" name="Configuration"/>
|
||||||
<element name="Filter" type="TypeFilter">
|
<element type="TypeFilter" name="Filter">
|
||||||
<element name="**" type="IncludeTypePattern"/>
|
<element type="IncludeTypePattern" name="**"/>
|
||||||
</element>
|
</element>
|
||||||
</scope>
|
</scope>
|
||||||
</context>
|
</context>
|
||||||
|
|||||||
@@ -1,145 +1,239 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<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">
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>spring-data-mongodb</artifactId>
|
||||||
|
|
||||||
|
<name>Spring Data MongoDB - Core</name>
|
||||||
|
<description>MongoDB support for Spring Data</description>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.data</groupId>
|
<groupId>org.springframework.data</groupId>
|
||||||
<artifactId>spring-data-document-parent</artifactId>
|
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||||
<version>1.0.0.M4</version>
|
<version>2.0.0.M1</version>
|
||||||
<relativePath>../spring-data-document-parent/pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>spring-data-mongodb</artifactId>
|
|
||||||
<packaging>jar</packaging>
|
|
||||||
<name>Spring Data MongoDB Support</name>
|
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<mongo.version>2.6.5</mongo.version>
|
<objenesis>1.3</objenesis>
|
||||||
<querydsl.version>2.2.0</querydsl.version>
|
<equalsverifier>1.5</equalsverifier>
|
||||||
|
<mongo>3.3.0</mongo>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
<!-- Spring -->
|
<!-- Spring -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-tx</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-context</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-beans</artifactId>
|
<artifactId>spring-beans</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-expression</artifactId>
|
<artifactId>spring-core</artifactId>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>commons-logging</groupId>
|
||||||
|
<artifactId>commons-logging</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-test</artifactId>
|
<artifactId>spring-expression</artifactId>
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Spring Data -->
|
<!-- Spring Data -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.data</groupId>
|
<groupId>${project.groupId}</groupId>
|
||||||
<artifactId>spring-data-commons-core</artifactId>
|
<artifactId>spring-data-commons</artifactId>
|
||||||
<version>${data.commons.version}</version>
|
<version>${springdata.commons}</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>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.mysema.querydsl</groupId>
|
<groupId>com.querydsl</groupId>
|
||||||
<artifactId>querydsl-mongodb</artifactId>
|
<artifactId>querydsl-mongodb</artifactId>
|
||||||
<version>${querydsl.version}</version>
|
<version>${querydsl}</version>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>com.google.code.morphia</groupId>
|
|
||||||
<artifactId>morphia</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.mysema.querydsl</groupId>
|
<groupId>com.querydsl</groupId>
|
||||||
<artifactId>querydsl-apt</artifactId>
|
<artifactId>querydsl-apt</artifactId>
|
||||||
<version>${querydsl.version}</version>
|
<version>${querydsl}</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.annotation</groupId>
|
<groupId>javax.annotation</groupId>
|
||||||
<artifactId>jsr250-api</artifactId>
|
<artifactId>jsr250-api</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Test dependencies -->
|
<!-- reactive -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mockito</groupId>
|
<groupId>org.mongodb</groupId>
|
||||||
<artifactId>mockito-all</artifactId>
|
<artifactId>mongodb-driver-reactivestreams</artifactId>
|
||||||
|
<version>${mongo.reactivestreams}</version>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mongodb</groupId>
|
||||||
|
<artifactId>mongodb-driver-async</artifactId>
|
||||||
|
<version>${mongo}</version>
|
||||||
|
<optional>true</optional>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.mongodb</groupId>
|
||||||
|
<artifactId>mongodb-driver-core</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.mongodb</groupId>
|
||||||
|
<artifactId>bson</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.projectreactor</groupId>
|
||||||
|
<artifactId>reactor-core</artifactId>
|
||||||
|
<version>${reactor}</version>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.reactivex</groupId>
|
||||||
|
<artifactId>rxjava</artifactId>
|
||||||
|
<version>${rxjava}</version>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.reactivex</groupId>
|
||||||
|
<artifactId>rxjava-reactive-streams</artifactId>
|
||||||
|
<version>${rxjava-reactive-streams}</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>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.hamcrest</groupId>
|
<groupId>org.apache.openwebbeans.test</groupId>
|
||||||
<artifactId>hamcrest-all</artifactId>
|
<artifactId>cditest-owb</artifactId>
|
||||||
<version>1.1</version>
|
<version>${webbeans}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>javax.servlet</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<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>org.objenesis</groupId>
|
||||||
|
<artifactId>objenesis</artifactId>
|
||||||
|
<version>${objenesis}</version>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hibernate</groupId>
|
||||||
|
<artifactId>hibernate-validator</artifactId>
|
||||||
|
<version>5.2.4.Final</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>joda-time</groupId>
|
<groupId>joda-time</groupId>
|
||||||
<artifactId>joda-time</artifactId>
|
<artifactId>joda-time</artifactId>
|
||||||
<version>1.6</version>
|
<version>${jodatime}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.threeten</groupId>
|
||||||
<artifactId>slf4j-api</artifactId>
|
<artifactId>threetenbp</artifactId>
|
||||||
<scope>test</scope>
|
<version>${threetenbp}</version>
|
||||||
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
<version>${jackson}</version>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>jcl-over-slf4j</artifactId>
|
<artifactId>jul-to-slf4j</artifactId>
|
||||||
|
<version>${slf4j}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>nl.jqno.equalsverifier</groupId>
|
||||||
<artifactId>slf4j-log4j12</artifactId>
|
<artifactId>equalsverifier</artifactId>
|
||||||
|
<version>${equalsverifier}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>log4j</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>log4j</artifactId>
|
<artifactId>spring-webmvc</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
|
||||||
<groupId>com.springsource.bundlor</groupId>
|
|
||||||
<artifactId>com.springsource.bundlor.maven</artifactId>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>com.mysema.maven</groupId>
|
<groupId>com.mysema.maven</groupId>
|
||||||
<artifactId>maven-apt-plugin</artifactId>
|
<artifactId>apt-maven-plugin</artifactId>
|
||||||
<version>1.0.2</version>
|
<version>${apt}</version>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.querydsl</groupId>
|
||||||
|
<artifactId>querydsl-apt</artifactId>
|
||||||
|
<version>${querydsl}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<phase>generate-test-sources</phase>
|
<phase>generate-test-sources</phase>
|
||||||
@@ -148,22 +242,37 @@
|
|||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<outputDirectory>target/generated-test-sources</outputDirectory>
|
<outputDirectory>target/generated-test-sources</outputDirectory>
|
||||||
<processor>org.springframework.data.mongodb.repository.MongoAnnotationProcessor</processor>
|
<processor>org.springframework.data.mongodb.repository.support.MongoAnnotationProcessor</processor>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</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>
|
||||||
|
<exclude>**/ReactivePerformanceTests.java</exclude>
|
||||||
|
</excludes>
|
||||||
|
<systemPropertyVariables>
|
||||||
|
<java.util.logging.config.file>src/test/resources/logging.properties</java.util.logging.config.file>
|
||||||
|
<reactor.trace.cancel>true</reactor.trace.cancel>
|
||||||
|
</systemPropertyVariables>
|
||||||
|
<properties>
|
||||||
|
<property>
|
||||||
|
<name>listener</name>
|
||||||
|
<value>org.springframework.data.mongodb.test.util.CleanMongoDBJunitRunListener</value>
|
||||||
|
</property>
|
||||||
|
</properties>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</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>
|
</project>
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 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;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.dao.DataAccessException;
|
||||||
|
|
||||||
|
import com.mongodb.BulkWriteError;
|
||||||
|
import com.mongodb.BulkWriteException;
|
||||||
|
import com.mongodb.BulkWriteResult;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is thrown when errors occur during bulk operations.
|
||||||
|
*
|
||||||
|
* @author Tobias Trelle
|
||||||
|
* @author Oliver Gierke
|
||||||
|
* @since 1.9
|
||||||
|
*/
|
||||||
|
public class BulkOperationException extends DataAccessException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 73929601661154421L;
|
||||||
|
|
||||||
|
private final List<BulkWriteError> errors;
|
||||||
|
private final BulkWriteResult result;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link BulkOperationException} with the given message and source {@link BulkWriteException}.
|
||||||
|
*
|
||||||
|
* @param message must not be {@literal null}.
|
||||||
|
* @param source must not be {@literal null}.
|
||||||
|
*/
|
||||||
|
public BulkOperationException(String message, BulkWriteException source) {
|
||||||
|
|
||||||
|
super(message, source);
|
||||||
|
|
||||||
|
this.errors = source.getWriteErrors();
|
||||||
|
this.result = source.getWriteResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<BulkWriteError> getErrors() {
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BulkWriteResult getResult() {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2011 the original author or authors.
|
* Copyright 2010-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -16,42 +16,51 @@
|
|||||||
package org.springframework.data.mongodb;
|
package org.springframework.data.mongodb;
|
||||||
|
|
||||||
import org.springframework.dao.DataAccessResourceFailureException;
|
import org.springframework.dao.DataAccessResourceFailureException;
|
||||||
|
import org.springframework.data.authentication.UserCredentials;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception being thrown in case we cannot connect to a MongoDB instance.
|
||||||
|
*
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
public class CannotGetMongoDbConnectionException extends DataAccessResourceFailureException {
|
public class CannotGetMongoDbConnectionException extends DataAccessResourceFailureException {
|
||||||
|
|
||||||
private String username;
|
private final UserCredentials credentials;
|
||||||
|
private final String database;
|
||||||
private char[] password;
|
|
||||||
|
|
||||||
private String database;
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1172099106475265589L;
|
private static final long serialVersionUID = 1172099106475265589L;
|
||||||
|
|
||||||
public CannotGetMongoDbConnectionException(String msg, Throwable cause) {
|
public CannotGetMongoDbConnectionException(String msg, Throwable cause) {
|
||||||
super(msg, cause);
|
super(msg, cause);
|
||||||
|
this.database = null;
|
||||||
|
this.credentials = UserCredentials.NO_CREDENTIALS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CannotGetMongoDbConnectionException(String msg) {
|
public CannotGetMongoDbConnectionException(String msg) {
|
||||||
super(msg);
|
this(msg, null, UserCredentials.NO_CREDENTIALS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CannotGetMongoDbConnectionException(String msg, String database, String username, char[] password2) {
|
public CannotGetMongoDbConnectionException(String msg, String database, UserCredentials credentials) {
|
||||||
super(msg);
|
super(msg);
|
||||||
this.username = username;
|
|
||||||
this.password = password2;
|
|
||||||
this.database = database;
|
this.database = database;
|
||||||
|
this.credentials = credentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUsername() {
|
/**
|
||||||
return username;
|
* Returns the {@link UserCredentials} that were used when trying to connect to the MongoDB instance.
|
||||||
}
|
*
|
||||||
|
* @return
|
||||||
public char[] getPassword() {
|
*/
|
||||||
return password;
|
public UserCredentials getCredentials() {
|
||||||
|
return this.credentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the database trying to be accessed.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public String getDatabase() {
|
public String getDatabase() {
|
||||||
return database;
|
return database;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2013 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -13,24 +13,22 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
package org.springframework.data.mongodb;
|
||||||
|
|
||||||
package org.springframework.data.document.couchdb.monitor;
|
import org.springframework.dao.UncategorizedDataAccessException;
|
||||||
|
|
||||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Server application to test JMX functionality.
|
* @author Oliver Gierke
|
||||||
*
|
|
||||||
* @author Mark Pollack
|
|
||||||
*/
|
*/
|
||||||
public class JmxServer {
|
public class LazyLoadingException extends UncategorizedDataAccessException {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
private static final long serialVersionUID = -7089224903873220037L;
|
||||||
new JmxServer().run();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
new ClassPathXmlApplicationContext(new String[]{"server-jmx.xml"});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param msg
|
||||||
|
* @param cause
|
||||||
|
*/
|
||||||
|
public LazyLoadingException(String msg, Throwable cause) {
|
||||||
|
super(msg, cause);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
package org.springframework.data.mongodb;
|
||||||
|
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
|
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||||
|
import org.springframework.data.mongodb.core.MongoExceptionTranslator;
|
||||||
|
|
||||||
import com.mongodb.DB;
|
import com.mongodb.DB;
|
||||||
|
import com.mongodb.client.MongoDatabase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for factories creating {@link DB} instances.
|
* Interface for factories creating {@link DB} instances.
|
||||||
*
|
*
|
||||||
* @author Mark Pollack
|
* @author Mark Pollack
|
||||||
|
* @author Thomas Darimont
|
||||||
*/
|
*/
|
||||||
public interface MongoDbFactory {
|
public interface MongoDbFactory {
|
||||||
|
|
||||||
@@ -17,7 +36,7 @@ public interface MongoDbFactory {
|
|||||||
* @return
|
* @return
|
||||||
* @throws DataAccessException
|
* @throws DataAccessException
|
||||||
*/
|
*/
|
||||||
DB getDb() throws DataAccessException;
|
MongoDatabase getDb() throws DataAccessException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@link DB} instance to access the database with the given name.
|
* Creates a {@link DB} instance to access the database with the given name.
|
||||||
@@ -26,5 +45,14 @@ public interface MongoDbFactory {
|
|||||||
* @return
|
* @return
|
||||||
* @throws DataAccessException
|
* @throws DataAccessException
|
||||||
*/
|
*/
|
||||||
DB getDb(String dbName) throws DataAccessException;
|
MongoDatabase getDb(String dbName) throws DataAccessException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exposes a shared {@link MongoExceptionTranslator}.
|
||||||
|
*
|
||||||
|
* @return will never be {@literal null}.
|
||||||
|
*/
|
||||||
|
PersistenceExceptionTranslator getExceptionTranslator();
|
||||||
|
|
||||||
|
DB getLegacyDb();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 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;
|
||||||
|
|
||||||
|
import org.springframework.dao.DataAccessException;
|
||||||
|
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||||
|
import org.springframework.data.mongodb.core.MongoExceptionTranslator;
|
||||||
|
|
||||||
|
import com.mongodb.reactivestreams.client.MongoDatabase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for factories creating reactive {@link MongoDatabase} instances.
|
||||||
|
*
|
||||||
|
* @author Mark Paluch
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public interface ReactiveMongoDatabaseFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a default {@link MongoDatabase} instance.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @throws DataAccessException
|
||||||
|
*/
|
||||||
|
MongoDatabase getMongoDatabase() throws DataAccessException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@link MongoDatabase} instance to access the database with the given name.
|
||||||
|
*
|
||||||
|
* @param dbName must not be {@literal null} or empty.
|
||||||
|
* @return
|
||||||
|
* @throws DataAccessException
|
||||||
|
*/
|
||||||
|
MongoDatabase getMongoDatabase(String dbName) throws DataAccessException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exposes a shared {@link MongoExceptionTranslator}.
|
||||||
|
*
|
||||||
|
* @return will never be {@literal null}.
|
||||||
|
*/
|
||||||
|
PersistenceExceptionTranslator getExceptionTranslator();
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2011 the original author or authors.
|
* Copyright 2011-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -15,97 +15,128 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.config;
|
package org.springframework.data.mongodb.config;
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import com.mongodb.Mongo;
|
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.core.type.filter.AnnotationTypeFilter;
|
|
||||||
import org.springframework.data.annotation.Persistent;
|
|
||||||
import org.springframework.data.authentication.UserCredentials;
|
import org.springframework.data.authentication.UserCredentials;
|
||||||
import org.springframework.data.mapping.context.MappingContextAwareBeanPostProcessor;
|
|
||||||
import org.springframework.data.mongodb.MongoDbFactory;
|
import org.springframework.data.mongodb.MongoDbFactory;
|
||||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||||
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
|
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
|
||||||
|
import org.springframework.data.mongodb.core.convert.DbRefResolver;
|
||||||
|
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
|
||||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||||
import org.springframework.data.mongodb.core.mapping.Document;
|
import org.springframework.data.mongodb.core.mapping.Document;
|
||||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
|
||||||
import org.springframework.util.ClassUtils;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
|
import com.mongodb.Mongo;
|
||||||
|
import com.mongodb.MongoClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for Spring Data MongoDB configuration using JavaConfig.
|
||||||
|
*
|
||||||
|
* @author Mark Pollack
|
||||||
|
* @author Oliver Gierke
|
||||||
|
* @author Thomas Darimont
|
||||||
|
* @author Ryan Tenney
|
||||||
|
* @author Christoph Strobl
|
||||||
|
* @author Mark Paluch
|
||||||
|
* @see MongoConfigurationSupport
|
||||||
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
public abstract class AbstractMongoConfiguration {
|
public abstract class AbstractMongoConfiguration extends MongoConfigurationSupport {
|
||||||
|
|
||||||
public abstract String getDatabaseName();
|
/**
|
||||||
|
* Return the name of the authentication database to use. Defaults to {@literal null} and will turn into the value
|
||||||
|
* returned by {@link #getDatabaseName()} later on effectively.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @deprecated since 1.7. {@link MongoClient} should hold authentication data within
|
||||||
|
* {@link MongoClient#getCredentialsList()}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
protected String getAuthenticationDatabaseName() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
/**
|
||||||
|
* Return the {@link Mongo} instance to connect to. Annotate with {@link Bean} in case you want to expose a
|
||||||
|
* {@link Mongo} instance to the {@link org.springframework.context.ApplicationContext}.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
public abstract Mongo mongo() throws Exception;
|
public abstract Mongo mongo() throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@link MongoTemplate}.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public MongoTemplate mongoTemplate() throws Exception {
|
public MongoTemplate mongoTemplate() throws Exception {
|
||||||
return new MongoTemplate(mongoDbFactory(), mappingMongoConverter());
|
return new MongoTemplate(mongoDbFactory(), mappingMongoConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@link SimpleMongoDbFactory} to be used by the {@link MongoTemplate}. Will use the {@link Mongo} instance
|
||||||
|
* configured in {@link #mongo()}.
|
||||||
|
*
|
||||||
|
* @see #mongo()
|
||||||
|
* @see #mongoTemplate()
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public MongoDbFactory mongoDbFactory() throws Exception {
|
public MongoDbFactory mongoDbFactory() throws Exception {
|
||||||
if (getUserCredentials() == null) {
|
return new SimpleMongoDbFactory(mongo(), getDatabaseName(), getUserCredentials(), getAuthenticationDatabaseName());
|
||||||
return new SimpleMongoDbFactory(mongo(), getDatabaseName());
|
|
||||||
} else {
|
|
||||||
return new SimpleMongoDbFactory(mongo(), getDatabaseName(), getUserCredentials());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMappingBasePackage() {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserCredentials getUserCredentials() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@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(mongoDbFactory(), mongoMappingContext());
|
|
||||||
afterMappingMongoConverterCreation(converter);
|
|
||||||
return converter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook that allows post-processing after the MappingMongoConverter has been successfully created.
|
* Return the base package to scan for mapped {@link Document}s. Will return the package name of the configuration
|
||||||
|
* class' (the concrete class, not this one here) by default. So if you have a {@code com.acme.AppConfig} extending
|
||||||
|
* {@link AbstractMongoConfiguration} the base package will be considered {@code com.acme} unless the method is
|
||||||
|
* overridden to implement alternate behavior.
|
||||||
*
|
*
|
||||||
* @param converter
|
* @return the base package to scan for mapped {@link Document} classes or {@literal null} to not enable scanning for
|
||||||
|
* entities.
|
||||||
|
* @deprecated use {@link #getMappingBasePackages()} instead.
|
||||||
*/
|
*/
|
||||||
protected void afterMappingMongoConverterCreation(MappingMongoConverter converter) {
|
@Deprecated
|
||||||
|
protected String getMappingBasePackage() {
|
||||||
|
|
||||||
|
Package mappingBasePackage = getClass().getPackage();
|
||||||
|
return mappingBasePackage == null ? null : mappingBasePackage.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return {@link UserCredentials} to be used when connecting to the MongoDB instance or {@literal null} if none shall
|
||||||
|
* be used.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @deprecated since 1.7. {@link MongoClient} should hold authentication data within
|
||||||
|
* {@link MongoClient#getCredentialsList()}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
protected UserCredentials getUserCredentials() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@link MappingMongoConverter} using the configured {@link #mongoDbFactory()} and
|
||||||
|
* {@link #mongoMappingContext()}. Will get {@link #customConversions()} applied.
|
||||||
|
*
|
||||||
|
* @see #customConversions()
|
||||||
|
* @see #mongoMappingContext()
|
||||||
|
* @see #mongoDbFactory()
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public MappingContextAwareBeanPostProcessor mappingContextAwareBeanPostProcessor() {
|
public MappingMongoConverter mappingMongoConverter() throws Exception {
|
||||||
MappingContextAwareBeanPostProcessor bpp = new MappingContextAwareBeanPostProcessor();
|
|
||||||
bpp.setMappingContextBeanName("mongoMappingContext");
|
|
||||||
return bpp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory());
|
||||||
|
MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, mongoMappingContext());
|
||||||
|
converter.setCustomConversions(customConversions());
|
||||||
|
|
||||||
|
return converter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 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.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.data.mongodb.ReactiveMongoDatabaseFactory;
|
||||||
|
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||||
|
import org.springframework.data.mongodb.core.ReactiveMongoOperations;
|
||||||
|
import org.springframework.data.mongodb.core.SimpleReactiveMongoDatabaseFactory;
|
||||||
|
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
|
||||||
|
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
|
||||||
|
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||||
|
|
||||||
|
import com.mongodb.reactivestreams.client.MongoClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for reactive Spring Data MongoDB configuration using JavaConfig.
|
||||||
|
*
|
||||||
|
* @author Mark Paluch
|
||||||
|
* @since 2.0
|
||||||
|
* @see MongoConfigurationSupport
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public abstract class AbstractReactiveMongoConfiguration extends MongoConfigurationSupport {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the {@link MongoClient} instance to connect to. Annotate with {@link Bean} in case you want to expose a
|
||||||
|
* {@link MongoClient} instance to the {@link org.springframework.context.ApplicationContext}.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public abstract MongoClient mongoClient();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@link ReactiveMongoTemplate}.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public ReactiveMongoOperations reactiveMongoTemplate() throws Exception {
|
||||||
|
return new ReactiveMongoTemplate(mongoDbFactory(), mappingMongoConverter());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@link SimpleMongoDbFactory} to be used by the {@link MongoTemplate}. Will use the {@link Mongo} instance
|
||||||
|
* configured in {@link #mongoClient()}.
|
||||||
|
*
|
||||||
|
* @see #mongoClient()
|
||||||
|
* @see #reactiveMongoTemplate()
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public ReactiveMongoDatabaseFactory mongoDbFactory() {
|
||||||
|
return new SimpleReactiveMongoDatabaseFactory(mongoClient(), getDatabaseName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@link MappingMongoConverter} using the configured {@link #mongoDbFactory()} and
|
||||||
|
* {@link #mongoMappingContext()}. Will get {@link #customConversions()} applied.
|
||||||
|
*
|
||||||
|
* @see #customConversions()
|
||||||
|
* @see #mongoMappingContext()
|
||||||
|
* @see #mongoDbFactory()
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public MappingMongoConverter mappingMongoConverter() throws Exception {
|
||||||
|
|
||||||
|
MappingMongoConverter converter = new MappingMongoConverter(ReactiveMongoTemplate.NO_OP_REF_RESOLVER,
|
||||||
|
mongoMappingContext());
|
||||||
|
converter.setCustomConversions(customConversions());
|
||||||
|
|
||||||
|
return converter;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 by the original author(s).
|
* Copyright 2011-2014 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
@@ -13,18 +13,25 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.data.mongodb.config;
|
package org.springframework.data.mongodb.config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
* Constants to declare bean names used by the namespace configuration.
|
||||||
|
*
|
||||||
|
* @author Jon Brisbin
|
||||||
|
* @author Oliver Gierke
|
||||||
|
* @author Martin Baumgartner
|
||||||
*/
|
*/
|
||||||
public abstract class BeanNames {
|
public abstract class BeanNames {
|
||||||
|
|
||||||
static final String MAPPING_CONTEXT = "mappingContext";
|
public static final String MAPPING_CONTEXT_BEAN_NAME = "mongoMappingContext";
|
||||||
static final String INDEX_HELPER = "indexCreationHelper";
|
|
||||||
static final String MONGO = "mongo";
|
|
||||||
static final String DB_FACTORY = "mongoDbFactory";
|
|
||||||
static final String POST_PROCESSOR = "mappingContextAwareBeanPostProcessor";
|
|
||||||
|
|
||||||
|
static final String INDEX_HELPER_BEAN_NAME = "indexCreationHelper";
|
||||||
|
static final String MONGO_BEAN_NAME = "mongo";
|
||||||
|
static final String DB_FACTORY_BEAN_NAME = "mongoDbFactory";
|
||||||
|
static final String VALIDATING_EVENT_LISTENER_BEAN_NAME = "validatingMongoEventListener";
|
||||||
|
static final String IS_NEW_STRATEGY_FACTORY_BEAN_NAME = "isNewStrategyFactory";
|
||||||
|
static final String DEFAULT_CONVERTER_BEAN_NAME = "mappingConverter";
|
||||||
|
static final String MONGO_TEMPLATE_BEAN_NAME = "mongoTemplate";
|
||||||
|
static final String GRID_FS_TEMPLATE_BEAN_NAME = "gridFsTemplate";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 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.config;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Inherited;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
import org.springframework.data.auditing.DateTimeProvider;
|
||||||
|
import org.springframework.data.domain.AuditorAware;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Annotation to enable auditing in MongoDB via annotation configuration.
|
||||||
|
*
|
||||||
|
* @author Thomas Darimont
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
|
@Inherited
|
||||||
|
@Documented
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Import(MongoAuditingRegistrar.class)
|
||||||
|
public @interface EnableMongoAuditing {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures the {@link AuditorAware} bean to be used to lookup the current principal.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String auditorAwareRef() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures whether the creation and modification dates are set. Defaults to {@literal true}.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean setDates() default true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures whether the entity shall be marked as modified on creation. Defaults to {@literal true}.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean modifyOnCreate() default true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures a {@link DateTimeProvider} bean name that allows customizing the {@link org.joda.time.DateTime} to be
|
||||||
|
* used for setting creation and modification dates.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String dateTimeProviderRef() default "";
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013-2014 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.config;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||||
|
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||||
|
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
|
||||||
|
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||||
|
import org.springframework.beans.factory.xml.ParserContext;
|
||||||
|
import org.springframework.data.config.BeanComponentDefinitionBuilder;
|
||||||
|
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link BeanDefinitionParser} to parse {@code gridFsTemplate} elements into {@link BeanDefinition}s.
|
||||||
|
*
|
||||||
|
* @author Martin Baumgartner
|
||||||
|
*/
|
||||||
|
class GridFsTemplateParser extends AbstractBeanDefinitionParser {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#resolveId(org.w3c.dom.Element, org.springframework.beans.factory.support.AbstractBeanDefinition, org.springframework.beans.factory.xml.ParserContext)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
|
||||||
|
throws BeanDefinitionStoreException {
|
||||||
|
|
||||||
|
String id = super.resolveId(element, definition, parserContext);
|
||||||
|
return StringUtils.hasText(id) ? id : BeanNames.GRID_FS_TEMPLATE_BEAN_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#parseInternal(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
|
||||||
|
|
||||||
|
BeanComponentDefinitionBuilder helper = new BeanComponentDefinitionBuilder(element, parserContext);
|
||||||
|
|
||||||
|
String converterRef = element.getAttribute("converter-ref");
|
||||||
|
String dbFactoryRef = element.getAttribute("db-factory-ref");
|
||||||
|
String bucket = element.getAttribute("bucket");
|
||||||
|
|
||||||
|
BeanDefinitionBuilder gridFsTemplateBuilder = BeanDefinitionBuilder.genericBeanDefinition(GridFsTemplate.class);
|
||||||
|
|
||||||
|
if (StringUtils.hasText(dbFactoryRef)) {
|
||||||
|
gridFsTemplateBuilder.addConstructorArgReference(dbFactoryRef);
|
||||||
|
} else {
|
||||||
|
gridFsTemplateBuilder.addConstructorArgReference(BeanNames.DB_FACTORY_BEAN_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.hasText(converterRef)) {
|
||||||
|
gridFsTemplateBuilder.addConstructorArgReference(converterRef);
|
||||||
|
} else {
|
||||||
|
gridFsTemplateBuilder.addConstructorArgReference(BeanNames.DEFAULT_CONVERTER_BEAN_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.hasText(bucket)) {
|
||||||
|
gridFsTemplateBuilder.addConstructorArgValue(bucket);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (AbstractBeanDefinition) helper.getComponentIdButFallback(gridFsTemplateBuilder, BeanNames.GRID_FS_TEMPLATE_BEAN_NAME)
|
||||||
|
.getBeanDefinition();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 by the original author(s).
|
* Copyright 2011-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
@@ -13,76 +13,98 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.data.mongodb.config;
|
package org.springframework.data.mongodb.config;
|
||||||
|
|
||||||
import static org.springframework.data.mongodb.config.BeanNames.*;
|
import static org.springframework.data.mongodb.config.BeanNames.*;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.springframework.beans.BeanMetadataElement;
|
import org.springframework.beans.BeanMetadataElement;
|
||||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
|
||||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||||
|
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
|
||||||
|
import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
|
||||||
|
import org.springframework.beans.factory.parsing.ReaderContext;
|
||||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
import org.springframework.beans.factory.support.GenericBeanDefinition;
|
import org.springframework.beans.factory.support.GenericBeanDefinition;
|
||||||
import org.springframework.beans.factory.support.ManagedList;
|
import org.springframework.beans.factory.support.ManagedList;
|
||||||
import org.springframework.beans.factory.support.ManagedSet;
|
import org.springframework.beans.factory.support.ManagedSet;
|
||||||
|
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||||
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
|
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
|
||||||
|
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||||
import org.springframework.beans.factory.xml.ParserContext;
|
import org.springframework.beans.factory.xml.ParserContext;
|
||||||
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
||||||
|
import org.springframework.core.convert.converter.Converter;
|
||||||
|
import org.springframework.core.convert.converter.GenericConverter;
|
||||||
|
import org.springframework.core.type.classreading.MetadataReader;
|
||||||
|
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||||
import org.springframework.core.type.filter.AnnotationTypeFilter;
|
import org.springframework.core.type.filter.AnnotationTypeFilter;
|
||||||
|
import org.springframework.core.type.filter.AssignableTypeFilter;
|
||||||
|
import org.springframework.core.type.filter.TypeFilter;
|
||||||
import org.springframework.data.annotation.Persistent;
|
import org.springframework.data.annotation.Persistent;
|
||||||
import org.springframework.data.mapping.context.MappingContextAwareBeanPostProcessor;
|
import org.springframework.data.config.BeanComponentDefinitionBuilder;
|
||||||
|
import org.springframework.data.mapping.context.MappingContextIsNewStrategyFactory;
|
||||||
|
import org.springframework.data.mapping.model.CamelCaseAbbreviatingFieldNamingStrategy;
|
||||||
import org.springframework.data.mongodb.core.convert.CustomConversions;
|
import org.springframework.data.mongodb.core.convert.CustomConversions;
|
||||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||||
import org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator;
|
import org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator;
|
||||||
import org.springframework.data.mongodb.core.mapping.Document;
|
import org.springframework.data.mongodb.core.mapping.Document;
|
||||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||||
|
import org.springframework.data.mongodb.core.mapping.event.ValidatingMongoEventListener;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.util.xml.DomUtils;
|
import org.springframework.util.xml.DomUtils;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Jon Brisbin <jbrisbin@vmware.com>
|
* Bean definition parser for the {@code mapping-converter} element.
|
||||||
|
*
|
||||||
|
* @author Jon Brisbin
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
|
* @author Maciej Walkowiak
|
||||||
|
* @author Thomas Darimont
|
||||||
|
* @author Christoph Strobl
|
||||||
|
* @author Mark Paluch
|
||||||
*/
|
*/
|
||||||
public class MappingMongoConverterParser extends AbstractBeanDefinitionParser {
|
public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||||
|
|
||||||
private static final String BASE_PACKAGE = "base-package";
|
private static final String BASE_PACKAGE = "base-package";
|
||||||
|
private static final boolean JSR_303_PRESENT = ClassUtils.isPresent("javax.validation.Validator",
|
||||||
|
MappingMongoConverterParser.class.getClassLoader());
|
||||||
|
|
||||||
@Override
|
/* (non-Javadoc)
|
||||||
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
|
* @see org.springframework.beans.factory.xml.BeanDefinitionParser#parse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)
|
||||||
throws BeanDefinitionStoreException {
|
*/
|
||||||
String id = super.resolveId(element, definition, parserContext);
|
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||||
return StringUtils.hasText(id) ? id : "mappingConverter";
|
|
||||||
}
|
if (parserContext.isNested()) {
|
||||||
|
parserContext.getReaderContext().error("Mongo Converter must not be defined as nested bean.", element);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
|
|
||||||
BeanDefinitionRegistry registry = parserContext.getRegistry();
|
BeanDefinitionRegistry registry = parserContext.getRegistry();
|
||||||
|
String id = element.getAttribute(AbstractBeanDefinitionParser.ID_ATTRIBUTE);
|
||||||
|
id = StringUtils.hasText(id) ? id : DEFAULT_CONVERTER_BEAN_NAME;
|
||||||
|
|
||||||
|
parserContext.pushContainingComponent(new CompositeComponentDefinition("Mapping Mongo Converter", element));
|
||||||
|
|
||||||
BeanDefinition conversionsDefinition = getCustomConversions(element, parserContext);
|
BeanDefinition conversionsDefinition = getCustomConversions(element, parserContext);
|
||||||
String ctxRef = potentiallyCreateMappingContext(element, parserContext, conversionsDefinition);
|
String ctxRef = potentiallyCreateMappingContext(element, parserContext, conversionsDefinition, id);
|
||||||
|
|
||||||
try {
|
createIsNewStrategyFactoryBeanDefinition(ctxRef, parserContext, element);
|
||||||
registry.getBeanDefinition(POST_PROCESSOR);
|
|
||||||
} catch (NoSuchBeanDefinitionException ignored) {
|
|
||||||
BeanDefinitionBuilder postProcBuilder = BeanDefinitionBuilder
|
|
||||||
.genericBeanDefinition(MappingContextAwareBeanPostProcessor.class);
|
|
||||||
postProcBuilder.addPropertyValue("mappingContextBeanName", ctxRef);
|
|
||||||
registry.registerBeanDefinition(POST_PROCESSOR, postProcBuilder.getBeanDefinition());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Need a reference to a Mongo instance
|
// Need a reference to a Mongo instance
|
||||||
String dbFactoryRef = element.getAttribute("db-factory-ref");
|
String dbFactoryRef = element.getAttribute("db-factory-ref");
|
||||||
if (!StringUtils.hasText(dbFactoryRef)) {
|
if (!StringUtils.hasText(dbFactoryRef)) {
|
||||||
dbFactoryRef = DB_FACTORY;
|
dbFactoryRef = DB_FACTORY_BEAN_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converter
|
// Converter
|
||||||
@@ -90,75 +112,186 @@ public class MappingMongoConverterParser extends AbstractBeanDefinitionParser {
|
|||||||
converterBuilder.addConstructorArgReference(dbFactoryRef);
|
converterBuilder.addConstructorArgReference(dbFactoryRef);
|
||||||
converterBuilder.addConstructorArgReference(ctxRef);
|
converterBuilder.addConstructorArgReference(ctxRef);
|
||||||
|
|
||||||
|
String typeMapperRef = element.getAttribute("type-mapper-ref");
|
||||||
|
if (StringUtils.hasText(typeMapperRef)) {
|
||||||
|
converterBuilder.addPropertyReference("typeMapper", typeMapperRef);
|
||||||
|
}
|
||||||
|
|
||||||
if (conversionsDefinition != null) {
|
if (conversionsDefinition != null) {
|
||||||
converterBuilder.addPropertyValue("customConversions", conversionsDefinition);
|
converterBuilder.addPropertyValue("customConversions", conversionsDefinition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!registry.containsBeanDefinition("indexOperationsProvider")){
|
||||||
|
|
||||||
|
BeanDefinitionBuilder indexOperationsProviderBuilder = BeanDefinitionBuilder.genericBeanDefinition("org.springframework.data.mongodb.core.DefaultIndexOperationsProvider");
|
||||||
|
indexOperationsProviderBuilder.addConstructorArgReference(dbFactoryRef);
|
||||||
|
parserContext.registerBeanComponent(new BeanComponentDefinition(indexOperationsProviderBuilder.getBeanDefinition(), "indexOperationsProvider"));
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
registry.getBeanDefinition(INDEX_HELPER);
|
registry.getBeanDefinition(INDEX_HELPER_BEAN_NAME);
|
||||||
} catch (NoSuchBeanDefinitionException ignored) {
|
} catch (NoSuchBeanDefinitionException ignored) {
|
||||||
if (!StringUtils.hasText(dbFactoryRef)) {
|
|
||||||
dbFactoryRef = DB_FACTORY;
|
|
||||||
}
|
|
||||||
BeanDefinitionBuilder indexHelperBuilder = BeanDefinitionBuilder
|
BeanDefinitionBuilder indexHelperBuilder = BeanDefinitionBuilder
|
||||||
.genericBeanDefinition(MongoPersistentEntityIndexCreator.class);
|
.genericBeanDefinition(MongoPersistentEntityIndexCreator.class);
|
||||||
indexHelperBuilder.addConstructorArgValue(new RuntimeBeanReference(ctxRef));
|
indexHelperBuilder.addConstructorArgReference(ctxRef);
|
||||||
indexHelperBuilder.addConstructorArgValue(new RuntimeBeanReference(dbFactoryRef));
|
indexHelperBuilder.addConstructorArgReference("indexOperationsProvider");
|
||||||
registry.registerBeanDefinition(INDEX_HELPER, indexHelperBuilder.getBeanDefinition());
|
indexHelperBuilder.addDependsOn(ctxRef);
|
||||||
|
|
||||||
|
parserContext.registerBeanComponent(new BeanComponentDefinition(indexHelperBuilder.getBeanDefinition(),
|
||||||
|
INDEX_HELPER_BEAN_NAME));
|
||||||
}
|
}
|
||||||
|
|
||||||
return converterBuilder.getBeanDefinition();
|
BeanDefinition validatingMongoEventListener = potentiallyCreateValidatingMongoEventListener(element, parserContext);
|
||||||
|
|
||||||
|
if (validatingMongoEventListener != null) {
|
||||||
|
parserContext.registerBeanComponent(new BeanComponentDefinition(validatingMongoEventListener,
|
||||||
|
VALIDATING_EVENT_LISTENER_BEAN_NAME));
|
||||||
|
}
|
||||||
|
|
||||||
|
parserContext.registerBeanComponent(new BeanComponentDefinition(converterBuilder.getBeanDefinition(), id));
|
||||||
|
parserContext.popAndRegisterContainingComponent();
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String potentiallyCreateMappingContext(Element element, ParserContext parserContext,
|
private BeanDefinition potentiallyCreateValidatingMongoEventListener(Element element, ParserContext parserContext) {
|
||||||
BeanDefinition conversionsDefinition) {
|
|
||||||
|
|
||||||
String ctxRef = element.getAttribute("mapping-context-ref");
|
String disableValidation = element.getAttribute("disable-validation");
|
||||||
if (!StringUtils.hasText(ctxRef)) {
|
boolean validationDisabled = StringUtils.hasText(disableValidation) && Boolean.valueOf(disableValidation);
|
||||||
BeanDefinitionBuilder mappingContextBuilder = BeanDefinitionBuilder
|
|
||||||
.genericBeanDefinition(MongoMappingContext.class);
|
|
||||||
|
|
||||||
Set<String> classesToAdd = getInititalEntityClasses(element, mappingContextBuilder);
|
if (!validationDisabled) {
|
||||||
if (classesToAdd != null) {
|
|
||||||
mappingContextBuilder.addPropertyValue("initialEntitySet", classesToAdd);
|
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
|
||||||
|
RuntimeBeanReference validator = getValidator(builder, parserContext);
|
||||||
|
|
||||||
|
if (validator != null) {
|
||||||
|
builder.getRawBeanDefinition().setBeanClass(ValidatingMongoEventListener.class);
|
||||||
|
builder.addConstructorArgValue(validator);
|
||||||
|
|
||||||
|
return builder.getBeanDefinition();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conversionsDefinition != null) {
|
|
||||||
AbstractBeanDefinition simpleTypesDefinition = new GenericBeanDefinition();
|
|
||||||
simpleTypesDefinition.setFactoryBeanName("customConversions");
|
|
||||||
simpleTypesDefinition.setFactoryMethodName("getSimpleTypeHolder");
|
|
||||||
|
|
||||||
mappingContextBuilder.addPropertyValue("simpleTypeHolder", simpleTypesDefinition);
|
|
||||||
}
|
|
||||||
|
|
||||||
parserContext.getRegistry().registerBeanDefinition(MAPPING_CONTEXT, mappingContextBuilder.getBeanDefinition());
|
|
||||||
ctxRef = MAPPING_CONTEXT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RuntimeBeanReference getValidator(Object source, ParserContext parserContext) {
|
||||||
|
|
||||||
|
if (!JSR_303_PRESENT) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
RootBeanDefinition validatorDef = new RootBeanDefinition(
|
||||||
|
"org.springframework.validation.beanvalidation.LocalValidatorFactoryBean");
|
||||||
|
validatorDef.setSource(source);
|
||||||
|
validatorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||||
|
String validatorName = parserContext.getReaderContext().registerWithGeneratedName(validatorDef);
|
||||||
|
parserContext.registerBeanComponent(new BeanComponentDefinition(validatorDef, validatorName));
|
||||||
|
|
||||||
|
return new RuntimeBeanReference(validatorName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String potentiallyCreateMappingContext(Element element, ParserContext parserContext,
|
||||||
|
BeanDefinition conversionsDefinition, String converterId) {
|
||||||
|
|
||||||
|
String ctxRef = element.getAttribute("mapping-context-ref");
|
||||||
|
|
||||||
|
if (StringUtils.hasText(ctxRef)) {
|
||||||
|
return ctxRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
BeanComponentDefinitionBuilder componentDefinitionBuilder = new BeanComponentDefinitionBuilder(element,
|
||||||
|
parserContext);
|
||||||
|
|
||||||
|
BeanDefinitionBuilder mappingContextBuilder = BeanDefinitionBuilder
|
||||||
|
.genericBeanDefinition(MongoMappingContext.class);
|
||||||
|
|
||||||
|
Set<String> classesToAdd = getInititalEntityClasses(element);
|
||||||
|
|
||||||
|
if (classesToAdd != null) {
|
||||||
|
mappingContextBuilder.addPropertyValue("initialEntitySet", classesToAdd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conversionsDefinition != null) {
|
||||||
|
AbstractBeanDefinition simpleTypesDefinition = new GenericBeanDefinition();
|
||||||
|
simpleTypesDefinition.setFactoryBeanName("customConversions");
|
||||||
|
simpleTypesDefinition.setFactoryMethodName("getSimpleTypeHolder");
|
||||||
|
|
||||||
|
mappingContextBuilder.addPropertyValue("simpleTypeHolder", simpleTypesDefinition);
|
||||||
|
}
|
||||||
|
|
||||||
|
parseFieldNamingStrategy(element, parserContext.getReaderContext(), mappingContextBuilder);
|
||||||
|
|
||||||
|
ctxRef = converterId == null || DEFAULT_CONVERTER_BEAN_NAME.equals(converterId) ? MAPPING_CONTEXT_BEAN_NAME
|
||||||
|
: converterId + "." + MAPPING_CONTEXT_BEAN_NAME;
|
||||||
|
|
||||||
|
parserContext.registerBeanComponent(componentDefinitionBuilder.getComponent(mappingContextBuilder, ctxRef));
|
||||||
return ctxRef;
|
return ctxRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void parseFieldNamingStrategy(Element element, ReaderContext context, BeanDefinitionBuilder builder) {
|
||||||
|
|
||||||
|
String abbreviateFieldNames = element.getAttribute("abbreviate-field-names");
|
||||||
|
String fieldNamingStrategy = element.getAttribute("field-naming-strategy-ref");
|
||||||
|
|
||||||
|
boolean fieldNamingStrategyReferenced = StringUtils.hasText(fieldNamingStrategy);
|
||||||
|
boolean abbreviationActivated = StringUtils.hasText(abbreviateFieldNames)
|
||||||
|
&& Boolean.parseBoolean(abbreviateFieldNames);
|
||||||
|
|
||||||
|
if (fieldNamingStrategyReferenced && abbreviationActivated) {
|
||||||
|
context.error("Field name abbreviation cannot be activated if a field-naming-strategy-ref is configured!",
|
||||||
|
element);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object value = null;
|
||||||
|
|
||||||
|
if ("true".equals(abbreviateFieldNames)) {
|
||||||
|
value = new RootBeanDefinition(CamelCaseAbbreviatingFieldNamingStrategy.class);
|
||||||
|
} else if (fieldNamingStrategyReferenced) {
|
||||||
|
value = new RuntimeBeanReference(fieldNamingStrategy);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value != null) {
|
||||||
|
builder.addPropertyValue("fieldNamingStrategy", value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private BeanDefinition getCustomConversions(Element element, ParserContext parserContext) {
|
private BeanDefinition getCustomConversions(Element element, ParserContext parserContext) {
|
||||||
|
|
||||||
List<Element> customConvertersElements = DomUtils.getChildElementsByTagName(element, "custom-converters");
|
List<Element> customConvertersElements = DomUtils.getChildElementsByTagName(element, "custom-converters");
|
||||||
|
|
||||||
if (customConvertersElements.size() == 1) {
|
if (customConvertersElements.size() == 1) {
|
||||||
|
|
||||||
Element customerConvertersElement = customConvertersElements.get(0);
|
Element customerConvertersElement = customConvertersElements.get(0);
|
||||||
ManagedList<BeanMetadataElement> converterBeans = new ManagedList<BeanMetadataElement>();
|
ManagedList<BeanMetadataElement> converterBeans = new ManagedList<BeanMetadataElement>();
|
||||||
List<Element> converterElements = DomUtils.getChildElementsByTagName(customerConvertersElement, "converter");
|
List<Element> converterElements = DomUtils.getChildElementsByTagName(customerConvertersElement, "converter");
|
||||||
|
|
||||||
if (converterElements != null) {
|
if (converterElements != null) {
|
||||||
for (Element listenerElement : converterElements) {
|
for (Element listenerElement : converterElements) {
|
||||||
converterBeans.add(parseConverter(listenerElement, parserContext));
|
converterBeans.add(parseConverter(listenerElement, parserContext));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Scan for Converter and GenericConverter beans in the given base-package
|
||||||
|
String packageToScan = customerConvertersElement.getAttribute(BASE_PACKAGE);
|
||||||
|
if (StringUtils.hasText(packageToScan)) {
|
||||||
|
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
|
||||||
|
provider.addExcludeFilter(new NegatingFilter(new AssignableTypeFilter(Converter.class),
|
||||||
|
new AssignableTypeFilter(GenericConverter.class)));
|
||||||
|
|
||||||
|
for (BeanDefinition candidate : provider.findCandidateComponents(packageToScan)) {
|
||||||
|
converterBeans.add(candidate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BeanDefinitionBuilder conversionsBuilder = BeanDefinitionBuilder.rootBeanDefinition(CustomConversions.class);
|
BeanDefinitionBuilder conversionsBuilder = BeanDefinitionBuilder.rootBeanDefinition(CustomConversions.class);
|
||||||
conversionsBuilder.addConstructorArgValue(converterBeans);
|
conversionsBuilder.addConstructorArgValue(converterBeans);
|
||||||
|
|
||||||
AbstractBeanDefinition conversionsBean = conversionsBuilder.getBeanDefinition();
|
AbstractBeanDefinition conversionsBean = conversionsBuilder.getBeanDefinition();
|
||||||
conversionsBean.setSource(parserContext.extractSource(element));
|
conversionsBean.setSource(parserContext.extractSource(element));
|
||||||
|
|
||||||
parserContext.getRegistry().registerBeanDefinition("customConversions", conversionsBean);
|
parserContext.registerBeanComponent(new BeanComponentDefinition(conversionsBean, "customConversions"));
|
||||||
|
|
||||||
return conversionsBean;
|
return conversionsBean;
|
||||||
}
|
}
|
||||||
@@ -166,7 +299,7 @@ public class MappingMongoConverterParser extends AbstractBeanDefinitionParser {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getInititalEntityClasses(Element element, BeanDefinitionBuilder builder) {
|
private static Set<String> getInititalEntityClasses(Element element) {
|
||||||
|
|
||||||
String basePackage = element.getAttribute(BASE_PACKAGE);
|
String basePackage = element.getAttribute(BASE_PACKAGE);
|
||||||
|
|
||||||
@@ -204,4 +337,53 @@ public class MappingMongoConverterParser extends AbstractBeanDefinitionParser {
|
|||||||
"Element <converter> must specify 'ref' or contain a bean definition for the converter", element);
|
"Element <converter> must specify 'ref' or contain a bean definition for the converter", element);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String createIsNewStrategyFactoryBeanDefinition(String mappingContextRef, ParserContext context,
|
||||||
|
Element element) {
|
||||||
|
|
||||||
|
BeanDefinitionBuilder mappingContextStrategyFactoryBuilder = BeanDefinitionBuilder
|
||||||
|
.rootBeanDefinition(MappingContextIsNewStrategyFactory.class);
|
||||||
|
mappingContextStrategyFactoryBuilder.addConstructorArgReference(mappingContextRef);
|
||||||
|
|
||||||
|
BeanComponentDefinitionBuilder builder = new BeanComponentDefinitionBuilder(element, context);
|
||||||
|
context.registerBeanComponent(builder.getComponent(mappingContextStrategyFactoryBuilder,
|
||||||
|
IS_NEW_STRATEGY_FACTORY_BEAN_NAME));
|
||||||
|
|
||||||
|
return IS_NEW_STRATEGY_FACTORY_BEAN_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link TypeFilter} that returns {@literal false} in case any of the given delegates matches.
|
||||||
|
*
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
|
private static class NegatingFilter implements TypeFilter {
|
||||||
|
|
||||||
|
private final Set<TypeFilter> delegates;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link NegatingFilter} with the given delegates.
|
||||||
|
*
|
||||||
|
* @param filters
|
||||||
|
*/
|
||||||
|
public NegatingFilter(TypeFilter... filters) {
|
||||||
|
Assert.notNull(filters);
|
||||||
|
this.delegates = new HashSet<TypeFilter>(Arrays.asList(filters));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.core.type.filter.TypeFilter#match(org.springframework.core.type.classreading.MetadataReader, org.springframework.core.type.classreading.MetadataReaderFactory)
|
||||||
|
*/
|
||||||
|
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
|
||||||
|
|
||||||
|
for (TypeFilter delegate : delegates) {
|
||||||
|
if (delegate.match(metadataReader, metadataReaderFactory)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2014 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.config;
|
||||||
|
|
||||||
|
import static org.springframework.data.config.ParsingUtils.*;
|
||||||
|
import static org.springframework.data.mongodb.config.BeanNames.*;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||||
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
|
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||||
|
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
|
||||||
|
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||||
|
import org.springframework.beans.factory.xml.ParserContext;
|
||||||
|
import org.springframework.data.auditing.config.IsNewAwareAuditingHandlerBeanDefinitionParser;
|
||||||
|
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||||
|
import org.springframework.data.mongodb.core.mapping.event.AuditingEventListener;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link BeanDefinitionParser} to register a {@link AuditingEventListener} to transparently set auditing information on
|
||||||
|
* an entity.
|
||||||
|
*
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
|
public class MongoAuditingBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#getBeanClass(org.w3c.dom.Element)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected Class<?> getBeanClass(Element element) {
|
||||||
|
return AuditingEventListener.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#shouldGenerateId()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected boolean shouldGenerateId() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#doParse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext, org.springframework.beans.factory.support.BeanDefinitionBuilder)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||||
|
|
||||||
|
String mappingContextRef = element.getAttribute("mapping-context-ref");
|
||||||
|
|
||||||
|
if (!StringUtils.hasText(mappingContextRef)) {
|
||||||
|
|
||||||
|
BeanDefinitionRegistry registry = parserContext.getRegistry();
|
||||||
|
|
||||||
|
if (!registry.containsBeanDefinition(MAPPING_CONTEXT_BEAN_NAME)) {
|
||||||
|
registry.registerBeanDefinition(MAPPING_CONTEXT_BEAN_NAME, new RootBeanDefinition(MongoMappingContext.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
mappingContextRef = MAPPING_CONTEXT_BEAN_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
IsNewAwareAuditingHandlerBeanDefinitionParser parser = new IsNewAwareAuditingHandlerBeanDefinitionParser(
|
||||||
|
mappingContextRef);
|
||||||
|
parser.parse(element, parserContext);
|
||||||
|
|
||||||
|
builder.addConstructorArgValue(getObjectFactoryBeanDefinition(parser.getResolvedBeanName(),
|
||||||
|
parserContext.extractSource(element)));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,162 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013-2016 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.config;
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.FactoryBean;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||||
|
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||||
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
|
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
|
||||||
|
import org.springframework.core.type.AnnotationMetadata;
|
||||||
|
import org.springframework.data.auditing.IsNewAwareAuditingHandler;
|
||||||
|
import org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport;
|
||||||
|
import org.springframework.data.auditing.config.AuditingConfiguration;
|
||||||
|
import org.springframework.data.config.ParsingUtils;
|
||||||
|
import org.springframework.data.mapping.context.MappingContext;
|
||||||
|
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||||
|
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||||
|
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||||
|
import org.springframework.data.mongodb.core.mapping.event.AuditingEventListener;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link ImportBeanDefinitionRegistrar} to enable {@link EnableMongoAuditing} annotation.
|
||||||
|
*
|
||||||
|
* @author Thomas Darimont
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
|
class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAnnotation()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected Class<? extends Annotation> getAnnotation() {
|
||||||
|
return EnableMongoAuditing.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditingHandlerBeanName()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getAuditingHandlerBeanName() {
|
||||||
|
return "mongoAuditingHandler";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#registerBeanDefinitions(org.springframework.core.type.AnnotationMetadata, org.springframework.beans.factory.support.BeanDefinitionRegistry)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) {
|
||||||
|
|
||||||
|
Assert.notNull(annotationMetadata, "AnnotationMetadata must not be null!");
|
||||||
|
Assert.notNull(registry, "BeanDefinitionRegistry must not be null!");
|
||||||
|
|
||||||
|
super.registerBeanDefinitions(annotationMetadata, registry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditHandlerBeanDefinitionBuilder(org.springframework.data.auditing.config.AuditingConfiguration)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AuditingConfiguration configuration) {
|
||||||
|
|
||||||
|
Assert.notNull(configuration, "AuditingConfiguration must not be null!");
|
||||||
|
|
||||||
|
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(IsNewAwareAuditingHandler.class);
|
||||||
|
|
||||||
|
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(MongoMappingContextLookup.class);
|
||||||
|
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
|
||||||
|
|
||||||
|
builder.addConstructorArgValue(definition.getBeanDefinition());
|
||||||
|
return configureDefaultAuditHandlerAttributes(configuration, builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#registerAuditListener(org.springframework.beans.factory.config.BeanDefinition, org.springframework.beans.factory.support.BeanDefinitionRegistry)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void registerAuditListenerBeanDefinition(BeanDefinition auditingHandlerDefinition,
|
||||||
|
BeanDefinitionRegistry registry) {
|
||||||
|
|
||||||
|
Assert.notNull(auditingHandlerDefinition, "BeanDefinition must not be null!");
|
||||||
|
Assert.notNull(registry, "BeanDefinitionRegistry must not be null!");
|
||||||
|
|
||||||
|
BeanDefinitionBuilder listenerBeanDefinitionBuilder = BeanDefinitionBuilder
|
||||||
|
.rootBeanDefinition(AuditingEventListener.class);
|
||||||
|
listenerBeanDefinitionBuilder
|
||||||
|
.addConstructorArgValue(ParsingUtils.getObjectFactoryBeanDefinition(getAuditingHandlerBeanName(), registry));
|
||||||
|
|
||||||
|
registerInfrastructureBeanWithId(listenerBeanDefinitionBuilder.getBeanDefinition(),
|
||||||
|
AuditingEventListener.class.getName(), registry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple helper to be able to wire the {@link MappingContext} from a {@link MappingMongoConverter} bean available in
|
||||||
|
* the application context.
|
||||||
|
*
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
|
static class MongoMappingContextLookup
|
||||||
|
implements FactoryBean<MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty>> {
|
||||||
|
|
||||||
|
private final MappingMongoConverter converter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link MongoMappingContextLookup} for the given {@link MappingMongoConverter}.
|
||||||
|
*
|
||||||
|
* @param converter must not be {@literal null}.
|
||||||
|
*/
|
||||||
|
public MongoMappingContextLookup(MappingMongoConverter converter) {
|
||||||
|
this.converter = converter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.FactoryBean#getObject()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> getObject() throws Exception {
|
||||||
|
return converter.getMappingContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Class<?> getObjectType() {
|
||||||
|
return MappingContext.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isSingleton() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 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.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.config.BeanComponentDefinitionBuilder;
|
||||||
|
import org.springframework.data.config.ParsingUtils;
|
||||||
|
import org.springframework.data.mongodb.core.MongoClientFactoryBean;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parser for {@code mongo-client} definitions.
|
||||||
|
*
|
||||||
|
* @author Christoph Strobl
|
||||||
|
* @since 1.7
|
||||||
|
*/
|
||||||
|
public class MongoClientParser implements BeanDefinitionParser {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.xml.BeanDefinitionParser#parse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)
|
||||||
|
*/
|
||||||
|
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||||
|
|
||||||
|
Object source = parserContext.extractSource(element);
|
||||||
|
String id = element.getAttribute("id");
|
||||||
|
|
||||||
|
BeanComponentDefinitionBuilder helper = new BeanComponentDefinitionBuilder(element, parserContext);
|
||||||
|
|
||||||
|
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MongoClientFactoryBean.class);
|
||||||
|
|
||||||
|
ParsingUtils.setPropertyValue(builder, element, "port", "port");
|
||||||
|
ParsingUtils.setPropertyValue(builder, element, "host", "host");
|
||||||
|
ParsingUtils.setPropertyValue(builder, element, "credentials", "credentials");
|
||||||
|
|
||||||
|
MongoParsingUtils.parseMongoClientOptions(element, builder);
|
||||||
|
MongoParsingUtils.parseReplicaSet(element, builder);
|
||||||
|
|
||||||
|
String defaultedId = StringUtils.hasText(id) ? id : BeanNames.MONGO_BEAN_NAME;
|
||||||
|
|
||||||
|
parserContext.pushContainingComponent(new CompositeComponentDefinition("Mongo", source));
|
||||||
|
|
||||||
|
BeanComponentDefinition mongoComponent = helper.getComponent(builder, defaultedId);
|
||||||
|
parserContext.registerBeanComponent(mongoComponent);
|
||||||
|
|
||||||
|
BeanComponentDefinition serverAddressPropertyEditor = helper.getComponent(MongoParsingUtils
|
||||||
|
.getServerAddressPropertyEditorBuilder());
|
||||||
|
parserContext.registerBeanComponent(serverAddressPropertyEditor);
|
||||||
|
|
||||||
|
BeanComponentDefinition writeConcernEditor = helper.getComponent(MongoParsingUtils
|
||||||
|
.getWriteConcernPropertyEditorBuilder());
|
||||||
|
parserContext.registerBeanComponent(writeConcernEditor);
|
||||||
|
|
||||||
|
BeanComponentDefinition readPreferenceEditor = helper.getComponent(MongoParsingUtils
|
||||||
|
.getReadPreferencePropertyEditorBuilder());
|
||||||
|
parserContext.registerBeanComponent(readPreferenceEditor);
|
||||||
|
|
||||||
|
BeanComponentDefinition credentialsEditor = helper.getComponent(MongoParsingUtils
|
||||||
|
.getMongoCredentialPropertyEditor());
|
||||||
|
parserContext.registerBeanComponent(credentialsEditor);
|
||||||
|
|
||||||
|
parserContext.popAndRegisterContainingComponent();
|
||||||
|
|
||||||
|
return mongoComponent.getBeanDefinition();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,203 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 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.config;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
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.core.convert.converter.Converter;
|
||||||
|
import org.springframework.core.type.filter.AnnotationTypeFilter;
|
||||||
|
import org.springframework.data.annotation.Persistent;
|
||||||
|
import org.springframework.data.authentication.UserCredentials;
|
||||||
|
import org.springframework.data.mapping.context.MappingContext;
|
||||||
|
import org.springframework.data.mapping.context.MappingContextIsNewStrategyFactory;
|
||||||
|
import org.springframework.data.mapping.context.PersistentEntities;
|
||||||
|
import org.springframework.data.mapping.model.CamelCaseAbbreviatingFieldNamingStrategy;
|
||||||
|
import org.springframework.data.mapping.model.FieldNamingStrategy;
|
||||||
|
import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy;
|
||||||
|
import org.springframework.data.mongodb.MongoDbFactory;
|
||||||
|
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||||
|
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
|
||||||
|
import org.springframework.data.mongodb.core.convert.CustomConversions;
|
||||||
|
import org.springframework.data.mongodb.core.convert.DbRefResolver;
|
||||||
|
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
|
||||||
|
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||||
|
import org.springframework.data.mongodb.core.mapping.Document;
|
||||||
|
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||||
|
import org.springframework.data.support.CachingIsNewStrategyFactory;
|
||||||
|
import org.springframework.data.support.IsNewStrategyFactory;
|
||||||
|
import org.springframework.util.ClassUtils;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import com.mongodb.Mongo;
|
||||||
|
import com.mongodb.MongoClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for Spring Data MongoDB to be extended for JavaConfiguration usage.
|
||||||
|
*
|
||||||
|
* @author Mark Paluch
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public abstract class MongoConfigurationSupport {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the name of the database to connect to.
|
||||||
|
*
|
||||||
|
* @return must not be {@literal null}.
|
||||||
|
*/
|
||||||
|
protected abstract String getDatabaseName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the base packages to scan for MongoDB mapped entities at startup. Will return the package name of the
|
||||||
|
* configuration class' (the concrete class, not this one here) by default. So if you have a
|
||||||
|
* {@code com.acme.AppConfig} extending {@link MongoConfigurationSupport} the base package will be considered
|
||||||
|
* {@code com.acme} unless the method is overridden to implement alternate behavior.
|
||||||
|
*
|
||||||
|
* @return the base packages to scan for mapped {@link Document} classes or an empty collection to not enable scanning
|
||||||
|
* for entities.
|
||||||
|
* @since 1.10
|
||||||
|
*/
|
||||||
|
protected Collection<String> getMappingBasePackages() {
|
||||||
|
|
||||||
|
Package mappingBasePackage = getClass().getPackage();
|
||||||
|
return Collections.singleton(mappingBasePackage == null ? null : mappingBasePackage.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@link MongoMappingContext} equipped with entity classes scanned from the mapping base package.
|
||||||
|
*
|
||||||
|
* @see #getMappingBasePackage()
|
||||||
|
* @return
|
||||||
|
* @throws ClassNotFoundException
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public MongoMappingContext mongoMappingContext() throws ClassNotFoundException {
|
||||||
|
|
||||||
|
MongoMappingContext mappingContext = new MongoMappingContext();
|
||||||
|
mappingContext.setInitialEntitySet(getInitialEntitySet());
|
||||||
|
mappingContext.setSimpleTypeHolder(customConversions().getSimpleTypeHolder());
|
||||||
|
mappingContext.setFieldNamingStrategy(fieldNamingStrategy());
|
||||||
|
|
||||||
|
return mappingContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a {@link MappingContextIsNewStrategyFactory} wrapped into a {@link CachingIsNewStrategyFactory}.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @throws ClassNotFoundException
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public IsNewStrategyFactory isNewStrategyFactory() throws ClassNotFoundException {
|
||||||
|
|
||||||
|
return new CachingIsNewStrategyFactory(new MappingContextIsNewStrategyFactory(
|
||||||
|
new PersistentEntities(Arrays.<MappingContext<?, ?>> asList(new MappingContext[] { mongoMappingContext() }))));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register custom {@link Converter}s in a {@link CustomConversions} object if required. These
|
||||||
|
* {@link CustomConversions} will be registered with the {@link #mappingMongoConverter()} and
|
||||||
|
* {@link #mongoMappingContext()}. Returns an empty {@link CustomConversions} instance by default.
|
||||||
|
*
|
||||||
|
* @return must not be {@literal null}.
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public CustomConversions customConversions() {
|
||||||
|
return new CustomConversions(Collections.emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scans the mapping base package for classes annotated with {@link Document}. By default, it scans for entities in
|
||||||
|
* all packages returned by {@link #getMappingBasePackages()}.
|
||||||
|
*
|
||||||
|
* @see #getMappingBasePackages()
|
||||||
|
* @return
|
||||||
|
* @throws ClassNotFoundException
|
||||||
|
*/
|
||||||
|
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
|
||||||
|
|
||||||
|
Set<Class<?>> initialEntitySet = new HashSet<Class<?>>();
|
||||||
|
|
||||||
|
for (String basePackage : getMappingBasePackages()) {
|
||||||
|
initialEntitySet.addAll(scanForEntities(basePackage));
|
||||||
|
}
|
||||||
|
|
||||||
|
return initialEntitySet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scans the given base package for entities, i.e. MongoDB specific types annotated with {@link Document} and
|
||||||
|
* {@link Persistent}.
|
||||||
|
*
|
||||||
|
* @param basePackage must not be {@literal null}.
|
||||||
|
* @return
|
||||||
|
* @throws ClassNotFoundException
|
||||||
|
* @since 1.10
|
||||||
|
*/
|
||||||
|
protected Set<Class<?>> scanForEntities(String basePackage) throws ClassNotFoundException {
|
||||||
|
|
||||||
|
if (!StringUtils.hasText(basePackage)) {
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<Class<?>> initialEntitySet = new HashSet<Class<?>>();
|
||||||
|
|
||||||
|
if (StringUtils.hasText(basePackage)) {
|
||||||
|
|
||||||
|
ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider(
|
||||||
|
false);
|
||||||
|
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Document.class));
|
||||||
|
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Persistent.class));
|
||||||
|
|
||||||
|
for (BeanDefinition candidate : componentProvider.findCandidateComponents(basePackage)) {
|
||||||
|
|
||||||
|
initialEntitySet
|
||||||
|
.add(ClassUtils.forName(candidate.getBeanClassName(), MongoConfigurationSupport.class.getClassLoader()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return initialEntitySet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures whether to abbreviate field names for domain objects by configuring a
|
||||||
|
* {@link CamelCaseAbbreviatingFieldNamingStrategy} on the {@link MongoMappingContext} instance created. For advanced
|
||||||
|
* customization needs, consider overriding {@link #mappingMongoConverter()}.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected boolean abbreviateFieldNames() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures a {@link FieldNamingStrategy} on the {@link MongoMappingContext} instance created.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @since 1.5
|
||||||
|
*/
|
||||||
|
protected FieldNamingStrategy fieldNamingStrategy() {
|
||||||
|
return abbreviateFieldNames() ? new CamelCaseAbbreviatingFieldNamingStrategy()
|
||||||
|
: PropertyNameFieldNamingStrategy.INSTANCE;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,198 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 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.config;
|
||||||
|
|
||||||
|
import java.beans.PropertyEditorSupport;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import com.mongodb.MongoCredential;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a {@link String} to a Collection of {@link MongoCredential}.
|
||||||
|
*
|
||||||
|
* @author Christoph Strobl
|
||||||
|
* @author Oliver Gierke
|
||||||
|
* @since 1.7
|
||||||
|
*/
|
||||||
|
public class MongoCredentialPropertyEditor extends PropertyEditorSupport {
|
||||||
|
|
||||||
|
private static final Pattern GROUP_PATTERN = Pattern.compile("(\\\\?')(.*?)\\1");
|
||||||
|
|
||||||
|
private static final String AUTH_MECHANISM_KEY = "uri.authMechanism";
|
||||||
|
private static final String USERNAME_PASSWORD_DELIMINATOR = ":";
|
||||||
|
private static final String DATABASE_DELIMINATOR = "@";
|
||||||
|
private static final String OPTIONS_DELIMINATOR = "?";
|
||||||
|
private static final String OPTION_VALUE_DELIMINATOR = "&";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.beans.PropertyEditorSupport#setAsText(java.lang.String)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setAsText(String text) throws IllegalArgumentException {
|
||||||
|
|
||||||
|
if (!StringUtils.hasText(text)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<MongoCredential> credentials = new ArrayList<MongoCredential>();
|
||||||
|
|
||||||
|
for (String credentialString : extractCredentialsString(text)) {
|
||||||
|
|
||||||
|
String[] userNameAndPassword = extractUserNameAndPassword(credentialString);
|
||||||
|
String database = extractDB(credentialString);
|
||||||
|
Properties options = extractOptions(credentialString);
|
||||||
|
|
||||||
|
if (!options.isEmpty()) {
|
||||||
|
|
||||||
|
if (options.containsKey(AUTH_MECHANISM_KEY)) {
|
||||||
|
|
||||||
|
String authMechanism = options.getProperty(AUTH_MECHANISM_KEY);
|
||||||
|
|
||||||
|
if (MongoCredential.GSSAPI_MECHANISM.equals(authMechanism)) {
|
||||||
|
|
||||||
|
verifyUserNamePresent(userNameAndPassword);
|
||||||
|
credentials.add(MongoCredential.createGSSAPICredential(userNameAndPassword[0]));
|
||||||
|
} else if (MongoCredential.MONGODB_CR_MECHANISM.equals(authMechanism)) {
|
||||||
|
|
||||||
|
verifyUsernameAndPasswordPresent(userNameAndPassword);
|
||||||
|
verifyDatabasePresent(database);
|
||||||
|
credentials.add(MongoCredential.createMongoCRCredential(userNameAndPassword[0], database,
|
||||||
|
userNameAndPassword[1].toCharArray()));
|
||||||
|
} else if (MongoCredential.MONGODB_X509_MECHANISM.equals(authMechanism)) {
|
||||||
|
|
||||||
|
verifyUserNamePresent(userNameAndPassword);
|
||||||
|
credentials.add(MongoCredential.createMongoX509Credential(userNameAndPassword[0]));
|
||||||
|
} else if (MongoCredential.PLAIN_MECHANISM.equals(authMechanism)) {
|
||||||
|
|
||||||
|
verifyUsernameAndPasswordPresent(userNameAndPassword);
|
||||||
|
verifyDatabasePresent(database);
|
||||||
|
credentials.add(MongoCredential.createPlainCredential(userNameAndPassword[0], database,
|
||||||
|
userNameAndPassword[1].toCharArray()));
|
||||||
|
} else if (MongoCredential.SCRAM_SHA_1_MECHANISM.equals(authMechanism)) {
|
||||||
|
|
||||||
|
verifyUsernameAndPasswordPresent(userNameAndPassword);
|
||||||
|
verifyDatabasePresent(database);
|
||||||
|
credentials.add(MongoCredential.createScramSha1Credential(userNameAndPassword[0], database,
|
||||||
|
userNameAndPassword[1].toCharArray()));
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
String.format("Cannot create MongoCredentials for unknown auth mechanism '%s'!", authMechanism));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
verifyUsernameAndPasswordPresent(userNameAndPassword);
|
||||||
|
verifyDatabasePresent(database);
|
||||||
|
credentials.add(
|
||||||
|
MongoCredential.createCredential(userNameAndPassword[0], database, userNameAndPassword[1].toCharArray()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setValue(credentials);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> extractCredentialsString(String source) {
|
||||||
|
|
||||||
|
Matcher matcher = GROUP_PATTERN.matcher(source);
|
||||||
|
List<String> list = new ArrayList<String>();
|
||||||
|
|
||||||
|
while (matcher.find()) {
|
||||||
|
|
||||||
|
String value = StringUtils.trimLeadingCharacter(matcher.group(), '\'');
|
||||||
|
list.add(StringUtils.trimTrailingCharacter(value, '\''));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!list.isEmpty()) {
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Arrays.asList(source.split(","));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String[] extractUserNameAndPassword(String text) {
|
||||||
|
|
||||||
|
int index = text.lastIndexOf(DATABASE_DELIMINATOR);
|
||||||
|
|
||||||
|
index = index != -1 ? index : text.lastIndexOf(OPTIONS_DELIMINATOR);
|
||||||
|
|
||||||
|
return index == -1 ? new String[] {} : text.substring(0, index).split(USERNAME_PASSWORD_DELIMINATOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String extractDB(String text) {
|
||||||
|
|
||||||
|
int dbSeperationIndex = text.lastIndexOf(DATABASE_DELIMINATOR);
|
||||||
|
|
||||||
|
if (dbSeperationIndex == -1) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
String tmp = text.substring(dbSeperationIndex + 1);
|
||||||
|
int optionsSeperationIndex = tmp.lastIndexOf(OPTIONS_DELIMINATOR);
|
||||||
|
|
||||||
|
return optionsSeperationIndex > -1 ? tmp.substring(0, optionsSeperationIndex) : tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Properties extractOptions(String text) {
|
||||||
|
|
||||||
|
int optionsSeperationIndex = text.lastIndexOf(OPTIONS_DELIMINATOR);
|
||||||
|
int dbSeperationIndex = text.lastIndexOf(OPTIONS_DELIMINATOR);
|
||||||
|
|
||||||
|
if (optionsSeperationIndex == -1 || dbSeperationIndex > optionsSeperationIndex) {
|
||||||
|
return new Properties();
|
||||||
|
}
|
||||||
|
|
||||||
|
Properties properties = new Properties();
|
||||||
|
|
||||||
|
for (String option : text.substring(optionsSeperationIndex + 1).split(OPTION_VALUE_DELIMINATOR)) {
|
||||||
|
String[] optionArgs = option.split("=");
|
||||||
|
properties.put(optionArgs[0], optionArgs[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void verifyUsernameAndPasswordPresent(String[] source) {
|
||||||
|
|
||||||
|
verifyUserNamePresent(source);
|
||||||
|
|
||||||
|
if (source.length != 2) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Credentials need to specify username and password like in 'username:password@database'!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void verifyDatabasePresent(String source) {
|
||||||
|
|
||||||
|
if (!StringUtils.hasText(source)) {
|
||||||
|
throw new IllegalArgumentException("Credentials need to specify database like in 'username:password@database'!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void verifyUserNamePresent(String[] source) {
|
||||||
|
|
||||||
|
if (source.length == 0 || !StringUtils.hasText(source[0])) {
|
||||||
|
throw new IllegalArgumentException("Credentials need to specify username!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 by the original author(s).
|
* Copyright 2011-2015 by the original author(s).
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -15,70 +15,110 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.config;
|
package org.springframework.data.mongodb.config;
|
||||||
|
|
||||||
import static org.springframework.data.mongodb.config.BeanNames.*;
|
import static org.springframework.data.config.ParsingUtils.*;
|
||||||
|
import static org.springframework.data.mongodb.config.MongoParsingUtils.*;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
|
||||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
|
||||||
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
|
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
|
||||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||||
import org.springframework.beans.factory.xml.ParserContext;
|
import org.springframework.beans.factory.xml.ParserContext;
|
||||||
import org.springframework.data.authentication.UserCredentials;
|
import org.springframework.data.authentication.UserCredentials;
|
||||||
import org.springframework.data.mongodb.core.MongoFactoryBean;
|
import org.springframework.data.config.BeanComponentDefinitionBuilder;
|
||||||
|
import org.springframework.data.mongodb.core.MongoClientFactoryBean;
|
||||||
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
|
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
import com.mongodb.Mongo;
|
import com.mongodb.Mongo;
|
||||||
|
import com.mongodb.MongoClientURI;
|
||||||
|
import com.mongodb.MongoURI;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link BeanDefinitionParser} to parse {@code db-factory} elements into {@link BeanDefinition}s.
|
* {@link BeanDefinitionParser} to parse {@code db-factory} elements into {@link BeanDefinition}s.
|
||||||
*
|
*
|
||||||
* @author Jon Brisbin
|
* @author Jon Brisbin
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
|
* @author Thomas Darimont
|
||||||
|
* @author Christoph Strobl
|
||||||
|
* @author Viktor Khoroshko
|
||||||
*/
|
*/
|
||||||
public class MongoDbFactoryParser extends AbstractBeanDefinitionParser {
|
public class MongoDbFactoryParser extends AbstractBeanDefinitionParser {
|
||||||
|
|
||||||
|
private static final Set<String> MONGO_URI_ALLOWED_ADDITIONAL_ATTRIBUTES;
|
||||||
|
|
||||||
|
static {
|
||||||
|
|
||||||
|
Set<String> mongoUriAllowedAdditionalAttributes = new HashSet<String>();
|
||||||
|
mongoUriAllowedAdditionalAttributes.add("id");
|
||||||
|
mongoUriAllowedAdditionalAttributes.add("write-concern");
|
||||||
|
|
||||||
|
MONGO_URI_ALLOWED_ADDITIONAL_ATTRIBUTES = Collections.unmodifiableSet(mongoUriAllowedAdditionalAttributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#resolveId(org.w3c.dom.Element, org.springframework.beans.factory.support.AbstractBeanDefinition, org.springframework.beans.factory.xml.ParserContext)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
|
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
|
||||||
throws BeanDefinitionStoreException {
|
throws BeanDefinitionStoreException {
|
||||||
String id = element.getAttribute("id");
|
|
||||||
if (!StringUtils.hasText(id)) {
|
String id = super.resolveId(element, definition, parserContext);
|
||||||
id = DB_FACTORY;
|
return StringUtils.hasText(id) ? id : BeanNames.DB_FACTORY_BEAN_NAME;
|
||||||
}
|
|
||||||
return id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#parseInternal(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
|
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
|
||||||
|
|
||||||
String mongoRef = element.getAttribute("mongo-ref");
|
// Common setup
|
||||||
if (!StringUtils.hasText(mongoRef)) {
|
|
||||||
mongoRef = registerMongoBeanDefinition(element, parserContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Database name
|
|
||||||
String dbname = element.getAttribute("dbname");
|
|
||||||
if (!StringUtils.hasText(dbname)) {
|
|
||||||
dbname = "db";
|
|
||||||
}
|
|
||||||
|
|
||||||
BeanDefinitionBuilder dbFactoryBuilder = BeanDefinitionBuilder.genericBeanDefinition(SimpleMongoDbFactory.class);
|
BeanDefinitionBuilder dbFactoryBuilder = BeanDefinitionBuilder.genericBeanDefinition(SimpleMongoDbFactory.class);
|
||||||
dbFactoryBuilder.addConstructorArgValue(new RuntimeBeanReference(mongoRef));
|
setPropertyValue(dbFactoryBuilder, element, "write-concern", "writeConcern");
|
||||||
dbFactoryBuilder.addConstructorArgValue(dbname);
|
|
||||||
|
|
||||||
BeanDefinition userCredentials = getUserCredentialsBeanDefinition(element);
|
BeanDefinition mongoUri = getMongoUri(element, parserContext);
|
||||||
if (userCredentials != null) {
|
|
||||||
dbFactoryBuilder.addConstructorArgValue(userCredentials);
|
if (mongoUri != null) {
|
||||||
|
|
||||||
|
dbFactoryBuilder.addConstructorArgValue(mongoUri);
|
||||||
|
return getSourceBeanDefinition(dbFactoryBuilder, parserContext, element);
|
||||||
}
|
}
|
||||||
|
|
||||||
ParsingUtils.setPropertyValue(element, dbFactoryBuilder, "write-concern", "writeConcern");
|
BeanComponentDefinitionBuilder helper = new BeanComponentDefinitionBuilder(element, parserContext);
|
||||||
|
|
||||||
return dbFactoryBuilder.getBeanDefinition();
|
String mongoRef = element.getAttribute("mongo-ref");
|
||||||
|
String dbname = element.getAttribute("dbname");
|
||||||
|
|
||||||
|
BeanDefinition userCredentials = getUserCredentialsBeanDefinition(element, parserContext);
|
||||||
|
|
||||||
|
// Defaulting
|
||||||
|
if (StringUtils.hasText(mongoRef)) {
|
||||||
|
dbFactoryBuilder.addConstructorArgReference(mongoRef);
|
||||||
|
} else {
|
||||||
|
dbFactoryBuilder.addConstructorArgValue(registerMongoBeanDefinition(element, parserContext));
|
||||||
|
}
|
||||||
|
|
||||||
|
dbFactoryBuilder.addConstructorArgValue(StringUtils.hasText(dbname) ? dbname : "db");
|
||||||
|
dbFactoryBuilder.addConstructorArgValue(userCredentials);
|
||||||
|
dbFactoryBuilder.addConstructorArgValue(element.getAttribute("authentication-dbname"));
|
||||||
|
|
||||||
|
BeanDefinitionBuilder writeConcernPropertyEditorBuilder = getWriteConcernPropertyEditorBuilder();
|
||||||
|
|
||||||
|
BeanComponentDefinition component = helper.getComponent(writeConcernPropertyEditorBuilder);
|
||||||
|
parserContext.registerBeanComponent(component);
|
||||||
|
|
||||||
|
return (AbstractBeanDefinition) helper.getComponentIdButFallback(dbFactoryBuilder, BeanNames.DB_FACTORY_BEAN_NAME)
|
||||||
|
.getBeanDefinition();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -89,14 +129,13 @@ public class MongoDbFactoryParser extends AbstractBeanDefinitionParser {
|
|||||||
* @param parserContext must not be {@literal null}.
|
* @param parserContext must not be {@literal null}.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private String registerMongoBeanDefinition(Element element, ParserContext parserContext) {
|
private BeanDefinition registerMongoBeanDefinition(Element element, ParserContext parserContext) {
|
||||||
|
|
||||||
BeanDefinitionBuilder mongoBuilder = BeanDefinitionBuilder.genericBeanDefinition(MongoFactoryBean.class);
|
BeanDefinitionBuilder mongoBuilder = BeanDefinitionBuilder.genericBeanDefinition(MongoClientFactoryBean.class);
|
||||||
ParsingUtils.setPropertyValue(element, mongoBuilder, "host");
|
setPropertyValue(mongoBuilder, element, "host");
|
||||||
ParsingUtils.setPropertyValue(element, mongoBuilder, "port");
|
setPropertyValue(mongoBuilder, element, "port");
|
||||||
|
|
||||||
return BeanDefinitionReaderUtils.registerWithGeneratedName(mongoBuilder.getBeanDefinition(),
|
return getSourceBeanDefinition(mongoBuilder, parserContext, element);
|
||||||
parserContext.getRegistry());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -105,7 +144,7 @@ public class MongoDbFactoryParser extends AbstractBeanDefinitionParser {
|
|||||||
* @param element
|
* @param element
|
||||||
* @return the {@link BeanDefinition} or {@literal null} if neither username nor password given.
|
* @return the {@link BeanDefinition} or {@literal null} if neither username nor password given.
|
||||||
*/
|
*/
|
||||||
private BeanDefinition getUserCredentialsBeanDefinition(Element element) {
|
private BeanDefinition getUserCredentialsBeanDefinition(Element element, ParserContext context) {
|
||||||
|
|
||||||
String username = element.getAttribute("username");
|
String username = element.getAttribute("username");
|
||||||
String password = element.getAttribute("password");
|
String password = element.getAttribute("password");
|
||||||
@@ -118,6 +157,48 @@ public class MongoDbFactoryParser extends AbstractBeanDefinitionParser {
|
|||||||
userCredentialsBuilder.addConstructorArgValue(StringUtils.hasText(username) ? username : null);
|
userCredentialsBuilder.addConstructorArgValue(StringUtils.hasText(username) ? username : null);
|
||||||
userCredentialsBuilder.addConstructorArgValue(StringUtils.hasText(password) ? password : null);
|
userCredentialsBuilder.addConstructorArgValue(StringUtils.hasText(password) ? password : null);
|
||||||
|
|
||||||
return userCredentialsBuilder.getBeanDefinition();
|
return getSourceBeanDefinition(userCredentialsBuilder, context, element);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@link BeanDefinition} for a {@link MongoURI} or {@link MongoClientURI} depending on configured
|
||||||
|
* attributes. <br />
|
||||||
|
* Errors when configured element contains {@literal uri} or {@literal client-uri} along with other attributes except
|
||||||
|
* {@literal write-concern} and/or {@literal id}.
|
||||||
|
*
|
||||||
|
* @param element must not be {@literal null}.
|
||||||
|
* @param parserContext
|
||||||
|
* @return {@literal null} in case no client-/uri defined.
|
||||||
|
*/
|
||||||
|
private BeanDefinition getMongoUri(Element element, ParserContext parserContext) {
|
||||||
|
|
||||||
|
boolean hasClientUri = element.hasAttribute("client-uri");
|
||||||
|
|
||||||
|
if (!hasClientUri && !element.hasAttribute("uri")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int allowedAttributesCount = 1;
|
||||||
|
for (String attribute : MONGO_URI_ALLOWED_ADDITIONAL_ATTRIBUTES) {
|
||||||
|
|
||||||
|
if (element.hasAttribute(attribute)) {
|
||||||
|
allowedAttributesCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (element.getAttributes().getLength() > allowedAttributesCount) {
|
||||||
|
|
||||||
|
parserContext.getReaderContext().error(
|
||||||
|
"Configure either " + (hasClientUri ? "Mongo Client URI" : "Mongo URI") + " or details individually!",
|
||||||
|
parserContext.extractSource(element));
|
||||||
|
}
|
||||||
|
|
||||||
|
Class<?> type = hasClientUri ? MongoClientURI.class : MongoURI.class;
|
||||||
|
String uri = hasClientUri ? element.getAttribute("client-uri") : element.getAttribute("uri");
|
||||||
|
|
||||||
|
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(type);
|
||||||
|
builder.addConstructorArgValue(uri);
|
||||||
|
|
||||||
|
return builder.getBeanDefinition();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2011 the original author or authors.
|
* Copyright 2011-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -18,23 +18,27 @@ package org.springframework.data.mongodb.config;
|
|||||||
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
|
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link org.springframework.beans.factory.xml.NamespaceHandler} for Mongo DB based repositories.
|
* {@link org.springframework.beans.factory.xml.NamespaceHandler} for Mongo DB configuration.
|
||||||
*
|
*
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
|
* @author Martin Baumgartner
|
||||||
|
* @author Christoph Strobl
|
||||||
*/
|
*/
|
||||||
public class MongoRepositoryNamespaceHandler extends NamespaceHandlerSupport {
|
public class MongoNamespaceHandler extends NamespaceHandlerSupport {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
* @see org.springframework.beans.factory.xml.NamespaceHandler#init()
|
||||||
* @see org.springframework.beans.factory.xml.NamespaceHandler#init()
|
*/
|
||||||
*/
|
|
||||||
public void init() {
|
public void init() {
|
||||||
|
|
||||||
registerBeanDefinitionParser("repositories", new MongoRepositoryConfigParser());
|
|
||||||
registerBeanDefinitionParser("mapping-converter", new MappingMongoConverterParser());
|
registerBeanDefinitionParser("mapping-converter", new MappingMongoConverterParser());
|
||||||
registerBeanDefinitionParser("mongo", new MongoParser());
|
registerBeanDefinitionParser("mongo", new MongoParser());
|
||||||
|
registerBeanDefinitionParser("mongo-client", new MongoClientParser());
|
||||||
registerBeanDefinitionParser("db-factory", new MongoDbFactoryParser());
|
registerBeanDefinitionParser("db-factory", new MongoDbFactoryParser());
|
||||||
registerBeanDefinitionParser("jmx", new MongoJmxParser());
|
registerBeanDefinitionParser("jmx", new MongoJmxParser());
|
||||||
|
registerBeanDefinitionParser("auditing", new MongoAuditingBeanDefinitionParser());
|
||||||
|
registerBeanDefinitionParser("template", new MongoTemplateParser());
|
||||||
|
registerBeanDefinitionParser("gridFsTemplate", new GridFsTemplateParser());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2011 the original author or authors.
|
* Copyright 2011-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -13,50 +13,64 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.data.mongodb.config;
|
package org.springframework.data.mongodb.config;
|
||||||
|
|
||||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
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.support.BeanDefinitionBuilder;
|
||||||
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
|
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||||
import org.springframework.beans.factory.xml.ParserContext;
|
import org.springframework.beans.factory.xml.ParserContext;
|
||||||
|
import org.springframework.data.config.BeanComponentDefinitionBuilder;
|
||||||
|
import org.springframework.data.config.ParsingUtils;
|
||||||
import org.springframework.data.mongodb.core.MongoFactoryBean;
|
import org.springframework.data.mongodb.core.MongoFactoryBean;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parser for <mongo;gt; definitions. If no name
|
* Parser for <mongo;gt; definitions.
|
||||||
*
|
*
|
||||||
* @author Mark Pollack
|
* @author Mark Pollack
|
||||||
|
* @author Oliver Gierke
|
||||||
|
* @author Christoph Strobl
|
||||||
*/
|
*/
|
||||||
public class MongoParser extends AbstractSingleBeanDefinitionParser {
|
public class MongoParser implements BeanDefinitionParser {
|
||||||
|
|
||||||
@Override
|
/*
|
||||||
protected Class<?> getBeanClass(Element element) {
|
* (non-Javadoc)
|
||||||
return MongoFactoryBean.class;
|
* @see org.springframework.beans.factory.xml.BeanDefinitionParser#parse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)
|
||||||
|
*/
|
||||||
|
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||||
|
|
||||||
|
Object source = parserContext.extractSource(element);
|
||||||
|
String id = element.getAttribute("id");
|
||||||
|
|
||||||
|
BeanComponentDefinitionBuilder helper = new BeanComponentDefinitionBuilder(element, parserContext);
|
||||||
|
|
||||||
|
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MongoFactoryBean.class);
|
||||||
|
ParsingUtils.setPropertyValue(builder, element, "port", "port");
|
||||||
|
ParsingUtils.setPropertyValue(builder, element, "host", "host");
|
||||||
|
ParsingUtils.setPropertyValue(builder, element, "write-concern", "writeConcern");
|
||||||
|
|
||||||
|
MongoParsingUtils.parseMongoOptions(element, builder);
|
||||||
|
MongoParsingUtils.parseReplicaSet(element, builder);
|
||||||
|
|
||||||
|
String defaultedId = StringUtils.hasText(id) ? id : BeanNames.MONGO_BEAN_NAME;
|
||||||
|
|
||||||
|
parserContext.pushContainingComponent(new CompositeComponentDefinition("Mongo", source));
|
||||||
|
|
||||||
|
BeanComponentDefinition mongoComponent = helper.getComponent(builder, defaultedId);
|
||||||
|
parserContext.registerBeanComponent(mongoComponent);
|
||||||
|
BeanComponentDefinition serverAddressPropertyEditor = helper.getComponent(MongoParsingUtils
|
||||||
|
.getServerAddressPropertyEditorBuilder());
|
||||||
|
parserContext.registerBeanComponent(serverAddressPropertyEditor);
|
||||||
|
BeanComponentDefinition writeConcernPropertyEditor = helper.getComponent(MongoParsingUtils
|
||||||
|
.getWriteConcernPropertyEditorBuilder());
|
||||||
|
parserContext.registerBeanComponent(writeConcernPropertyEditor);
|
||||||
|
|
||||||
|
parserContext.popAndRegisterContainingComponent();
|
||||||
|
|
||||||
|
return mongoComponent.getBeanDefinition();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
|
||||||
super.doParse(element, builder);
|
|
||||||
|
|
||||||
ParsingUtils.setPropertyValue(element, builder, "port", "port");
|
|
||||||
ParsingUtils.setPropertyValue(element, builder, "host", "host");
|
|
||||||
ParsingUtils.setPropertyValue(element, builder, "write-concern", "writeConcern");
|
|
||||||
|
|
||||||
ParsingUtils.parseMongoOptions(parserContext, element, builder);
|
|
||||||
ParsingUtils.parseReplicaSet(parserContext, element, builder);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,206 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011-2015 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.config;
|
||||||
|
|
||||||
|
import static org.springframework.data.config.ParsingUtils.*;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.beans.factory.config.CustomEditorConfigurer;
|
||||||
|
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||||
|
import org.springframework.beans.factory.support.ManagedMap;
|
||||||
|
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||||
|
import org.springframework.data.mongodb.core.MongoClientOptionsFactoryBean;
|
||||||
|
import org.springframework.data.mongodb.core.MongoOptionsFactoryBean;
|
||||||
|
import org.springframework.util.xml.DomUtils;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility methods for {@link BeanDefinitionParser} implementations for MongoDB.
|
||||||
|
*
|
||||||
|
* @author Mark Pollack
|
||||||
|
* @author Oliver Gierke
|
||||||
|
* @author Thomas Darimont
|
||||||
|
* @author Christoph Strobl
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
abstract class MongoParsingUtils {
|
||||||
|
|
||||||
|
private MongoParsingUtils() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the mongo replica-set element.
|
||||||
|
*
|
||||||
|
* @param parserContext the parser context
|
||||||
|
* @param element the mongo element
|
||||||
|
* @param mongoBuilder the bean definition builder to populate
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static void parseReplicaSet(Element element, BeanDefinitionBuilder mongoBuilder) {
|
||||||
|
setPropertyValue(mongoBuilder, element, "replica-set", "replicaSetSeeds");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the {@code mongo:options} sub-element. Populates the given attribute factory with the proper attributes.
|
||||||
|
*
|
||||||
|
* @return true if parsing actually occured, {@literal false} otherwise
|
||||||
|
*/
|
||||||
|
static boolean parseMongoOptions(Element element, BeanDefinitionBuilder mongoBuilder) {
|
||||||
|
|
||||||
|
Element optionsElement = DomUtils.getChildElementByTagName(element, "options");
|
||||||
|
|
||||||
|
if (optionsElement == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BeanDefinitionBuilder optionsDefBuilder = BeanDefinitionBuilder
|
||||||
|
.genericBeanDefinition(MongoOptionsFactoryBean.class);
|
||||||
|
|
||||||
|
setPropertyValue(optionsDefBuilder, optionsElement, "connections-per-host", "connectionsPerHost");
|
||||||
|
setPropertyValue(optionsDefBuilder, optionsElement, "threads-allowed-to-block-for-connection-multiplier",
|
||||||
|
"threadsAllowedToBlockForConnectionMultiplier");
|
||||||
|
setPropertyValue(optionsDefBuilder, optionsElement, "max-wait-time", "maxWaitTime");
|
||||||
|
setPropertyValue(optionsDefBuilder, optionsElement, "connect-timeout", "connectTimeout");
|
||||||
|
setPropertyValue(optionsDefBuilder, optionsElement, "socket-timeout", "socketTimeout");
|
||||||
|
setPropertyValue(optionsDefBuilder, optionsElement, "socket-keep-alive", "socketKeepAlive");
|
||||||
|
setPropertyValue(optionsDefBuilder, optionsElement, "auto-connect-retry", "autoConnectRetry");
|
||||||
|
setPropertyValue(optionsDefBuilder, optionsElement, "max-auto-connect-retry-time", "maxAutoConnectRetryTime");
|
||||||
|
setPropertyValue(optionsDefBuilder, optionsElement, "write-number", "writeNumber");
|
||||||
|
setPropertyValue(optionsDefBuilder, optionsElement, "write-timeout", "writeTimeout");
|
||||||
|
setPropertyValue(optionsDefBuilder, optionsElement, "write-fsync", "writeFsync");
|
||||||
|
setPropertyValue(optionsDefBuilder, optionsElement, "slave-ok", "slaveOk");
|
||||||
|
setPropertyValue(optionsDefBuilder, optionsElement, "ssl", "ssl");
|
||||||
|
setPropertyReference(optionsDefBuilder, optionsElement, "ssl-socket-factory-ref", "sslSocketFactory");
|
||||||
|
|
||||||
|
mongoBuilder.addPropertyValue("mongoOptions", optionsDefBuilder.getBeanDefinition());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the {@code mongo:client-options} sub-element. Populates the given attribute factory with the proper
|
||||||
|
* attributes.
|
||||||
|
*
|
||||||
|
* @param element must not be {@literal null}.
|
||||||
|
* @param mongoClientBuilder must not be {@literal null}.
|
||||||
|
* @return
|
||||||
|
* @since 1.7
|
||||||
|
*/
|
||||||
|
public static boolean parseMongoClientOptions(Element element, BeanDefinitionBuilder mongoClientBuilder) {
|
||||||
|
|
||||||
|
Element optionsElement = DomUtils.getChildElementByTagName(element, "client-options");
|
||||||
|
|
||||||
|
if (optionsElement == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BeanDefinitionBuilder clientOptionsDefBuilder = BeanDefinitionBuilder
|
||||||
|
.genericBeanDefinition(MongoClientOptionsFactoryBean.class);
|
||||||
|
|
||||||
|
setPropertyValue(clientOptionsDefBuilder, optionsElement, "description", "description");
|
||||||
|
setPropertyValue(clientOptionsDefBuilder, optionsElement, "min-connections-per-host", "minConnectionsPerHost");
|
||||||
|
setPropertyValue(clientOptionsDefBuilder, optionsElement, "connections-per-host", "connectionsPerHost");
|
||||||
|
setPropertyValue(clientOptionsDefBuilder, optionsElement, "threads-allowed-to-block-for-connection-multiplier",
|
||||||
|
"threadsAllowedToBlockForConnectionMultiplier");
|
||||||
|
setPropertyValue(clientOptionsDefBuilder, optionsElement, "max-wait-time", "maxWaitTime");
|
||||||
|
setPropertyValue(clientOptionsDefBuilder, optionsElement, "max-connection-idle-time", "maxConnectionIdleTime");
|
||||||
|
setPropertyValue(clientOptionsDefBuilder, optionsElement, "max-connection-life-time", "maxConnectionLifeTime");
|
||||||
|
setPropertyValue(clientOptionsDefBuilder, optionsElement, "connect-timeout", "connectTimeout");
|
||||||
|
setPropertyValue(clientOptionsDefBuilder, optionsElement, "socket-timeout", "socketTimeout");
|
||||||
|
setPropertyValue(clientOptionsDefBuilder, optionsElement, "socket-keep-alive", "socketKeepAlive");
|
||||||
|
setPropertyValue(clientOptionsDefBuilder, optionsElement, "read-preference", "readPreference");
|
||||||
|
setPropertyValue(clientOptionsDefBuilder, optionsElement, "write-concern", "writeConcern");
|
||||||
|
setPropertyValue(clientOptionsDefBuilder, optionsElement, "heartbeat-frequency", "heartbeatFrequency");
|
||||||
|
setPropertyValue(clientOptionsDefBuilder, optionsElement, "min-heartbeat-frequency", "minHeartbeatFrequency");
|
||||||
|
setPropertyValue(clientOptionsDefBuilder, optionsElement, "heartbeat-connect-timeout", "heartbeatConnectTimeout");
|
||||||
|
setPropertyValue(clientOptionsDefBuilder, optionsElement, "heartbeat-socket-timeout", "heartbeatSocketTimeout");
|
||||||
|
setPropertyValue(clientOptionsDefBuilder, optionsElement, "ssl", "ssl");
|
||||||
|
setPropertyReference(clientOptionsDefBuilder, optionsElement, "ssl-socket-factory-ref", "sslSocketFactory");
|
||||||
|
|
||||||
|
mongoClientBuilder.addPropertyValue("mongoClientOptions", clientOptionsDefBuilder.getBeanDefinition());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link BeanDefinitionBuilder} to build a {@link BeanDefinition} for a
|
||||||
|
* {@link WriteConcernPropertyEditor}.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static BeanDefinitionBuilder getWriteConcernPropertyEditorBuilder() {
|
||||||
|
|
||||||
|
Map<String, Class<?>> customEditors = new ManagedMap<String, Class<?>>();
|
||||||
|
customEditors.put("com.mongodb.WriteConcern", WriteConcernPropertyEditor.class);
|
||||||
|
|
||||||
|
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CustomEditorConfigurer.class);
|
||||||
|
builder.addPropertyValue("customEditors", customEditors);
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* One should only register one bean definition but want to have the convenience of using
|
||||||
|
* AbstractSingleBeanDefinitionParser but have the side effect of registering a 'default' property editor with the
|
||||||
|
* container.
|
||||||
|
*/
|
||||||
|
static BeanDefinitionBuilder getServerAddressPropertyEditorBuilder() {
|
||||||
|
|
||||||
|
Map<String, String> customEditors = new ManagedMap<String, String>();
|
||||||
|
customEditors.put("com.mongodb.ServerAddress[]",
|
||||||
|
"org.springframework.data.mongodb.config.ServerAddressPropertyEditor");
|
||||||
|
|
||||||
|
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CustomEditorConfigurer.class);
|
||||||
|
builder.addPropertyValue("customEditors", customEditors);
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link BeanDefinitionBuilder} to build a {@link BeanDefinition} for a
|
||||||
|
* {@link ReadPreferencePropertyEditor}.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @since 1.7
|
||||||
|
*/
|
||||||
|
static BeanDefinitionBuilder getReadPreferencePropertyEditorBuilder() {
|
||||||
|
|
||||||
|
Map<String, Class<?>> customEditors = new ManagedMap<String, Class<?>>();
|
||||||
|
customEditors.put("com.mongodb.ReadPreference", ReadPreferencePropertyEditor.class);
|
||||||
|
|
||||||
|
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CustomEditorConfigurer.class);
|
||||||
|
builder.addPropertyValue("customEditors", customEditors);
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link BeanDefinitionBuilder} to build a {@link BeanDefinition} for a
|
||||||
|
* {@link MongoCredentialPropertyEditor}.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @since 1.7
|
||||||
|
*/
|
||||||
|
static BeanDefinitionBuilder getMongoCredentialPropertyEditor() {
|
||||||
|
|
||||||
|
Map<String, Class<?>> customEditors = new ManagedMap<String, Class<?>>();
|
||||||
|
customEditors.put("com.mongodb.MongoCredential[]", MongoCredentialPropertyEditor.class);
|
||||||
|
|
||||||
|
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CustomEditorConfigurer.class);
|
||||||
|
builder.addPropertyValue("customEditors", customEditors);
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,54 +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.mongodb.config;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
|
||||||
import org.springframework.data.mongodb.config.SimpleMongoRepositoryConfiguration.MongoRepositoryConfiguration;
|
|
||||||
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> {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (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());
|
|
||||||
builder.addPropertyValue("createIndexesForQueryMethods", context.getCreateQueryIndexes());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011-2014 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.config;
|
||||||
|
|
||||||
|
import static org.springframework.data.config.ParsingUtils.*;
|
||||||
|
import static org.springframework.data.mongodb.config.MongoParsingUtils.*;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
|
||||||
|
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||||
|
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||||
|
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
|
||||||
|
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||||
|
import org.springframework.beans.factory.xml.ParserContext;
|
||||||
|
import org.springframework.data.config.BeanComponentDefinitionBuilder;
|
||||||
|
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link BeanDefinitionParser} to parse {@code template} elements into {@link BeanDefinition}s.
|
||||||
|
*
|
||||||
|
* @author Martin Baumgartner
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
|
class MongoTemplateParser extends AbstractBeanDefinitionParser {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#resolveId(org.w3c.dom.Element, org.springframework.beans.factory.support.AbstractBeanDefinition, org.springframework.beans.factory.xml.ParserContext)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
|
||||||
|
throws BeanDefinitionStoreException {
|
||||||
|
|
||||||
|
String id = super.resolveId(element, definition, parserContext);
|
||||||
|
return StringUtils.hasText(id) ? id : BeanNames.MONGO_TEMPLATE_BEAN_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#parseInternal(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
|
||||||
|
|
||||||
|
BeanComponentDefinitionBuilder helper = new BeanComponentDefinitionBuilder(element, parserContext);
|
||||||
|
|
||||||
|
String converterRef = element.getAttribute("converter-ref");
|
||||||
|
String dbFactoryRef = element.getAttribute("db-factory-ref");
|
||||||
|
|
||||||
|
BeanDefinitionBuilder mongoTemplateBuilder = BeanDefinitionBuilder.genericBeanDefinition(MongoTemplate.class);
|
||||||
|
setPropertyValue(mongoTemplateBuilder, element, "write-concern", "writeConcern");
|
||||||
|
|
||||||
|
if (StringUtils.hasText(dbFactoryRef)) {
|
||||||
|
mongoTemplateBuilder.addConstructorArgReference(dbFactoryRef);
|
||||||
|
} else {
|
||||||
|
mongoTemplateBuilder.addConstructorArgReference(BeanNames.DB_FACTORY_BEAN_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.hasText(converterRef)) {
|
||||||
|
mongoTemplateBuilder.addConstructorArgReference(converterRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
BeanDefinitionBuilder writeConcernPropertyEditorBuilder = getWriteConcernPropertyEditorBuilder();
|
||||||
|
|
||||||
|
BeanComponentDefinition component = helper.getComponent(writeConcernPropertyEditorBuilder);
|
||||||
|
parserContext.registerBeanComponent(component);
|
||||||
|
|
||||||
|
return (AbstractBeanDefinition) helper.getComponentIdButFallback(mongoTemplateBuilder,
|
||||||
|
BeanNames.MONGO_TEMPLATE_BEAN_NAME).getBeanDefinition();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,112 +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.mongodb.config;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
|
||||||
import org.springframework.beans.factory.support.ManagedList;
|
|
||||||
import org.springframework.beans.factory.xml.ParserContext;
|
|
||||||
import org.springframework.data.mongodb.core.MongoOptionsFactoryBean;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
import org.springframework.util.xml.DomUtils;
|
|
||||||
import org.w3c.dom.Element;
|
|
||||||
|
|
||||||
import com.mongodb.ServerAddress;
|
|
||||||
|
|
||||||
abstract class ParsingUtils {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the mongo replica-set element.
|
|
||||||
*
|
|
||||||
* @param parserContext the parser context
|
|
||||||
* @param element the mongo element
|
|
||||||
* @param mongoBuilder the bean definition builder to populate
|
|
||||||
* @return true if parsing actually occured, false otherwise
|
|
||||||
*/
|
|
||||||
static boolean parseReplicaSet(ParserContext parserContext, Element element, BeanDefinitionBuilder mongoBuilder) {
|
|
||||||
|
|
||||||
String replicaSetString = element.getAttribute("replica-set");
|
|
||||||
if (StringUtils.hasText(replicaSetString)) {
|
|
||||||
ManagedList<Object> serverAddresses = new ManagedList<Object>();
|
|
||||||
String[] replicaSetStringArray = StringUtils.commaDelimitedListToStringArray(replicaSetString);
|
|
||||||
for (String element2 : replicaSetStringArray) {
|
|
||||||
String[] hostAndPort = StringUtils.delimitedListToStringArray(element2, ":");
|
|
||||||
BeanDefinitionBuilder defBuilder = BeanDefinitionBuilder.genericBeanDefinition(ServerAddress.class);
|
|
||||||
defBuilder.addConstructorArgValue(hostAndPort[0]);
|
|
||||||
defBuilder.addConstructorArgValue(hostAndPort[1]);
|
|
||||||
serverAddresses.add(defBuilder.getBeanDefinition());
|
|
||||||
}
|
|
||||||
if (!serverAddresses.isEmpty()) {
|
|
||||||
mongoBuilder.addPropertyValue("replicaSetSeeds", serverAddresses);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the mongo:options sub-element. Populates the given attribute factory with the proper attributes.
|
|
||||||
*
|
|
||||||
* @return true if parsing actually occured, false otherwise
|
|
||||||
*/
|
|
||||||
static boolean parseMongoOptions(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, "connections-per-host", "connectionsPerHost");
|
|
||||||
setPropertyValue(optionsElement, optionsDefBuilder, "threads-allowed-to-block-for-connection-multiplier",
|
|
||||||
"threadsAllowedToBlockForConnectionMultiplier");
|
|
||||||
setPropertyValue(optionsElement, optionsDefBuilder, "max-wait-time", "maxWaitTime");
|
|
||||||
setPropertyValue(optionsElement, optionsDefBuilder, "connect-timeout", "connectTimeout");
|
|
||||||
setPropertyValue(optionsElement, optionsDefBuilder, "socket-timeout", "socketTimeout");
|
|
||||||
setPropertyValue(optionsElement, optionsDefBuilder, "socket-keep-alive", "socketKeepAlive");
|
|
||||||
setPropertyValue(optionsElement, optionsDefBuilder, "auto-connect-retry", "autoConnectRetry");
|
|
||||||
setPropertyValue(optionsElement, optionsDefBuilder, "write-number", "writeNumber");
|
|
||||||
setPropertyValue(optionsElement, optionsDefBuilder, "write-timeout", "writeTimeout");
|
|
||||||
setPropertyValue(optionsElement, optionsDefBuilder, "write-fsync", "writeFsync");
|
|
||||||
setPropertyValue(optionsElement, optionsDefBuilder, "slave-ok", "slaveOk");
|
|
||||||
|
|
||||||
mongoBuilder.addPropertyValue("mongoOptions", optionsDefBuilder.getBeanDefinition());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void setPropertyValue(Element element, BeanDefinitionBuilder builder, String attrName, String propertyName) {
|
|
||||||
String attr = element.getAttribute(attrName);
|
|
||||||
if (StringUtils.hasText(attr)) {
|
|
||||||
builder.addPropertyValue(propertyName, attr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the property with the given attribute name on the given {@link BeanDefinitionBuilder} to the value of the
|
|
||||||
* attribute with the given name.
|
|
||||||
*
|
|
||||||
* @param element must not be {@literal null}.
|
|
||||||
* @param builder must not be {@literal null}.
|
|
||||||
* @param attrName must not be {@literal null} or empty.
|
|
||||||
*/
|
|
||||||
static void setPropertyValue(Element element, BeanDefinitionBuilder builder, String attrName) {
|
|
||||||
String attr = element.getAttribute(attrName);
|
|
||||||
if (StringUtils.hasText(attr)) {
|
|
||||||
builder.addPropertyValue(attrName, attr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 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.config;
|
||||||
|
|
||||||
|
import java.beans.PropertyEditorSupport;
|
||||||
|
|
||||||
|
import com.mongodb.ReadPreference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a {@link String} to a {@link ReadPreference}.
|
||||||
|
*
|
||||||
|
* @author Christoph Strobl
|
||||||
|
* @since 1.7
|
||||||
|
*/
|
||||||
|
public class ReadPreferencePropertyEditor extends PropertyEditorSupport {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.beans.PropertyEditorSupport#setAsText(java.lang.String)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setAsText(String readPreferenceString) throws IllegalArgumentException {
|
||||||
|
|
||||||
|
if (readPreferenceString == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReadPreference preference = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
preference = ReadPreference.valueOf(readPreferenceString);
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
// ignore this one and try to map it differently
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preference != null) {
|
||||||
|
setValue(preference);
|
||||||
|
} else if ("PRIMARY".equalsIgnoreCase(readPreferenceString)) {
|
||||||
|
setValue(ReadPreference.primary());
|
||||||
|
} else if ("PRIMARY_PREFERRED".equalsIgnoreCase(readPreferenceString)) {
|
||||||
|
setValue(ReadPreference.primaryPreferred());
|
||||||
|
} else if ("SECONDARY".equalsIgnoreCase(readPreferenceString)) {
|
||||||
|
setValue(ReadPreference.secondary());
|
||||||
|
} else if ("SECONDARY_PREFERRED".equalsIgnoreCase(readPreferenceString)) {
|
||||||
|
setValue(ReadPreference.secondaryPreferred());
|
||||||
|
} else if ("NEAREST".equalsIgnoreCase(readPreferenceString)) {
|
||||||
|
setValue(ReadPreference.nearest());
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException(String.format("Cannot find matching ReadPreference for %s",
|
||||||
|
readPreferenceString));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
/*
|
||||||
|
* 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.config;
|
||||||
|
|
||||||
|
import java.beans.PropertyEditorSupport;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import com.mongodb.ServerAddress;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a {@link String} to a {@link ServerAddress} array. The format is host1:port1,host2:port2,host3:port3.
|
||||||
|
*
|
||||||
|
* @author Mark Pollack
|
||||||
|
* @author Oliver Gierke
|
||||||
|
* @author Thomas Darimont
|
||||||
|
*/
|
||||||
|
public class ServerAddressPropertyEditor extends PropertyEditorSupport {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A port is a number without a leading 0 at the end of the address that is proceeded by just a single :.
|
||||||
|
*/
|
||||||
|
private static final String HOST_PORT_SPLIT_PATTERN = "(?<!:):(?=[123456789]\\d*$)";
|
||||||
|
private static final String COULD_NOT_PARSE_ADDRESS_MESSAGE = "Could not parse address {} '{}'. Check your replica set configuration!";
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(ServerAddressPropertyEditor.class);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.beans.PropertyEditorSupport#setAsText(java.lang.String)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setAsText(String replicaSetString) {
|
||||||
|
|
||||||
|
if (!StringUtils.hasText(replicaSetString)) {
|
||||||
|
setValue(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] replicaSetStringArray = StringUtils.commaDelimitedListToStringArray(replicaSetString);
|
||||||
|
Set<ServerAddress> serverAddresses = new HashSet<ServerAddress>(replicaSetStringArray.length);
|
||||||
|
|
||||||
|
for (String element : replicaSetStringArray) {
|
||||||
|
|
||||||
|
ServerAddress address = parseServerAddress(element);
|
||||||
|
|
||||||
|
if (address != null) {
|
||||||
|
serverAddresses.add(address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serverAddresses.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Could not resolve at least one server of the replica set configuration! Validate your config!");
|
||||||
|
}
|
||||||
|
|
||||||
|
setValue(serverAddresses.toArray(new ServerAddress[serverAddresses.size()]));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the given source into a {@link ServerAddress}.
|
||||||
|
*
|
||||||
|
* @param source
|
||||||
|
* @return the
|
||||||
|
*/
|
||||||
|
private ServerAddress parseServerAddress(String source) {
|
||||||
|
|
||||||
|
if (!StringUtils.hasText(source)) {
|
||||||
|
LOG.warn(COULD_NOT_PARSE_ADDRESS_MESSAGE, "source", source);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] hostAndPort = extractHostAddressAndPort(source.trim());
|
||||||
|
|
||||||
|
if (hostAndPort.length > 2) {
|
||||||
|
LOG.warn(COULD_NOT_PARSE_ADDRESS_MESSAGE, "source", source);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
InetAddress hostAddress = InetAddress.getByName(hostAndPort[0]);
|
||||||
|
Integer port = hostAndPort.length == 1 ? null : Integer.parseInt(hostAndPort[1]);
|
||||||
|
|
||||||
|
return port == null ? new ServerAddress(hostAddress) : new ServerAddress(hostAddress, port);
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
LOG.warn(COULD_NOT_PARSE_ADDRESS_MESSAGE, "host", hostAndPort[0]);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
LOG.warn(COULD_NOT_PARSE_ADDRESS_MESSAGE, "port", hostAndPort[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract the host and port from the given {@link String}.
|
||||||
|
*
|
||||||
|
* @param addressAndPortSource must not be {@literal null}.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String[] extractHostAddressAndPort(String addressAndPortSource) {
|
||||||
|
|
||||||
|
Assert.notNull(addressAndPortSource, "Address and port source must not be null!");
|
||||||
|
|
||||||
|
String[] hostAndPort = addressAndPortSource.split(HOST_PORT_SPLIT_PATTERN);
|
||||||
|
String hostAddress = hostAndPort[0];
|
||||||
|
|
||||||
|
if (isHostAddressInIPv6BracketNotation(hostAddress)) {
|
||||||
|
hostAndPort[0] = hostAddress.substring(1, hostAddress.length() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hostAndPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isHostAddressInIPv6BracketNotation(String hostAddress) {
|
||||||
|
return hostAddress.startsWith("[") && hostAddress.endsWith("]");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,196 +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.mongodb.config;
|
|
||||||
|
|
||||||
import org.springframework.data.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 CREATE_QUERY_INDEXES = "create-query-indexes";
|
|
||||||
private static final String DEFAULT_MONGO_TEMPLATE_REF = "mongoTemplate";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.mongodb.core.core.MongoTemplate} to be referenced.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public String getMongoTemplateRef() {
|
|
||||||
|
|
||||||
String templateRef = getSource().getAttribute(MONGO_TEMPLATE_REF);
|
|
||||||
return StringUtils.hasText(templateRef) ? templateRef : DEFAULT_MONGO_TEMPLATE_REF;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether to create indexes for query methods.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public boolean getCreateQueryIndexes() {
|
|
||||||
|
|
||||||
String createQueryIndexes = getSource().getAttribute(CREATE_QUERY_INDEXES);
|
|
||||||
return StringUtils.hasText(createQueryIndexes) ? Boolean.parseBoolean(createQueryIndexes) : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (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.RepositoryConfig#getNamedQueriesLocation()
|
|
||||||
*/
|
|
||||||
public String getNamedQueriesLocation() {
|
|
||||||
return "classpath*:META-INF/mongo-named-queries.properties";
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (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();
|
|
||||||
|
|
||||||
boolean getCreateQueryIndexes();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.mongodb.repository.config.
|
|
||||||
* SimpleMongoRepositoryConfiguration
|
|
||||||
* .MongoRepositoryConfiguration#getMongoTemplateRef()
|
|
||||||
*/
|
|
||||||
public String getMongoTemplateRef() {
|
|
||||||
|
|
||||||
return getAttribute(MONGO_TEMPLATE_REF);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.springframework.data.mongodb.config.SimpleMongoRepositoryConfiguration.MongoRepositoryConfiguration#getCreateQueryIndexes()
|
|
||||||
*/
|
|
||||||
public boolean getCreateQueryIndexes() {
|
|
||||||
|
|
||||||
String attribute = getAttribute(CREATE_QUERY_INDEXES);
|
|
||||||
return attribute == null ? false : Boolean.parseBoolean(attribute);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.mongodb.repository.config.
|
|
||||||
* SimpleMongoRepositoryConfiguration
|
|
||||||
* .MongoRepositoryConfiguration#getMongoTemplateRef()
|
|
||||||
*/
|
|
||||||
public String getMongoTemplateRef() {
|
|
||||||
|
|
||||||
return getParent().getMongoTemplateRef();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.springframework.data.mongodb.config.SimpleMongoRepositoryConfiguration.MongoRepositoryConfiguration#getCreateQueryIndexes()
|
|
||||||
*/
|
|
||||||
public boolean getCreateQueryIndexes() {
|
|
||||||
return getParent().getCreateQueryIndexes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user