Compare commits
656 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
c2d7f3ebc6 | ||
|
8f1ff56d34 | ||
|
11ae0ea7d3 | ||
|
afa78857f9 | ||
|
ae2423b2e9 | ||
|
01d3e746d8 | ||
|
13cd03a762 | ||
|
ac7b3c4eb9 | ||
|
7effbc8de0 | ||
|
8c5f0c78e7 | ||
|
45e00ac93d | ||
|
80454afc0d | ||
|
428e898a7a | ||
|
13762eb67f | ||
|
04c43ebf7b | ||
|
f9b5a5212d | ||
|
0351f94761 | ||
|
a89543b555 | ||
|
ce30b1a6ff | ||
|
1b382004cb | ||
|
ab7ff25929 | ||
|
eedf19ad9d | ||
|
941ace99c6 | ||
|
95e0b870f6 | ||
|
2bdb2dc34f | ||
|
22a44d0c8d | ||
|
a9cdbdc03e | ||
|
3fd5470eae | ||
39f96cbd28 | |||
4501f10429 | |||
bd0cde7e87 | |||
|
dd36e08d7d | ||
|
4634def93e | ||
|
1974a8bb8d | ||
|
e9a6609593 | ||
|
b20577026e | ||
|
dae9e137f7 | ||
|
1509d0c5bb | ||
430ebbd1c5 | |||
|
b561eaee6d | ||
|
1aa21c3762 | ||
|
c8a67177d8 | ||
|
59597e962d | ||
|
c85a951a9e | ||
|
7f47a17633 | ||
|
690c961a55 | ||
|
21efd1e4a7 | ||
|
ad27228429 | ||
|
dd4a1667ca | ||
|
399d2b7951 | ||
|
d51dfd6636 | ||
|
ca85c1fa9f | ||
|
5e7f06070e | ||
|
dc0c20cd0c | ||
|
98aa33341a | ||
|
1f7c0afc1e | ||
|
1ccce3f942 | ||
|
90d5bc8de7 | ||
|
c6a685d7c0 | ||
|
e6cfd899e5 | ||
|
bd23f14792 | ||
|
46f6b9e537 | ||
|
d5832c48e1 | ||
|
64ec0f63ca | ||
|
0b7c42e814 | ||
|
d8dc63fc98 | ||
|
81a7f154c2 | ||
|
af3263d471 | ||
|
bbe5f19997 | ||
|
f33650c099 | ||
|
58f81ec851 | ||
|
c9262eb204 | ||
|
3637b832e5 | ||
|
ee56cfe2b4 | ||
|
721410c7d0 | ||
|
f0310e3933 | ||
|
302d7cccc4 | ||
|
f9977d5ce6 | ||
|
0a927fd320 | ||
|
523501a592 | ||
|
ff8155be6a | ||
|
6c5d697051 | ||
|
b19145160e | ||
|
c7ada71ef5 | ||
|
4951229576 | ||
|
d98c1bddec | ||
|
b0d0e93364 | ||
|
f20a562439 | ||
|
4ae8475f5e | ||
|
fd4c627c61 | ||
|
a867d48232 | ||
|
f6bf61fce9 | ||
|
c60c9a8f74 | ||
|
dc021ab71e | ||
|
18b5551f6c | ||
|
6fcd8771a5 | ||
|
1fef4c3d2e | ||
|
ee6ed2bf0b | ||
|
57b67fee09 | ||
|
a6cbacae72 | ||
|
1e0f8e2484 | ||
|
bcb4c6d7b0 | ||
|
ea1d5907c1 | ||
|
05bac38fc3 | ||
|
69746cd369 | ||
|
ff3db531e5 | ||
|
558de7ba3f | ||
|
af15116bf9 | ||
|
36e5a9747b | ||
|
1d66b47f5f | ||
|
1346dd3616 | ||
|
b6ec5e108b | ||
|
5b2833350c | ||
|
66acb380ab | ||
|
00c62f2ad4 | ||
|
7205863d95 | ||
|
2a4274d583 | ||
|
087184b598 | ||
|
e5600e0be7 | ||
|
964f3128d2 | ||
|
69905cdc55 | ||
|
bf4e277db7 | ||
|
eaa7cca278 | ||
|
0e115bb808 | ||
|
1897f5567b | ||
|
d647528b3c | ||
|
07d42cdb9c | ||
|
dabb960c94 | ||
|
c71e794051 | ||
|
1584c0cbb2 | ||
|
22f0f1abf4 | ||
|
205f92d093 | ||
|
7488ac15a7 | ||
|
44f5db993a | ||
|
f76eae23ca | ||
|
5e2a18f819 | ||
|
2f6e5d53c2 | ||
|
50e6c4d965 | ||
|
3ad0554a7d | ||
|
113ec78c67 | ||
|
f814927eca | ||
|
a9719feeec | ||
|
6dc4f1b448 | ||
|
e1fa17691d | ||
|
42e61d6e1f | ||
|
2bf3e6bd3c | ||
|
608b2f868d | ||
|
46638bab5b | ||
|
4607362e46 | ||
|
041b2dfcc1 | ||
|
7ad0dd43e2 | ||
|
35339f7328 | ||
|
e474e7cd75 | ||
|
612fab2aef | ||
|
3f67bd471b | ||
|
cb29dcd6cc | ||
|
d428e89c30 | ||
|
9b2aeb7480 | ||
|
d9ad69c7ff | ||
|
16fc058264 | ||
|
520b143165 | ||
|
95c37a03f8 | ||
|
0d058b9c9c | ||
|
7c72b5e69b | ||
|
3ec254e908 | ||
|
fda13c004e | ||
|
3af85eeea6 | ||
|
c08616e6df | ||
|
7faa0f8a54 | ||
|
26c5fe2e69 | ||
|
6bdaa8352b | ||
|
6367a1fd15 | ||
|
2c5ff64d42 | ||
|
e614cb41d8 | ||
|
82737e2280 | ||
|
3b5c27096b | ||
|
8a85830bd3 | ||
|
19ac90688e | ||
|
5f4a6bc462 | ||
|
4c7f3166d4 | ||
|
4233f4dd88 | ||
|
bd09312418 | ||
|
11ab07b238 | ||
|
d2e2f089fb | ||
|
d619f98de7 | ||
|
89228a52dc | ||
|
90a49efa4a | ||
|
a7423caeb1 | ||
|
6f31a2c228 | ||
|
fc98b0882f | ||
|
dff05967ea | ||
|
ec836a2f9d | ||
|
737c85cf00 | ||
|
ff7b07f464 | ||
|
19422b5afa | ||
|
6b93e413b6 | ||
|
ab72736bcc | ||
|
38939e5d05 | ||
|
1a90a0e0ad | ||
|
7aa9fa4646 | ||
|
82d788c8d3 | ||
|
ab8176efcb | ||
|
b4c3e7a928 | ||
|
2db263fb68 | ||
|
5fd4d37972 | ||
|
9b1dbf351a | ||
|
4c7c058e0d | ||
|
f8dc08b02b | ||
|
0e6bc3ce54 | ||
|
fcb018406d | ||
|
40756a5e4b | ||
|
61b12bdebd | ||
|
8b1c41ae1e | ||
|
d654564f6b | ||
|
8bd22ebafa | ||
|
647e66d57b | ||
|
67c8ac1aa3 | ||
|
f336c7ae53 | ||
|
9ea1dad62d | ||
|
58bc374e64 | ||
|
cea0d4887d | ||
|
d5e73ecd8b | ||
|
2235a0498b | ||
|
3f9b92831c | ||
|
5680750c82 | ||
|
298e3efe49 | ||
|
7b2bd6f9eb | ||
|
d935e07990 | ||
|
868a74c184 | ||
|
a86af9736b | ||
|
8bd4d27d2f | ||
|
94951c59f3 | ||
|
e39c83a5a6 | ||
|
516a5f03e3 | ||
|
992150804a | ||
|
e905aa76a0 | ||
|
940b365447 | ||
|
d4d1c35264 | ||
|
5b818c8258 | ||
|
dedfae7b33 | ||
|
aa91a7fe24 | ||
|
822a4ae776 | ||
|
c6eb1c813c | ||
|
0d50676586 | ||
|
a2a3297986 | ||
|
8bdab73ae9 | ||
|
4469bb7bee | ||
|
b2dc460b4b | ||
|
3b281a8c3f | ||
|
fe40a0a677 | ||
|
b8c2bd3564 | ||
|
be236313e9 | ||
|
7a285d11a5 | ||
|
6e56a0f568 | ||
|
10d5c4334b | ||
|
8a5e90e562 | ||
|
c7c7badaf0 | ||
|
183e86aad6 | ||
|
5fbbcfc888 | ||
|
5169deb005 | ||
|
98fa89bd80 | ||
|
db4f5f9011 | ||
|
33aaf8afd2 | ||
|
3902d6361e | ||
|
d8d5249a23 | ||
|
42828efa19 | ||
|
a75b40bbfb | ||
|
4ebf621e11 | ||
|
cee82f39c2 | ||
|
eb9e0e0543 | ||
|
35c3ee023b | ||
|
2134f116da | ||
|
feb3d15968 | ||
|
4910dfd527 | ||
|
94252de73f | ||
|
dc5a157dad | ||
|
bf8411cc24 | ||
|
a9648f803c | ||
|
b2b4eed4fa | ||
|
7665eb6bf2 | ||
|
40c1ff0e1a | ||
|
6ceb1f6c02 | ||
|
8c37af6207 | ||
|
7baf5e44fd | ||
|
8fff672d2f | ||
|
d4fe719a2c | ||
|
108d5ae830 | ||
|
867c3207c5 | ||
|
0c257b763d | ||
|
58af2b00cb | ||
|
1d78ce4b72 | ||
|
26d9d826a3 | ||
|
bb9957be24 | ||
|
0dce279fd0 | ||
|
884239bc26 | ||
|
dfdd5f8d20 | ||
|
b5f0612e78 | ||
|
dc044e684d | ||
|
8f1dddb8a3 | ||
|
763f91fd4c | ||
|
dd1c06013b | ||
|
748659e78e | ||
|
b265b8b1e0 | ||
|
7b3c0915d8 | ||
|
d0335b6b16 | ||
|
6d35020840 | ||
|
cedd4b47b3 | ||
|
45a672ab0d | ||
|
6798e01f49 | ||
|
c0678e9a90 | ||
|
156e67bc52 | ||
|
9b1456e1a7 | ||
|
f9b61546ab | ||
|
1b3a33104a | ||
|
d819c05669 | ||
|
68729e3b54 | ||
|
90a3d7aa68 | ||
|
b3349176d9 | ||
|
e72dab2a6e | ||
|
b54debe2e5 | ||
|
95ce4f0dc0 | ||
|
c9ba182a2e | ||
|
716954aa9a | ||
|
5c5a3f614f | ||
|
229d845a42 | ||
|
d1a8fa38b0 | ||
|
899f13cb35 | ||
|
0409c2ef79 | ||
|
83b065180f | ||
|
34a003d0e5 | ||
|
7b89bb449d | ||
|
4aca4ad495 | ||
|
99d44f2a92 | ||
|
c9606f98d3 | ||
|
af217b4831 | ||
|
f45f2d5df9 | ||
|
c8c4208bb4 | ||
|
dc8b8ae6c4 | ||
|
7aa4a1bf82 | ||
|
e2548ef6b1 | ||
|
abde9b7897 | ||
|
be1c2a7b90 | ||
|
55a4bb7621 | ||
|
37ca5ff84e | ||
|
d2256eabfa | ||
|
cbb8d4e1b6 | ||
|
785ad7f3a1 | ||
|
5d9b87dace | ||
|
feb5484cf6 | ||
|
3821a15f9d | ||
|
e5f85c931c | ||
|
6c99de1e89 | ||
|
3613f6f8de | ||
|
945e619d55 | ||
|
5220b13e7d | ||
|
7ea8d0c0f7 | ||
|
996585d7ac | ||
|
ce115eadbb | ||
|
aebdc9e208 | ||
|
b0bceefc0e | ||
|
bf37c5cb51 | ||
|
16215dde3b | ||
|
2ac10e8127 | ||
|
dcb924abac | ||
|
94e18146fd | ||
|
2a619849f4 | ||
|
1e57ee5fb3 | ||
|
db721a9d10 | ||
|
40951e8da0 | ||
|
f44b4bb0e0 | ||
|
b330d54ca2 | ||
|
2678ff4477 | ||
|
995e45d28f | ||
|
9ca27d7c12 | ||
|
4183dae458 | ||
|
5426be9fa0 | ||
|
9d8034e010 | ||
|
647ad841df | ||
|
a66a1e6f8e | ||
|
ebfd860458 | ||
|
740476460f | ||
|
2b6a14a348 | ||
|
77311f42cd | ||
|
a0e89103af | ||
|
5cdbe9338b | ||
|
f7b84238df | ||
|
8b039c61ed | ||
|
f227335e14 | ||
|
ce7a8590db | ||
|
d497fa8ed7 | ||
|
6b940c4366 | ||
|
f167e8ea0a | ||
|
de703531f6 | ||
|
c72f9fbdb1 | ||
|
09eaf18632 | ||
|
5cee20163d | ||
|
63c7e9710b | ||
|
6f27b9c13f | ||
|
76e68c09d8 | ||
|
aea389cd3d | ||
|
9ce18b128e | ||
|
a7c954c6bc | ||
|
a0880c4a16 | ||
|
2c90df2c2d | ||
|
71f15e1736 | ||
|
0b14ab5032 | ||
|
2771e56357 | ||
|
1479b818ea | ||
|
4f6de892b5 | ||
|
e540260377 | ||
|
f3f21bbf73 | ||
|
44a1389dd7 | ||
|
1b05261a97 | ||
|
d55334739c | ||
|
c511ed380e | ||
|
b59ecf0370 | ||
|
65b038afcd | ||
|
5fbde0dca0 | ||
|
ab69e502da | ||
|
52065dda6b | ||
|
7cd8e48145 | ||
|
2a7f143bbf | ||
|
4a676b01e1 | ||
|
18c9833104 | ||
|
7e2787704b | ||
|
b13c2ccd32 | ||
|
4795d8f48c | ||
|
808a06b0af | ||
|
70a42afab8 | ||
|
ea210d6aac | ||
|
f70cded634 | ||
|
cc6e1b4052 | ||
|
1ce5ba4f06 | ||
|
2b23a1d048 | ||
|
37f262177d | ||
|
7ded510625 | ||
|
797a987e2b | ||
|
062dee987f | ||
|
1054931e63 | ||
|
3720a881a4 | ||
|
f379b4e5ab | ||
|
9a9e86829e | ||
|
66cd4abd8b | ||
|
ba4470f155 | ||
|
b95ec019de | ||
|
d3a40ebca8 | ||
|
5d335049a2 | ||
|
bd51e2ab55 | ||
|
f8278bd44e | ||
|
4797cd1eca | ||
|
706d244ff8 | ||
|
5b8cd18128 | ||
|
8a854bb37d | ||
|
6e6f892cb0 | ||
|
2b4ddfa072 | ||
|
c9adff5a25 | ||
|
503cfff82e | ||
|
5e713f0c2a | ||
|
e035007070 | ||
|
17a94395f3 | ||
|
0ab6c8e4b0 | ||
|
8284169923 | ||
|
5f9094c540 | ||
|
332ac9c109 | ||
|
9ba49f35ff | ||
|
d0646f12e6 | ||
|
a8817c75b0 | ||
|
7fc50f2629 | ||
|
b2d9684738 | ||
|
8ab284ff98 | ||
|
a099d29524 | ||
|
cf44af0065 | ||
|
b5bf8b6545 | ||
|
4cc3fa4d89 | ||
|
ed50e202d7 | ||
|
6d865af15a | ||
|
66d331ddb8 | ||
|
0903c03a29 | ||
|
5f546b6c6d | ||
|
9bb73bb35b | ||
|
2ca5b04de2 | ||
|
e883c1e678 | ||
|
4fc434a222 | ||
|
ecfa747a2c | ||
|
dc28ebfa50 | ||
|
6596eba6ca | ||
|
7194f9aac0 | ||
|
e4fe1cfa90 | ||
|
5bc73548b3 | ||
|
2156848e4a | ||
|
3f807b3e51 | ||
|
d786862a60 | ||
|
fb75bafe96 | ||
|
66f781b716 | ||
|
b3dc409926 | ||
|
287ed06b6a | ||
|
df1d013b1c | ||
|
fdb95484c1 | ||
|
4cf1f29e0a | ||
|
332fd9d1f6 | ||
|
039d881a07 | ||
|
b8176a9fe9 | ||
|
65937d6f4c | ||
|
590bf74e98 | ||
|
642a3e10ce | ||
|
52a8cf92c8 | ||
|
fc68ee56d5 | ||
|
644f4803df | ||
|
eda6106de8 | ||
|
3a1691066e | ||
|
b02039bad4 | ||
|
6527a9e9bb | ||
|
c59ad4d446 | ||
|
f475cbc5d8 | ||
|
00452cc505 | ||
|
23660961bd | ||
|
742ff183bf | ||
|
dca8c28b84 | ||
|
46079393d5 | ||
|
517e4a4507 | ||
|
6f3ae6da9d | ||
|
273136ab23 | ||
|
e74f86e118 | ||
|
84d4d3b165 | ||
|
c355cb8bd5 | ||
|
2957034286 | ||
|
36b4fbd303 | ||
|
f57cf46313 | ||
|
244ddc7ce2 | ||
|
4d161aea07 | ||
|
cf9101d157 | ||
|
614c8a1d13 | ||
|
879ab7951d | ||
|
311b42ad25 | ||
|
0ebbbac9a6 | ||
|
d2f9fcdda0 | ||
|
cfe5690a73 | ||
|
a055b3ff5c | ||
|
18f37ec2a8 | ||
|
14b4e5aeec | ||
|
a980930e69 | ||
|
1b4eb70d8d | ||
|
1856ccc3aa | ||
|
3217c67ff6 | ||
|
54d5f1cb1b | ||
|
e49d002941 | ||
|
4822b8bf23 | ||
|
198a6d5665 | ||
|
c7b9ec3a4c | ||
|
f46e10e11c | ||
|
b9acc4ecf8 | ||
|
403d094a3d | ||
|
3b1f11e5a8 | ||
|
ddba06cca3 | ||
|
bf89af0da9 | ||
|
5a30164848 | ||
|
0c4e200900 | ||
|
fe8e8f041c | ||
|
43084d9d86 | ||
|
e1e1b4e278 | ||
|
14f8239ba3 | ||
|
e660a70d00 | ||
|
119d30bb16 | ||
|
5686de56e2 | ||
|
e0214a6a9f | ||
|
330de495db | ||
|
dcc7fe55f4 | ||
|
3274b4c79a | ||
|
cbfa4b1c41 | ||
|
5f7d2f2a68 | ||
|
e38bdbe508 | ||
|
c352b94b38 | ||
|
6b0106e385 | ||
|
60021e5123 | ||
|
76d3157247 | ||
|
7c24778460 | ||
|
d43072663e | ||
|
8231db4a5a | ||
|
eb3562567d | ||
|
fe5dd5e8dc | ||
|
5872928812 | ||
|
8a8f4bb388 | ||
|
0e8d5fd5ec | ||
|
b9344149b0 | ||
|
5053a6852f | ||
|
bb3faca533 | ||
|
4f7fcbfdf0 | ||
|
87c1cc88be | ||
|
1d78551f4c | ||
|
b36d08db8e | ||
|
c99b1a1867 | ||
|
fc4380e5cc | ||
|
850ed7f76b | ||
|
0f6aa3befb | ||
|
ddd976162c | ||
|
cdd19e182b | ||
|
afc22a547e | ||
|
79ca54c5af | ||
|
0aacf20c16 | ||
|
cdfb43dbd8 | ||
|
35ec8b951c | ||
|
05bfaa0035 | ||
|
f5705b1153 | ||
|
ed1353a4eb | ||
|
a79922d7c9 | ||
|
7a7cbd570c | ||
|
d7865cfaf0 | ||
|
ead01ce1d0 | ||
|
8aca012c99 | ||
|
67a4dc63ca | ||
|
ce0678784b | ||
|
cbc4bbb818 | ||
|
1c558a884d | ||
|
d84d1428b2 | ||
|
b870ee8d62 | ||
|
ef18581e71 | ||
|
177bbceaf4 | ||
|
a13174ac4d | ||
|
e181b7d24b | ||
|
e631aa0e8a | ||
|
575ad75a0a | ||
|
394f667ab0 | ||
|
f80cf43ae8 | ||
|
6b57d29f51 | ||
|
f2c4dde56e | ||
|
3a22132363 | ||
|
767099b7ea | ||
|
6aef7246a0 | ||
|
1f6d9f0211 | ||
|
3248637e8c | ||
|
bf8e0827e2 | ||
|
ad1e57316f | ||
|
737b3299ff | ||
|
1934bb71f0 | ||
|
b3ef9b0476 | ||
|
8477920475 | ||
|
f98a12b96f | ||
|
bee8a4fcdc | ||
|
f984595b97 | ||
|
f01d78a9ea | ||
|
97f25de0dc | ||
|
3d1b5a7394 | ||
|
df1eaf54c8 | ||
|
3851408100 | ||
|
794c5012ad | ||
|
1ba9f7d7d9 | ||
|
9b4330d618 | ||
|
3a32b742e8 | ||
|
87b3d25c0f | ||
|
9f28649a3a | ||
|
8f9df8961b | ||
|
9e9217bfcb | ||
|
ffdd5a3631 | ||
|
db4bf8d35a | ||
|
7b2859f96e | ||
|
03c5c33ea7 |
3
.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: [jendib]
|
84
.github/workflows/build-deploy.yml
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
name: Maven CI/CD
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
tags: [v*]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build_and_publish:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: "11"
|
||||
distribution: "temurin"
|
||||
cache: maven
|
||||
- name: Install test dependencies
|
||||
run: sudo apt-get update && sudo apt-get -y -q --no-install-recommends install ffmpeg mediainfo tesseract-ocr tesseract-ocr-deu
|
||||
- name: Build with Maven
|
||||
run: mvn --batch-mode -Pprod clean install
|
||||
- name: Upload war artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: docs-web-ci.war
|
||||
path: docs-web/target/docs*.war
|
||||
|
||||
build_docker_image:
|
||||
name: Publish to Docker Hub
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build_and_publish]
|
||||
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Download war artifact
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: docs-web-ci.war
|
||||
path: docs-web/target
|
||||
-
|
||||
name: Setup up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
-
|
||||
name: Login to DockerHub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
-
|
||||
name: Populate Docker metadata
|
||||
id: metadata
|
||||
uses: docker/metadata-action@v3
|
||||
with:
|
||||
images: sismics/docs
|
||||
flavor: |
|
||||
latest=false
|
||||
tags: |
|
||||
type=ref,event=tag
|
||||
type=raw,value=latest,enable=${{ github.ref_type != 'tag' }}
|
||||
labels: |
|
||||
org.opencontainers.image.title = Teedy
|
||||
org.opencontainers.image.description = Teedy is an open source, lightweight document management system for individuals and businesses.
|
||||
org.opencontainers.image.created = ${{ github.event_created_at }}
|
||||
org.opencontainers.image.author = Sismics
|
||||
org.opencontainers.image.url = https://teedy.io/
|
||||
org.opencontainers.image.vendor = Sismics
|
||||
org.opencontainers.image.license = GPLv2
|
||||
org.opencontainers.image.version = ${{ github.event_head_commit.id }}
|
||||
-
|
||||
name: Build and push
|
||||
id: docker_build
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.metadata.outputs.tags }}
|
||||
labels: ${{ steps.metadata.outputs.labels }}
|
10
.gitignore
vendored
@ -9,3 +9,13 @@
|
||||
/.idea
|
||||
/.project
|
||||
*.iml
|
||||
node_modules
|
||||
import_test
|
||||
teedy-importer-linux
|
||||
teedy-importer-macos
|
||||
teedy-importer-win.exe
|
||||
docs/*
|
||||
!docs/.gitkeep
|
||||
|
||||
#macos
|
||||
.DS_Store
|
||||
|
11
.travis.yml
@ -1,11 +0,0 @@
|
||||
sudo: required
|
||||
dist: trusty
|
||||
language: java
|
||||
before_install:
|
||||
- sudo apt-get -qq update
|
||||
- sudo apt-get -y -q install tesseract-ocr tesseract-ocr-fra tesseract-ocr-jpn
|
||||
- sudo apt-get -y -q install haveged && sudo service haveged start
|
||||
env:
|
||||
global:
|
||||
- TESSDATA_PREFIX=/usr/share/tesseract-ocr
|
||||
- LC_NUMERIC=C
|
46
CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,46 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
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.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at contact@sismicsdocs.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
79
Dockerfile
@ -1,10 +1,75 @@
|
||||
FROM sismics/debian-java7-jetty9
|
||||
MAINTAINER benjamin.gam@gmail.com
|
||||
FROM ubuntu:22.04
|
||||
LABEL maintainer="b.gamard@sismics.com"
|
||||
|
||||
RUN apt-get -y -q install tesseract-ocr tesseract-ocr-fra tesseract-ocr-jpn
|
||||
# Run Debian in non interactive mode
|
||||
ENV DEBIAN_FRONTEND noninteractive
|
||||
|
||||
ENV TESSDATA_PREFIX /usr/share/tesseract-ocr
|
||||
ENV LC_NUMERIC C
|
||||
# Configure env
|
||||
ENV LANG C.UTF-8
|
||||
ENV LC_ALL C.UTF-8
|
||||
ENV JAVA_HOME /usr/lib/jvm/java-11-openjdk-amd64/
|
||||
ENV JAVA_OPTIONS -Dfile.encoding=UTF-8 -Xmx1g
|
||||
ENV JETTY_VERSION 11.0.20
|
||||
ENV JETTY_HOME /opt/jetty
|
||||
|
||||
ADD docs-web/target/docs-web-*.war /opt/jetty/webapps/docs.war
|
||||
ADD docs.xml /opt/jetty/webapps/docs.xml
|
||||
# Install packages
|
||||
RUN apt-get update && \
|
||||
apt-get -y -q --no-install-recommends install \
|
||||
vim less procps unzip wget tzdata openjdk-11-jdk \
|
||||
ffmpeg \
|
||||
mediainfo \
|
||||
tesseract-ocr \
|
||||
tesseract-ocr-ara \
|
||||
tesseract-ocr-ces \
|
||||
tesseract-ocr-chi-sim \
|
||||
tesseract-ocr-chi-tra \
|
||||
tesseract-ocr-dan \
|
||||
tesseract-ocr-deu \
|
||||
tesseract-ocr-fin \
|
||||
tesseract-ocr-fra \
|
||||
tesseract-ocr-heb \
|
||||
tesseract-ocr-hin \
|
||||
tesseract-ocr-hun \
|
||||
tesseract-ocr-ita \
|
||||
tesseract-ocr-jpn \
|
||||
tesseract-ocr-kor \
|
||||
tesseract-ocr-lav \
|
||||
tesseract-ocr-nld \
|
||||
tesseract-ocr-nor \
|
||||
tesseract-ocr-pol \
|
||||
tesseract-ocr-por \
|
||||
tesseract-ocr-rus \
|
||||
tesseract-ocr-spa \
|
||||
tesseract-ocr-swe \
|
||||
tesseract-ocr-tha \
|
||||
tesseract-ocr-tur \
|
||||
tesseract-ocr-ukr \
|
||||
tesseract-ocr-vie \
|
||||
tesseract-ocr-sqi \
|
||||
&& apt-get clean && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
RUN dpkg-reconfigure -f noninteractive tzdata
|
||||
|
||||
# Install Jetty
|
||||
RUN wget -nv -O /tmp/jetty.tar.gz \
|
||||
"https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-home/${JETTY_VERSION}/jetty-home-${JETTY_VERSION}.tar.gz" \
|
||||
&& tar xzf /tmp/jetty.tar.gz -C /opt \
|
||||
&& mv /opt/jetty* /opt/jetty \
|
||||
&& useradd jetty -U -s /bin/false \
|
||||
&& chown -R jetty:jetty /opt/jetty \
|
||||
&& mkdir /opt/jetty/webapps \
|
||||
&& chmod +x /opt/jetty/bin/jetty.sh
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
# Install app
|
||||
RUN mkdir /app && \
|
||||
cd /app && \
|
||||
java -jar /opt/jetty/start.jar --add-modules=server,http,webapp,deploy
|
||||
|
||||
ADD docs.xml /app/webapps/docs.xml
|
||||
ADD docs-web/target/docs-web-*.war /app/webapps/docs.war
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
CMD ["java", "-jar", "/opt/jetty/start.jar"]
|
||||
|
230
README.md
@ -1,84 +1,246 @@
|
||||
Sismics Docs [](http://travis-ci.org/sismics/docs)
|
||||
============
|
||||
<h3 align="center">
|
||||
<img src="https://teedy.io/img/github-title.png" alt="Teedy" width=500 />
|
||||
</h3>
|
||||
|
||||
_Web interface_
|
||||
[](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
|
||||
[](https://github.com/sismics/docs/actions/workflows/build-deploy.yml)
|
||||
|
||||

|
||||
Teedy is an open source, lightweight document management system for individuals and businesses.
|
||||
|
||||
_Android application_
|
||||
<hr />
|
||||
<h2 align="center">
|
||||
✨ <a href="https://github.com/users/jendib/sponsorship">Sponsor this project if you use and appreciate it!</a> ✨
|
||||
</h2>
|
||||
<hr />
|
||||
|
||||
   
|
||||

|
||||
|
||||
What is Docs?
|
||||
---------------
|
||||
# Demo
|
||||
|
||||
Docs is an open source, lightweight document management system.
|
||||
A demo is available at [demo.teedy.io](https://demo.teedy.io)
|
||||
|
||||
Docs is written in Java, and may be run on any operating system with Java support.
|
||||
- Guest login is enabled with read access on all documents
|
||||
- "admin" login with "admin" password
|
||||
- "demo" login with "password" password
|
||||
|
||||
Features
|
||||
--------
|
||||
# Features
|
||||
|
||||
- Responsive user interface
|
||||
- Optical character recognition
|
||||
- Support image, PDF, ODT and DOCX files
|
||||
- Flexible search engine
|
||||
- LDAP authentication 
|
||||
- Support image, PDF, ODT, DOCX, PPTX files
|
||||
- Video file support
|
||||
- Flexible search engine with suggestions and highlighting
|
||||
- Full text search in all supported files
|
||||
- All [Dublin Core](http://dublincore.org/) metadata
|
||||
- Custom user-defined metadata 
|
||||
- Workflow system 
|
||||
- 256-bit AES encryption of stored files
|
||||
- File versioning 
|
||||
- Tag system with nesting
|
||||
- Import document from email (EML format)
|
||||
- Automatic inbox scanning and importing
|
||||
- User/group permission system
|
||||
- 2-factor authentication
|
||||
- Hierarchical groups
|
||||
- Audit log
|
||||
- Comments
|
||||
- Storage quota per user
|
||||
- Document sharing by URL
|
||||
- RESTful Web API
|
||||
- Webhooks to trigger external service
|
||||
- Fully featured Android client
|
||||
- Tested to 100k documents
|
||||
- [Bulk files importer](https://github.com/sismics/docs/tree/master/docs-importer) (single or scan mode)
|
||||
- Tested to one million documents
|
||||
|
||||
Download
|
||||
--------
|
||||
# Install with Docker
|
||||
|
||||
A preconfigured Docker image is available, including OCR and media conversion tools, listening on port 8080. If no PostgreSQL config is provided, the database is an embedded H2 database. The H2 embedded database should only be used for testing. For production usage use the provided PostgreSQL configuration (check the Docker Compose example)
|
||||
|
||||
**The default admin password is "admin". Don't forget to change it before going to production.**
|
||||
|
||||
- Master branch, can be unstable. Not recommended for production use: `sismics/docs:latest`
|
||||
- Latest stable version: `sismics/docs:v1.11`
|
||||
|
||||
The data directory is `/data`. Don't forget to mount a volume on it.
|
||||
|
||||
To build external URL, the server is expecting a `DOCS_BASE_URL` environment variable (for example https://teedy.mycompany.com)
|
||||
|
||||
## Available environment variables
|
||||
|
||||
- General
|
||||
- `DOCS_BASE_URL`: The base url used by the application. Generated url's will be using this as base.
|
||||
- `DOCS_GLOBAL_QUOTA`: Defines the default quota applying to all users.
|
||||
- `DOCS_BCRYPT_WORK`: Defines the work factor which is used for password hashing. The default is `10`. This value may be `4...31` including `4` and `31`. The specified value will be used for all new users and users changing their password. Be aware that setting this factor to high can heavily impact login and user creation performance.
|
||||
|
||||
- Admin
|
||||
- `DOCS_ADMIN_EMAIL_INIT`: Defines the e-mail-address the admin user should have upon initialization.
|
||||
- `DOCS_ADMIN_PASSWORD_INIT`: Defines the password the admin user should have upon initialization. Needs to be a bcrypt hash. **Be aware that `$` within the hash have to be escaped with a second `$`.**
|
||||
|
||||
- Database
|
||||
- `DATABASE_URL`: The jdbc connection string to be used by `hibernate`.
|
||||
- `DATABASE_USER`: The user which should be used for the database connection.
|
||||
- `DATABASE_PASSWORD`: The password to be used for the database connection.
|
||||
- `DATABASE_POOL_SIZE`: The pool size to be used for the database connection.
|
||||
|
||||
- Language
|
||||
- `DOCS_DEFAULT_LANGUAGE`: The language which will be used as default. Currently supported values are:
|
||||
- `eng`, `fra`, `ita`, `deu`, `spa`, `por`, `pol`, `rus`, `ukr`, `ara`, `hin`, `chi_sim`, `chi_tra`, `jpn`, `tha`, `kor`, `nld`, `tur`, `heb`, `hun`, `fin`, `swe`, `lav`, `dan`
|
||||
|
||||
- E-Mail
|
||||
- `DOCS_SMTP_HOSTNAME`: Hostname of the SMTP-Server to be used by Teedy.
|
||||
- `DOCS_SMTP_PORT`: The port which should be used.
|
||||
- `DOCS_SMTP_USERNAME`: The username to be used.
|
||||
- `DOCS_SMTP_PASSWORD`: The password to be used.
|
||||
|
||||
## Examples
|
||||
|
||||
In the following examples some passwords are exposed in cleartext. This was done in order to keep the examples simple. We strongly encourage you to use variables with an `.env` file or other means to securely store your passwords.
|
||||
|
||||
|
||||
### Default, using PostgreSQL
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
services:
|
||||
# Teedy Application
|
||||
teedy-server:
|
||||
image: sismics/docs:v1.11
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
# Map internal port to host
|
||||
- 8080:8080
|
||||
environment:
|
||||
# Base url to be used
|
||||
DOCS_BASE_URL: "https://docs.example.com"
|
||||
# Set the admin email
|
||||
DOCS_ADMIN_EMAIL_INIT: "admin@example.com"
|
||||
# Set the admin password (in this example: "superSecure")
|
||||
DOCS_ADMIN_PASSWORD_INIT: "$$2a$$05$$PcMNUbJvsk7QHFSfEIDaIOjk1VI9/E7IPjTKx.jkjPxkx2EOKSoPS"
|
||||
# Setup the database connection. "teedy-db" is the hostname
|
||||
# and "teedy" is the name of the database the application
|
||||
# will connect to.
|
||||
DATABASE_URL: "jdbc:postgresql://teedy-db:5432/teedy"
|
||||
DATABASE_USER: "teedy_db_user"
|
||||
DATABASE_PASSWORD: "teedy_db_password"
|
||||
DATABASE_POOL_SIZE: "10"
|
||||
volumes:
|
||||
- ./docs/data:/data
|
||||
networks:
|
||||
- docker-internal
|
||||
- internet
|
||||
depends_on:
|
||||
- teedy-db
|
||||
|
||||
# DB for Teedy
|
||||
teedy-db:
|
||||
image: postgres:13.1-alpine
|
||||
restart: unless-stopped
|
||||
expose:
|
||||
- 5432
|
||||
environment:
|
||||
POSTGRES_USER: "teedy_db_user"
|
||||
POSTGRES_PASSWORD: "teedy_db_password"
|
||||
POSTGRES_DB: "teedy"
|
||||
volumes:
|
||||
- ./docs/db:/var/lib/postgresql/data
|
||||
networks:
|
||||
- docker-internal
|
||||
|
||||
networks:
|
||||
# Network without internet access. The db does not need
|
||||
# access to the host network.
|
||||
docker-internal:
|
||||
driver: bridge
|
||||
internal: true
|
||||
internet:
|
||||
driver: bridge
|
||||
```
|
||||
|
||||
### Using the internal database (only for testing)
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
services:
|
||||
# Teedy Application
|
||||
teedy-server:
|
||||
image: sismics/docs:v1.11
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
# Map internal port to host
|
||||
- 8080:8080
|
||||
environment:
|
||||
# Base url to be used
|
||||
DOCS_BASE_URL: "https://docs.example.com"
|
||||
# Set the admin email
|
||||
DOCS_ADMIN_EMAIL_INIT: "admin@example.com"
|
||||
# Set the admin password (in this example: "superSecure")
|
||||
DOCS_ADMIN_PASSWORD_INIT: "$$2a$$05$$PcMNUbJvsk7QHFSfEIDaIOjk1VI9/E7IPjTKx.jkjPxkx2EOKSoPS"
|
||||
volumes:
|
||||
- ./docs/data:/data
|
||||
```
|
||||
|
||||
# Manual installation
|
||||
|
||||
## Requirements
|
||||
|
||||
- Java 11
|
||||
- Tesseract 4 for OCR
|
||||
- ffmpeg for video thumbnails
|
||||
- mediainfo for video metadata extraction
|
||||
- A webapp server like [Jetty](http://eclipse.org/jetty/) or [Tomcat](http://tomcat.apache.org/)
|
||||
|
||||
## Download
|
||||
|
||||
The latest release is downloadable here: <https://github.com/sismics/docs/releases> in WAR format.
|
||||
You will need a Java webapp server to run it, like [Jetty](http://eclipse.org/jetty/) or [Tomcat](http://tomcat.apache.org/)
|
||||
**The default admin password is "admin". Don't forget to change it before going to production.**
|
||||
|
||||
How to build Docs from the sources
|
||||
----------------------------------
|
||||
## How to build Teedy from the sources
|
||||
|
||||
Prerequisites: JDK 7 with JCE, Maven 3, Tesseract 3.02
|
||||
Prerequisites: JDK 11, Maven 3, NPM, Grunt, Tesseract 4
|
||||
|
||||
Docs is organized in several Maven modules:
|
||||
Teedy is organized in several Maven modules:
|
||||
|
||||
- docs-core
|
||||
- docs-web
|
||||
- docs-web-common
|
||||
- docs-core
|
||||
- docs-web
|
||||
- docs-web-common
|
||||
|
||||
First off, clone the repository: `git clone git://github.com/sismics/docs.git`
|
||||
or download the sources from GitHub.
|
||||
|
||||
#### Launch the build
|
||||
### Launch the build
|
||||
|
||||
From the root directory:
|
||||
|
||||
mvn clean -DskipTests install
|
||||
```console
|
||||
mvn clean -DskipTests install
|
||||
```
|
||||
|
||||
#### Run a stand-alone version
|
||||
### Run a stand-alone version
|
||||
|
||||
From the `docs-web` directory:
|
||||
|
||||
mvn jetty:run
|
||||
```console
|
||||
mvn jetty:run
|
||||
```
|
||||
|
||||
#### Build a .war to deploy to your servlet container
|
||||
### Build a .war to deploy to your servlet container
|
||||
|
||||
From the `docs-web` directory:
|
||||
|
||||
mvn -Pprod -DskipTests clean install
|
||||
```console
|
||||
mvn -Pprod -DskipTests clean install
|
||||
```
|
||||
|
||||
You will get your deployable WAR in the `docs-web/target` directory.
|
||||
|
||||
License
|
||||
-------
|
||||
# Contributing
|
||||
|
||||
Docs is released under the terms of the GPL license. See `COPYING` for more
|
||||
All contributions are more than welcomed. Contributions may close an issue, fix a bug (reported or not reported), improve the existing code, add new feature, and so on.
|
||||
|
||||
The `master` branch is the default and base branch for the project. It is used for development and all Pull Requests should go there.
|
||||
|
||||
# License
|
||||
|
||||
Teedy is released under the terms of the GPL license. See `COPYING` for more
|
||||
information or see <http://opensource.org/licenses/GPL-2.0>.
|
||||
|
18
docker-compose.yml
Normal file
@ -0,0 +1,18 @@
|
||||
version: '3'
|
||||
services:
|
||||
# Teedy Application
|
||||
teedy-server:
|
||||
image: sismics/docs:v1.10
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
# Map internal port to host
|
||||
- 8080:8080
|
||||
environment:
|
||||
# Base url to be used
|
||||
DOCS_BASE_URL: "https://docs.example.com"
|
||||
# Set the admin email
|
||||
DOCS_ADMIN_EMAIL_INIT: "admin@example.com"
|
||||
# Set the admin password (in this example: "superSecure")
|
||||
DOCS_ADMIN_PASSWORD_INIT: "$$2a$$05$$PcMNUbJvsk7QHFSfEIDaIOjk1VI9/E7IPjTKx.jkjPxkx2EOKSoPS"
|
||||
volumes:
|
||||
- ./docs/data:/data
|
@ -1,46 +1,27 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
google()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.1.0-beta1'
|
||||
classpath 'com.android.tools.build:gradle:3.4.0'
|
||||
}
|
||||
}
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
google()
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 23
|
||||
buildToolsVersion '23.0.3'
|
||||
compileSdkVersion 28
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 23
|
||||
targetSdkVersion 28
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_7
|
||||
targetCompatibility JavaVersion.VERSION_1_7
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
release {
|
||||
storeFile file(System.getenv("TRACKINO_STORE_PATH"))
|
||||
storePassword System.getenv("TRACKINO_STORE_PASS")
|
||||
keyAlias System.getenv("TRACKINO_STORE_ALIAS")
|
||||
keyPassword System.getenv("TRACKINO_STORE_KEYPASS")
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
signingConfig signingConfigs.release
|
||||
}
|
||||
versionName '1.0'
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
@ -49,14 +30,14 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: '*.jar')
|
||||
compile 'com.android.support:appcompat-v7:23.3.0'
|
||||
compile 'com.android.support:recyclerview-v7:23.3.0'
|
||||
compile 'com.android.support:design:23.3.0'
|
||||
compile 'it.sephiroth.android.library.imagezoom:imagezoom:1.0.5'
|
||||
compile 'org.greenrobot:eventbus:3.0.0'
|
||||
compile 'com.squareup.picasso:picasso:2.5.2'
|
||||
compile 'com.squareup.okhttp3:okhttp:3.1.1'
|
||||
compile "com.squareup.okhttp3:okhttp-urlconnection:3.1.1"
|
||||
compile 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.0.2'
|
||||
implementation fileTree(dir: 'libs', include: '*.jar')
|
||||
implementation 'com.android.support:appcompat-v7:28.0.0'
|
||||
implementation 'com.android.support:recyclerview-v7:28.0.0'
|
||||
implementation 'com.android.support:design:28.0.0'
|
||||
implementation 'it.sephiroth.android.library.imagezoom:imagezoom:1.0.5'
|
||||
implementation 'org.greenrobot:eventbus:3.1.1'
|
||||
implementation 'com.squareup.picasso:picasso:2.5.2'
|
||||
implementation 'com.squareup.okhttp3:okhttp:3.10.0'
|
||||
implementation 'com.squareup.okhttp3:okhttp-urlconnection:3.10.0'
|
||||
implementation 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0'
|
||||
}
|
||||
|
@ -8,13 +8,14 @@
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
|
||||
<application
|
||||
android:name=".MainApplication"
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme" >
|
||||
android:theme="@style/AppTheme">
|
||||
<activity
|
||||
android:name=".activity.LoginActivity"
|
||||
android:label="@string/app_name"
|
||||
@ -28,6 +29,7 @@
|
||||
android:name=".activity.MainActivity"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/AppTheme.NoActionBar"
|
||||
android:windowSoftInputMode="adjustNothing">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEARCH" />
|
||||
@ -43,6 +45,9 @@
|
||||
<activity
|
||||
android:name=".activity.DocumentViewActivity"
|
||||
android:label="">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.DocumentEditActivity"
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.sismics.docs;
|
||||
|
||||
import android.app.Application;
|
||||
import android.support.v7.app.AppCompatDelegate;
|
||||
|
||||
import com.sismics.docs.model.application.ApplicationContext;
|
||||
import com.sismics.docs.util.PreferenceUtil;
|
||||
@ -22,5 +23,7 @@ public class MainApplication extends Application {
|
||||
// TODO Provide documents to intent action get content
|
||||
|
||||
super.onCreate();
|
||||
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ public class AuditLogActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
// Configure the swipe refresh layout
|
||||
SwipeRefreshLayout swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);
|
||||
SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swipeRefreshLayout);
|
||||
swipeRefreshLayout.setColorSchemeResources(android.R.color.holo_blue_bright,
|
||||
android.R.color.holo_green_light,
|
||||
android.R.color.holo_orange_light,
|
||||
@ -65,7 +65,7 @@ public class AuditLogActivity extends AppCompatActivity {
|
||||
});
|
||||
|
||||
// Navigate to user profile on click
|
||||
final ListView auditLogListView = (ListView) findViewById(R.id.auditLogListView);
|
||||
final ListView auditLogListView = findViewById(R.id.auditLogListView);
|
||||
auditLogListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
@ -88,15 +88,15 @@ public class AuditLogActivity extends AppCompatActivity {
|
||||
* Refresh the view.
|
||||
*/
|
||||
private void refreshView(String documentId) {
|
||||
final SwipeRefreshLayout swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);
|
||||
final ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar);
|
||||
final ListView auditLogListView = (ListView) findViewById(R.id.auditLogListView);
|
||||
final SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swipeRefreshLayout);
|
||||
final ProgressBar progressBar = findViewById(R.id.progressBar);
|
||||
final ListView auditLogListView = findViewById(R.id.auditLogListView);
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
auditLogListView.setVisibility(View.GONE);
|
||||
AuditLogResource.list(this, documentId, new HttpCallback() {
|
||||
@Override
|
||||
public void onSuccess(JSONObject response) {
|
||||
auditLogListView.setAdapter(new AuditLogListAdapter(response.optJSONArray("logs")));
|
||||
auditLogListView.setAdapter(new AuditLogListAdapter(AuditLogActivity.this, response.optJSONArray("logs")));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -101,7 +101,7 @@ public class DocumentEditActivity extends AppCompatActivity {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
JSONArray tagArray = tags.optJSONArray("stats");
|
||||
JSONArray tagArray = tags.optJSONArray("tags");
|
||||
|
||||
List<JSONObject> tagList = new ArrayList<>();
|
||||
for (int i = 0; i < tagArray.length(); i++) {
|
||||
|
@ -16,6 +16,7 @@ import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.DateFormat;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
@ -51,7 +52,7 @@ import com.sismics.docs.resource.FileResource;
|
||||
import com.sismics.docs.service.FileUploadService;
|
||||
import com.sismics.docs.util.NetworkUtil;
|
||||
import com.sismics.docs.util.PreferenceUtil;
|
||||
import com.sismics.docs.util.TagUtil;
|
||||
import com.sismics.docs.util.SpannableUtil;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
@ -75,11 +76,6 @@ public class DocumentViewActivity extends AppCompatActivity {
|
||||
*/
|
||||
public static final int REQUEST_CODE_ADD_FILE = 1;
|
||||
|
||||
/**
|
||||
* Request code of editing document.
|
||||
*/
|
||||
public static final int REQUEST_CODE_EDIT_DOCUMENT = 2;
|
||||
|
||||
/**
|
||||
* File view pager.
|
||||
*/
|
||||
@ -176,9 +172,11 @@ public class DocumentViewActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
// Fill the layout
|
||||
// Create date
|
||||
TextView createdDateTextView = (TextView) findViewById(R.id.createdDateTextView);
|
||||
createdDateTextView.setText(date);
|
||||
|
||||
// Description
|
||||
TextView descriptionTextView = (TextView) findViewById(R.id.descriptionTextView);
|
||||
if (description.isEmpty() || document.isNull("description")) {
|
||||
descriptionTextView.setVisibility(View.GONE);
|
||||
@ -187,17 +185,20 @@ public class DocumentViewActivity extends AppCompatActivity {
|
||||
descriptionTextView.setText(description);
|
||||
}
|
||||
|
||||
// Tags
|
||||
TextView tagTextView = (TextView) findViewById(R.id.tagTextView);
|
||||
if (tags.length() == 0) {
|
||||
tagTextView.setVisibility(View.GONE);
|
||||
} else {
|
||||
tagTextView.setVisibility(View.VISIBLE);
|
||||
tagTextView.setText(TagUtil.buildSpannable(tags));
|
||||
tagTextView.setText(SpannableUtil.buildSpannableTags(tags));
|
||||
}
|
||||
|
||||
// Language
|
||||
ImageView languageImageView = (ImageView) findViewById(R.id.languageImageView);
|
||||
languageImageView.setImageResource(getResources().getIdentifier(language, "drawable", getPackageName()));
|
||||
|
||||
// Shared status
|
||||
ImageView sharedImageView = (ImageView) findViewById(R.id.sharedImageView);
|
||||
sharedImageView.setVisibility(shared ? View.VISIBLE : View.GONE);
|
||||
|
||||
@ -208,7 +209,7 @@ public class DocumentViewActivity extends AppCompatActivity {
|
||||
public void onClick(View view) {
|
||||
Intent intent = new Intent(DocumentViewActivity.this, DocumentEditActivity.class);
|
||||
intent.putExtra("document", DocumentViewActivity.this.document.toString());
|
||||
startActivityForResult(intent, REQUEST_CODE_EDIT_DOCUMENT);
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
|
||||
@ -642,10 +643,10 @@ public class DocumentViewActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
// Action only available if the document is writable
|
||||
findViewById(R.id.actionEditDocument).setVisibility(writable ? View.VISIBLE : View.INVISIBLE);
|
||||
findViewById(R.id.actionUploadFile).setVisibility(writable ? View.VISIBLE : View.INVISIBLE);
|
||||
findViewById(R.id.actionSharing).setVisibility(writable ? View.VISIBLE : View.INVISIBLE);
|
||||
findViewById(R.id.actionDelete).setVisibility(writable ? View.VISIBLE : View.INVISIBLE);
|
||||
findViewById(R.id.actionEditDocument).setVisibility(writable ? View.VISIBLE : View.GONE);
|
||||
findViewById(R.id.actionUploadFile).setVisibility(writable ? View.VISIBLE : View.GONE);
|
||||
findViewById(R.id.actionSharing).setVisibility(writable ? View.VISIBLE : View.GONE);
|
||||
findViewById(R.id.actionDelete).setVisibility(writable ? View.VISIBLE : View.GONE);
|
||||
|
||||
// ACLs
|
||||
ListView aclListView = (ListView) findViewById(R.id.aclListView);
|
||||
@ -679,10 +680,54 @@ public class DocumentViewActivity extends AppCompatActivity {
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
|
||||
// Contributors
|
||||
TextView contributorsTextView = (TextView) findViewById(R.id.contributorsTextView);
|
||||
contributorsTextView.setText(SpannableUtil.buildSpannableContributors(document.optJSONArray("contributors")));
|
||||
|
||||
// Relations
|
||||
JSONArray relations = document.optJSONArray("relations");
|
||||
if (relations.length() > 0) {
|
||||
TextView relationsTextView = (TextView) findViewById(R.id.relationsTextView);
|
||||
relationsTextView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
relationsTextView.setText(SpannableUtil.buildSpannableRelations(relations));
|
||||
} else {
|
||||
findViewById(R.id.relationsLayout).setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
// Additional dublincore metadata
|
||||
displayDublincoreMetadata(R.id.subjectTextView, R.id.subjectLayout, "subject");
|
||||
displayDublincoreMetadata(R.id.identifierTextView, R.id.identifierLayout, "identifier");
|
||||
displayDublincoreMetadata(R.id.publisherTextView, R.id.publisherLayout, "publisher");
|
||||
displayDublincoreMetadata(R.id.formatTextView, R.id.formatLayout, "format");
|
||||
displayDublincoreMetadata(R.id.sourceTextView, R.id.sourceLayout, "source");
|
||||
displayDublincoreMetadata(R.id.typeTextView, R.id.typeLayout, "type");
|
||||
displayDublincoreMetadata(R.id.coverageTextView, R.id.coverageLayout, "coverage");
|
||||
displayDublincoreMetadata(R.id.rightsTextView, R.id.rightsLayout, "rights");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a dublincore metadata.
|
||||
*
|
||||
* @param textViewId TextView ID
|
||||
* @param blockViewId View ID
|
||||
* @param name Name
|
||||
*/
|
||||
private void displayDublincoreMetadata(int textViewId, int blockViewId, String name) {
|
||||
if (document == null) return;
|
||||
String value = document.optString(name);
|
||||
if (document.isNull(name) || value.isEmpty()) {
|
||||
findViewById(blockViewId).setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
|
||||
findViewById(blockViewId).setVisibility(View.VISIBLE);
|
||||
TextView textView = (TextView) findViewById(textViewId);
|
||||
textView.setText(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {
|
||||
switch (view.getId()) {
|
||||
|
@ -9,11 +9,13 @@ import android.provider.SearchRecentSuggestions;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
import android.support.v7.app.ActionBarDrawerToggle;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ListView;
|
||||
import android.widget.SearchView;
|
||||
import android.widget.TextView;
|
||||
@ -61,7 +63,10 @@ public class MainActivity extends AppCompatActivity {
|
||||
setContentView(R.layout.main_activity);
|
||||
|
||||
// Enable ActionBar app icon to behave as action to toggle nav drawer
|
||||
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
|
||||
drawerLayout = findViewById(R.id.drawer_layout);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
toolbar.setTitleTextColor(getResources().getColor(android.R.color.white));
|
||||
setSupportActionBar(toolbar);
|
||||
if (getSupportActionBar() != null) {
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
getSupportActionBar().setHomeButtonEnabled(true);
|
||||
@ -75,25 +80,25 @@ public class MainActivity extends AppCompatActivity {
|
||||
|
||||
// Fill the drawer user info
|
||||
JSONObject userInfo = ApplicationContext.getInstance().getUserInfo();
|
||||
TextView usernameTextView = (TextView) findViewById(R.id.usernameTextView);
|
||||
TextView usernameTextView = findViewById(R.id.usernameTextView);
|
||||
usernameTextView.setText(userInfo.optString("username"));
|
||||
TextView emailTextView = (TextView) findViewById(R.id.emailTextView);
|
||||
TextView emailTextView = findViewById(R.id.emailTextView);
|
||||
emailTextView.setText(userInfo.optString("email"));
|
||||
|
||||
// Get tag list to fill the drawer
|
||||
final ListView tagListView = (ListView) findViewById(R.id.tagListView);
|
||||
final ListView tagListView = findViewById(R.id.tagListView);
|
||||
final View tagProgressView = findViewById(R.id.tagProgressView);
|
||||
final TextView tagEmptyView = (TextView) findViewById(R.id.tagEmptyView);
|
||||
final TextView tagEmptyView = findViewById(R.id.tagEmptyView);
|
||||
tagListView.setEmptyView(tagProgressView);
|
||||
JSONObject cacheTags = PreferenceUtil.getCachedJson(this, PreferenceUtil.PREF_CACHED_TAGS_JSON);
|
||||
if (cacheTags != null) {
|
||||
tagListView.setAdapter(new TagListAdapter(cacheTags.optJSONArray("stats")));
|
||||
tagListView.setAdapter(new TagListAdapter(cacheTags.optJSONArray("tags")));
|
||||
}
|
||||
TagResource.stats(this, new HttpCallback() {
|
||||
TagResource.list(this, new HttpCallback() {
|
||||
@Override
|
||||
public void onSuccess(JSONObject response) {
|
||||
PreferenceUtil.setCachedJson(MainActivity.this, PreferenceUtil.PREF_CACHED_TAGS_JSON, response);
|
||||
tagListView.setAdapter(new TagListAdapter(response.optJSONArray("stats")));
|
||||
tagListView.setAdapter(new TagListAdapter(response.optJSONArray("tags")));
|
||||
tagProgressView.setVisibility(View.GONE);
|
||||
tagListView.setEmptyView(tagEmptyView);
|
||||
}
|
||||
@ -145,6 +150,15 @@ public class MainActivity extends AppCompatActivity {
|
||||
}
|
||||
});
|
||||
|
||||
// Add document button
|
||||
ImageButton addDocumentButton = findViewById(R.id.addDocumentButton);
|
||||
addDocumentButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
startActivity(new Intent(MainActivity.this, DocumentEditActivity.class));
|
||||
}
|
||||
});
|
||||
|
||||
handleIntent(getIntent());
|
||||
|
||||
EventBus.getDefault().register(this);
|
||||
@ -158,6 +172,7 @@ public class MainActivity extends AppCompatActivity {
|
||||
@Override
|
||||
public void onFinish() {
|
||||
// Force logout in all cases, so the user is not stuck in case of network error
|
||||
PreferenceUtil.clearAuthToken(MainActivity.this);
|
||||
ApplicationContext.getInstance().setUserInfo(getApplicationContext(), null);
|
||||
startActivity(new Intent(MainActivity.this, LoginActivity.class));
|
||||
finish();
|
||||
|
@ -1,8 +1,6 @@
|
||||
package com.sismics.docs.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.DateFormat;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@ -30,12 +28,19 @@ public class AuditLogListAdapter extends BaseAdapter {
|
||||
*/
|
||||
private List<JSONObject> logList;
|
||||
|
||||
/**
|
||||
* Context.
|
||||
*/
|
||||
private Context context;
|
||||
|
||||
/**
|
||||
* Audit log list adapter.
|
||||
*
|
||||
* @param context Context
|
||||
* @param logs Logs
|
||||
*/
|
||||
public AuditLogListAdapter(JSONArray logs) {
|
||||
public AuditLogListAdapter(Context context, JSONArray logs) {
|
||||
this.context = context;
|
||||
this.logList = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < logs.length(); i++) {
|
||||
@ -67,11 +72,21 @@ public class AuditLogListAdapter extends BaseAdapter {
|
||||
|
||||
// Build message
|
||||
final JSONObject log = getItem(position);
|
||||
StringBuilder message = new StringBuilder(log.optString("class"));
|
||||
StringBuilder message = new StringBuilder();
|
||||
|
||||
// Translate entity name
|
||||
int stringId = context.getResources().getIdentifier("auditlog_" + log.optString("class"), "string", context.getPackageName());
|
||||
if (stringId == 0) {
|
||||
message.append(log.optString("class"));
|
||||
} else {
|
||||
message.append(context.getResources().getString(stringId));
|
||||
}
|
||||
message.append(" ");
|
||||
|
||||
switch (log.optString("type")) {
|
||||
case "CREATE": message.append(" created"); break;
|
||||
case "UPDATE": message.append(" updated"); break;
|
||||
case "DELETE": message.append(" deleted"); break;
|
||||
case "CREATE": message.append(context.getResources().getString(R.string.auditlog_created)); break;
|
||||
case "UPDATE": message.append(context.getResources().getString(R.string.auditlog_updated)); break;
|
||||
case "DELETE": message.append(context.getResources().getString(R.string.auditlog_deleted)); break;
|
||||
}
|
||||
switch (log.optString("class")) {
|
||||
case "Document":
|
||||
@ -85,9 +100,9 @@ public class AuditLogListAdapter extends BaseAdapter {
|
||||
}
|
||||
|
||||
// Fill the view
|
||||
TextView usernameTextView = (TextView) view.findViewById(R.id.usernameTextView);
|
||||
TextView messageTextView = (TextView) view.findViewById(R.id.messageTextView);
|
||||
TextView dateTextView = (TextView) view.findViewById(R.id.dateTextView);
|
||||
TextView usernameTextView = view.findViewById(R.id.usernameTextView);
|
||||
TextView messageTextView = view.findViewById(R.id.messageTextView);
|
||||
TextView dateTextView = view.findViewById(R.id.dateTextView);
|
||||
usernameTextView.setText(log.optString("username"));
|
||||
messageTextView.setText(message);
|
||||
String date = DateFormat.getDateFormat(parent.getContext()).format(new Date(log.optLong("create_date")));
|
||||
|
@ -9,7 +9,7 @@ import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.sismics.docs.R;
|
||||
import com.sismics.docs.util.TagUtil;
|
||||
import com.sismics.docs.util.SpannableUtil;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
@ -69,7 +69,7 @@ public class DocListAdapter extends RecyclerView.Adapter<DocListAdapter.ViewHold
|
||||
holder.titleTextView.setText(document.optString("title"));
|
||||
|
||||
JSONArray tags = document.optJSONArray("tags");
|
||||
holder.subtitleTextView.setText(TagUtil.buildSpannable(tags));
|
||||
holder.subtitleTextView.setText(SpannableUtil.buildSpannableTags(tags));
|
||||
|
||||
String date = DateFormat.getDateFormat(holder.dateTextView.getContext()).format(new Date(document.optLong("create_date")));
|
||||
holder.dateTextView.setText(date);
|
||||
|
@ -33,7 +33,8 @@ public class LanguageAdapter extends BaseAdapter {
|
||||
}
|
||||
languageList.add(new Language("fra", R.string.language_french, R.drawable.fra));
|
||||
languageList.add(new Language("eng", R.string.language_english, R.drawable.eng));
|
||||
languageList.add(new Language("jpn", R.string.language_japanese, R.drawable.jpn));
|
||||
languageList.add(new Language("deu", R.string.language_german, R.drawable.deu));
|
||||
languageList.add(new Language("pol", R.string.language_polish, R.drawable.pol));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -46,7 +46,7 @@ public class TagListAdapter extends BaseAdapter {
|
||||
|
||||
// Reorder tags by parent/child relation and compute depth
|
||||
int depth = 0;
|
||||
initTags(tags, JSONObject.NULL.toString(), depth);
|
||||
initTags(tags, "", depth);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -60,11 +60,10 @@ public class TagListAdapter extends BaseAdapter {
|
||||
// Get all tags with this parent
|
||||
for (JSONObject tag : tags) {
|
||||
String tagParentId = tag.optString("parent");
|
||||
if (tagParentId.equals(parentId)) {
|
||||
if (parentId.equals(tagParentId)) {
|
||||
TagItem tagItem = new TagItem();
|
||||
tagItem.id = tag.optString("id");
|
||||
tagItem.name = tag.optString("name");
|
||||
tagItem.count = tag.optInt("count");
|
||||
tagItem.color = tag.optString("color");
|
||||
tagItem.depth = depth;
|
||||
tagItemList.add(tagItem);
|
||||
@ -99,8 +98,6 @@ public class TagListAdapter extends BaseAdapter {
|
||||
TagItem tagItem = getItem(position);
|
||||
TextView tagTextView = (TextView) view.findViewById(R.id.tagTextView);
|
||||
tagTextView.setText(tagItem.name);
|
||||
TextView tagCountTextView = (TextView) view.findViewById(R.id.tagCountTextView);
|
||||
tagCountTextView.setText(String.format(Locale.ENGLISH, "%d", tagItem.count));
|
||||
|
||||
// Label color filtering
|
||||
ImageView labelImageView = (ImageView) view.findViewById(R.id.labelImageView);
|
||||
@ -125,7 +122,6 @@ public class TagListAdapter extends BaseAdapter {
|
||||
public static class TagItem {
|
||||
private String id;
|
||||
private String name;
|
||||
private int count;
|
||||
private String color;
|
||||
private int depth;
|
||||
|
||||
|
@ -2,6 +2,7 @@ package com.sismics.docs.fragment;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
@ -9,12 +10,10 @@ import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.sismics.docs.R;
|
||||
import com.sismics.docs.activity.DocumentEditActivity;
|
||||
import com.sismics.docs.activity.DocumentViewActivity;
|
||||
import com.sismics.docs.adapter.DocListAdapter;
|
||||
import com.sismics.docs.event.DocumentAddEvent;
|
||||
@ -46,11 +45,6 @@ public class DocListFragment extends Fragment {
|
||||
*/
|
||||
private String query;
|
||||
|
||||
/**
|
||||
* Request code of adding document.
|
||||
*/
|
||||
private static final int REQUEST_CODE_ADD_DOCUMENT = 1;
|
||||
|
||||
// View cache
|
||||
private EmptyRecyclerView recyclerView;
|
||||
private SwipeRefreshLayout swipeRefreshLayout;
|
||||
@ -60,23 +54,22 @@ public class DocListFragment extends Fragment {
|
||||
private int previousTotal = 0;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
final View view = inflater.inflate(R.layout.doc_list_fragment, container, false);
|
||||
|
||||
// Configure the RecyclerView
|
||||
recyclerView = (EmptyRecyclerView) view.findViewById(R.id.docList);
|
||||
recyclerView = view.findViewById(R.id.docList);
|
||||
adapter = new DocListAdapter();
|
||||
recyclerView.setAdapter(adapter);
|
||||
recyclerView.setHasFixedSize(true);
|
||||
recyclerView.setLongClickable(true);
|
||||
recyclerView.addItemDecoration(new DividerItemDecoration(getResources().getDrawable(R.drawable.abc_list_divider_mtrl_alpha)));
|
||||
|
||||
// Configure the LayoutManager
|
||||
final LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
|
||||
// Configure the swipe refresh layout
|
||||
swipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipeRefreshLayout);
|
||||
swipeRefreshLayout = view.findViewById(R.id.swipeRefreshLayout);
|
||||
swipeRefreshLayout.setColorSchemeResources(android.R.color.holo_blue_bright,
|
||||
android.R.color.holo_green_light,
|
||||
android.R.color.holo_orange_light,
|
||||
@ -122,16 +115,6 @@ public class DocListFragment extends Fragment {
|
||||
}
|
||||
});
|
||||
|
||||
// Add document button
|
||||
ImageButton addDocumentButton = (ImageButton) view.findViewById(R.id.addDocumentButton);
|
||||
addDocumentButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(getActivity(), DocumentEditActivity.class);
|
||||
startActivityForResult(intent, REQUEST_CODE_ADD_DOCUMENT);
|
||||
}
|
||||
});
|
||||
|
||||
// Grab the documents
|
||||
loadDocuments(view, true);
|
||||
|
||||
@ -210,7 +193,7 @@ public class DocListFragment extends Fragment {
|
||||
private void loadDocuments(final View view, final boolean reset) {
|
||||
if (view == null) return;
|
||||
final View progressBar = view.findViewById(R.id.progressBar);
|
||||
final TextView documentsEmptyView = (TextView) view.findViewById(R.id.documentsEmptyView);
|
||||
final TextView documentsEmptyView = view.findViewById(R.id.documentsEmptyView);
|
||||
|
||||
if (reset) {
|
||||
loading = true;
|
||||
|
@ -73,7 +73,7 @@ public class SearchFragment extends DialogFragment {
|
||||
dialog.cancel();
|
||||
return dialog;
|
||||
}
|
||||
JSONArray tagArray = tags.optJSONArray("stats");
|
||||
JSONArray tagArray = tags.optJSONArray("tags");
|
||||
|
||||
List<JSONObject> tagList = new ArrayList<>();
|
||||
for (int i = 0; i < tagArray.length(); i++) {
|
||||
|
@ -16,14 +16,14 @@ import okhttp3.Request;
|
||||
*/
|
||||
public class TagResource extends BaseResource {
|
||||
/**
|
||||
* GET /tag/stats.
|
||||
* GET /tag/list.
|
||||
*
|
||||
* @param context Context
|
||||
* @param callback Callback
|
||||
*/
|
||||
public static void stats(Context context, HttpCallback callback) {
|
||||
public static void list(Context context, HttpCallback callback) {
|
||||
Request request = new Request.Builder()
|
||||
.url(HttpUrl.parse(getApiUrl(context) + "/tag/stats"))
|
||||
.url(HttpUrl.parse(getApiUrl(context) + "/tag/list"))
|
||||
.get()
|
||||
.build();
|
||||
OkHttpUtil.buildClient(context)
|
||||
|
@ -1,10 +1,12 @@
|
||||
package com.sismics.docs.service;
|
||||
|
||||
import android.app.IntentService;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.PowerManager;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.support.v4.app.NotificationCompat.Builder;
|
||||
@ -29,7 +31,8 @@ import okhttp3.internal.Util;
|
||||
* @author bgamard
|
||||
*/
|
||||
public class FileUploadService extends IntentService {
|
||||
private static final String TAG = "FileUploadService";
|
||||
private static final String TAG = "sismicsdocs:fileupload";
|
||||
private static final String CHANNEL_ID = "FileUploadService";
|
||||
|
||||
private static final int UPLOAD_NOTIFICATION_ID = 1;
|
||||
private static final int UPLOAD_NOTIFICATION_ID_DONE = 2;
|
||||
@ -49,18 +52,30 @@ public class FileUploadService extends IntentService {
|
||||
super.onCreate();
|
||||
|
||||
notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||
notification = new NotificationCompat.Builder(this);
|
||||
initChannels();
|
||||
notification = new NotificationCompat.Builder(this, CHANNEL_ID);
|
||||
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
|
||||
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
|
||||
}
|
||||
|
||||
private void initChannels() {
|
||||
if (Build.VERSION.SDK_INT < 26) {
|
||||
return;
|
||||
}
|
||||
|
||||
NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
|
||||
"File Upload", NotificationManager.IMPORTANCE_HIGH);
|
||||
channel.setDescription("Used to show file upload progress");
|
||||
notificationManager.createNotificationChannel(channel);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHandleIntent(Intent intent) {
|
||||
if (intent == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
wakeLock.acquire();
|
||||
wakeLock.acquire(60_000 * 30); // 30 minutes upload time maximum
|
||||
try {
|
||||
onStart();
|
||||
handleFileUpload(intent.getStringExtra(PARAM_DOCUMENT_ID), (Uri) intent.getParcelableExtra(PARAM_URI));
|
||||
@ -77,7 +92,7 @@ public class FileUploadService extends IntentService {
|
||||
*
|
||||
* @param documentId Document ID
|
||||
* @param uri Data URI
|
||||
* @throws IOException
|
||||
* @throws IOException e
|
||||
*/
|
||||
private void handleFileUpload(final String documentId, final Uri uri) throws Exception {
|
||||
final InputStream is = getContentResolver().openInputStream(uri);
|
||||
|
@ -0,0 +1,47 @@
|
||||
package com.sismics.docs.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.design.widget.AppBarLayout;
|
||||
import android.support.design.widget.CoordinatorLayout;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import com.sismics.docs.R;
|
||||
|
||||
public class ScrollingFABBehavior extends CoordinatorLayout.Behavior<FloatingActionButton> {
|
||||
private int toolbarHeight;
|
||||
|
||||
public ScrollingFABBehavior(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
this.toolbarHeight = getToolbarHeight(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean layoutDependsOn(@NonNull CoordinatorLayout parent, @NonNull FloatingActionButton fab, @NonNull View dependency) {
|
||||
return dependency instanceof AppBarLayout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDependentViewChanged(@NonNull CoordinatorLayout parent, @NonNull FloatingActionButton fab, @NonNull View dependency) {
|
||||
if (dependency instanceof AppBarLayout) {
|
||||
CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();
|
||||
int fabBottomMargin = lp.bottomMargin;
|
||||
int distanceToScroll = fab.getHeight() + fabBottomMargin;
|
||||
float ratio = dependency.getY() /(float) toolbarHeight;
|
||||
fab.setTranslationY(- distanceToScroll * ratio);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private int getToolbarHeight(Context context) {
|
||||
final TypedArray styledAttributes = context.getTheme().obtainStyledAttributes(
|
||||
new int[] { R.attr.actionBarSize });
|
||||
int toolbarHeight = (int) styledAttributes.getDimension(0, 0);
|
||||
styledAttributes.recycle();
|
||||
|
||||
return toolbarHeight;
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.sismics.docs.ui.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ListView;
|
||||
|
||||
/**
|
||||
* Non-scrollable ListView.
|
||||
* All items are visible from the start.
|
||||
*
|
||||
* @author http://stackoverflow.com/questions/18813296/non-scrollable-listview-inside-scrollview/24629341#24629341
|
||||
*/
|
||||
public class NonScrollListView extends ListView {
|
||||
|
||||
public NonScrollListView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
public NonScrollListView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
public NonScrollListView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
@Override
|
||||
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
|
||||
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
|
||||
ViewGroup.LayoutParams params = getLayoutParams();
|
||||
params.height = getMeasuredHeight();
|
||||
}
|
||||
}
|
@ -1,9 +1,14 @@
|
||||
package com.sismics.docs.util;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.app.DownloadManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Environment;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
|
||||
/**
|
||||
* Utility class for network actions.
|
||||
@ -19,9 +24,14 @@ public class NetworkUtil {
|
||||
* @param title Notification title
|
||||
* @param description Notification description
|
||||
*/
|
||||
public static void downloadFile(Context context, String url, String fileName, String title, String description) {
|
||||
String authToken = PreferenceUtil.getAuthToken(context);
|
||||
DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
|
||||
public static void downloadFile(Activity activity, String url, String fileName, String title, String description) {
|
||||
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
||||
ActivityCompat.requestPermissions(activity, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
String authToken = PreferenceUtil.getAuthToken(activity);
|
||||
DownloadManager downloadManager = (DownloadManager) activity.getSystemService(Context.DOWNLOAD_SERVICE);
|
||||
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
|
||||
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
|
||||
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
|
||||
|
@ -156,7 +156,7 @@ public class OkHttpUtil {
|
||||
public static OkHttpClient buildClient(final Context context) {
|
||||
// One-time header computation
|
||||
if (userAgent == null) {
|
||||
userAgent = "Sismics Docs Android " + ApplicationUtil.getVersionName(context) + "/Android " + Build.VERSION.RELEASE + "/" + Build.MODEL;
|
||||
userAgent = "Teedy Android " + ApplicationUtil.getVersionName(context) + "/Android " + Build.VERSION.RELEASE + "/" + Build.MODEL;
|
||||
}
|
||||
|
||||
if (acceptLanguage == null) {
|
||||
|
@ -126,6 +126,7 @@ public class PreferenceUtil {
|
||||
/**
|
||||
* Returns auth token cookie from shared preferences.
|
||||
*
|
||||
* @param context Context
|
||||
* @return Auth token
|
||||
*/
|
||||
public static String getAuthToken(Context context) {
|
||||
@ -140,6 +141,16 @@ public class PreferenceUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all auth tokens.
|
||||
*
|
||||
* @param context Context
|
||||
*/
|
||||
public static void clearAuthToken(Context context) {
|
||||
PersistentCookieStore cookieStore = new PersistentCookieStore(context);
|
||||
cookieStore.removeAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns cleaned server URL.
|
||||
*
|
||||
|
@ -39,7 +39,9 @@ public class SearchQueryBuilder {
|
||||
*/
|
||||
public SearchQueryBuilder simpleSearch(String simpleSearch) {
|
||||
if (isValid(simpleSearch)) {
|
||||
query.append(SEARCH_SEPARATOR).append(simpleSearch);
|
||||
query.append(SEARCH_SEPARATOR)
|
||||
.append("simple:")
|
||||
.append(simpleSearch);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
@ -0,0 +1,85 @@
|
||||
package com.sismics.docs.util;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.text.style.BackgroundColorSpan;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
/**
|
||||
* Utility class for spannable.
|
||||
*
|
||||
* @author bgamard.
|
||||
*/
|
||||
public class SpannableUtil {
|
||||
/**
|
||||
* Create a colored spannable from tags.
|
||||
*
|
||||
* @param tags Tags
|
||||
* @return Colored spannable
|
||||
*/
|
||||
public static Spannable buildSpannableTags(JSONArray tags) {
|
||||
return buildSpannable(tags, "name", "color");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a spannable for contributors.
|
||||
*
|
||||
* @param contributors Contributors
|
||||
* @return Spannable
|
||||
*/
|
||||
public static Spannable buildSpannableContributors(JSONArray contributors) {
|
||||
return buildSpannable(contributors, "username", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a spannable for relations.
|
||||
*
|
||||
* @param relations Relations
|
||||
* @return Spannable
|
||||
*/
|
||||
public static Spannable buildSpannableRelations(JSONArray relations) {
|
||||
return buildSpannable(relations, "title", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a spannable from a JSONArray.
|
||||
*
|
||||
* @param array JSONArray
|
||||
* @param valueName Name of the value part
|
||||
* @param colorName Name of the color part (optional)
|
||||
* @return Spannable
|
||||
*/
|
||||
private static Spannable buildSpannable(JSONArray array, String valueName, String colorName) {
|
||||
SpannableStringBuilder builder = new SpannableStringBuilder();
|
||||
|
||||
for (int i = 0; i < array.length(); i++) {
|
||||
final JSONObject tag = array.optJSONObject(i);
|
||||
int start = builder.length();
|
||||
builder.append(" ").append(tag.optString(valueName)).append(" ");
|
||||
builder.setSpan(new ForegroundColorSpan(Color.WHITE), start, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
builder.setSpan(new BackgroundColorSpan(Color.parseColor(tag.optString(colorName, "#5bc0de"))), start, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
/*
|
||||
TODO : Make tags, relations and contributors clickable
|
||||
builder.setSpan(new ClickableSpan() {
|
||||
@Override
|
||||
public void onClick(View widget) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDrawState(TextPaint ds) {
|
||||
super.updateDrawState(ds);
|
||||
ds.setColor(Color.WHITE);
|
||||
ds.setUnderlineText(false);
|
||||
}
|
||||
}, start, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);*/
|
||||
builder.append(" ");
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
package com.sismics.docs.util;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.text.style.BackgroundColorSpan;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
/**
|
||||
* Utility class for tags.
|
||||
*
|
||||
* @author bgamard.
|
||||
*/
|
||||
public class TagUtil {
|
||||
/**
|
||||
* Create a colored spannable from tags.
|
||||
*
|
||||
* @param tags Tags
|
||||
* @return Colored spannable
|
||||
*/
|
||||
public static Spannable buildSpannable(JSONArray tags) {
|
||||
SpannableStringBuilder builder = new SpannableStringBuilder();
|
||||
|
||||
for (int i = 0; i < tags.length(); i++) {
|
||||
JSONObject tag = tags.optJSONObject(i);
|
||||
int start = builder.length();
|
||||
builder.append(" ").append(tag.optString("name")).append(" ");
|
||||
builder.setSpan(new ForegroundColorSpan(Color.WHITE), start, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
builder.setSpan(new BackgroundColorSpan(Color.parseColor(tag.optString("color"))), start, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
builder.append(" ");
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
BIN
docs-android/app/src/main/res/drawable-xhdpi/deu.png
Normal file
After Width: | Height: | Size: 9.1 KiB |
Before Width: | Height: | Size: 558 B |
BIN
docs-android/app/src/main/res/drawable-xhdpi/pol.png
Normal file
After Width: | Height: | Size: 238 B |
BIN
docs-android/app/src/main/res/drawable-xxhdpi/deu.png
Normal file
After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 813 B |
@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
@ -37,17 +36,4 @@
|
||||
android:textSize="16sp"
|
||||
android:layout_centerInParent="true"/>
|
||||
|
||||
<android.support.design.widget.FloatingActionButton
|
||||
android:id="@+id/addDocumentButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:src="@drawable/ic_add_white_24dp"
|
||||
app:fabSize="normal"/>
|
||||
|
||||
</RelativeLayout>
|
@ -29,7 +29,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-light"
|
||||
android:textColor="#212121"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:text="Test"
|
||||
android:textSize="16sp"
|
||||
android:ellipsize="end"
|
||||
@ -46,7 +46,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-light"
|
||||
android:textColor="#777777"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:text="test2"
|
||||
android:textSize="16sp"
|
||||
android:maxLines="1"
|
||||
@ -69,7 +69,7 @@
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:textColor="#777777"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:fontFamily="sans-serif-light"/>
|
||||
|
||||
</RelativeLayout>
|
@ -142,15 +142,19 @@
|
||||
|
||||
<!-- Right drawer -->
|
||||
|
||||
<LinearLayout
|
||||
<ScrollView
|
||||
android:id="@+id/right_drawer"
|
||||
android:layout_width="300dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="end"
|
||||
android:orientation="vertical"
|
||||
android:clickable="true"
|
||||
android:background="#fff"
|
||||
android:elevation="5dp">
|
||||
android:elevation="5dp"
|
||||
android:layout_gravity="end">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- Actions -->
|
||||
|
||||
@ -166,28 +170,6 @@
|
||||
android:orientation="horizontal"
|
||||
style="?android:buttonBarStyle">
|
||||
|
||||
<Button
|
||||
android:id="@+id/actionEditDocument"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableTop="@drawable/ic_create_grey600_24dp"
|
||||
style="?android:buttonBarButtonStyle"
|
||||
android:text="@string/edit_document"
|
||||
android:textColor="#ff5a595b"
|
||||
android:textAllCaps="false"
|
||||
android:layout_margin="8dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/actionUploadFile"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableTop="@drawable/ic_file_upload_grey600_24dp"
|
||||
style="?android:buttonBarButtonStyle"
|
||||
android:text="@string/upload_file"
|
||||
android:textColor="#ff5a595b"
|
||||
android:textAllCaps="false"
|
||||
android:layout_margin="8dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/actionDownload"
|
||||
android:layout_width="wrap_content"
|
||||
@ -199,6 +181,28 @@
|
||||
android:textAllCaps="false"
|
||||
android:layout_margin="8dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/actionExportPdf"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableTop="@drawable/ic_description_grey600_24dp"
|
||||
style="?android:buttonBarButtonStyle"
|
||||
android:text="@string/export_pdf"
|
||||
android:textColor="#ff5a595b"
|
||||
android:textAllCaps="false"
|
||||
android:layout_margin="8dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/actionAuditLog"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableTop="@drawable/ic_assignment_grey600_24dp"
|
||||
style="?android:buttonBarButtonStyle"
|
||||
android:text="@string/activity"
|
||||
android:textColor="#ff5a595b"
|
||||
android:textAllCaps="false"
|
||||
android:layout_margin="8dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
@ -208,12 +212,23 @@
|
||||
style="?android:buttonBarStyle">
|
||||
|
||||
<Button
|
||||
android:id="@+id/actionExportPdf"
|
||||
android:id="@+id/actionEditDocument"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableTop="@drawable/ic_description_grey600_24dp"
|
||||
android:drawableTop="@drawable/ic_create_grey600_24dp"
|
||||
style="?android:buttonBarButtonStyle"
|
||||
android:text="@string/export_pdf"
|
||||
android:text="@string/edit_document"
|
||||
android:textColor="#ff5a595b"
|
||||
android:textAllCaps="false"
|
||||
android:layout_margin="0dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/actionUploadFile"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableTop="@drawable/ic_file_upload_grey600_24dp"
|
||||
style="?android:buttonBarButtonStyle"
|
||||
android:text="@string/upload_file"
|
||||
android:textColor="#ff5a595b"
|
||||
android:textAllCaps="false"
|
||||
android:layout_margin="0dp"/>
|
||||
@ -229,17 +244,6 @@
|
||||
android:textAllCaps="false"
|
||||
android:layout_margin="0dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/actionAuditLog"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableTop="@drawable/ic_assignment_grey600_24dp"
|
||||
style="?android:buttonBarButtonStyle"
|
||||
android:text="@string/activity"
|
||||
android:textColor="#ff5a595b"
|
||||
android:textAllCaps="false"
|
||||
android:layout_margin="0dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/actionDelete"
|
||||
android:layout_width="wrap_content"
|
||||
@ -285,6 +289,8 @@
|
||||
android:id="@+id/createdDateTextView"
|
||||
android:layout_toRightOf="@id/createdDateLabel"
|
||||
android:layout_toEndOf="@id/createdDateLabel"
|
||||
android:layout_toLeftOf="@id/sharedImageView"
|
||||
android:layout_toStartOf="@id/sharedImageView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="24dp"
|
||||
android:gravity="center_vertical"
|
||||
@ -332,6 +338,7 @@
|
||||
android:fontFamily="sans-serif-light"/>
|
||||
|
||||
<ImageView
|
||||
android:contentDescription="@string/shared"
|
||||
android:id="@+id/sharedImageView"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
@ -343,6 +350,7 @@
|
||||
android:layout_toStartOf="@+id/languageImageView"/>
|
||||
|
||||
<ImageView
|
||||
android:contentDescription="@string/language"
|
||||
android:id="@+id/languageImageView"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
@ -352,6 +360,278 @@
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<!-- Additional dublincore metadata -->
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="12dp"
|
||||
android:paddingRight="12dp"
|
||||
android:paddingBottom="12dp">
|
||||
|
||||
<!-- Subject -->
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/subjectLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_weight="0.33"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:fontFamily="sans-serif"
|
||||
android:text="@string/subject"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/subjectTextView"
|
||||
android:layout_weight="0.67"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-light"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Identifier -->
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/identifierLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_weight="0.33"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:fontFamily="sans-serif"
|
||||
android:text="@string/identifier"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/identifierTextView"
|
||||
android:layout_weight="0.67"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-light"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Publisher -->
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/publisherLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_weight="0.33"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:fontFamily="sans-serif"
|
||||
android:text="@string/publisher"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/publisherTextView"
|
||||
android:layout_weight="0.67"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-light"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Format -->
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/formatLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_weight="0.33"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:fontFamily="sans-serif"
|
||||
android:text="@string/format"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/formatTextView"
|
||||
android:layout_weight="0.67"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-light"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Source -->
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/sourceLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_weight="0.33"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:fontFamily="sans-serif"
|
||||
android:text="@string/source"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sourceTextView"
|
||||
android:layout_weight="0.67"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-light"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Type -->
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/typeLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_weight="0.33"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:fontFamily="sans-serif"
|
||||
android:text="@string/type"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/typeTextView"
|
||||
android:layout_weight="0.67"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-light"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Coverage -->
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/coverageLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_weight="0.33"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:fontFamily="sans-serif"
|
||||
android:text="@string/coverage"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/coverageTextView"
|
||||
android:layout_weight="0.67"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-light"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Rights -->
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/rightsLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_weight="0.33"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:fontFamily="sans-serif"
|
||||
android:text="@string/rights"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/rightsTextView"
|
||||
android:layout_weight="0.67"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-light"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Contributors -->
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_weight="0.33"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:fontFamily="sans-serif"
|
||||
android:text="@string/contributors"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/contributorsTextView"
|
||||
android:layout_weight="0.67"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-light"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Relations -->
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/relationsLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="2dp">
|
||||
|
||||
<TextView
|
||||
android:layout_weight="0.33"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:fontFamily="sans-serif"
|
||||
android:text="@string/relations"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/relationsTextView"
|
||||
android:layout_weight="0.67"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-light"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
@ -369,14 +649,16 @@
|
||||
android:text="@string/who_can_access"
|
||||
android:layout_margin="12dp"/>
|
||||
|
||||
<ListView
|
||||
<com.sismics.docs.ui.view.NonScrollListView
|
||||
android:id="@+id/aclListView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:choiceMode="singleChoice"
|
||||
android:divider="@android:color/transparent"
|
||||
android:dividerHeight="0dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
</android.support.v4.widget.DrawerLayout>
|
@ -6,12 +6,47 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.design.widget.CoordinatorLayout
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/overview_coordinator_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.design.widget.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:popupTheme="@style/AppTheme"
|
||||
app:layout_scrollFlags="enterAlways|scroll|snap" />
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/main_fragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
class="com.sismics.docs.fragment.DocListFragment"/>
|
||||
|
||||
<android.support.design.widget.FloatingActionButton
|
||||
android:id="@+id/addDocumentButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|bottom"
|
||||
android:layout_margin="16dp"
|
||||
android:src="@drawable/ic_add_white_24dp"
|
||||
app:layout_anchor="@id/main_fragment"
|
||||
app:layout_behavior="com.sismics.docs.ui.ScrollingFABBehavior"
|
||||
app:layout_anchorGravity="bottom|right|end"
|
||||
app:fabSize="normal"/>
|
||||
|
||||
</android.support.design.widget.CoordinatorLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/left_drawer"
|
||||
android:layout_width="240dp"
|
||||
|
@ -29,16 +29,4 @@
|
||||
android:text="Appartement"
|
||||
android:textSize="14sp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tagCountTextView"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif"
|
||||
android:textColor="#888"
|
||||
android:text="5"
|
||||
android:textSize="14sp"/>
|
||||
|
||||
</RelativeLayout>
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 9.7 KiB |
159
docs-android/app/src/main/res/values-de/strings.xml
Normal file
@ -0,0 +1,159 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<!-- Validation -->
|
||||
<string name="validate_error_email">Ungültige E-Mail</string>
|
||||
<string name="validate_error_length_min">Zu kurz (min. %d)</string>
|
||||
<string name="validate_error_length_max">Zu lang (max. %d)</string>
|
||||
<string name="validate_error_required">Erforderlich</string>
|
||||
<string name="validate_error_alphanumeric">Nur Buchstaben und Zahlen</string>
|
||||
|
||||
<!-- App -->
|
||||
<string name="drawer_open">Navigationsleiste öffnen</string>
|
||||
<string name="drawer_close">Navigationsleiste schließen</string>
|
||||
<string name="login_explain"><![CDATA[Um zu beginnen, müssen Sie Teedy Server herunterladen und installieren <a href="https://github.com/sismics/docs">github.com/sismics/docs</a>, sowie die Login-Daten unten eingeben]]></string>
|
||||
<string name="server">Server</string>
|
||||
<string name="username">Username</string>
|
||||
<string name="password">Password</string>
|
||||
<string name="login">Login</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="cancel">Abbrechen</string>
|
||||
<string name="login_fail_title">Login gescheitert</string>
|
||||
<string name="login_fail">Benutzername oder Passwort falsch</string>
|
||||
<string name="network_error_title">Netzwerkfehler</string>
|
||||
<string name="network_error">Netzwerkfehler, überprüfen Sie die Internetverbindung und die Server-URL</string>
|
||||
<string name="invalid_url_title">Ungültige URL</string>
|
||||
<string name="invalid_url">Bitte überprüfen Sie die Server-URL und versuchen Sie es erneut</string>
|
||||
<string name="crash_toast_text">Ein Absturz ist aufgetreten, ein Bericht wurde gesendet, um dieses Problem zu beheben</string>
|
||||
<string name="created_date">Erstellungsdatum</string>
|
||||
<string name="download_file">Aktuelle Datei herunterladen</string>
|
||||
<string name="download_document">Herunterladen</string>
|
||||
<string name="action_search">Dokumente durchsuchen</string>
|
||||
<string name="all_documents">Alle Dokumente</string>
|
||||
<string name="shared_documents">Geteilte Dokumente</string>
|
||||
<string name="all_tags">Alle Tags</string>
|
||||
<string name="no_tags">Keine Tags</string>
|
||||
<string name="error_loading_tags">Fehler beim Laden von Tags</string>
|
||||
<string name="no_documents">Keine Dokumente</string>
|
||||
<string name="error_loading_documents">Fehler beim Laden von Dokumenten</string>
|
||||
<string name="no_files">Keine Dateien</string>
|
||||
<string name="error_loading_files">Fehler beim Laden von Dateien</string>
|
||||
<string name="new_document">Neues Dokument</string>
|
||||
<string name="share">Teilen</string>
|
||||
<string name="close">Schließen</string>
|
||||
<string name="add">Hinzufügen</string>
|
||||
<string name="add_share_hint">Freigabename (optional)</string>
|
||||
<string name="document_not_shared">Dieses Dokument wird derzeit nicht freigegeben</string>
|
||||
<string name="delete_share">Diese Freigabe löschen</string>
|
||||
<string name="send_share">Send this share link</string>
|
||||
<string name="error_loading_shares">Fehler beim Laden von Freigaben</string>
|
||||
<string name="error_adding_share">Fehler beim Hinzufügen der Freigabe</string>
|
||||
<string name="share_default_name">Freigabe Link</string>
|
||||
<string name="error_deleting_share">Fehler beim Löschen der Freigabe</string>
|
||||
<string name="send_share_to">Freigabe senden an</string>
|
||||
<string name="upload_file">Datei hinzufügen</string>
|
||||
<string name="upload_from">Datei hochladen von</string>
|
||||
<string name="settings">Einstellungen</string>
|
||||
<string name="logout">Ausloggen</string>
|
||||
<string name="version">Version</string>
|
||||
<string name="build">Build</string>
|
||||
<string name="pref_advanced_category">Erweiterte Einstellungen</string>
|
||||
<string name="pref_about_category">Über</string>
|
||||
<string name="pref_github">GitHub</string>
|
||||
<string name="pref_issue">Fehler berichten</string>
|
||||
<string name="pref_clear_cache_title">Cache leeren</string>
|
||||
<string name="pref_clear_cache_summary">Zwischengespeicherte Dateien löschen</string>
|
||||
<string name="pref_clear_cache_success">Cache wurde geleert</string>
|
||||
<string name="pref_clear_history_title">Suchhistorie löschen</string>
|
||||
<string name="pref_clear_history_summary">Leert die aktuellen Suchvorschläge</string>
|
||||
<string name="pref_clear_history_success">Suchvorschläge wurden gelöscht</string>
|
||||
<string name="pref_cache_size">Cache Größe</string>
|
||||
<string name="save">Speichern</string>
|
||||
<string name="edit_document">Bearbeiten</string>
|
||||
<string name="error_editing_document">Netzwerkfehler, bitte versuchen Sie es erneut</string>
|
||||
<string name="please_wait">Bitte warten</string>
|
||||
<string name="document_editing_message">Daten werden gesendet</string>
|
||||
<string name="delete_document">Löschen</string>
|
||||
<string name="delete_document_title">Dokument löschen</string>
|
||||
<string name="delete_document_message">Dieses Dokument und alle zugehörigen Dateien wirklich löschen?</string>
|
||||
<string name="document_delete_failure">Netzwerkfehler beim Löschen des Dokuments</string>
|
||||
<string name="document_deleting_message">Lösche Dokument</string>
|
||||
<string name="delete_file_title">Datei löschen</string>
|
||||
<string name="delete_file_message">Die aktuelle Datei wirklich löschen?</string>
|
||||
<string name="file_delete_failure">Netzwerkfehler beim Löschen der Datei</string>
|
||||
<string name="file_deleting_message">Lösche Datei</string>
|
||||
<string name="error_reading_file">Fehler beim Lesen der Datei</string>
|
||||
<string name="upload_notification_title">Teedy</string>
|
||||
<string name="upload_notification_message">Neue Datei in das Dokument hochladen</string>
|
||||
<string name="upload_notification_error">Fehler beim Hochladen der neuen Datei</string>
|
||||
<string name="delete_file">Aktuelle Datei löschen</string>
|
||||
<string name="advanced_search">Erweiterte Suche</string>
|
||||
<string name="search">Suche</string>
|
||||
<string name="add_tags">Tags hinzufügen</string>
|
||||
<string name="creation_date">Erstellungsdatum</string>
|
||||
<string name="description">Beschreibung</string>
|
||||
<string name="title">Titel</string>
|
||||
<string name="simple_search">Einfache Suche</string>
|
||||
<string name="fulltext_search">Volltextsuche</string>
|
||||
<string name="creator">Ersteller</string>
|
||||
<string name="after_date">Nach Datum</string>
|
||||
<string name="before_date">Vor Datum</string>
|
||||
<string name="search_tags">Tags durchsuchen</string>
|
||||
<string name="all_languages">Alle Sprachen</string>
|
||||
<string name="toggle_informations">Informationen anzeigen</string>
|
||||
<string name="who_can_access">Wer kann darauf zugreifen?</string>
|
||||
<string name="comments">Kommentare</string>
|
||||
<string name="no_comments">Keine Kommentare</string>
|
||||
<string name="error_loading_comments">Fehler beim Laden von Kommentaren</string>
|
||||
<string name="send">Senden</string>
|
||||
<string name="add_comment">Kommentar hinzufügen</string>
|
||||
<string name="comment_add_failure">Fehler beim Hinzufügen des Kommentars</string>
|
||||
<string name="adding_comment">Füge Kommentar hinzu</string>
|
||||
<string name="comment_delete">Kommentar löschen</string>
|
||||
<string name="deleting_comment">Lösche Kommentar</string>
|
||||
<string name="error_deleting_comment">Fehler beim Löschen des Kommentars</string>
|
||||
<string name="export_pdf">PDF</string>
|
||||
<string name="download">Download</string>
|
||||
<string name="margin">Rand</string>
|
||||
<string name="fit_image_to_page">Bild an Seite anpassen</string>
|
||||
<string name="export_comments">Kommentare exportieren</string>
|
||||
<string name="export_metadata">Metadaten exportieren</string>
|
||||
<string name="mm">mm</string>
|
||||
<string name="download_file_title">Teedy Datei Export</string>
|
||||
<string name="download_document_title">Teedy Dokumentenexport</string>
|
||||
<string name="download_pdf_title">Teedy PDF Export</string>
|
||||
<string name="latest_activity">Letzte Aktivität</string>
|
||||
<string name="activity">Aktivitäten</string>
|
||||
<string name="email">E-Mail</string>
|
||||
<string name="storage_quota">Speicherbegrenzung</string>
|
||||
<string name="storage_display">%1$d/%2$d MB</string>
|
||||
<string name="validation_code">Validierungscode</string>
|
||||
<string name="shared">Geteilt</string>
|
||||
<string name="language">Sprache</string>
|
||||
<string name="coverage">Geltungsbereich</string>
|
||||
<string name="type">Typ</string>
|
||||
<string name="source">Quelle</string>
|
||||
<string name="format">Format</string>
|
||||
<string name="publisher">Verleger</string>
|
||||
<string name="identifier">Identifikator</string>
|
||||
<string name="subject">Thema</string>
|
||||
<string name="rights">Rechte</string>
|
||||
<string name="contributors">Mitwirkende</string>
|
||||
<string name="relations">Beziehungen</string>
|
||||
|
||||
<!-- Audit log -->
|
||||
<string name="auditlog_Acl">ACL</string>
|
||||
<string name="auditlog_Comment">Kommentar</string>
|
||||
<string name="auditlog_Document">Dokument</string>
|
||||
<string name="auditlog_File">Datei</string>
|
||||
<string name="auditlog_Group">Gruppe</string>
|
||||
<string name="auditlog_Route">Workflow</string>
|
||||
<string name="auditlog_RouteModel">Workflow-Muster</string>
|
||||
<string name="auditlog_Tag">Tag</string>
|
||||
<string name="auditlog_User">Benutzer</string>
|
||||
<string name="auditlog_Webhook">Webhook</string>
|
||||
<string name="auditlog_created">erstellt</string>
|
||||
<string name="auditlog_updated">aktualisiert</string>
|
||||
<string name="auditlog_deleted">gelöscht</string>
|
||||
|
||||
</resources>
|
159
docs-android/app/src/main/res/values-fr/strings.xml
Normal file
@ -0,0 +1,159 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<!-- Validation -->
|
||||
<string name="validate_error_email">Email invalide</string>
|
||||
<string name="validate_error_length_min">Trop court (min. %d)</string>
|
||||
<string name="validate_error_length_max">Trop long (max. %d)</string>
|
||||
<string name="validate_error_required">Requis</string>
|
||||
<string name="validate_error_alphanumeric">Seuls les lettres et les nombres sont autorisés</string>
|
||||
|
||||
<!-- App -->
|
||||
<string name="drawer_open">Ouvrir le menu de navigation</string>
|
||||
<string name="drawer_close">Fermer le menu de navigation</string>
|
||||
<string name="login_explain"><![CDATA[Pour commencer, vous devez télécharger et installer le serveur Teedy sur <a href="https://github.com/sismics/docs">github.com/sismics/docs</a> et entrer son URL ci-dessous]]></string>
|
||||
<string name="server">Serveur</string>
|
||||
<string name="username">Nom d\'utilisateur</string>
|
||||
<string name="password">Mot de passe</string>
|
||||
<string name="login">Connexion</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="cancel">Annuler</string>
|
||||
<string name="login_fail_title">Echec de la connexion</string>
|
||||
<string name="login_fail">Mauvais nom d\'utilisateur ou de mot de passe</string>
|
||||
<string name="network_error_title">Erreur réseau</string>
|
||||
<string name="network_error">Erreur réseau, veuillez vérifier votre connexion internet et l\'URL du serveur</string>
|
||||
<string name="invalid_url_title">URL invalide</string>
|
||||
<string name="invalid_url">Veuillez vérifier l\URL du serveur et réessayer</string>
|
||||
<string name="crash_toast_text">Une erreur s\'est produite, un rapport a été envoyé afin de corriger ce problème</string>
|
||||
<string name="created_date">Date création</string>
|
||||
<string name="download_file">Télécharger ce fichier</string>
|
||||
<string name="download_document">Télécharger</string>
|
||||
<string name="action_search">Rechercher dans les documents</string>
|
||||
<string name="all_documents">Tous les documents</string>
|
||||
<string name="shared_documents">Documents partagés</string>
|
||||
<string name="all_tags">Tous les tags</string>
|
||||
<string name="no_tags">Aucun tag</string>
|
||||
<string name="error_loading_tags">Erreur de chargement des tags</string>
|
||||
<string name="no_documents">Aucun document</string>
|
||||
<string name="error_loading_documents">Erreur de chargement des documents</string>
|
||||
<string name="no_files">Aucun fichier</string>
|
||||
<string name="error_loading_files">Erreur de chargement des fichiers</string>
|
||||
<string name="new_document">Nouveau document</string>
|
||||
<string name="share">Partage</string>
|
||||
<string name="close">Fermer</string>
|
||||
<string name="add">Ajouter</string>
|
||||
<string name="add_share_hint">Nom du partage (facultatif)</string>
|
||||
<string name="document_not_shared">Ce document n\'est pas partagé</string>
|
||||
<string name="delete_share">Supprimer ce partage</string>
|
||||
<string name="send_share">Envoi ce lien de partage</string>
|
||||
<string name="error_loading_shares">Erreur de chargement des partages</string>
|
||||
<string name="error_adding_share">Erreur lors de l\'ajout du partage</string>
|
||||
<string name="share_default_name">Lien de partage</string>
|
||||
<string name="error_deleting_share">Erreur lors de la suppression de ce partage</string>
|
||||
<string name="send_share_to">Envoi ce lien de partage à</string>
|
||||
<string name="upload_file">Aj. fichier</string>
|
||||
<string name="upload_from">Envoyer un fichier depuis</string>
|
||||
<string name="settings">Paramètres</string>
|
||||
<string name="logout">Déconnexion</string>
|
||||
<string name="version">Version</string>
|
||||
<string name="build">Build</string>
|
||||
<string name="pref_advanced_category">Paramètres avancés</string>
|
||||
<string name="pref_about_category">A propors</string>
|
||||
<string name="pref_github">GitHub</string>
|
||||
<string name="pref_issue">Rapporter un bug</string>
|
||||
<string name="pref_clear_cache_title">Vider le cache</string>
|
||||
<string name="pref_clear_cache_summary">Nettoyer les fichiers en cache</string>
|
||||
<string name="pref_clear_cache_success">Cache vidé</string>
|
||||
<string name="pref_clear_history_title">Vider l\'historique de recherche</string>
|
||||
<string name="pref_clear_history_summary">Supprimer les recherches récentes</string>
|
||||
<string name="pref_clear_history_success">Historique de recherche vidé</string>
|
||||
<string name="pref_cache_size">Taille du cache</string>
|
||||
<string name="save">Enregistrer</string>
|
||||
<string name="edit_document">Modifier</string>
|
||||
<string name="error_editing_document">Erreur réseau, veuillez réessayer</string>
|
||||
<string name="please_wait">Veuillez patienter</string>
|
||||
<string name="document_editing_message">Envoi des données</string>
|
||||
<string name="delete_document">Suppr.</string>
|
||||
<string name="delete_document_title">Supprimer le document</string>
|
||||
<string name="delete_document_message">Etes-vous sûr de vouloir supprimer ce document et tous les fichiers associés ?</string>
|
||||
<string name="document_delete_failure">Erreur réseau lors de la suppression de ce document</string>
|
||||
<string name="document_deleting_message">Suppression du document</string>
|
||||
<string name="delete_file_title">Supprimer le fichier</string>
|
||||
<string name="delete_file_message">Etes-vous sûr de vouloir supprimer ce fichier ?</string>
|
||||
<string name="file_delete_failure">Erreur réseau lors de la suppression du fichier</string>
|
||||
<string name="file_deleting_message">Suppression du fichier</string>
|
||||
<string name="error_reading_file">Erreur lors de la lecture du fichier</string>
|
||||
<string name="upload_notification_title">Teedy</string>
|
||||
<string name="upload_notification_message">Envoi du nouveau fichier</string>
|
||||
<string name="upload_notification_error">Erreur lors de l\'envoi du nouveau fichier</string>
|
||||
<string name="delete_file">Supprimer ce fichier</string>
|
||||
<string name="advanced_search">Recherche avancée</string>
|
||||
<string name="search">Rechercher</string>
|
||||
<string name="add_tags">Ajouter des tags</string>
|
||||
<string name="creation_date">Date de création</string>
|
||||
<string name="description">Description</string>
|
||||
<string name="title">Titre</string>
|
||||
<string name="simple_search">Recherche simple</string>
|
||||
<string name="fulltext_search">Recherche texte intégral</string>
|
||||
<string name="creator">Créateur</string>
|
||||
<string name="after_date">Après cette date</string>
|
||||
<string name="before_date">Avant cette date</string>
|
||||
<string name="search_tags">Rechercher dans les tags</string>
|
||||
<string name="all_languages">Toutes les langues</string>
|
||||
<string name="toggle_informations">Afficher/masquer les informations</string>
|
||||
<string name="who_can_access">Qui a accès</string>
|
||||
<string name="comments">Commentaires</string>
|
||||
<string name="no_comments">Aucun commentaire</string>
|
||||
<string name="error_loading_comments">Erreur de chargement des commentaires</string>
|
||||
<string name="send">Envoyer</string>
|
||||
<string name="add_comment">Ajouter un commentaire</string>
|
||||
<string name="comment_add_failure">Erreur lors de l\'ajout du commentaire</string>
|
||||
<string name="adding_comment">Ajout du commentaire</string>
|
||||
<string name="comment_delete">Supprimer le commentaire</string>
|
||||
<string name="deleting_comment">Suppression du commentaire</string>
|
||||
<string name="error_deleting_comment">Erreur lors de la suppression du commentaire</string>
|
||||
<string name="export_pdf">PDF</string>
|
||||
<string name="download">Télécharger</string>
|
||||
<string name="margin">Marge</string>
|
||||
<string name="fit_image_to_page">Ajuster les images à la page</string>
|
||||
<string name="export_comments">Exporter les commentaires</string>
|
||||
<string name="export_metadata">Exporter les métadonnées</string>
|
||||
<string name="mm">mm</string>
|
||||
<string name="download_file_title">Export de fichier Teedy</string>
|
||||
<string name="download_document_title">Export de document Teedy</string>
|
||||
<string name="download_pdf_title">Export PDF Teedy</string>
|
||||
<string name="latest_activity">Activité récente</string>
|
||||
<string name="activity">Activité</string>
|
||||
<string name="email">E-mail</string>
|
||||
<string name="storage_quota">Quota de stockage</string>
|
||||
<string name="storage_display">%1$d/%2$d Mo</string>
|
||||
<string name="validation_code">Code de validation</string>
|
||||
<string name="shared">Partagé</string>
|
||||
<string name="language">Langue</string>
|
||||
<string name="coverage">Couverture</string>
|
||||
<string name="type">Type</string>
|
||||
<string name="source">Source</string>
|
||||
<string name="format">Format</string>
|
||||
<string name="publisher">Editeur</string>
|
||||
<string name="identifier">Identifiant</string>
|
||||
<string name="subject">Sujet</string>
|
||||
<string name="rights">Droits</string>
|
||||
<string name="contributors">Contributeurs</string>
|
||||
<string name="relations">Relations</string>
|
||||
|
||||
<!-- Audit log -->
|
||||
<string name="auditlog_Acl">ACL</string>
|
||||
<string name="auditlog_Comment">Commentaire</string>
|
||||
<string name="auditlog_Document">Document</string>
|
||||
<string name="auditlog_File">Fichier</string>
|
||||
<string name="auditlog_Group">Groupe</string>
|
||||
<string name="auditlog_Route">Workflow</string>
|
||||
<string name="auditlog_RouteModel">Modèle de workflow</string>
|
||||
<string name="auditlog_Tag">Tag</string>
|
||||
<string name="auditlog_User">Utilisateur</string>
|
||||
<string name="auditlog_Webhook">Webhook</string>
|
||||
<string name="auditlog_created">créé</string>
|
||||
<string name="auditlog_updated">mis à jour</string>
|
||||
<string name="auditlog_deleted">supprimé</string>
|
||||
|
||||
</resources>
|
164
docs-android/app/src/main/res/values-pl/strings.xml
Normal file
@ -0,0 +1,164 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<!-- Validation -->
|
||||
<string name="validate_error_email">Nieprawidłowy email</string>
|
||||
<string name="validate_error_length_min">Za krótki (min. %d)</string>
|
||||
<string name="validate_error_length_max">Za długi (max. %d)</string>
|
||||
<string name="validate_error_required">Wymagany</string>
|
||||
<string name="validate_error_alphanumeric">Tylko litery i cyfry</string>
|
||||
|
||||
<!-- App -->
|
||||
<string name="app_name" translatable="false">Teedy</string>
|
||||
<string name="drawer_open">Otwórz szufladę nawigacji</string>
|
||||
<string name="drawer_close">Zamknij szufladę nawigacji</string>
|
||||
<string name="login_explain"><![CDATA[Aby rozpocząć, musisz pobrać i zainstalować serwer Teedy na <a href="https://github.com/sismics/docs">github.com/sismics/docs</a> i poniżej wprowadzić adres]]></string>
|
||||
<string name="server">Serwer</string>
|
||||
<string name="username">Użytkownik</string>
|
||||
<string name="password">Hasło</string>
|
||||
<string name="login">Zaloguj</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="cancel">Anuluj</string>
|
||||
<string name="login_fail_title">Błąd logowania</string>
|
||||
<string name="login_fail">Nieprawidłowa nazwa użytkownika lub hasło</string>
|
||||
<string name="network_error_title">Błąd sieci</string>
|
||||
<string name="network_error">Błąd sieci, sprawdź połączenie z interneterm oraz adres URL serwera</string>
|
||||
<string name="invalid_url_title">Nieprawidłowy adres URL</string>
|
||||
<string name="invalid_url">Sprawdź adres URL serwera i spróbuj ponownie</string>
|
||||
<string name="crash_toast_text">Wystąpiła awaria, wysłano raport w celu rozwiązania tego problemu</string>
|
||||
<string name="created_date">Data utworzenia</string>
|
||||
<string name="download_file">Pobierz bieżący plik</string>
|
||||
<string name="download_document">Pobierz</string>
|
||||
<string name="action_search">Znadź dokumenty</string>
|
||||
<string name="all_documents">Wszystkie dokumenty</string>
|
||||
<string name="shared_documents">Udostępnione dokumenty</string>
|
||||
<string name="all_tags">Wszystkie etykiety</string>
|
||||
<string name="no_tags">Brak etykiet</string>
|
||||
<string name="error_loading_tags">Błąd ładowania etykiet</string>
|
||||
<string name="no_documents">Brak dokumentów</string>
|
||||
<string name="error_loading_documents">Błąd ładowania dokumentów</string>
|
||||
<string name="no_files">Brak plików</string>
|
||||
<string name="error_loading_files">Błąd ładowania plików</string>
|
||||
<string name="new_document">Nowy dokument</string>
|
||||
<string name="share">Udostępnij</string>
|
||||
<string name="close">Zamknij</string>
|
||||
<string name="add">Dodaj</string>
|
||||
<string name="add_share_hint">Nazwa udostępnienia (opcjonalnie)</string>
|
||||
<string name="document_not_shared">Ten dokument nie jest obecnie udostępniony</string>
|
||||
<string name="delete_share">Usuń udostępnienie</string>
|
||||
<string name="send_share">Wyślij link udostępnienia</string>
|
||||
<string name="error_loading_shares">Błąd ładowania udostępnień</string>
|
||||
<string name="error_adding_share">Błąd dodawania udostępnienia</string>
|
||||
<string name="share_default_name">Udostępnij link</string>
|
||||
<string name="error_deleting_share">Błąd usuwania udostępnienia</string>
|
||||
<string name="send_share_to">Wyślij link udostępnienia do</string>
|
||||
<string name="upload_file">dodaj plik</string>
|
||||
<string name="upload_from">Przeslij plik z</string>
|
||||
<string name="settings">ustawienia</string>
|
||||
<string name="logout">Wyloguj</string>
|
||||
<string name="version">Wersja</string>
|
||||
<string name="build">Kompilacja</string>
|
||||
<string name="pref_advanced_category">Ustawienia zaawansowane</string>
|
||||
<string name="pref_about_category">O programie</string>
|
||||
<string name="pref_github">GitHub</string>
|
||||
<string name="pref_issue">Zgłoś błąd</string>
|
||||
<string name="pref_clear_cache_title">Wyczyść cache</string>
|
||||
<string name="pref_clear_cache_summary">Wyczyść podręczne pliki</string>
|
||||
<string name="pref_clear_cache_success">Cache wyczyszczony</string>
|
||||
<string name="pref_clear_history_title">Wyczyść historię wyszukiwania</string>
|
||||
<string name="pref_clear_history_summary">Opróżnij ostatnie sugestie wyszukiwania</string>
|
||||
<string name="pref_clear_history_success">Historia wyszukiwania wyczyszczona</string>
|
||||
<string name="pref_cache_size">Rozmiar cache</string>
|
||||
<string name="language_french" translatable="false">Francuski</string>
|
||||
<string name="language_english" translatable="false">Angielski</string>
|
||||
<string name="language_german" translatable="false">Niemiecki</string>
|
||||
<string name="language_polish" translatable="false">Polski</string>
|
||||
<string name="save">Zapisz</string>
|
||||
<string name="edit_document">Edytuj</string>
|
||||
<string name="error_editing_document">Błąd sieci, spróbuj ponownie</string>
|
||||
<string name="please_wait">Proszę czekać</string>
|
||||
<string name="document_editing_message">Wysyłam twoje dane</string>
|
||||
<string name="delete_document">Usuń</string>
|
||||
<string name="delete_document_title">Usuń dokument</string>
|
||||
<string name="delete_document_message">Naprawdę chcesz usunąć dokument i powiązane z nim pliki?</string>
|
||||
<string name="document_delete_failure">Błąd sieci w czasie usuwania tego dokumentu</string>
|
||||
<string name="document_deleting_message">Usuwanie dokumentu</string>
|
||||
<string name="delete_file_title">Usuń plik</string>
|
||||
<string name="delete_file_message">Naprawdę chcesz usunąć ten plik?</string>
|
||||
<string name="file_delete_failure">Błąd sieci w czasie usuwania bieżącego pliku</string>
|
||||
<string name="file_deleting_message">Usuwanie pliku</string>
|
||||
<string name="error_reading_file">Błąd podczas odczytu pliku</string>
|
||||
<string name="upload_notification_title">Teedy</string>
|
||||
<string name="upload_notification_message">Przesyłanie nowego pliku do dokumentu</string>
|
||||
<string name="upload_notification_error">Błąd przsyłania nowego pliku</string>
|
||||
<string name="delete_file">Usuń bieżący plik</string>
|
||||
<string name="advanced_search">Zaawansowane wyszukiwanie</string>
|
||||
<string name="search">Znajdź</string>
|
||||
<string name="add_tags">Dodaj eytkiety</string>
|
||||
<string name="creation_date">Data utworzenia</string>
|
||||
<string name="description">Opis</string>
|
||||
<string name="title">Tytuł</string>
|
||||
<string name="simple_search">Proste wyszukiwanie</string>
|
||||
<string name="fulltext_search">Wyszukiwanie pełnotekstowe</string>
|
||||
<string name="creator">Autor</string>
|
||||
<string name="after_date">Po dacie</string>
|
||||
<string name="before_date">Przed datą</string>
|
||||
<string name="search_tags">Znajdź etykiety</string>
|
||||
<string name="all_languages">Wszystkie języki</string>
|
||||
<string name="toggle_informations">Przełącz informacje</string>
|
||||
<string name="who_can_access">Kto ma dostęp</string>
|
||||
<string name="comments">Komentarze</string>
|
||||
<string name="no_comments">Brak komentarzy</string>
|
||||
<string name="error_loading_comments">Błąd ładowania komentarzy</string>
|
||||
<string name="send">Wyślij</string>
|
||||
<string name="add_comment">Dodaj komentarz</string>
|
||||
<string name="comment_add_failure">Błąd dodawania komentarza</string>
|
||||
<string name="adding_comment">Dodawanie komentarza</string>
|
||||
<string name="comment_delete">Usuń komentarz</string>
|
||||
<string name="deleting_comment">Usuwanie komentarza</string>
|
||||
<string name="error_deleting_comment">Błąd usuwania komentarza</string>
|
||||
<string name="export_pdf">PDF</string>
|
||||
<string name="download">Pobierz</string>
|
||||
<string name="margin">Margines</string>
|
||||
<string name="fit_image_to_page">Dostosuj obraz do strony</string>
|
||||
<string name="export_comments">Eksport komentarzy</string>
|
||||
<string name="export_metadata">Eksport metadanych</string>
|
||||
<string name="mm">mm</string>
|
||||
<string name="download_file_title">Eksport plików Teedy</string>
|
||||
<string name="download_document_title">Eksport dokumentu Teedy</string>
|
||||
<string name="download_pdf_title">Eksport Teedy jako PDF</string>
|
||||
<string name="latest_activity">Ostatnie aktywności</string>
|
||||
<string name="activity">Aktywności</string>
|
||||
<string name="email">E-mail</string>
|
||||
<string name="storage_quota">Limit magazynu</string>
|
||||
<string name="storage_display">%1$d/%2$d MB</string>
|
||||
<string name="validation_code">Kod weryfikujący</string>
|
||||
<string name="shared">Udostępnienie</string>
|
||||
<string name="language">Język</string>
|
||||
<string name="coverage">Zakres</string>
|
||||
<string name="type">Rodzaj</string>
|
||||
<string name="source">Źródło</string>
|
||||
<string name="format">Format</string>
|
||||
<string name="publisher">Udostępniający</string>
|
||||
<string name="identifier">Identifikator</string>
|
||||
<string name="subject">temat</string>
|
||||
<string name="rights">Prawa</string>
|
||||
<string name="contributors">Współtwórcy</string>
|
||||
<string name="relations">Powiązania</string>
|
||||
|
||||
<!-- Audit log -->
|
||||
<string name="auditlog_Acl">ACL</string>
|
||||
<string name="auditlog_Comment">Komentarz</string>
|
||||
<string name="auditlog_Document">Dokument</string>
|
||||
<string name="auditlog_File">Plik</string>
|
||||
<string name="auditlog_Group">Grupa</string>
|
||||
<string name="auditlog_Route">Przepływ</string>
|
||||
<string name="auditlog_RouteModel">Model przepływu</string>
|
||||
<string name="auditlog_Tag">Etykieta</string>
|
||||
<string name="auditlog_User">Użytkownik</string>
|
||||
<string name="auditlog_Webhook">Webhook</string>
|
||||
<string name="auditlog_created">utworzony</string>
|
||||
<string name="auditlog_updated">zaktualizowany</string>
|
||||
<string name="auditlog_deleted">usunięty</string>
|
||||
|
||||
</resources>
|
@ -9,10 +9,10 @@
|
||||
<string name="validate_error_alphanumeric">Only letters and numbers</string>
|
||||
|
||||
<!-- App -->
|
||||
<string name="app_name">Sismics Docs</string>
|
||||
<string name="app_name" translatable="false">Teedy</string>
|
||||
<string name="drawer_open">Open navigation drawer</string>
|
||||
<string name="drawer_close">Close navigation drawer</string>
|
||||
<string name="login_explain"><![CDATA[To start, you must download and install Sismics Docs Server on <a href="http://www.sismics.com/docs">www.sismics.com/docs</a> and enter your server URL below]]></string>
|
||||
<string name="login_explain"><![CDATA[To start, you must download and install Teedy Server on <a href="https://github.com/sismics/docs">github.com/sismics/docs</a> and enter its below]]></string>
|
||||
<string name="server">Server</string>
|
||||
<string name="username">Username</string>
|
||||
<string name="password">Password</string>
|
||||
@ -46,7 +46,7 @@
|
||||
<string name="add_share_hint">Name the share (optional)</string>
|
||||
<string name="document_not_shared">This document is not currently shared</string>
|
||||
<string name="delete_share">Delete this share</string>
|
||||
<string name="send_share">Send this share</string>
|
||||
<string name="send_share">Send this share link</string>
|
||||
<string name="error_loading_shares">Error loading shares</string>
|
||||
<string name="error_adding_share">Error adding share</string>
|
||||
<string name="share_default_name">Share link</string>
|
||||
@ -69,9 +69,10 @@
|
||||
<string name="pref_clear_history_summary">Wipe the recent search suggestions</string>
|
||||
<string name="pref_clear_history_success">Search history cleared</string>
|
||||
<string name="pref_cache_size">Cache size</string>
|
||||
<string name="language_french">French</string>
|
||||
<string name="language_english">English</string>
|
||||
<string name="language_japanese">Japanese</string>
|
||||
<string name="language_french" translatable="false">Français</string>
|
||||
<string name="language_english" translatable="false">English</string>
|
||||
<string name="language_german" translatable="false">Deutsch</string>
|
||||
<string name="language_polish" translatable="false">Polski</string>
|
||||
<string name="save">Save</string>
|
||||
<string name="edit_document">Edit</string>
|
||||
<string name="error_editing_document">Network error, please try again</string>
|
||||
@ -87,7 +88,7 @@
|
||||
<string name="file_delete_failure">Network error while deleting the current file</string>
|
||||
<string name="file_deleting_message">Deleting file</string>
|
||||
<string name="error_reading_file">Error while reading the file</string>
|
||||
<string name="upload_notification_title">Sismics Docs</string>
|
||||
<string name="upload_notification_title">Teedy</string>
|
||||
<string name="upload_notification_message">Uploading the new file to the document</string>
|
||||
<string name="upload_notification_error">Error uploading the new file</string>
|
||||
<string name="delete_file">Delete current file</string>
|
||||
@ -123,14 +124,41 @@
|
||||
<string name="export_comments">Export comments</string>
|
||||
<string name="export_metadata">Export metadata</string>
|
||||
<string name="mm">mm</string>
|
||||
<string name="download_file_title">Sismics Docs file export</string>
|
||||
<string name="download_document_title">Sismics Docs document export</string>
|
||||
<string name="download_pdf_title">Sismics Docs PDF export</string>
|
||||
<string name="download_file_title">Teedy file export</string>
|
||||
<string name="download_document_title">Teedy document export</string>
|
||||
<string name="download_pdf_title">Teedy PDF export</string>
|
||||
<string name="latest_activity">Latest activity</string>
|
||||
<string name="activity">Activity</string>
|
||||
<string name="email">E-mail</string>
|
||||
<string name="storage_quota">Storage quota</string>
|
||||
<string name="storage_display">%1$d/%2$d MB</string>
|
||||
<string name="validation_code">Validation code</string>
|
||||
<string name="shared">Shared</string>
|
||||
<string name="language">Language</string>
|
||||
<string name="coverage">Coverage</string>
|
||||
<string name="type">Type</string>
|
||||
<string name="source">Source</string>
|
||||
<string name="format">Format</string>
|
||||
<string name="publisher">Publisher</string>
|
||||
<string name="identifier">Identifier</string>
|
||||
<string name="subject">Subject</string>
|
||||
<string name="rights">Rights</string>
|
||||
<string name="contributors">Contributors</string>
|
||||
<string name="relations">Relations</string>
|
||||
|
||||
<!-- Audit log -->
|
||||
<string name="auditlog_Acl">ACL</string>
|
||||
<string name="auditlog_Comment">Comment</string>
|
||||
<string name="auditlog_Document">Document</string>
|
||||
<string name="auditlog_File">File</string>
|
||||
<string name="auditlog_Group">Group</string>
|
||||
<string name="auditlog_Route">Workflow</string>
|
||||
<string name="auditlog_RouteModel">Workflow model</string>
|
||||
<string name="auditlog_Tag">Tag</string>
|
||||
<string name="auditlog_User">User</string>
|
||||
<string name="auditlog_Webhook">Webhook</string>
|
||||
<string name="auditlog_created">created</string>
|
||||
<string name="auditlog_updated">updated</string>
|
||||
<string name="auditlog_deleted">deleted</string>
|
||||
|
||||
</resources>
|
||||
|
@ -1,12 +1,20 @@
|
||||
<resources>
|
||||
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<style name="AppTheme" parent="Theme.AppCompat.DayNight">
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
</style>
|
||||
|
||||
<style name="AppThemeDark" parent="Theme.AppCompat.NoActionBar">
|
||||
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.DayNight.NoActionBar">
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
</style>
|
||||
|
||||
<style name="AppThemeDark" parent="Theme.AppCompat.DayNight.NoActionBar">
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
|
@ -12,6 +12,8 @@
|
||||
# Default value: -Xmx10248m -XX:MaxPermSize=256m
|
||||
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
|
||||
org.gradle.jvmargs=-Xmx3072m
|
||||
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
|
@ -1,6 +1,6 @@
|
||||
#Sat Jan 16 19:15:13 CET 2016
|
||||
#Tue May 07 11:49:13 CEST 2019
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
|
||||
|
@ -5,8 +5,8 @@
|
||||
<parent>
|
||||
<groupId>com.sismics.docs</groupId>
|
||||
<artifactId>docs-parent</artifactId>
|
||||
<version>1.4</version>
|
||||
<relativePath>..</relativePath>
|
||||
<version>1.12-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@ -17,20 +17,10 @@
|
||||
<dependencies>
|
||||
<!-- Persistence layer dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<groupId>org.hibernate.orm</groupId>
|
||||
<artifactId>hibernate-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-entitymanager</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-c3p0</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Other external dependencies -->
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
@ -48,8 +38,28 @@
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-email</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.freemarker</groupId>
|
||||
<artifactId>freemarker</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>jakarta.json</groupId>
|
||||
<artifactId>jakarta.json-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jsoup</groupId>
|
||||
<artifactId>jsoup</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@ -73,8 +83,8 @@
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mindrot</groupId>
|
||||
<artifactId>jbcrypt</artifactId>
|
||||
<groupId>at.favre.lib</groupId>
|
||||
<artifactId>bcrypt</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@ -92,6 +102,31 @@
|
||||
<artifactId>lucene-queryparser</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.lucene</groupId>
|
||||
<artifactId>lucene-suggest</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.lucene</groupId>
|
||||
<artifactId>lucene-highlighter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.directory.api</groupId>
|
||||
<artifactId>api-ldap-client-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.directory.api</groupId>
|
||||
<artifactId>api-ldap-codec-standalone</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Only there to read old index and rebuild them -->
|
||||
<dependency>
|
||||
<groupId>org.apache.lucene</groupId>
|
||||
@ -115,33 +150,39 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>fr.opensagres.xdocreport</groupId>
|
||||
<artifactId>org.odftoolkit.odfdom.converter.pdf</artifactId>
|
||||
<artifactId>fr.opensagres.odfdom.converter.pdf</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>fr.opensagres.xdocreport</groupId>
|
||||
<artifactId>org.apache.poi.xwpf.converter.pdf</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.java.dev.jna</groupId>
|
||||
<artifactId>jna</artifactId>
|
||||
<artifactId>fr.opensagres.poi.xwpf.converter.pdf</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- ImageIO plugins -->
|
||||
<dependency>
|
||||
<groupId>com.levigo.jbig2</groupId>
|
||||
<artifactId>levigo-jbig2-imageio</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-jpeg</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-tiff</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.jai-imageio</groupId>
|
||||
<artifactId>jai-imageio-core</artifactId>
|
||||
<artifactId>jai-imageio-jpeg2000</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.levigo.jbig2</groupId>
|
||||
<artifactId>levigo-jbig2-imageio</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Only for connecting to PostgreSQL database -->
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Test dependencies -->
|
||||
@ -184,20 +225,6 @@
|
||||
<profile>
|
||||
<id>prod</id>
|
||||
</profile>
|
||||
|
||||
<!-- Demo profile -->
|
||||
<profile>
|
||||
<id>demo</id>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/demo/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<build>
|
||||
|
@ -0,0 +1,18 @@
|
||||
package com.sismics.docs.core.constant;
|
||||
|
||||
/**
|
||||
* ACL type.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public enum AclType {
|
||||
/**
|
||||
* User created ACL.
|
||||
*/
|
||||
USER,
|
||||
|
||||
/**
|
||||
* ACL created by the routing module.
|
||||
*/
|
||||
ROUTING
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.sismics.docs.core.constant;
|
||||
|
||||
/**
|
||||
* Action types.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public enum ActionType {
|
||||
/**
|
||||
* Add a tag.
|
||||
*/
|
||||
ADD_TAG,
|
||||
|
||||
/**
|
||||
* Remove a tag.
|
||||
*/
|
||||
REMOVE_TAG,
|
||||
|
||||
/**
|
||||
* Process files.
|
||||
*/
|
||||
PROCESS_FILES
|
||||
}
|
@ -13,5 +13,57 @@ public enum ConfigType {
|
||||
/**
|
||||
* Theme configuration.
|
||||
*/
|
||||
THEME
|
||||
THEME,
|
||||
|
||||
/**
|
||||
* Guest login.
|
||||
*/
|
||||
GUEST_LOGIN,
|
||||
|
||||
/**
|
||||
* OCR enabled.
|
||||
*/
|
||||
OCR_ENABLED,
|
||||
|
||||
/**
|
||||
* Default language.
|
||||
*/
|
||||
DEFAULT_LANGUAGE,
|
||||
|
||||
/**
|
||||
* SMTP server configuration.
|
||||
*/
|
||||
SMTP_HOSTNAME,
|
||||
SMTP_PORT,
|
||||
SMTP_FROM,
|
||||
SMTP_USERNAME,
|
||||
SMTP_PASSWORD,
|
||||
|
||||
/**
|
||||
* Inbox scanning configuration.
|
||||
*/
|
||||
INBOX_ENABLED,
|
||||
INBOX_HOSTNAME,
|
||||
INBOX_PORT,
|
||||
INBOX_STARTTLS,
|
||||
INBOX_USERNAME,
|
||||
INBOX_PASSWORD,
|
||||
INBOX_FOLDER,
|
||||
INBOX_TAG,
|
||||
INBOX_AUTOMATIC_TAGS,
|
||||
INBOX_DELETE_IMPORTED,
|
||||
|
||||
/**
|
||||
* LDAP connection.
|
||||
*/
|
||||
LDAP_ENABLED,
|
||||
LDAP_HOST,
|
||||
LDAP_PORT,
|
||||
LDAP_USESSL,
|
||||
LDAP_ADMIN_DN,
|
||||
LDAP_ADMIN_PASSWORD,
|
||||
LDAP_BASE_DN,
|
||||
LDAP_FILTER,
|
||||
LDAP_DEFAULT_EMAIL,
|
||||
LDAP_DEFAULT_STORAGE
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
package com.sismics.docs.core.constant;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Application constants.
|
||||
*
|
||||
@ -18,17 +18,22 @@ public class Constants {
|
||||
/**
|
||||
* Administrator's default password ("admin").
|
||||
*/
|
||||
public static final String DEFAULT_ADMIN_PASSWORD = "$2a$05$6Ny3TjrW3aVAL1or2SlcR.fhuDgPKp5jp.P9fBXwVNePgeLqb4i3C";
|
||||
public static final String DEFAULT_ADMIN_PASSWORD = "$2y$10$xg0EEKVUehutDI1m6qQhVeFz7SMQMl1jQzjf2KkVsR2c7aV2vyyjK";
|
||||
|
||||
/**
|
||||
* RAM Lucene directory storage.
|
||||
* Administrator's default email.
|
||||
*/
|
||||
public static final String LUCENE_DIRECTORY_STORAGE_RAM = "RAM";
|
||||
public static final String DEFAULT_ADMIN_EMAIL = "admin@localhost";
|
||||
|
||||
/**
|
||||
* File Lucene directory storage.
|
||||
* Bcrypt default work factor
|
||||
*/
|
||||
public static final String LUCENE_DIRECTORY_STORAGE_FILE = "FILE";
|
||||
public static final int DEFAULT_BCRYPT_WORK = 10;
|
||||
|
||||
/**
|
||||
* Guest user ID.
|
||||
*/
|
||||
public static final String GUEST_USER_ID = "guest";
|
||||
|
||||
/**
|
||||
* Default generic user role.
|
||||
@ -38,5 +43,63 @@ public class Constants {
|
||||
/**
|
||||
* Supported document languages.
|
||||
*/
|
||||
public static final List<String> SUPPORTED_LANGUAGES = Lists.newArrayList("eng", "fra", "jpn");
|
||||
public static final List<String> SUPPORTED_LANGUAGES = Lists.newArrayList("eng", "fra", "ita", "deu", "spa", "por", "pol", "rus", "ukr", "ara", "hin", "chi_sim", "chi_tra", "jpn", "tha", "kor", "nld", "tur", "heb", "hun", "fin", "swe", "lav", "dan", "nor", "vie", "ces", "sqi");
|
||||
|
||||
/**
|
||||
* Base URL environment variable.
|
||||
*/
|
||||
public static final String BASE_URL_ENV = "DOCS_BASE_URL";
|
||||
|
||||
/**
|
||||
* Default language environment variable.
|
||||
*/
|
||||
public static final String DEFAULT_LANGUAGE_ENV = "DOCS_DEFAULT_LANGUAGE";
|
||||
|
||||
/**
|
||||
* SMTP configuration environment variables.
|
||||
*/
|
||||
public static final String SMTP_HOSTNAME_ENV = "DOCS_SMTP_HOSTNAME";
|
||||
public static final String SMTP_PORT_ENV = "DOCS_SMTP_PORT";
|
||||
public static final String SMTP_USERNAME_ENV = "DOCS_SMTP_USERNAME";
|
||||
public static final String SMTP_PASSWORD_ENV = "DOCS_SMTP_PASSWORD";
|
||||
|
||||
/**
|
||||
* Global quota environment variable.
|
||||
*/
|
||||
public static final String GLOBAL_QUOTA_ENV = "DOCS_GLOBAL_QUOTA";
|
||||
|
||||
/**
|
||||
* Initial admin password environment variable.
|
||||
*/
|
||||
public static final String ADMIN_PASSWORD_INIT_ENV = "DOCS_ADMIN_PASSWORD_INIT";
|
||||
|
||||
/**
|
||||
* Initial admin password environment variable.
|
||||
*/
|
||||
public static final String ADMIN_EMAIL_INIT_ENV = "DOCS_ADMIN_EMAIL_INIT";
|
||||
|
||||
/**
|
||||
* Work factor to be used by Bcrypt
|
||||
*/
|
||||
public static final String BCRYPT_WORK_ENV = "DOCS_BCRYPT_WORK";
|
||||
|
||||
/**
|
||||
* Expiration time of the password recovery in hours.
|
||||
*/
|
||||
public static final int PASSWORD_RECOVERY_EXPIRATION_HOUR = 2;
|
||||
|
||||
/**
|
||||
* Email template for password recovery.
|
||||
*/
|
||||
public static final String EMAIL_TEMPLATE_PASSWORD_RECOVERY = "password_recovery";
|
||||
|
||||
/**
|
||||
* Email template for route step validate.
|
||||
*/
|
||||
public static final String EMAIL_TEMPLATE_ROUTE_STEP_VALIDATE = "route_step_validate";
|
||||
|
||||
/**
|
||||
* mm per inch.
|
||||
*/
|
||||
public static float MM_PER_INCH = 1 / (10 * 2.54f) * 72f;
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
package com.sismics.docs.core.constant;
|
||||
|
||||
/**
|
||||
* Metadata type.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public enum MetadataType {
|
||||
STRING,
|
||||
INTEGER,
|
||||
FLOAT,
|
||||
DATE,
|
||||
BOOLEAN
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.sismics.docs.core.constant;
|
||||
|
||||
/**
|
||||
* Route step transitions.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public enum RouteStepTransition {
|
||||
/**
|
||||
* Route step approved.
|
||||
*/
|
||||
APPROVED,
|
||||
|
||||
/**
|
||||
* Route step rejected.
|
||||
*/
|
||||
REJECTED,
|
||||
|
||||
/**
|
||||
* Route step validated.
|
||||
*/
|
||||
VALIDATED
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.sismics.docs.core.constant;
|
||||
|
||||
/**
|
||||
* Route step types.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public enum RouteStepType {
|
||||
/**
|
||||
* Approval step with 2 choices.
|
||||
*/
|
||||
APPROVE,
|
||||
|
||||
/**
|
||||
* Simple validation step, no possible choice.
|
||||
*/
|
||||
VALIDATE
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.sismics.docs.core.constant;
|
||||
|
||||
/**
|
||||
* Webhook events.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public enum WebhookEvent {
|
||||
DOCUMENT_CREATED,
|
||||
DOCUMENT_UPDATED,
|
||||
DOCUMENT_DELETED,
|
||||
FILE_CREATED,
|
||||
FILE_UPDATED,
|
||||
FILE_DELETED
|
||||
}
|
@ -1,21 +1,22 @@
|
||||
package com.sismics.docs.core.dao.jpa;
|
||||
package com.sismics.docs.core.dao;
|
||||
|
||||
import com.sismics.docs.core.constant.AclTargetType;
|
||||
import com.sismics.docs.core.constant.AclType;
|
||||
import com.sismics.docs.core.constant.AuditLogType;
|
||||
import com.sismics.docs.core.constant.PermType;
|
||||
import com.sismics.docs.core.dao.dto.AclDto;
|
||||
import com.sismics.docs.core.model.jpa.Acl;
|
||||
import com.sismics.docs.core.util.AuditLogUtil;
|
||||
import com.sismics.docs.core.util.SecurityUtil;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.Query;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import com.sismics.docs.core.constant.AclTargetType;
|
||||
import com.sismics.docs.core.constant.AuditLogType;
|
||||
import com.sismics.docs.core.constant.PermType;
|
||||
import com.sismics.docs.core.dao.jpa.dto.AclDto;
|
||||
import com.sismics.docs.core.model.jpa.Acl;
|
||||
import com.sismics.docs.core.util.AuditLogUtil;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
|
||||
/**
|
||||
* ACL DAO.
|
||||
*
|
||||
@ -65,19 +66,25 @@ public class AclDao {
|
||||
* @return ACL DTO list
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<AclDto> getBySourceId(String sourceId) {
|
||||
public List<AclDto> getBySourceId(String sourceId, AclType type) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
StringBuilder sb = new StringBuilder("select a.ACL_ID_C, a.ACL_PERM_C, a.ACL_TARGETID_C, ");
|
||||
sb.append(" u.USE_USERNAME_C, s.SHA_ID_C, s.SHA_NAME_C, g.GRP_NAME_C ");
|
||||
sb.append(" from T_ACL a ");
|
||||
sb.append(" left join T_USER u on u.USE_ID_C = a.ACL_TARGETID_C ");
|
||||
sb.append(" left join T_SHARE s on s.SHA_ID_C = a.ACL_TARGETID_C ");
|
||||
sb.append(" left join T_GROUP g on g.GRP_ID_C = a.ACL_TARGETID_C ");
|
||||
sb.append(" where a.ACL_DELETEDATE_D is null and a.ACL_SOURCEID_C = :sourceId ");
|
||||
StringBuilder sb = new StringBuilder("select a.ACL_ID_C, a.ACL_PERM_C, a.ACL_TARGETID_C, ")
|
||||
.append(" u.USE_USERNAME_C, s.SHA_ID_C, s.SHA_NAME_C, g.GRP_NAME_C ")
|
||||
.append(" from T_ACL a ")
|
||||
.append(" left join T_USER u on u.USE_ID_C = a.ACL_TARGETID_C ")
|
||||
.append(" left join T_SHARE s on s.SHA_ID_C = a.ACL_TARGETID_C ")
|
||||
.append(" left join T_GROUP g on g.GRP_ID_C = a.ACL_TARGETID_C ")
|
||||
.append(" where a.ACL_DELETEDATE_D is null and a.ACL_SOURCEID_C = :sourceId ");
|
||||
if (type != null) {
|
||||
sb.append(" and a.ACL_TYPE_C = :type");
|
||||
}
|
||||
|
||||
// Perform the query
|
||||
Query q = em.createNativeQuery(sb.toString());
|
||||
q.setParameter("sourceId", sourceId);
|
||||
if (type != null) {
|
||||
q.setParameter("type", type.name());
|
||||
}
|
||||
List<Object[]> l = q.getResultList();
|
||||
|
||||
// Assemble results
|
||||
@ -118,12 +125,20 @@ public class AclDao {
|
||||
* @return True if the document is accessible
|
||||
*/
|
||||
public boolean checkPermission(String sourceId, PermType perm, List<String> targetIdList) {
|
||||
if (SecurityUtil.skipAclCheck(targetIdList)) {
|
||||
return true;
|
||||
}
|
||||
if (targetIdList.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
StringBuilder sb = new StringBuilder("select a.ACL_ID_C from T_ACL a ");
|
||||
sb.append(" where a.ACL_TARGETID_C in (:targetIdList) and a.ACL_SOURCEID_C = :sourceId and a.ACL_PERM_C = :perm and a.ACL_DELETEDATE_D is null ");
|
||||
sb.append(" union all ");
|
||||
sb.append(" select a.ACL_ID_C from T_ACL a, T_DOCUMENT_TAG dt ");
|
||||
sb.append(" where a.ACL_SOURCEID_C = dt.DOT_IDTAG_C and dt.DOT_IDDOCUMENT_C = :sourceId and dt.DOT_DELETEDATE_D is null ");
|
||||
sb.append(" select a.ACL_ID_C from T_ACL a, T_DOCUMENT_TAG dt, T_DOCUMENT d ");
|
||||
sb.append(" where a.ACL_SOURCEID_C = dt.DOT_IDTAG_C and dt.DOT_IDDOCUMENT_C = d.DOC_ID_C and dt.DOT_DELETEDATE_D is null ");
|
||||
sb.append(" and d.DOC_ID_C = :sourceId and d.DOC_DELETEDATE_D is null ");
|
||||
sb.append(" and a.ACL_TARGETID_C in (:targetIdList) and a.ACL_PERM_C = :perm and a.ACL_DELETEDATE_D is null ");
|
||||
Query q = em.createNativeQuery(sb.toString());
|
||||
q.setParameter("sourceId", sourceId);
|
||||
@ -141,26 +156,29 @@ public class AclDao {
|
||||
* @param perm Permission
|
||||
* @param targetId Target ID
|
||||
* @param userId User ID
|
||||
* @param type Type
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void delete(String sourceId, PermType perm, String targetId, String userId) {
|
||||
public void delete(String sourceId, PermType perm, String targetId, String userId, AclType type) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
|
||||
// Create audit log
|
||||
Query q = em.createQuery("from Acl a where a.sourceId = :sourceId and a.perm = :perm and a.targetId = :targetId");
|
||||
Query q = em.createQuery("from Acl a where a.sourceId = :sourceId and a.perm = :perm and a.targetId = :targetId and a.type = :type and a.deleteDate is null");
|
||||
q.setParameter("sourceId", sourceId);
|
||||
q.setParameter("perm", perm);
|
||||
q.setParameter("targetId", targetId);
|
||||
q.setParameter("type", type);
|
||||
List<Acl> aclList = q.getResultList();
|
||||
for (Acl acl : aclList) {
|
||||
AuditLogUtil.create(acl, AuditLogType.DELETE, userId);
|
||||
}
|
||||
|
||||
// Soft delete the ACLs
|
||||
q = em.createQuery("update Acl a set a.deleteDate = :dateNow where a.sourceId = :sourceId and a.perm = :perm and a.targetId = :targetId");
|
||||
q = em.createQuery("update Acl a set a.deleteDate = :dateNow where a.sourceId = :sourceId and a.perm = :perm and a.targetId = :targetId and a.type = :type and a.deleteDate is null");
|
||||
q.setParameter("sourceId", sourceId);
|
||||
q.setParameter("perm", perm);
|
||||
q.setParameter("targetId", targetId);
|
||||
q.setParameter("type", type);
|
||||
q.setParameter("dateNow", new Date());
|
||||
q.executeUpdate();
|
||||
}
|
@ -1,20 +1,10 @@
|
||||
package com.sismics.docs.core.dao.jpa;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
package com.sismics.docs.core.dao;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.sismics.docs.core.constant.AuditLogType;
|
||||
import com.sismics.docs.core.dao.jpa.criteria.AuditLogCriteria;
|
||||
import com.sismics.docs.core.dao.jpa.dto.AuditLogDto;
|
||||
import com.sismics.docs.core.dao.criteria.AuditLogCriteria;
|
||||
import com.sismics.docs.core.dao.dto.AuditLogDto;
|
||||
import com.sismics.docs.core.model.jpa.AuditLog;
|
||||
import com.sismics.docs.core.util.jpa.PaginatedList;
|
||||
import com.sismics.docs.core.util.jpa.PaginatedLists;
|
||||
@ -22,6 +12,10 @@ import com.sismics.docs.core.util.jpa.QueryParam;
|
||||
import com.sismics.docs.core.util.jpa.SortCriteria;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Audit log DAO.
|
||||
*
|
||||
@ -33,7 +27,6 @@ public class AuditLogDao {
|
||||
*
|
||||
* @param auditLog Audit log
|
||||
* @return New ID
|
||||
* @throws Exception
|
||||
*/
|
||||
public String create(AuditLog auditLog) {
|
||||
// Create the UUID
|
||||
@ -53,10 +46,9 @@ public class AuditLogDao {
|
||||
* @param paginatedList List of audit logs (updated by side effects)
|
||||
* @param criteria Search criteria
|
||||
* @param sortCriteria Sort criteria
|
||||
* @return List of audit logs
|
||||
*/
|
||||
public void findByCriteria(PaginatedList<AuditLogDto> paginatedList, AuditLogCriteria criteria, SortCriteria sortCriteria) {
|
||||
Map<String, Object> parameterMap = new HashMap<String, Object>();
|
||||
Map<String, Object> parameterMap = new HashMap<>();
|
||||
|
||||
StringBuilder baseQuery = new StringBuilder("select l.LOG_ID_C c0, l.LOG_CREATEDATE_D c1, u.USE_USERNAME_C c2, l.LOG_IDENTITY_C c3, l.LOG_CLASSENTITY_C c4, l.LOG_TYPE_C c5, l.LOG_MESSAGE_C c6 from T_AUDIT_LOG l ");
|
||||
baseQuery.append(" join T_USER u on l.LOG_IDUSER_C = u.USE_ID_C ");
|
||||
@ -69,22 +61,28 @@ public class AuditLogDao {
|
||||
queries.add(baseQuery + " where l.LOG_IDENTITY_C in (select f.FIL_ID_C from T_FILE f where f.FIL_IDDOC_C = :documentId) ");
|
||||
queries.add(baseQuery + " where l.LOG_IDENTITY_C in (select c.COM_ID_C from T_COMMENT c where c.COM_IDDOC_C = :documentId) ");
|
||||
queries.add(baseQuery + " where l.LOG_IDENTITY_C in (select a.ACL_ID_C from T_ACL a where a.ACL_SOURCEID_C = :documentId) ");
|
||||
queries.add(baseQuery + " where l.LOG_IDENTITY_C in (select r.RTE_ID_C from T_ROUTE r where r.RTE_IDDOCUMENT_C = :documentId) ");
|
||||
parameterMap.put("documentId", criteria.getDocumentId());
|
||||
}
|
||||
|
||||
if (criteria.getUserId() != null) {
|
||||
if (criteria.isAdmin()) {
|
||||
// For admin users, display all logs except ACL logs
|
||||
queries.add(baseQuery + " where l.LOG_CLASSENTITY_C != 'Acl' ");
|
||||
} else {
|
||||
// Get all logs originating from the user, not necessarly on owned items
|
||||
// Filter out ACL logs
|
||||
queries.add(baseQuery + " where l.LOG_IDUSER_C = :userId and l.LOG_CLASSENTITY_C != 'Acl' ");
|
||||
parameterMap.put("userId", criteria.getUserId());
|
||||
}
|
||||
}
|
||||
|
||||
// Perform the search
|
||||
QueryParam queryParam = new QueryParam(Joiner.on(" union ").join(queries), parameterMap);
|
||||
List<Object[]> l = PaginatedLists.executePaginatedQuery(paginatedList, queryParam, sortCriteria);
|
||||
|
||||
// Assemble results
|
||||
List<AuditLogDto> auditLogDtoList = new ArrayList<AuditLogDto>();
|
||||
List<AuditLogDto> auditLogDtoList = new ArrayList<>();
|
||||
for (Object[] o : l) {
|
||||
int i = 0;
|
||||
AuditLogDto auditLogDto = new AuditLogDto();
|
@ -1,11 +1,11 @@
|
||||
package com.sismics.docs.core.dao.jpa;
|
||||
package com.sismics.docs.core.dao;
|
||||
|
||||
import com.sismics.docs.core.model.jpa.AuthenticationToken;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Query;
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.Query;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
@ -86,7 +86,7 @@ public class AuthenticationTokenDao {
|
||||
*/
|
||||
public void updateLastConnectionDate(String id) {
|
||||
StringBuilder sb = new StringBuilder("update T_AUTHENTICATION_TOKEN ato ");
|
||||
sb.append(" set ato.AUT_LASTCONNECTIONDATE_D = :currentDate ");
|
||||
sb.append(" set AUT_LASTCONNECTIONDATE_D = :currentDate ");
|
||||
sb.append(" where ato.AUT_ID_C = :id");
|
||||
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
@ -1,21 +1,20 @@
|
||||
package com.sismics.docs.core.dao.jpa;
|
||||
package com.sismics.docs.core.dao;
|
||||
|
||||
import com.sismics.docs.core.constant.AuditLogType;
|
||||
import com.sismics.docs.core.dao.dto.CommentDto;
|
||||
import com.sismics.docs.core.model.jpa.Comment;
|
||||
import com.sismics.docs.core.util.AuditLogUtil;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.NoResultException;
|
||||
import jakarta.persistence.Query;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.NoResultException;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import com.sismics.docs.core.constant.AuditLogType;
|
||||
import com.sismics.docs.core.dao.jpa.dto.CommentDto;
|
||||
import com.sismics.docs.core.model.jpa.Comment;
|
||||
import com.sismics.docs.core.util.AuditLogUtil;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
|
||||
/**
|
||||
* Comment DAO.
|
||||
*
|
||||
@ -28,7 +27,6 @@ public class CommentDao {
|
||||
* @param comment Comment
|
||||
* @param userId User ID
|
||||
* @return New ID
|
||||
* @throws Exception
|
||||
*/
|
||||
public String create(Comment comment, String userId) {
|
||||
// Create the UUID
|
||||
@ -100,7 +98,7 @@ public class CommentDao {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Object[]> l = q.getResultList();
|
||||
|
||||
List<CommentDto> commentDtoList = new ArrayList<CommentDto>();
|
||||
List<CommentDto> commentDtoList = new ArrayList<>();
|
||||
for (Object[] o : l) {
|
||||
int i = 0;
|
||||
CommentDto commentDto = new CommentDto();
|
||||
@ -108,7 +106,7 @@ public class CommentDao {
|
||||
commentDto.setContent((String) o[i++]);
|
||||
commentDto.setCreateTimestamp(((Timestamp) o[i++]).getTime());
|
||||
commentDto.setCreatorName((String) o[i++]);
|
||||
commentDto.setCreatorEmail((String) o[i++]);
|
||||
commentDto.setCreatorEmail((String) o[i]);
|
||||
commentDtoList.add(commentDto);
|
||||
}
|
||||
return commentDtoList;
|
@ -1,11 +1,11 @@
|
||||
package com.sismics.docs.core.dao.jpa;
|
||||
package com.sismics.docs.core.dao;
|
||||
|
||||
import com.sismics.docs.core.constant.ConfigType;
|
||||
import com.sismics.docs.core.model.jpa.Config;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.NoResultException;
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.NoResultException;
|
||||
|
||||
/**
|
||||
* Configuration parameter DAO.
|
@ -1,16 +1,15 @@
|
||||
package com.sismics.docs.core.dao.jpa;
|
||||
package com.sismics.docs.core.dao;
|
||||
|
||||
import com.sismics.docs.core.dao.dto.ContributorDto;
|
||||
import com.sismics.docs.core.model.jpa.Contributor;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.Query;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import com.sismics.docs.core.dao.jpa.dto.ContributorDto;
|
||||
import com.sismics.docs.core.model.jpa.Contributor;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
|
||||
/**
|
||||
* Contributor DAO.
|
||||
*
|
||||
@ -57,7 +56,7 @@ public class ContributorDao {
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<ContributorDto> getByDocumentId(String documentId) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
StringBuilder sb = new StringBuilder("select u.USE_USERNAME_C, u.USE_EMAIL_C from T_CONTRIBUTOR c ");
|
||||
StringBuilder sb = new StringBuilder("select distinct u.USE_USERNAME_C, u.USE_EMAIL_C from T_CONTRIBUTOR c ");
|
||||
sb.append(" join T_USER u on u.USE_ID_C = c.CTR_IDUSER_C ");
|
||||
sb.append(" where c.CTR_IDDOC_C = :documentId ");
|
||||
Query q = em.createNativeQuery(sb.toString());
|
@ -0,0 +1,252 @@
|
||||
package com.sismics.docs.core.dao;
|
||||
|
||||
import com.sismics.docs.core.constant.AuditLogType;
|
||||
import com.sismics.docs.core.constant.PermType;
|
||||
import com.sismics.docs.core.dao.dto.DocumentDto;
|
||||
import com.sismics.docs.core.model.jpa.Document;
|
||||
import com.sismics.docs.core.util.AuditLogUtil;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.NoResultException;
|
||||
import jakarta.persistence.Query;
|
||||
import jakarta.persistence.TypedQuery;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Document DAO.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public class DocumentDao {
|
||||
/**
|
||||
* Creates a new document.
|
||||
*
|
||||
* @param document Document
|
||||
* @param userId User ID
|
||||
* @return New ID
|
||||
*/
|
||||
public String create(Document document, String userId) {
|
||||
// Create the UUID
|
||||
document.setId(UUID.randomUUID().toString());
|
||||
document.setUpdateDate(new Date());
|
||||
|
||||
// Create the document
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
em.persist(document);
|
||||
|
||||
// Create audit log
|
||||
AuditLogUtil.create(document, AuditLogType.CREATE, userId);
|
||||
|
||||
return document.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of all active documents.
|
||||
*
|
||||
* @param offset Offset
|
||||
* @param limit Limit
|
||||
* @return List of documents
|
||||
*/
|
||||
public List<Document> findAll(int offset, int limit) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
TypedQuery<Document> q = em.createQuery("select d from Document d where d.deleteDate is null", Document.class);
|
||||
q.setFirstResult(offset);
|
||||
q.setMaxResults(limit);
|
||||
return q.getResultList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of all active documents from a user.
|
||||
*
|
||||
* @param userId User ID
|
||||
* @return List of documents
|
||||
*/
|
||||
public List<Document> findByUserId(String userId) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
TypedQuery<Document> q = em.createQuery("select d from Document d where d.userId = :userId and d.deleteDate is null", Document.class);
|
||||
q.setParameter("userId", userId);
|
||||
return q.getResultList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an active document with permission checking.
|
||||
*
|
||||
* @param id Document ID
|
||||
* @param perm Permission needed
|
||||
* @param targetIdList List of targets
|
||||
* @return Document
|
||||
*/
|
||||
public DocumentDto getDocument(String id, PermType perm, List<String> targetIdList) {
|
||||
AclDao aclDao = new AclDao();
|
||||
if (!aclDao.checkPermission(id, perm, targetIdList)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
StringBuilder sb = new StringBuilder("select distinct d.DOC_ID_C, d.DOC_TITLE_C, d.DOC_DESCRIPTION_C, d.DOC_SUBJECT_C, d.DOC_IDENTIFIER_C, d.DOC_PUBLISHER_C, d.DOC_FORMAT_C, d.DOC_SOURCE_C, d.DOC_TYPE_C, d.DOC_COVERAGE_C, d.DOC_RIGHTS_C, d.DOC_CREATEDATE_D, d.DOC_UPDATEDATE_D, d.DOC_LANGUAGE_C, d.DOC_IDFILE_C,");
|
||||
sb.append(" (select count(s.SHA_ID_C) from T_SHARE s, T_ACL ac where ac.ACL_SOURCEID_C = d.DOC_ID_C and ac.ACL_TARGETID_C = s.SHA_ID_C and ac.ACL_DELETEDATE_D is null and s.SHA_DELETEDATE_D is null) shareCount, ");
|
||||
sb.append(" (select count(f.FIL_ID_C) from T_FILE f where f.FIL_DELETEDATE_D is null and f.FIL_IDDOC_C = d.DOC_ID_C) fileCount, ");
|
||||
sb.append(" u.USE_USERNAME_C ");
|
||||
sb.append(" from T_DOCUMENT d ");
|
||||
sb.append(" join T_USER u on d.DOC_IDUSER_C = u.USE_ID_C ");
|
||||
sb.append(" where d.DOC_ID_C = :id and d.DOC_DELETEDATE_D is null ");
|
||||
|
||||
Query q = em.createNativeQuery(sb.toString());
|
||||
q.setParameter("id", id);
|
||||
|
||||
Object[] o;
|
||||
try {
|
||||
o = (Object[]) q.getSingleResult();
|
||||
} catch (NoResultException e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
DocumentDto documentDto = new DocumentDto();
|
||||
int i = 0;
|
||||
documentDto.setId((String) o[i++]);
|
||||
documentDto.setTitle((String) o[i++]);
|
||||
documentDto.setDescription((String) o[i++]);
|
||||
documentDto.setSubject((String) o[i++]);
|
||||
documentDto.setIdentifier((String) o[i++]);
|
||||
documentDto.setPublisher((String) o[i++]);
|
||||
documentDto.setFormat((String) o[i++]);
|
||||
documentDto.setSource((String) o[i++]);
|
||||
documentDto.setType((String) o[i++]);
|
||||
documentDto.setCoverage((String) o[i++]);
|
||||
documentDto.setRights((String) o[i++]);
|
||||
documentDto.setCreateTimestamp(((Timestamp) o[i++]).getTime());
|
||||
documentDto.setUpdateTimestamp(((Timestamp) o[i++]).getTime());
|
||||
documentDto.setLanguage((String) o[i++]);
|
||||
documentDto.setFileId((String) o[i++]);
|
||||
documentDto.setShared(((Number) o[i++]).intValue() > 0);
|
||||
documentDto.setFileCount(((Number) o[i++]).intValue());
|
||||
documentDto.setCreator((String) o[i]);
|
||||
return documentDto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a document.
|
||||
*
|
||||
* @param id Document ID
|
||||
* @param userId User ID
|
||||
*/
|
||||
public void delete(String id, String userId) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
|
||||
// Get the document
|
||||
TypedQuery<Document> dq = em.createQuery("select d from Document d where d.id = :id and d.deleteDate is null", Document.class);
|
||||
dq.setParameter("id", id);
|
||||
Document documentDb = dq.getSingleResult();
|
||||
|
||||
// Delete the document
|
||||
Date dateNow = new Date();
|
||||
documentDb.setDeleteDate(dateNow);
|
||||
|
||||
// Delete linked data
|
||||
Query q = em.createQuery("update File f set f.deleteDate = :dateNow where f.documentId = :documentId and f.deleteDate is null");
|
||||
q.setParameter("documentId", id);
|
||||
q.setParameter("dateNow", dateNow);
|
||||
q.executeUpdate();
|
||||
|
||||
q = em.createQuery("update Acl a set a.deleteDate = :dateNow where a.sourceId = :documentId and a.deleteDate is null");
|
||||
q.setParameter("documentId", id);
|
||||
q.setParameter("dateNow", dateNow);
|
||||
q.executeUpdate();
|
||||
|
||||
q = em.createQuery("update DocumentTag dt set dt.deleteDate = :dateNow where dt.documentId = :documentId and dt.deleteDate is not null");
|
||||
q.setParameter("documentId", id);
|
||||
q.setParameter("dateNow", dateNow);
|
||||
q.executeUpdate();
|
||||
|
||||
q = em.createQuery("update Relation r set r.deleteDate = :dateNow where (r.fromDocumentId = :documentId or r.toDocumentId = :documentId) and r.deleteDate is not null");
|
||||
q.setParameter("documentId", id);
|
||||
q.setParameter("dateNow", dateNow);
|
||||
q.executeUpdate();
|
||||
|
||||
// Create audit log
|
||||
AuditLogUtil.create(documentDb, AuditLogType.DELETE, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an active document by its ID.
|
||||
*
|
||||
* @param id Document ID
|
||||
* @return Document
|
||||
*/
|
||||
public Document getById(String id) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
TypedQuery<Document> q = em.createQuery("select d from Document d where d.id = :id and d.deleteDate is null", Document.class);
|
||||
q.setParameter("id", id);
|
||||
try {
|
||||
return q.getSingleResult();
|
||||
} catch (NoResultException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a document and log the action.
|
||||
*
|
||||
* @param document Document to update
|
||||
* @param userId User ID
|
||||
* @return Updated document
|
||||
*/
|
||||
public Document update(Document document, String userId) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
|
||||
// Get the document
|
||||
TypedQuery<Document> q = em.createQuery("select d from Document d where d.id = :id and d.deleteDate is null", Document.class);
|
||||
q.setParameter("id", document.getId());
|
||||
Document documentDb = q.getSingleResult();
|
||||
|
||||
// Update the document
|
||||
documentDb.setTitle(document.getTitle());
|
||||
documentDb.setDescription(document.getDescription());
|
||||
documentDb.setSubject(document.getSubject());
|
||||
documentDb.setIdentifier(document.getIdentifier());
|
||||
documentDb.setPublisher(document.getPublisher());
|
||||
documentDb.setFormat(document.getFormat());
|
||||
documentDb.setSource(document.getSource());
|
||||
documentDb.setType(document.getType());
|
||||
documentDb.setCoverage(document.getCoverage());
|
||||
documentDb.setRights(document.getRights());
|
||||
documentDb.setCreateDate(document.getCreateDate());
|
||||
documentDb.setLanguage(document.getLanguage());
|
||||
documentDb.setFileId(document.getFileId());
|
||||
documentDb.setUpdateDate(new Date());
|
||||
|
||||
// Create audit log
|
||||
AuditLogUtil.create(documentDb, AuditLogType.UPDATE, userId);
|
||||
|
||||
return documentDb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the file ID on a document.
|
||||
*
|
||||
* @param document Document
|
||||
*/
|
||||
public void updateFileId(Document document) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
Query query = em.createNativeQuery("update T_DOCUMENT d set DOC_IDFILE_C = :fileId, DOC_UPDATEDATE_D = :updateDate where d.DOC_ID_C = :id");
|
||||
query.setParameter("updateDate", new Date());
|
||||
query.setParameter("fileId", document.getFileId());
|
||||
query.setParameter("id", document.getId());
|
||||
query.executeUpdate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of documents.
|
||||
*
|
||||
* @return Number of documents
|
||||
*/
|
||||
public long getDocumentCount() {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
Query query = em.createNativeQuery("select count(d.DOC_ID_C) from T_DOCUMENT d where d.DOC_DELETEDATE_D is null");
|
||||
return ((Number) query.getSingleResult()).longValue();
|
||||
}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
package com.sismics.docs.core.dao;
|
||||
|
||||
import com.sismics.docs.core.constant.MetadataType;
|
||||
import com.sismics.docs.core.dao.dto.DocumentMetadataDto;
|
||||
import com.sismics.docs.core.model.jpa.DocumentMetadata;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.Query;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Document metadata DAO.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public class DocumentMetadataDao {
|
||||
/**
|
||||
* Creates a new document metadata.
|
||||
*
|
||||
* @param documentMetadata Document metadata
|
||||
* @return New ID
|
||||
*/
|
||||
public String create(DocumentMetadata documentMetadata) {
|
||||
// Create the UUID
|
||||
documentMetadata.setId(UUID.randomUUID().toString());
|
||||
|
||||
// Create the document metadata
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
em.persist(documentMetadata);
|
||||
|
||||
return documentMetadata.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a document metadata.
|
||||
*
|
||||
* @param documentMetadata Document metadata
|
||||
* @return Updated document metadata
|
||||
*/
|
||||
public DocumentMetadata update(DocumentMetadata documentMetadata) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
|
||||
// Get the document metadata
|
||||
Query q = em.createQuery("select u from DocumentMetadata u where u.id = :id");
|
||||
q.setParameter("id", documentMetadata.getId());
|
||||
DocumentMetadata documentMetadataDb = (DocumentMetadata) q.getSingleResult();
|
||||
|
||||
// Update the document metadata
|
||||
documentMetadataDb.setValue(documentMetadata.getValue());
|
||||
|
||||
return documentMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of all metadata values on a document.
|
||||
*
|
||||
* @param documentId Document ID
|
||||
* @return List of metadata
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<DocumentMetadataDto> getByDocumentId(String documentId) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
StringBuilder sb = new StringBuilder("select dm.DME_ID_C, dm.DME_IDDOCUMENT_C, dm.DME_IDMETADATA_C, dm.DME_VALUE_C, m.MET_TYPE_C");
|
||||
sb.append(" from T_DOCUMENT_METADATA dm, T_METADATA m ");
|
||||
sb.append(" where dm.DME_IDMETADATA_C = m.MET_ID_C and dm.DME_IDDOCUMENT_C = :documentId and m.MET_DELETEDATE_D is null");
|
||||
|
||||
// Perform the search
|
||||
Query q = em.createNativeQuery(sb.toString());
|
||||
q.setParameter("documentId", documentId);
|
||||
List<Object[]> l = q.getResultList();
|
||||
|
||||
// Assemble results
|
||||
List<DocumentMetadataDto> dtoList = new ArrayList<>();
|
||||
for (Object[] o : l) {
|
||||
int i = 0;
|
||||
DocumentMetadataDto dto = new DocumentMetadataDto();
|
||||
dto.setId((String) o[i++]);
|
||||
dto.setDocumentId((String) o[i++]);
|
||||
dto.setMetadataId((String) o[i++]);
|
||||
dto.setValue((String) o[i++]);
|
||||
dto.setType(MetadataType.valueOf((String) o[i]));
|
||||
dtoList.add(dto);
|
||||
}
|
||||
return dtoList;
|
||||
}
|
||||
}
|
257
docs-core/src/main/java/com/sismics/docs/core/dao/FileDao.java
Normal file
@ -0,0 +1,257 @@
|
||||
package com.sismics.docs.core.dao;
|
||||
|
||||
import com.sismics.docs.core.constant.AuditLogType;
|
||||
import com.sismics.docs.core.model.jpa.File;
|
||||
import com.sismics.docs.core.util.AuditLogUtil;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.NoResultException;
|
||||
import jakarta.persistence.Query;
|
||||
import jakarta.persistence.TypedQuery;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* File DAO.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public class FileDao {
|
||||
/**
|
||||
* Creates a new file.
|
||||
*
|
||||
* @param file File
|
||||
* @param userId User ID
|
||||
* @return New ID
|
||||
*/
|
||||
public String create(File file, String userId) {
|
||||
// Create the UUID
|
||||
file.setId(UUID.randomUUID().toString());
|
||||
|
||||
// Create the file
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
file.setCreateDate(new Date());
|
||||
em.persist(file);
|
||||
|
||||
// Create audit log
|
||||
AuditLogUtil.create(file, AuditLogType.CREATE, userId);
|
||||
|
||||
return file.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of all files.
|
||||
*
|
||||
* @param offset Offset
|
||||
* @param limit Limit
|
||||
* @return List of files
|
||||
*/
|
||||
public List<File> findAll(int offset, int limit) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
TypedQuery<File> q = em.createQuery("select f from File f where f.deleteDate is null", File.class);
|
||||
q.setFirstResult(offset);
|
||||
q.setMaxResults(limit);
|
||||
return q.getResultList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of all files from a user.
|
||||
*
|
||||
* @param userId User ID
|
||||
* @return List of files
|
||||
*/
|
||||
public List<File> findByUserId(String userId) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
TypedQuery<File> q = em.createQuery("select f from File f where f.userId = :userId and f.deleteDate is null", File.class);
|
||||
q.setParameter("userId", userId);
|
||||
return q.getResultList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of active files.
|
||||
*
|
||||
* @param ids Files IDs
|
||||
* @return List of files
|
||||
*/
|
||||
public List<File> getFiles(List<String> ids) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
TypedQuery<File> q = em.createQuery("select f from File f where f.id in :ids and f.deleteDate is null", File.class);
|
||||
q.setParameter("ids", ids);
|
||||
return q.getResultList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an active file or null.
|
||||
*
|
||||
* @param id File ID
|
||||
* @return File
|
||||
*/
|
||||
public File getFile(String id) {
|
||||
List<File> files = getFiles(List.of(id));
|
||||
if (files.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
return files.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an active file.
|
||||
*
|
||||
* @param id File ID
|
||||
* @param userId User ID
|
||||
* @return File
|
||||
*/
|
||||
public File getFile(String id, String userId) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
TypedQuery<File> q = em.createQuery("select f from File f where f.id = :id and f.userId = :userId and f.deleteDate is null", File.class);
|
||||
q.setParameter("id", id);
|
||||
q.setParameter("userId", userId);
|
||||
try {
|
||||
return q.getSingleResult();
|
||||
} catch (NoResultException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a file.
|
||||
*
|
||||
* @param id File ID
|
||||
* @param userId User ID
|
||||
*/
|
||||
public void delete(String id, String userId) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
|
||||
// Get the file
|
||||
TypedQuery<File> q = em.createQuery("select f from File f where f.id = :id and f.deleteDate is null", File.class);
|
||||
q.setParameter("id", id);
|
||||
File fileDb = q.getSingleResult();
|
||||
|
||||
// Delete the file
|
||||
Date dateNow = new Date();
|
||||
fileDb.setDeleteDate(dateNow);
|
||||
|
||||
// Create audit log
|
||||
AuditLogUtil.create(fileDb, AuditLogType.DELETE, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a file.
|
||||
*
|
||||
* @param file File to update
|
||||
* @return Updated file
|
||||
*/
|
||||
public File update(File file) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
|
||||
// Get the file
|
||||
TypedQuery<File> q = em.createQuery("select f from File f where f.id = :id and f.deleteDate is null", File.class);
|
||||
q.setParameter("id", file.getId());
|
||||
File fileDb = q.getSingleResult();
|
||||
|
||||
// Update the file
|
||||
fileDb.setDocumentId(file.getDocumentId());
|
||||
fileDb.setName(file.getName());
|
||||
fileDb.setContent(file.getContent());
|
||||
fileDb.setOrder(file.getOrder());
|
||||
fileDb.setMimeType(file.getMimeType());
|
||||
fileDb.setVersionId(file.getVersionId());
|
||||
fileDb.setLatestVersion(file.isLatestVersion());
|
||||
fileDb.setSize(file.getSize());
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a file by its ID.
|
||||
*
|
||||
* @param id File ID
|
||||
* @return File
|
||||
*/
|
||||
public File getActiveById(String id) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
TypedQuery<File> q = em.createQuery("select f from File f where f.id = :id and f.deleteDate is null", File.class);
|
||||
q.setParameter("id", id);
|
||||
try {
|
||||
return q.getSingleResult();
|
||||
} catch (NoResultException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get files by document ID or all orphan files of a user.
|
||||
*
|
||||
* @param userId User ID
|
||||
* @param documentId Document ID
|
||||
* @return List of files
|
||||
*/
|
||||
public List<File> getByDocumentId(String userId, String documentId) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
if (documentId == null) {
|
||||
TypedQuery<File> q = em.createQuery("select f from File f where f.documentId is null and f.deleteDate is null and f.latestVersion = true and f.userId = :userId order by f.createDate asc", File.class);
|
||||
q.setParameter("userId", userId);
|
||||
return q.getResultList();
|
||||
} else {
|
||||
return getByDocumentsIds(Collections.singleton(documentId));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get files by documents IDs.
|
||||
*
|
||||
* @param documentIds Documents IDs
|
||||
* @return List of files
|
||||
*/
|
||||
public List<File> getByDocumentsIds(Iterable<String> documentIds) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
TypedQuery<File> q = em.createQuery("select f from File f where f.documentId in :documentIds and f.latestVersion = true and f.deleteDate is null order by f.order asc", File.class);
|
||||
q.setParameter("documentIds", documentIds);
|
||||
return q.getResultList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get files count by documents IDs.
|
||||
*
|
||||
* @param documentIds Documents IDs
|
||||
* @return the number of files per document id
|
||||
*/
|
||||
public Map<String, Long> countByDocumentsIds(Iterable<String> documentIds) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
Query q = em.createQuery("select f.documentId, count(*) from File f where f.documentId in :documentIds and f.latestVersion = true and f.deleteDate is null group by (f.documentId)");
|
||||
q.setParameter("documentIds", documentIds);
|
||||
Map<String, Long> result = new HashMap<>();
|
||||
q.getResultList().forEach(o -> {
|
||||
Object[] resultLine = (Object[]) o;
|
||||
result.put((String) resultLine[0], (Long) resultLine[1]);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all files from a version.
|
||||
*
|
||||
* @param versionId Version ID
|
||||
* @return List of files
|
||||
*/
|
||||
public List<File> getByVersionId(String versionId) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
TypedQuery<File> q = em.createQuery("select f from File f where f.versionId = :versionId and f.deleteDate is null order by f.order asc", File.class);
|
||||
q.setParameter("versionId", versionId);
|
||||
return q.getResultList();
|
||||
}
|
||||
|
||||
public List<File> getFilesWithUnknownSize(int limit) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
TypedQuery<File> q = em.createQuery("select f from File f where f.size = :size and f.deleteDate is null order by f.order asc", File.class);
|
||||
q.setParameter("size", File.UNKNOWN_SIZE);
|
||||
q.setMaxResults(limit);
|
||||
return q.getResultList();
|
||||
}
|
||||
}
|
@ -1,22 +1,9 @@
|
||||
package com.sismics.docs.core.dao.jpa;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.NoResultException;
|
||||
import javax.persistence.Query;
|
||||
package com.sismics.docs.core.dao;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.sismics.docs.core.constant.AuditLogType;
|
||||
import com.sismics.docs.core.dao.jpa.criteria.GroupCriteria;
|
||||
import com.sismics.docs.core.dao.jpa.dto.GroupDto;
|
||||
import com.sismics.docs.core.dao.criteria.GroupCriteria;
|
||||
import com.sismics.docs.core.dao.dto.GroupDto;
|
||||
import com.sismics.docs.core.model.jpa.Group;
|
||||
import com.sismics.docs.core.model.jpa.UserGroup;
|
||||
import com.sismics.docs.core.util.AuditLogUtil;
|
||||
@ -25,6 +12,11 @@ import com.sismics.docs.core.util.jpa.QueryUtil;
|
||||
import com.sismics.docs.core.util.jpa.SortCriteria;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.NoResultException;
|
||||
import jakarta.persistence.Query;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Group DAO.
|
||||
*
|
||||
@ -192,10 +184,8 @@ public class GroupDao {
|
||||
|
||||
criteriaList.add("g.GRP_DELETEDATE_D is null");
|
||||
|
||||
if (!criteriaList.isEmpty()) {
|
||||
sb.append(" where ");
|
||||
sb.append(Joiner.on(" and ").join(criteriaList));
|
||||
}
|
||||
|
||||
// Perform the search
|
||||
QueryParam queryParam = QueryUtil.getSortedQueryParam(new QueryParam(sb.toString(), parameterMap), sortCriteria);
|
||||
@ -266,16 +256,16 @@ public class GroupDao {
|
||||
// Get the group
|
||||
Query q = em.createQuery("select g from Group g where g.id = :id and g.deleteDate is null");
|
||||
q.setParameter("id", group.getId());
|
||||
Group groupFromDb = (Group) q.getSingleResult();
|
||||
Group groupDb = (Group) q.getSingleResult();
|
||||
|
||||
// Update the group
|
||||
groupFromDb.setName(group.getName());
|
||||
groupFromDb.setParentId(group.getParentId());
|
||||
groupDb.setName(group.getName());
|
||||
groupDb.setParentId(group.getParentId());
|
||||
|
||||
// Create audit log
|
||||
AuditLogUtil.create(groupFromDb, AuditLogType.UPDATE, userId);
|
||||
AuditLogUtil.create(groupDb, AuditLogType.UPDATE, userId);
|
||||
|
||||
return groupFromDb;
|
||||
return groupDb;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,146 @@
|
||||
package com.sismics.docs.core.dao;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.sismics.docs.core.constant.AuditLogType;
|
||||
import com.sismics.docs.core.constant.MetadataType;
|
||||
import com.sismics.docs.core.dao.criteria.MetadataCriteria;
|
||||
import com.sismics.docs.core.dao.dto.MetadataDto;
|
||||
import com.sismics.docs.core.model.jpa.Metadata;
|
||||
import com.sismics.docs.core.util.AuditLogUtil;
|
||||
import com.sismics.docs.core.util.jpa.QueryParam;
|
||||
import com.sismics.docs.core.util.jpa.QueryUtil;
|
||||
import com.sismics.docs.core.util.jpa.SortCriteria;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.NoResultException;
|
||||
import jakarta.persistence.Query;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Metadata DAO.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public class MetadataDao {
|
||||
/**
|
||||
* Creates a new metdata.
|
||||
*
|
||||
* @param metadata Metadata
|
||||
* @param userId User ID
|
||||
* @return New ID
|
||||
*/
|
||||
public String create(Metadata metadata, String userId) {
|
||||
// Create the UUID
|
||||
metadata.setId(UUID.randomUUID().toString());
|
||||
|
||||
// Create the metadata
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
em.persist(metadata);
|
||||
|
||||
// Create audit log
|
||||
AuditLogUtil.create(metadata, AuditLogType.CREATE, userId);
|
||||
|
||||
return metadata.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a metadata.
|
||||
*
|
||||
* @param metadata Metadata to update
|
||||
* @param userId User ID
|
||||
* @return Updated metadata
|
||||
*/
|
||||
public Metadata update(Metadata metadata, String userId) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
|
||||
// Get the metadata
|
||||
Query q = em.createQuery("select r from Metadata r where r.id = :id and r.deleteDate is null");
|
||||
q.setParameter("id", metadata.getId());
|
||||
Metadata metadataDb = (Metadata) q.getSingleResult();
|
||||
|
||||
// Update the metadata
|
||||
metadataDb.setName(metadata.getName());
|
||||
|
||||
// Create audit log
|
||||
AuditLogUtil.create(metadataDb, AuditLogType.UPDATE, userId);
|
||||
|
||||
return metadataDb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an active metadata by its ID.
|
||||
*
|
||||
* @param id Metadata ID
|
||||
* @return Metadata
|
||||
*/
|
||||
public Metadata getActiveById(String id) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
try {
|
||||
Query q = em.createQuery("select r from Metadata r where r.id = :id and r.deleteDate is null");
|
||||
q.setParameter("id", id);
|
||||
return (Metadata) q.getSingleResult();
|
||||
} catch (NoResultException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a metadata.
|
||||
*
|
||||
* @param id Metadata ID
|
||||
* @param userId User ID
|
||||
*/
|
||||
public void delete(String id, String userId) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
|
||||
// Get the metadata
|
||||
Query q = em.createQuery("select r from Metadata r where r.id = :id and r.deleteDate is null");
|
||||
q.setParameter("id", id);
|
||||
Metadata metadataDb = (Metadata) q.getSingleResult();
|
||||
|
||||
// Delete the metadata
|
||||
Date dateNow = new Date();
|
||||
metadataDb.setDeleteDate(dateNow);
|
||||
|
||||
// Create audit log
|
||||
AuditLogUtil.create(metadataDb, AuditLogType.DELETE, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of all metadata.
|
||||
*
|
||||
* @param criteria Search criteria
|
||||
* @param sortCriteria Sort criteria
|
||||
* @return List of metadata
|
||||
*/
|
||||
public List<MetadataDto> findByCriteria(MetadataCriteria criteria, SortCriteria sortCriteria) {
|
||||
Map<String, Object> parameterMap = new HashMap<>();
|
||||
List<String> criteriaList = new ArrayList<>();
|
||||
|
||||
StringBuilder sb = new StringBuilder("select m.MET_ID_C c0, m.MET_NAME_C c1, m.MET_TYPE_C c2");
|
||||
sb.append(" from T_METADATA m ");
|
||||
|
||||
criteriaList.add("m.MET_DELETEDATE_D is null");
|
||||
|
||||
sb.append(" where ");
|
||||
sb.append(Joiner.on(" and ").join(criteriaList));
|
||||
|
||||
// Perform the search
|
||||
QueryParam queryParam = QueryUtil.getSortedQueryParam(new QueryParam(sb.toString(), parameterMap), sortCriteria);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Object[]> l = QueryUtil.getNativeQuery(queryParam).getResultList();
|
||||
|
||||
// Assemble results
|
||||
List<MetadataDto> dtoList = new ArrayList<>();
|
||||
for (Object[] o : l) {
|
||||
int i = 0;
|
||||
MetadataDto dto = new MetadataDto();
|
||||
dto.setId((String) o[i++]);
|
||||
dto.setName((String) o[i++]);
|
||||
dto.setType(MetadataType.valueOf((String) o[i]));
|
||||
dtoList.add(dto);
|
||||
}
|
||||
return dtoList;
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package com.sismics.docs.core.dao;
|
||||
|
||||
import com.sismics.docs.core.constant.Constants;
|
||||
import com.sismics.docs.core.model.jpa.PasswordRecovery;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DurationFieldType;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.NoResultException;
|
||||
import jakarta.persistence.Query;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Password recovery DAO.
|
||||
*
|
||||
* @author jtremeaux
|
||||
*/
|
||||
public class PasswordRecoveryDao {
|
||||
/**
|
||||
* Create a new password recovery request.
|
||||
*
|
||||
* @param passwordRecovery Password recovery
|
||||
* @return Unique identifier
|
||||
*/
|
||||
public String create(PasswordRecovery passwordRecovery) {
|
||||
passwordRecovery.setId(UUID.randomUUID().toString());
|
||||
passwordRecovery.setCreateDate(new Date());
|
||||
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
em.persist(passwordRecovery);
|
||||
|
||||
return passwordRecovery.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Search an active password recovery by unique identifier.
|
||||
*
|
||||
* @param id Unique identifier
|
||||
* @return Password recovery
|
||||
*/
|
||||
public PasswordRecovery getActiveById(String id) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
try {
|
||||
Query q = em.createQuery("select r from PasswordRecovery r where r.id = :id and r.createDate > :createDateMin and r.deleteDate is null");
|
||||
q.setParameter("id", id);
|
||||
q.setParameter("createDateMin", new DateTime().withFieldAdded(DurationFieldType.hours(), -1 * Constants.PASSWORD_RECOVERY_EXPIRATION_HOUR).toDate());
|
||||
return (PasswordRecovery) q.getSingleResult();
|
||||
} catch (NoResultException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes active password recovery by username.
|
||||
*
|
||||
* @param username Username
|
||||
*/
|
||||
public void deleteActiveByLogin(String username) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
Query q = em.createQuery("update PasswordRecovery r set r.deleteDate = :deleteDate where r.username = :username and r.createDate > :createDateMin and r.deleteDate is null");
|
||||
q.setParameter("username", username);
|
||||
q.setParameter("deleteDate", new Date());
|
||||
q.setParameter("createDateMin", new DateTime().withFieldAdded(DurationFieldType.hours(), -1 * Constants.PASSWORD_RECOVERY_EXPIRATION_HOUR).toDate());
|
||||
q.executeUpdate();
|
||||
}
|
||||
}
|
@ -1,18 +1,13 @@
|
||||
package com.sismics.docs.core.dao.jpa;
|
||||
package com.sismics.docs.core.dao;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import com.sismics.docs.core.dao.jpa.dto.RelationDto;
|
||||
import com.sismics.docs.core.dao.dto.RelationDto;
|
||||
import com.sismics.docs.core.model.jpa.Relation;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.Query;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Relation DAO.
|
||||
*
|
||||
@ -41,13 +36,13 @@ public class RelationDao {
|
||||
List<Object[]> l = q.getResultList();
|
||||
|
||||
// Assemble results
|
||||
List<RelationDto> relationDtoList = new ArrayList<RelationDto>();
|
||||
List<RelationDto> relationDtoList = new ArrayList<>();
|
||||
for (Object[] o : l) {
|
||||
int i = 0;
|
||||
RelationDto relationDto = new RelationDto();
|
||||
relationDto.setId((String) o[i++]);
|
||||
relationDto.setTitle((String) o[i++]);
|
||||
String fromDocId = (String) o[i++];
|
||||
String fromDocId = (String) o[i];
|
||||
relationDto.setSource(documentId.equals(fromDocId));
|
||||
relationDtoList.add(relationDto);
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
package com.sismics.docs.core.dao.jpa;
|
||||
package com.sismics.docs.core.dao;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Query;
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.Query;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
111
docs-core/src/main/java/com/sismics/docs/core/dao/RouteDao.java
Normal file
@ -0,0 +1,111 @@
|
||||
package com.sismics.docs.core.dao;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.sismics.docs.core.constant.AuditLogType;
|
||||
import com.sismics.docs.core.dao.criteria.RouteCriteria;
|
||||
import com.sismics.docs.core.dao.dto.RouteDto;
|
||||
import com.sismics.docs.core.model.jpa.Route;
|
||||
import com.sismics.docs.core.util.AuditLogUtil;
|
||||
import com.sismics.docs.core.util.jpa.QueryParam;
|
||||
import com.sismics.docs.core.util.jpa.QueryUtil;
|
||||
import com.sismics.docs.core.util.jpa.SortCriteria;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Route DAO.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public class RouteDao {
|
||||
/**
|
||||
* Creates a new route.
|
||||
*
|
||||
* @param route Route
|
||||
* @param userId User ID
|
||||
* @return New ID
|
||||
*/
|
||||
public String create(Route route, String userId) {
|
||||
// Create the UUID
|
||||
route.setId(UUID.randomUUID().toString());
|
||||
|
||||
// Create the route
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
route.setCreateDate(new Date());
|
||||
em.persist(route);
|
||||
|
||||
// Create audit log
|
||||
AuditLogUtil.create(route, AuditLogType.CREATE, userId);
|
||||
|
||||
return route.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of all routes.
|
||||
*
|
||||
* @param criteria Search criteria
|
||||
* @param sortCriteria Sort criteria
|
||||
* @return List of routes
|
||||
*/
|
||||
public List<RouteDto> findByCriteria(RouteCriteria criteria, SortCriteria sortCriteria) {
|
||||
Map<String, Object> parameterMap = new HashMap<String, Object>();
|
||||
List<String> criteriaList = new ArrayList<>();
|
||||
|
||||
StringBuilder sb = new StringBuilder("select r.RTE_ID_C c0, r.RTE_NAME_C c1, r.RTE_CREATEDATE_D c2");
|
||||
sb.append(" from T_ROUTE r ");
|
||||
|
||||
// Add search criterias
|
||||
if (criteria.getDocumentId() != null) {
|
||||
criteriaList.add("r.RTE_IDDOCUMENT_C = :documentId");
|
||||
parameterMap.put("documentId", criteria.getDocumentId());
|
||||
}
|
||||
criteriaList.add("r.RTE_DELETEDATE_D is null");
|
||||
|
||||
sb.append(" where ");
|
||||
sb.append(Joiner.on(" and ").join(criteriaList));
|
||||
|
||||
// Perform the search
|
||||
QueryParam queryParam = QueryUtil.getSortedQueryParam(new QueryParam(sb.toString(), parameterMap), sortCriteria);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Object[]> l = QueryUtil.getNativeQuery(queryParam).getResultList();
|
||||
|
||||
// Assemble results
|
||||
List<RouteDto> dtoList = new ArrayList<>();
|
||||
for (Object[] o : l) {
|
||||
int i = 0;
|
||||
RouteDto dto = new RouteDto();
|
||||
dto.setId((String) o[i++]);
|
||||
dto.setName((String) o[i++]);
|
||||
dto.setCreateTimestamp(((Timestamp) o[i++]).getTime());
|
||||
dtoList.add(dto);
|
||||
}
|
||||
return dtoList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a route and the associated steps.
|
||||
*
|
||||
* @param routeId Route ID
|
||||
* @param userId User ID
|
||||
*/
|
||||
public void deleteRoute(String routeId, String userId) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
|
||||
// Create audit log
|
||||
Route route = em.find(Route.class, routeId);
|
||||
AuditLogUtil.create(route, AuditLogType.DELETE, userId);
|
||||
|
||||
em.createNativeQuery("update T_ROUTE_STEP rs set RTP_DELETEDATE_D = :dateNow where rs.RTP_IDROUTE_C = :routeId and rs.RTP_DELETEDATE_D is null")
|
||||
.setParameter("routeId", routeId)
|
||||
.setParameter("dateNow", new Date())
|
||||
.executeUpdate();
|
||||
|
||||
em.createNativeQuery("update T_ROUTE r set RTE_DELETEDATE_D = :dateNow where r.RTE_ID_C = :routeId and r.RTE_DELETEDATE_D is null")
|
||||
.setParameter("routeId", routeId)
|
||||
.setParameter("dateNow", new Date())
|
||||
.executeUpdate();
|
||||
}
|
||||
}
|
@ -0,0 +1,168 @@
|
||||
package com.sismics.docs.core.dao;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.sismics.docs.core.constant.AuditLogType;
|
||||
import com.sismics.docs.core.dao.criteria.RouteModelCriteria;
|
||||
import com.sismics.docs.core.dao.dto.RouteModelDto;
|
||||
import com.sismics.docs.core.model.jpa.RouteModel;
|
||||
import com.sismics.docs.core.util.AuditLogUtil;
|
||||
import com.sismics.docs.core.util.SecurityUtil;
|
||||
import com.sismics.docs.core.util.jpa.QueryParam;
|
||||
import com.sismics.docs.core.util.jpa.QueryUtil;
|
||||
import com.sismics.docs.core.util.jpa.SortCriteria;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.NoResultException;
|
||||
import jakarta.persistence.Query;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Route model DAO.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public class RouteModelDao {
|
||||
/**
|
||||
* Creates a new route model.
|
||||
*
|
||||
* @param routeModel Route model
|
||||
* @param userId User ID
|
||||
* @return New ID
|
||||
*/
|
||||
public String create(RouteModel routeModel, String userId) {
|
||||
// Create the UUID
|
||||
routeModel.setId(UUID.randomUUID().toString());
|
||||
|
||||
// Create the route model
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
routeModel.setCreateDate(new Date());
|
||||
em.persist(routeModel);
|
||||
|
||||
// Create audit log
|
||||
AuditLogUtil.create(routeModel, AuditLogType.CREATE, userId);
|
||||
|
||||
return routeModel.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a route model.
|
||||
*
|
||||
* @param routeModel Route model to update
|
||||
* @param userId User ID
|
||||
* @return Updated route model
|
||||
*/
|
||||
public RouteModel update(RouteModel routeModel, String userId) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
|
||||
// Get the route model
|
||||
Query q = em.createQuery("select r from RouteModel r where r.id = :id and r.deleteDate is null");
|
||||
q.setParameter("id", routeModel.getId());
|
||||
RouteModel routeModelDb = (RouteModel) q.getSingleResult();
|
||||
|
||||
// Update the route model
|
||||
routeModelDb.setName(routeModel.getName());
|
||||
routeModelDb.setSteps(routeModel.getSteps());
|
||||
|
||||
// Create audit log
|
||||
AuditLogUtil.create(routeModelDb, AuditLogType.UPDATE, userId);
|
||||
|
||||
return routeModelDb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an active route model by its ID.
|
||||
*
|
||||
* @param id Route model ID
|
||||
* @return Route model
|
||||
*/
|
||||
public RouteModel getActiveById(String id) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
try {
|
||||
Query q = em.createQuery("select r from RouteModel r where r.id = :id and r.deleteDate is null");
|
||||
q.setParameter("id", id);
|
||||
return (RouteModel) q.getSingleResult();
|
||||
} catch (NoResultException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of all route models.
|
||||
*
|
||||
* @return List of route models
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<RouteModel> findAll() {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
Query q = em.createQuery("select r from RouteModel r where r.deleteDate is null");
|
||||
return q.getResultList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a route model.
|
||||
*
|
||||
* @param id Route model ID
|
||||
* @param userId User ID
|
||||
*/
|
||||
public void delete(String id, String userId) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
|
||||
// Get the route model
|
||||
Query q = em.createQuery("select r from RouteModel r where r.id = :id and r.deleteDate is null");
|
||||
q.setParameter("id", id);
|
||||
RouteModel routeModelDb = (RouteModel) q.getSingleResult();
|
||||
|
||||
// Delete the route model
|
||||
Date dateNow = new Date();
|
||||
routeModelDb.setDeleteDate(dateNow);
|
||||
|
||||
// Create audit log
|
||||
AuditLogUtil.create(routeModelDb, AuditLogType.DELETE, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of all route models.
|
||||
*
|
||||
* @param criteria Search criteria
|
||||
* @param sortCriteria Sort criteria
|
||||
* @return List of route models
|
||||
*/
|
||||
public List<RouteModelDto> findByCriteria(RouteModelCriteria criteria, SortCriteria sortCriteria) {
|
||||
Map<String, Object> parameterMap = new HashMap<String, Object>();
|
||||
List<String> criteriaList = new ArrayList<>();
|
||||
|
||||
StringBuilder sb = new StringBuilder("select rm.RTM_ID_C c0, rm.RTM_NAME_C c1, rm.RTM_CREATEDATE_D c2");
|
||||
sb.append(" from T_ROUTE_MODEL rm ");
|
||||
|
||||
// Add search criterias
|
||||
if (criteria.getTargetIdList() != null && !SecurityUtil.skipAclCheck(criteria.getTargetIdList())) {
|
||||
sb.append(" left join T_ACL a on a.ACL_TARGETID_C in (:targetIdList) and a.ACL_SOURCEID_C = rm.RTM_ID_C and a.ACL_PERM_C = 'READ' and a.ACL_DELETEDATE_D is null ");
|
||||
criteriaList.add("a.ACL_ID_C is not null");
|
||||
parameterMap.put("targetIdList", criteria.getTargetIdList());
|
||||
}
|
||||
|
||||
criteriaList.add("rm.RTM_DELETEDATE_D is null");
|
||||
|
||||
sb.append(" where ");
|
||||
sb.append(Joiner.on(" and ").join(criteriaList));
|
||||
|
||||
// Perform the search
|
||||
QueryParam queryParam = QueryUtil.getSortedQueryParam(new QueryParam(sb.toString(), parameterMap), sortCriteria);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Object[]> l = QueryUtil.getNativeQuery(queryParam).getResultList();
|
||||
|
||||
// Assemble results
|
||||
List<RouteModelDto> dtoList = new ArrayList<>();
|
||||
for (Object[] o : l) {
|
||||
int i = 0;
|
||||
RouteModelDto dto = new RouteModelDto();
|
||||
dto.setId((String) o[i++]);
|
||||
dto.setName((String) o[i++]);
|
||||
dto.setCreateTimestamp(((Timestamp) o[i++]).getTime());
|
||||
dtoList.add(dto);
|
||||
}
|
||||
return dtoList;
|
||||
}
|
||||
}
|
@ -0,0 +1,154 @@
|
||||
package com.sismics.docs.core.dao;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.sismics.docs.core.constant.AclTargetType;
|
||||
import com.sismics.docs.core.constant.RouteStepTransition;
|
||||
import com.sismics.docs.core.constant.RouteStepType;
|
||||
import com.sismics.docs.core.dao.criteria.RouteStepCriteria;
|
||||
import com.sismics.docs.core.dao.dto.RouteStepDto;
|
||||
import com.sismics.docs.core.model.jpa.RouteStep;
|
||||
import com.sismics.docs.core.util.jpa.QueryParam;
|
||||
import com.sismics.docs.core.util.jpa.QueryUtil;
|
||||
import com.sismics.docs.core.util.jpa.SortCriteria;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.Query;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Route step DAO.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public class RouteStepDao {
|
||||
/**
|
||||
* Creates a new route step.
|
||||
*
|
||||
* @param routeStep Route step
|
||||
* @return New ID
|
||||
*/
|
||||
public String create(RouteStep routeStep) {
|
||||
// Create the UUID
|
||||
routeStep.setId(UUID.randomUUID().toString());
|
||||
|
||||
// Create the route step
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
routeStep.setCreateDate(new Date());
|
||||
em.persist(routeStep);
|
||||
|
||||
return routeStep.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current route step from a document.
|
||||
*
|
||||
* @param documentId Document ID
|
||||
* @return Current route step
|
||||
*/
|
||||
public RouteStepDto getCurrentStep(String documentId) {
|
||||
List<RouteStepDto> routeStepDtoList = findByCriteria(new RouteStepCriteria()
|
||||
.setDocumentId(documentId)
|
||||
.setEndDateIsNull(true), new SortCriteria(6, true));
|
||||
if (routeStepDtoList.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return routeStepDtoList.get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of all route steps.
|
||||
*
|
||||
* @param criteria Search criteria
|
||||
* @param sortCriteria Sort criteria
|
||||
* @return List of route steps
|
||||
*/
|
||||
public List<RouteStepDto> findByCriteria(RouteStepCriteria criteria, SortCriteria sortCriteria) {
|
||||
Map<String, Object> parameterMap = new HashMap<>();
|
||||
List<String> criteriaList = new ArrayList<>();
|
||||
|
||||
StringBuilder sb = new StringBuilder("select rs.RTP_ID_C, rs.RTP_NAME_C c0, rs.RTP_TYPE_C c1, rs.RTP_TRANSITION_C c2, rs.RTP_COMMENT_C c3, rs.RTP_IDTARGET_C c4, u.USE_USERNAME_C as targetUsername, g.GRP_NAME_C, rs.RTP_ENDDATE_D c5, uv.USE_USERNAME_C as validatorUsername, rs.RTP_IDROUTE_C, rs.RTP_TRANSITIONS_C, rs.RTP_ORDER_N c6")
|
||||
.append(" from T_ROUTE_STEP rs ")
|
||||
.append(" join T_ROUTE r on r.RTE_ID_C = rs.RTP_IDROUTE_C ")
|
||||
.append(" left join T_USER uv on uv.USE_ID_C = rs.RTP_IDVALIDATORUSER_C ")
|
||||
.append(" left join T_USER u on u.USE_ID_C = rs.RTP_IDTARGET_C ")
|
||||
.append(" left join T_SHARE s on s.SHA_ID_C = rs.RTP_IDTARGET_C ")
|
||||
.append(" left join T_GROUP g on g.GRP_ID_C = rs.RTP_IDTARGET_C ");
|
||||
|
||||
// Add search criterias
|
||||
if (criteria.getDocumentId() != null) {
|
||||
criteriaList.add("r.RTE_IDDOCUMENT_C = :documentId");
|
||||
parameterMap.put("documentId", criteria.getDocumentId());
|
||||
}
|
||||
if (criteria.getRouteId() != null) {
|
||||
criteriaList.add("rs.RTP_IDROUTE_C = :routeId");
|
||||
parameterMap.put("routeId", criteria.getRouteId());
|
||||
}
|
||||
if (criteria.getEndDateIsNull() != null) {
|
||||
criteriaList.add("RTP_ENDDATE_D is " + (criteria.getEndDateIsNull() ? "" : "not") + " null");
|
||||
}
|
||||
criteriaList.add("rs.RTP_DELETEDATE_D is null");
|
||||
|
||||
sb.append(" where ");
|
||||
sb.append(Joiner.on(" and ").join(criteriaList));
|
||||
|
||||
// Perform the search
|
||||
QueryParam queryParam = QueryUtil.getSortedQueryParam(new QueryParam(sb.toString(), parameterMap), sortCriteria);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Object[]> l = QueryUtil.getNativeQuery(queryParam).getResultList();
|
||||
|
||||
// Assemble results
|
||||
List<RouteStepDto> dtoList = new ArrayList<>();
|
||||
for (Object[] o : l) {
|
||||
int i = 0;
|
||||
RouteStepDto dto = new RouteStepDto();
|
||||
dto.setId((String) o[i++]);
|
||||
dto.setName((String) o[i++]);
|
||||
dto.setType(RouteStepType.valueOf((String) o[i++]));
|
||||
dto.setTransition((String) o[i++]);
|
||||
dto.setComment((String) o[i++]);
|
||||
dto.setTargetId((String) o[i++]);
|
||||
String userName = (String) o[i++];
|
||||
String groupName = (String) o[i++];
|
||||
if (userName != null) {
|
||||
dto.setTargetName(userName);
|
||||
dto.setTargetType(AclTargetType.USER.name());
|
||||
}
|
||||
if (groupName != null) {
|
||||
dto.setTargetName(groupName);
|
||||
dto.setTargetType(AclTargetType.GROUP.name());
|
||||
}
|
||||
Timestamp endDateTimestamp = (Timestamp) o[i++];
|
||||
dto.setEndDateTimestamp(endDateTimestamp == null ? null : endDateTimestamp.getTime());
|
||||
dto.setValidatorUserName((String) o[i++]);
|
||||
dto.setRouteId((String) o[i++]);
|
||||
dto.setTransitions((String) o[i]);
|
||||
dtoList.add(dto);
|
||||
}
|
||||
return dtoList;
|
||||
}
|
||||
|
||||
/**
|
||||
* End a route step.
|
||||
*
|
||||
* @param id Route step ID
|
||||
* @param transition Transition
|
||||
* @param comment Comment
|
||||
* @param validatorUserId Validator user ID
|
||||
*/
|
||||
public void endRouteStep(String id, RouteStepTransition transition, String comment, String validatorUserId) {
|
||||
StringBuilder sb = new StringBuilder("update T_ROUTE_STEP r ");
|
||||
sb.append(" set RTP_ENDDATE_D = :endDate, RTP_TRANSITION_C = :transition, RTP_COMMENT_C = :comment, RTP_IDVALIDATORUSER_C = :validatorUserId ");
|
||||
sb.append(" where r.RTP_ID_C = :id");
|
||||
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
Query q = em.createNativeQuery(sb.toString());
|
||||
q.setParameter("endDate", new Date());
|
||||
q.setParameter("transition", transition.name());
|
||||
q.setParameter("comment", comment);
|
||||
q.setParameter("validatorUserId", validatorUserId);
|
||||
q.setParameter("id", id);
|
||||
q.executeUpdate();
|
||||
}
|
||||
}
|
@ -1,14 +1,13 @@
|
||||
package com.sismics.docs.core.dao.jpa;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Query;
|
||||
package com.sismics.docs.core.dao;
|
||||
|
||||
import com.sismics.docs.core.model.jpa.Share;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.Query;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Share DAO.
|
||||
*
|
||||
@ -20,7 +19,6 @@ public class ShareDao {
|
||||
*
|
||||
* @param share Share
|
||||
* @return New ID
|
||||
* @throws Exception
|
||||
*/
|
||||
public String create(Share share) {
|
||||
// Create the UUID
|
@ -1,29 +1,23 @@
|
||||
package com.sismics.docs.core.dao.jpa;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.NoResultException;
|
||||
import javax.persistence.Query;
|
||||
package com.sismics.docs.core.dao;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.sismics.docs.core.constant.AuditLogType;
|
||||
import com.sismics.docs.core.dao.jpa.criteria.TagCriteria;
|
||||
import com.sismics.docs.core.dao.jpa.dto.TagDto;
|
||||
import com.sismics.docs.core.dao.criteria.TagCriteria;
|
||||
import com.sismics.docs.core.dao.dto.TagDto;
|
||||
import com.sismics.docs.core.model.jpa.DocumentTag;
|
||||
import com.sismics.docs.core.model.jpa.Tag;
|
||||
import com.sismics.docs.core.util.AuditLogUtil;
|
||||
import com.sismics.docs.core.util.SecurityUtil;
|
||||
import com.sismics.docs.core.util.jpa.QueryParam;
|
||||
import com.sismics.docs.core.util.jpa.QueryUtil;
|
||||
import com.sismics.docs.core.util.jpa.SortCriteria;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.NoResultException;
|
||||
import jakarta.persistence.Query;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Tag DAO.
|
||||
*
|
||||
@ -138,6 +132,10 @@ public class TagDao {
|
||||
q.setParameter("dateNow", dateNow);
|
||||
q.executeUpdate();
|
||||
|
||||
q = em.createQuery("update Tag t set t.parentId = null where t.parentId = :tagId and t.deleteDate is null");
|
||||
q.setParameter("tagId", tagId);
|
||||
q.executeUpdate();
|
||||
|
||||
// Create audit log
|
||||
AuditLogUtil.create(tagDb, AuditLogType.DELETE, userId);
|
||||
}
|
||||
@ -155,17 +153,17 @@ public class TagDao {
|
||||
// Get the tag
|
||||
Query q = em.createQuery("select t from Tag t where t.id = :id and t.deleteDate is null");
|
||||
q.setParameter("id", tag.getId());
|
||||
Tag tagFromDb = (Tag) q.getSingleResult();
|
||||
Tag tagDb = (Tag) q.getSingleResult();
|
||||
|
||||
// Update the tag
|
||||
tagFromDb.setName(tag.getName());
|
||||
tagFromDb.setColor(tag.getColor());
|
||||
tagFromDb.setParentId(tag.getParentId());
|
||||
tagDb.setName(tag.getName());
|
||||
tagDb.setColor(tag.getColor());
|
||||
tagDb.setParentId(tag.getParentId());
|
||||
|
||||
// Create audit log
|
||||
AuditLogUtil.create(tagFromDb, AuditLogType.UPDATE, userId);
|
||||
AuditLogUtil.create(tagDb, AuditLogType.UPDATE, userId);
|
||||
|
||||
return tagFromDb;
|
||||
return tagDb;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -188,7 +186,7 @@ public class TagDao {
|
||||
criteriaList.add("t.TAG_ID_C = :id");
|
||||
parameterMap.put("id", criteria.getId());
|
||||
}
|
||||
if (criteria.getTargetIdList() != null) {
|
||||
if (criteria.getTargetIdList() != null && !SecurityUtil.skipAclCheck(criteria.getTargetIdList())) {
|
||||
sb.append(" left join T_ACL a on a.ACL_TARGETID_C in (:targetIdList) and a.ACL_SOURCEID_C = t.TAG_ID_C and a.ACL_PERM_C = 'READ' and a.ACL_DELETEDATE_D is null ");
|
||||
criteriaList.add("a.ACL_ID_C is not null");
|
||||
parameterMap.put("targetIdList", criteria.getTargetIdList());
|
||||
@ -198,21 +196,11 @@ public class TagDao {
|
||||
criteriaList.add("dt.DOT_IDDOCUMENT_C = :documentId");
|
||||
parameterMap.put("documentId", criteria.getDocumentId());
|
||||
}
|
||||
if (criteria.getName() != null) {
|
||||
criteriaList.add("t.TAG_NAME_C = :name");
|
||||
parameterMap.put("name", criteria.getName());
|
||||
}
|
||||
if (criteria.getNameLike() != null) {
|
||||
criteriaList.add("t.TAG_NAME_C like :nameLike");
|
||||
parameterMap.put("nameLike", "%" + criteria.getNameLike() + "%");
|
||||
}
|
||||
|
||||
criteriaList.add("t.TAG_DELETEDATE_D is null");
|
||||
|
||||
if (!criteriaList.isEmpty()) {
|
||||
sb.append(" where ");
|
||||
sb.append(Joiner.on(" and ").join(criteriaList));
|
||||
}
|
||||
|
||||
// Perform the search
|
||||
QueryParam queryParam = QueryUtil.getSortedQueryParam(new QueryParam(sb.toString(), parameterMap), sortCriteria);
|
@ -1,36 +1,41 @@
|
||||
package com.sismics.docs.core.dao.jpa;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.NoResultException;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import org.mindrot.jbcrypt.BCrypt;
|
||||
package com.sismics.docs.core.dao;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Strings;
|
||||
import at.favre.lib.crypto.bcrypt.BCrypt;
|
||||
import org.joda.time.DateTime;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.sismics.docs.core.constant.AuditLogType;
|
||||
import com.sismics.docs.core.dao.jpa.criteria.UserCriteria;
|
||||
import com.sismics.docs.core.dao.jpa.dto.UserDto;
|
||||
import com.sismics.docs.core.constant.Constants;
|
||||
import com.sismics.docs.core.dao.criteria.UserCriteria;
|
||||
import com.sismics.docs.core.dao.dto.UserDto;
|
||||
import com.sismics.docs.core.model.jpa.User;
|
||||
import com.sismics.docs.core.util.AuditLogUtil;
|
||||
import com.sismics.docs.core.util.EncryptionUtil;
|
||||
import com.sismics.docs.core.util.jpa.QueryParam;
|
||||
import com.sismics.docs.core.util.jpa.QueryUtil;
|
||||
import com.sismics.docs.core.util.jpa.SortCriteria;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.NoResultException;
|
||||
import jakarta.persistence.Query;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* User DAO.
|
||||
*
|
||||
* @author jtremeaux
|
||||
*/
|
||||
public class UserDao {
|
||||
/**
|
||||
* Logger.
|
||||
*/
|
||||
private static final Logger log = LoggerFactory.getLogger(UserDao.class);
|
||||
|
||||
/**
|
||||
* Authenticates an user.
|
||||
*
|
||||
@ -44,7 +49,8 @@ public class UserDao {
|
||||
q.setParameter("username", username);
|
||||
try {
|
||||
User user = (User) q.getSingleResult();
|
||||
if (!BCrypt.checkpw(password, user.getPassword())) {
|
||||
BCrypt.Result result = BCrypt.verifyer().verify(password.toCharArray(), user.getPassword());
|
||||
if (!result.verified || user.getDisableDate() != null) {
|
||||
return null;
|
||||
}
|
||||
return user;
|
||||
@ -59,7 +65,7 @@ public class UserDao {
|
||||
* @param user User to create
|
||||
* @param userId User ID
|
||||
* @return User ID
|
||||
* @throws Exception
|
||||
* @throws Exception e
|
||||
*/
|
||||
public String create(User user, String userId) throws Exception {
|
||||
// Create the user UUID
|
||||
@ -77,6 +83,8 @@ public class UserDao {
|
||||
// Create the user
|
||||
user.setCreateDate(new Date());
|
||||
user.setPassword(hashPassword(user.getPassword()));
|
||||
user.setPrivateKey(EncryptionUtil.generatePrivateKey());
|
||||
user.setStorageCurrent(0L);
|
||||
em.persist(user);
|
||||
|
||||
// Create audit log
|
||||
@ -98,16 +106,17 @@ public class UserDao {
|
||||
// Get the user
|
||||
Query q = em.createQuery("select u from User u where u.id = :id and u.deleteDate is null");
|
||||
q.setParameter("id", user.getId());
|
||||
User userFromDb = (User) q.getSingleResult();
|
||||
User userDb = (User) q.getSingleResult();
|
||||
|
||||
// Update the user (except password)
|
||||
userFromDb.setEmail(user.getEmail());
|
||||
userFromDb.setStorageQuota(user.getStorageQuota());
|
||||
userFromDb.setStorageCurrent(user.getStorageCurrent());
|
||||
userFromDb.setTotpKey(user.getTotpKey());
|
||||
userDb.setEmail(user.getEmail());
|
||||
userDb.setStorageQuota(user.getStorageQuota());
|
||||
userDb.setStorageCurrent(user.getStorageCurrent());
|
||||
userDb.setTotpKey(user.getTotpKey());
|
||||
userDb.setDisableDate(user.getDisableDate());
|
||||
|
||||
// Create audit log
|
||||
AuditLogUtil.create(userFromDb, AuditLogType.UPDATE, userId);
|
||||
AuditLogUtil.create(userDb, AuditLogType.UPDATE, userId);
|
||||
|
||||
return user;
|
||||
}
|
||||
@ -116,20 +125,17 @@ public class UserDao {
|
||||
* Updates a user's quota.
|
||||
*
|
||||
* @param user User to update
|
||||
* @return Updated user
|
||||
*/
|
||||
public User updateQuota(User user) {
|
||||
public void updateQuota(User user) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
|
||||
// Get the user
|
||||
Query q = em.createQuery("select u from User u where u.id = :id and u.deleteDate is null");
|
||||
q.setParameter("id", user.getId());
|
||||
User userFromDb = (User) q.getSingleResult();
|
||||
User userDb = (User) q.getSingleResult();
|
||||
|
||||
// Update the user
|
||||
userFromDb.setStorageQuota(user.getStorageQuota());
|
||||
|
||||
return user;
|
||||
userDb.setStorageCurrent(user.getStorageCurrent());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -145,13 +151,53 @@ public class UserDao {
|
||||
// Get the user
|
||||
Query q = em.createQuery("select u from User u where u.id = :id and u.deleteDate is null");
|
||||
q.setParameter("id", user.getId());
|
||||
User userFromDb = (User) q.getSingleResult();
|
||||
User userDb = (User) q.getSingleResult();
|
||||
|
||||
// Update the user
|
||||
userFromDb.setPassword(hashPassword(user.getPassword()));
|
||||
userDb.setPassword(hashPassword(user.getPassword()));
|
||||
|
||||
// Create audit log
|
||||
AuditLogUtil.create(userFromDb, AuditLogType.UPDATE, userId);
|
||||
AuditLogUtil.create(userDb, AuditLogType.UPDATE, userId);
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the hashed password silently.
|
||||
*
|
||||
* @param user User to update
|
||||
* @return Updated user
|
||||
*/
|
||||
public User updateHashedPassword(User user) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
|
||||
// Get the user
|
||||
Query q = em.createQuery("select u from User u where u.id = :id and u.deleteDate is null");
|
||||
q.setParameter("id", user.getId());
|
||||
User userDb = (User) q.getSingleResult();
|
||||
|
||||
// Update the user
|
||||
userDb.setPassword(user.getPassword());
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the onboarding status.
|
||||
*
|
||||
* @param user User to update
|
||||
* @return Updated user
|
||||
*/
|
||||
public User updateOnboarding(User user) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
|
||||
// Get the user
|
||||
Query q = em.createQuery("select u from User u where u.id = :id and u.deleteDate is null");
|
||||
q.setParameter("id", user.getId());
|
||||
User userDb = (User) q.getSingleResult();
|
||||
|
||||
// Update the user
|
||||
userDb.setOnboarding(user.isOnboarding());
|
||||
|
||||
return user;
|
||||
}
|
||||
@ -200,39 +246,39 @@ public class UserDao {
|
||||
// Get the user
|
||||
Query q = em.createQuery("select u from User u where u.username = :username and u.deleteDate is null");
|
||||
q.setParameter("username", username);
|
||||
User userFromDb = (User) q.getSingleResult();
|
||||
User userDb = (User) q.getSingleResult();
|
||||
|
||||
// Delete the user
|
||||
Date dateNow = new Date();
|
||||
userFromDb.setDeleteDate(dateNow);
|
||||
userDb.setDeleteDate(dateNow);
|
||||
|
||||
// Delete linked data
|
||||
q = em.createQuery("delete from AuthenticationToken at where at.userId = :userId");
|
||||
q.setParameter("userId", userFromDb.getId());
|
||||
q.setParameter("userId", userDb.getId());
|
||||
q.executeUpdate();
|
||||
|
||||
q = em.createQuery("update Document d set d.deleteDate = :dateNow where d.userId = :userId and d.deleteDate is null");
|
||||
q.setParameter("userId", userFromDb.getId());
|
||||
q.setParameter("userId", userDb.getId());
|
||||
q.setParameter("dateNow", dateNow);
|
||||
q.executeUpdate();
|
||||
|
||||
q = em.createQuery("update File f set f.deleteDate = :dateNow where f.userId = :userId and f.deleteDate is null");
|
||||
q.setParameter("userId", userFromDb.getId());
|
||||
q.setParameter("userId", userDb.getId());
|
||||
q.setParameter("dateNow", dateNow);
|
||||
q.executeUpdate();
|
||||
|
||||
q = em.createQuery("update Acl a set a.deleteDate = :dateNow where a.targetId = :userId and a.deleteDate is null");
|
||||
q.setParameter("userId", userFromDb.getId());
|
||||
q.setParameter("userId", userDb.getId());
|
||||
q.setParameter("dateNow", dateNow);
|
||||
q.executeUpdate();
|
||||
|
||||
q = em.createQuery("update Comment c set c.deleteDate = :dateNow where c.userId = :userId and c.deleteDate is null");
|
||||
q.setParameter("userId", userFromDb.getId());
|
||||
q.setParameter("userId", userDb.getId());
|
||||
q.setParameter("dateNow", dateNow);
|
||||
q.executeUpdate();
|
||||
|
||||
// Create audit log
|
||||
AuditLogUtil.create(userFromDb, AuditLogType.DELETE, userId);
|
||||
AuditLogUtil.create(userDb, AuditLogType.DELETE, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -242,7 +288,21 @@ public class UserDao {
|
||||
* @return Hashed password
|
||||
*/
|
||||
private String hashPassword(String password) {
|
||||
return BCrypt.hashpw(password, BCrypt.gensalt());
|
||||
int bcryptWork = Constants.DEFAULT_BCRYPT_WORK;
|
||||
String envBcryptWork = System.getenv(Constants.BCRYPT_WORK_ENV);
|
||||
if (!Strings.isNullOrEmpty(envBcryptWork)) {
|
||||
try {
|
||||
int envBcryptWorkInt = Integer.parseInt(envBcryptWork);
|
||||
if (envBcryptWorkInt >= 4 && envBcryptWorkInt <= 31) {
|
||||
bcryptWork = envBcryptWorkInt;
|
||||
} else {
|
||||
log.warn(Constants.BCRYPT_WORK_ENV + " needs to be in range 4...31. Falling back to " + Constants.DEFAULT_BCRYPT_WORK + ".");
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn(Constants.BCRYPT_WORK_ENV + " needs to be a number in range 4...31. Falling back to " + Constants.DEFAULT_BCRYPT_WORK + ".");
|
||||
}
|
||||
}
|
||||
return BCrypt.withDefaults().hashToString(bcryptWork, password.toCharArray());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -256,7 +316,7 @@ public class UserDao {
|
||||
Map<String, Object> parameterMap = new HashMap<>();
|
||||
List<String> criteriaList = new ArrayList<>();
|
||||
|
||||
StringBuilder sb = new StringBuilder("select u.USE_ID_C as c0, u.USE_USERNAME_C as c1, u.USE_EMAIL_C as c2, u.USE_CREATEDATE_D as c3, u.USE_STORAGECURRENT_N as c4, u.USE_STORAGEQUOTA_N as c5");
|
||||
StringBuilder sb = new StringBuilder("select u.USE_ID_C as c0, u.USE_USERNAME_C as c1, u.USE_EMAIL_C as c2, u.USE_CREATEDATE_D as c3, u.USE_STORAGECURRENT_N as c4, u.USE_STORAGEQUOTA_N as c5, u.USE_TOTPKEY_C as c6, u.USE_DISABLEDATE_D as c7");
|
||||
sb.append(" from T_USER u ");
|
||||
|
||||
// Add search criterias
|
||||
@ -264,7 +324,14 @@ public class UserDao {
|
||||
criteriaList.add("lower(u.USE_USERNAME_C) like lower(:search)");
|
||||
parameterMap.put("search", "%" + criteria.getSearch() + "%");
|
||||
}
|
||||
|
||||
if (criteria.getUserId() != null) {
|
||||
criteriaList.add("u.USE_ID_C = :userId");
|
||||
parameterMap.put("userId", criteria.getUserId());
|
||||
}
|
||||
if (criteria.getUserName() != null) {
|
||||
criteriaList.add("u.USE_USERNAME_C = :userName");
|
||||
parameterMap.put("userName", criteria.getUserName());
|
||||
}
|
||||
if (criteria.getGroupId() != null) {
|
||||
sb.append(" join T_USER_GROUP ug on ug.UGP_IDUSER_C = u.USE_ID_C and ug.UGP_IDGROUP_C = :groupId and ug.UGP_DELETEDATE_D is null ");
|
||||
parameterMap.put("groupId", criteria.getGroupId());
|
||||
@ -292,9 +359,39 @@ public class UserDao {
|
||||
userDto.setEmail((String) o[i++]);
|
||||
userDto.setCreateTimestamp(((Timestamp) o[i++]).getTime());
|
||||
userDto.setStorageCurrent(((Number) o[i++]).longValue());
|
||||
userDto.setStorageQuota(((Number) o[i]).longValue());
|
||||
userDto.setStorageQuota(((Number) o[i++]).longValue());
|
||||
userDto.setTotpKey((String) o[i++]);
|
||||
if (o[i] != null) {
|
||||
userDto.setDisableTimestamp(((Timestamp) o[i]).getTime());
|
||||
}
|
||||
userDtoList.add(userDto);
|
||||
}
|
||||
return userDtoList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the global storage used by all users.
|
||||
*
|
||||
* @return Current global storage
|
||||
*/
|
||||
public long getGlobalStorageCurrent() {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
Query query = em.createNativeQuery("select sum(u.USE_STORAGECURRENT_N) from T_USER u where u.USE_DELETEDATE_D is null");
|
||||
return ((Number) query.getSingleResult()).longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of active users.
|
||||
*
|
||||
* @return Number of active users
|
||||
*/
|
||||
public long getActiveUserCount() {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
Query query = em.createNativeQuery("select count(u.USE_ID_C) from T_USER u where u.USE_DELETEDATE_D is null and (u.USE_DISABLEDATE_D is null or u.USE_DISABLEDATE_D >= :fromDate and u.USE_DISABLEDATE_D < :toDate)");
|
||||
DateTime fromDate = DateTime.now().minusMonths(1).dayOfMonth().withMinimumValue().withTimeAtStartOfDay();
|
||||
DateTime toDate = fromDate.plusMonths(1);
|
||||
query.setParameter("fromDate", fromDate.toDate());
|
||||
query.setParameter("toDate", toDate.toDate());
|
||||
return ((Number) query.getSingleResult()).longValue();
|
||||
}
|
||||
}
|
@ -1,15 +1,14 @@
|
||||
package com.sismics.docs.core.dao.jpa;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.NoResultException;
|
||||
import javax.persistence.Query;
|
||||
package com.sismics.docs.core.dao;
|
||||
|
||||
import com.sismics.docs.core.model.jpa.Vocabulary;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.NoResultException;
|
||||
import jakarta.persistence.Query;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Vocabulary DAO.
|
||||
*
|
||||
@ -21,7 +20,6 @@ public class VocabularyDao {
|
||||
*
|
||||
* @param vocabulary Vocabulary
|
||||
* @return New ID
|
||||
* @throws Exception
|
||||
*/
|
||||
public String create(Vocabulary vocabulary) {
|
||||
// Create the UUID
|
||||
@ -76,14 +74,14 @@ public class VocabularyDao {
|
||||
// Get the vocabulary entry
|
||||
Query q = em.createQuery("select v from Vocabulary v where v.id = :id");
|
||||
q.setParameter("id", vocabulary.getId());
|
||||
Vocabulary vocabularyFromDb = (Vocabulary) q.getSingleResult();
|
||||
Vocabulary vocabularyDb = (Vocabulary) q.getSingleResult();
|
||||
|
||||
// Update the vocabulary entry
|
||||
vocabularyFromDb.setName(vocabulary.getName());
|
||||
vocabularyFromDb.setValue(vocabulary.getValue());
|
||||
vocabularyFromDb.setOrder(vocabulary.getOrder());
|
||||
vocabularyDb.setName(vocabulary.getName());
|
||||
vocabularyDb.setValue(vocabulary.getValue());
|
||||
vocabularyDb.setOrder(vocabulary.getOrder());
|
||||
|
||||
return vocabularyFromDb;
|
||||
return vocabularyDb;
|
||||
}
|
||||
|
||||
/**
|
@ -0,0 +1,121 @@
|
||||
package com.sismics.docs.core.dao;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.sismics.docs.core.dao.criteria.WebhookCriteria;
|
||||
import com.sismics.docs.core.dao.dto.WebhookDto;
|
||||
import com.sismics.docs.core.model.jpa.Webhook;
|
||||
import com.sismics.docs.core.util.jpa.QueryParam;
|
||||
import com.sismics.docs.core.util.jpa.QueryUtil;
|
||||
import com.sismics.docs.core.util.jpa.SortCriteria;
|
||||
import com.sismics.util.context.ThreadLocalContext;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.NoResultException;
|
||||
import jakarta.persistence.Query;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Webhook DAO.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public class WebhookDao {
|
||||
/**
|
||||
* Returns the list of all webhooks.
|
||||
*
|
||||
* @param criteria Search criteria
|
||||
* @param sortCriteria Sort criteria
|
||||
* @return List of webhooks
|
||||
*/
|
||||
public List<WebhookDto> findByCriteria(WebhookCriteria criteria, SortCriteria sortCriteria) {
|
||||
Map<String, Object> parameterMap = new HashMap<>();
|
||||
List<String> criteriaList = new ArrayList<>();
|
||||
|
||||
StringBuilder sb = new StringBuilder("select w.WHK_ID_C as c0, w.WHK_EVENT_C as c1, w.WHK_URL_C as c2, w.WHK_CREATEDATE_D as c3 ");
|
||||
sb.append(" from T_WEBHOOK w ");
|
||||
|
||||
// Add search criterias
|
||||
if (criteria.getEvent() != null) {
|
||||
criteriaList.add("w.WHK_EVENT_C = :event");
|
||||
parameterMap.put("event", criteria.getEvent().name());
|
||||
}
|
||||
criteriaList.add("w.WHK_DELETEDATE_D is null");
|
||||
|
||||
sb.append(" where ");
|
||||
sb.append(Joiner.on(" and ").join(criteriaList));
|
||||
|
||||
// Perform the search
|
||||
QueryParam queryParam = QueryUtil.getSortedQueryParam(new QueryParam(sb.toString(), parameterMap), sortCriteria);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Object[]> l = QueryUtil.getNativeQuery(queryParam).getResultList();
|
||||
|
||||
// Assemble results
|
||||
List<WebhookDto> webhookDtoList = new ArrayList<>();
|
||||
for (Object[] o : l) {
|
||||
int i = 0;
|
||||
WebhookDto webhookDto = new WebhookDto()
|
||||
.setId((String) o[i++])
|
||||
.setEvent((String) o[i++])
|
||||
.setUrl((String) o[i++])
|
||||
.setCreateTimestamp(((Timestamp) o[i]).getTime());
|
||||
webhookDtoList.add(webhookDto);
|
||||
}
|
||||
|
||||
return webhookDtoList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a webhook by ID.
|
||||
*
|
||||
* @param id Webhook ID
|
||||
* @return Webhook
|
||||
*/
|
||||
public Webhook getActiveById(String id) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
Query q = em.createQuery("select w from Webhook w where w.id = :id and w.deleteDate is null");
|
||||
q.setParameter("id", id);
|
||||
try {
|
||||
return (Webhook) q.getSingleResult();
|
||||
} catch (NoResultException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new webhook.
|
||||
*
|
||||
* @param webhook Webhook
|
||||
* @return New ID
|
||||
*/
|
||||
public String create(Webhook webhook) {
|
||||
// Create the UUID
|
||||
webhook.setId(UUID.randomUUID().toString());
|
||||
|
||||
// Create the webhook
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
webhook.setCreateDate(new Date());
|
||||
em.persist(webhook);
|
||||
|
||||
return webhook.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a webhook.
|
||||
*
|
||||
* @param webhookId Webhook ID
|
||||
*/
|
||||
public void delete(String webhookId) {
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
|
||||
// Get the group
|
||||
Query q = em.createQuery("select w from Webhook w where w.id = :id and w.deleteDate is null");
|
||||
q.setParameter("id", webhookId);
|
||||
Webhook webhookDb = (Webhook) q.getSingleResult();
|
||||
|
||||
// Delete the group
|
||||
Date dateNow = new Date();
|
||||
webhookDb.setDeleteDate(dateNow);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
package com.sismics.docs.core.dao.jpa.criteria;
|
||||
|
||||
package com.sismics.docs.core.dao.criteria;
|
||||
|
||||
|
||||
/**
|
||||
@ -18,6 +17,11 @@ public class AuditLogCriteria {
|
||||
*/
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* The search is done for an admin user.
|
||||
*/
|
||||
private boolean isAdmin = false;
|
||||
|
||||
public String getDocumentId() {
|
||||
return documentId;
|
||||
}
|
||||
@ -33,4 +37,13 @@ public class AuditLogCriteria {
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public boolean isAdmin() {
|
||||
return isAdmin;
|
||||
}
|
||||
|
||||
public AuditLogCriteria setAdmin(boolean admin) {
|
||||
isAdmin = admin;
|
||||
return this;
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package com.sismics.docs.core.dao.jpa.criteria;
|
||||
package com.sismics.docs.core.dao.criteria;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@ -18,7 +19,7 @@ public class DocumentCriteria {
|
||||
/**
|
||||
* Search query.
|
||||
*/
|
||||
private String search;
|
||||
private String simpleSearch;
|
||||
|
||||
/**
|
||||
* Full content search query.
|
||||
@ -36,9 +37,26 @@ public class DocumentCriteria {
|
||||
private Date createDateMax;
|
||||
|
||||
/**
|
||||
* Tag IDs.
|
||||
* Minimum update date.
|
||||
*/
|
||||
private List<String> tagIdList;
|
||||
private Date updateDateMin;
|
||||
|
||||
/**
|
||||
* Maximum update date.
|
||||
*/
|
||||
private Date updateDateMax;
|
||||
|
||||
/**
|
||||
* Tag IDs.
|
||||
* The first level list will be AND'ed and the second level list will be OR'ed.
|
||||
*/
|
||||
private List<List<String>> tagIdList = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Tag IDs to exclude.
|
||||
* The first and second level list will be excluded.
|
||||
*/
|
||||
private List<List<String>> excludedTagIdList = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Shared status.
|
||||
@ -55,6 +73,21 @@ public class DocumentCriteria {
|
||||
*/
|
||||
private String creatorId;
|
||||
|
||||
/**
|
||||
* A route is active.
|
||||
*/
|
||||
private Boolean activeRoute;
|
||||
|
||||
/**
|
||||
* MIME type of a file.
|
||||
*/
|
||||
private String mimeType;
|
||||
|
||||
/**
|
||||
* Titles to include.
|
||||
*/
|
||||
private List<String> titleList = new ArrayList<>();
|
||||
|
||||
public List<String> getTargetIdList() {
|
||||
return targetIdList;
|
||||
}
|
||||
@ -63,12 +96,12 @@ public class DocumentCriteria {
|
||||
this.targetIdList = targetIdList;
|
||||
}
|
||||
|
||||
public String getSearch() {
|
||||
return search;
|
||||
public String getSimpleSearch() {
|
||||
return simpleSearch;
|
||||
}
|
||||
|
||||
public void setSearch(String search) {
|
||||
this.search = search;
|
||||
public void setSimpleSearch(String search) {
|
||||
this.simpleSearch = search;
|
||||
}
|
||||
|
||||
public String getFullSearch() {
|
||||
@ -95,12 +128,12 @@ public class DocumentCriteria {
|
||||
this.createDateMax = createDateMax;
|
||||
}
|
||||
|
||||
public List<String> getTagIdList() {
|
||||
public List<List<String>> getTagIdList() {
|
||||
return tagIdList;
|
||||
}
|
||||
|
||||
public void setTagIdList(List<String> tagIdList) {
|
||||
this.tagIdList = tagIdList;
|
||||
public List<List<String>> getExcludedTagIdList() {
|
||||
return excludedTagIdList;
|
||||
}
|
||||
|
||||
public Boolean getShared() {
|
||||
@ -126,4 +159,40 @@ public class DocumentCriteria {
|
||||
public void setCreatorId(String creatorId) {
|
||||
this.creatorId = creatorId;
|
||||
}
|
||||
|
||||
public Date getUpdateDateMin() {
|
||||
return updateDateMin;
|
||||
}
|
||||
|
||||
public void setUpdateDateMin(Date updateDateMin) {
|
||||
this.updateDateMin = updateDateMin;
|
||||
}
|
||||
|
||||
public Date getUpdateDateMax() {
|
||||
return updateDateMax;
|
||||
}
|
||||
|
||||
public void setUpdateDateMax(Date updateDateMax) {
|
||||
this.updateDateMax = updateDateMax;
|
||||
}
|
||||
|
||||
public Boolean getActiveRoute() {
|
||||
return activeRoute;
|
||||
}
|
||||
|
||||
public void setActiveRoute(Boolean activeRoute) {
|
||||
this.activeRoute = activeRoute;
|
||||
}
|
||||
|
||||
public String getMimeType() {
|
||||
return mimeType;
|
||||
}
|
||||
|
||||
public void setMimeType(String mimeType) {
|
||||
this.mimeType = mimeType;
|
||||
}
|
||||
|
||||
public List<String> getTitleList() {
|
||||
return titleList;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.sismics.docs.core.dao.jpa.criteria;
|
||||
package com.sismics.docs.core.dao.criteria;
|
||||
|
||||
/**
|
||||
* Group criteria.
|
@ -0,0 +1,9 @@
|
||||
package com.sismics.docs.core.dao.criteria;
|
||||
|
||||
/**
|
||||
* Metadata criteria.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public class MetadataCriteria {
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.sismics.docs.core.dao.criteria;
|
||||
|
||||
|
||||
/**
|
||||
* Route criteria.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public class RouteCriteria {
|
||||
/**
|
||||
* Document ID.
|
||||
*/
|
||||
private String documentId;
|
||||
|
||||
public String getDocumentId() {
|
||||
return documentId;
|
||||
}
|
||||
|
||||
public RouteCriteria setDocumentId(String documentId) {
|
||||
this.documentId = documentId;
|
||||
return this;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package com.sismics.docs.core.dao.criteria;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Route model criteria.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public class RouteModelCriteria {
|
||||
/**
|
||||
* ACL target ID list.
|
||||
*/
|
||||
private List<String> targetIdList;
|
||||
|
||||
public List<String> getTargetIdList() {
|
||||
return targetIdList;
|
||||
}
|
||||
|
||||
public RouteModelCriteria setTargetIdList(List<String> targetIdList) {
|
||||
this.targetIdList = targetIdList;
|
||||
return this;
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package com.sismics.docs.core.dao.criteria;
|
||||
|
||||
|
||||
/**
|
||||
* Route step criteria.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public class RouteStepCriteria {
|
||||
/**
|
||||
* Document ID.
|
||||
*/
|
||||
private String documentId;
|
||||
|
||||
/**
|
||||
* Route ID.
|
||||
*/
|
||||
private String routeId;
|
||||
|
||||
/**
|
||||
* End date is null.
|
||||
*/
|
||||
private Boolean endDateIsNull;
|
||||
|
||||
public String getDocumentId() {
|
||||
return documentId;
|
||||
}
|
||||
|
||||
public RouteStepCriteria setDocumentId(String documentId) {
|
||||
this.documentId = documentId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getRouteId() {
|
||||
return routeId;
|
||||
}
|
||||
|
||||
public RouteStepCriteria setRouteId(String routeId) {
|
||||
this.routeId = routeId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Boolean getEndDateIsNull() {
|
||||
return endDateIsNull;
|
||||
}
|
||||
|
||||
public RouteStepCriteria setEndDateIsNull(Boolean endDateIsNull) {
|
||||
this.endDateIsNull = endDateIsNull;
|
||||
return this;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.sismics.docs.core.dao.jpa.criteria;
|
||||
package com.sismics.docs.core.dao.criteria;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -23,16 +23,6 @@ public class TagCriteria {
|
||||
*/
|
||||
private String documentId;
|
||||
|
||||
/**
|
||||
* Tag name.
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* Approximate tag name.
|
||||
*/
|
||||
private String nameLike;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
@ -59,22 +49,4 @@ public class TagCriteria {
|
||||
this.documentId = documentId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public TagCriteria setName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getNameLike() {
|
||||
return nameLike;
|
||||
}
|
||||
|
||||
public TagCriteria setNameLike(String nameLike) {
|
||||
this.nameLike = nameLike;
|
||||
return this;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.sismics.docs.core.dao.jpa.criteria;
|
||||
package com.sismics.docs.core.dao.criteria;
|
||||
|
||||
/**
|
||||
* User criteria.
|
||||
@ -16,6 +16,16 @@ public class UserCriteria {
|
||||
*/
|
||||
private String groupId;
|
||||
|
||||
/**
|
||||
* User ID.
|
||||
*/
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* Username.
|
||||
*/
|
||||
private String userName;
|
||||
|
||||
public String getSearch() {
|
||||
return search;
|
||||
}
|
||||
@ -33,4 +43,22 @@ public class UserCriteria {
|
||||
this.groupId = groupId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public UserCriteria setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public UserCriteria setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
return this;
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.sismics.docs.core.dao.criteria;
|
||||
|
||||
import com.sismics.docs.core.constant.WebhookEvent;
|
||||
|
||||
/**
|
||||
* Webhook criteria.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public class WebhookCriteria {
|
||||
/**
|
||||
* Webhook event.
|
||||
*/
|
||||
private WebhookEvent event;
|
||||
|
||||
public WebhookEvent getEvent() {
|
||||
return event;
|
||||
}
|
||||
|
||||
public WebhookCriteria setEvent(WebhookEvent event) {
|
||||
this.event = event;
|
||||
return this;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.sismics.docs.core.dao.jpa.dto;
|
||||
package com.sismics.docs.core.dao.dto;
|
||||
|
||||
import com.sismics.docs.core.constant.PermType;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.sismics.docs.core.dao.jpa.dto;
|
||||
package com.sismics.docs.core.dao.dto;
|
||||
|
||||
import com.sismics.docs.core.constant.AuditLogType;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.sismics.docs.core.dao.jpa.dto;
|
||||
package com.sismics.docs.core.dao.dto;
|
||||
|
||||
/**
|
||||
* Comment DTO.
|
@ -1,4 +1,4 @@
|
||||
package com.sismics.docs.core.dao.jpa.dto;
|
||||
package com.sismics.docs.core.dao.dto;
|
||||
|
||||
/**
|
||||
* Contributor DTO.
|
@ -1,4 +1,4 @@
|
||||
package com.sismics.docs.core.dao.jpa.dto;
|
||||
package com.sismics.docs.core.dao.dto;
|
||||
|
||||
/**
|
||||
* Document DTO.
|
||||
@ -11,6 +11,11 @@ public class DocumentDto {
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* Main file ID.
|
||||
*/
|
||||
private String fileId;
|
||||
|
||||
/**
|
||||
* Title.
|
||||
*/
|
||||
@ -71,6 +76,11 @@ public class DocumentDto {
|
||||
*/
|
||||
private Long createTimestamp;
|
||||
|
||||
/**
|
||||
* Update date.
|
||||
*/
|
||||
private Long updateTimestamp;
|
||||
|
||||
/**
|
||||
* Shared status.
|
||||
*/
|
||||
@ -86,6 +96,21 @@ public class DocumentDto {
|
||||
*/
|
||||
private String creator;
|
||||
|
||||
/**
|
||||
* A route is active.
|
||||
*/
|
||||
private boolean activeRoute;
|
||||
|
||||
/**
|
||||
* Current route step name.
|
||||
*/
|
||||
private String currentStepName;
|
||||
|
||||
/**
|
||||
* Search highlight.
|
||||
*/
|
||||
private String highlight;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
@ -94,6 +119,15 @@ public class DocumentDto {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getFileId() {
|
||||
return fileId;
|
||||
}
|
||||
|
||||
public DocumentDto setFileId(String fileId) {
|
||||
this.fileId = fileId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
@ -213,4 +247,38 @@ public class DocumentDto {
|
||||
public void setCreator(String creator) {
|
||||
this.creator = creator;
|
||||
}
|
||||
|
||||
public boolean isActiveRoute() {
|
||||
return activeRoute;
|
||||
}
|
||||
|
||||
public void setActiveRoute(boolean activeRoute) {
|
||||
this.activeRoute = activeRoute;
|
||||
}
|
||||
|
||||
public String getCurrentStepName() {
|
||||
return currentStepName;
|
||||
}
|
||||
|
||||
public Long getUpdateTimestamp() {
|
||||
return updateTimestamp;
|
||||
}
|
||||
|
||||
public void setUpdateTimestamp(Long updateTimestamp) {
|
||||
this.updateTimestamp = updateTimestamp;
|
||||
}
|
||||
|
||||
public DocumentDto setCurrentStepName(String currentStepName) {
|
||||
this.currentStepName = currentStepName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getHighlight() {
|
||||
return highlight;
|
||||
}
|
||||
|
||||
public DocumentDto setHighlight(String highlight) {
|
||||
this.highlight = highlight;
|
||||
return this;
|
||||
}
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
package com.sismics.docs.core.dao.dto;
|
||||
|
||||
import com.sismics.docs.core.constant.MetadataType;
|
||||
|
||||
/**
|
||||
* Document metadata DTO.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public class DocumentMetadataDto {
|
||||
/**
|
||||
* Document metadata ID.
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* Document ID.
|
||||
*/
|
||||
private String documentId;
|
||||
|
||||
/**
|
||||
* Metadata ID.
|
||||
*/
|
||||
private String metadataId;
|
||||
|
||||
/**
|
||||
* Name.
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* Value.
|
||||
*/
|
||||
private String value;
|
||||
|
||||
/**
|
||||
* Type.
|
||||
*/
|
||||
private MetadataType type;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public DocumentMetadataDto setId(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public DocumentMetadataDto setName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MetadataType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public DocumentMetadataDto setType(MetadataType type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getDocumentId() {
|
||||
return documentId;
|
||||
}
|
||||
|
||||
public DocumentMetadataDto setDocumentId(String documentId) {
|
||||
this.documentId = documentId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getMetadataId() {
|
||||
return metadataId;
|
||||
}
|
||||
|
||||
public DocumentMetadataDto setMetadataId(String metadataId) {
|
||||
this.metadataId = metadataId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public DocumentMetadataDto setValue(String value) {
|
||||
this.value = value;
|
||||
return this;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.sismics.docs.core.dao.jpa.dto;
|
||||
package com.sismics.docs.core.dao.dto;
|
||||
|
||||
/**
|
||||
* Group DTO.
|
@ -0,0 +1,52 @@
|
||||
package com.sismics.docs.core.dao.dto;
|
||||
|
||||
import com.sismics.docs.core.constant.MetadataType;
|
||||
|
||||
/**
|
||||
* Metadata DTO.
|
||||
*
|
||||
* @author bgamard
|
||||
*/
|
||||
public class MetadataDto {
|
||||
/**
|
||||
* Metadata ID.
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* Name.
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* Type.
|
||||
*/
|
||||
private MetadataType type;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public MetadataDto setId(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public MetadataDto setName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MetadataType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public MetadataDto setType(MetadataType type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
}
|