mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-14 16:51:28 +00:00
Compare commits
364 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff373b9a3f | ||
|
|
0a7d102981 | ||
|
|
10867e87c9 | ||
|
|
7900f0ea8c | ||
|
|
f0d364a6c5 | ||
|
|
5ed50c50c7 | ||
|
|
020f12a2a9 | ||
|
|
8aa5a8d7e8 | ||
|
|
72733f556c | ||
|
|
0fa03e05a8 | ||
|
|
b7ac5dcf88 | ||
|
|
0ce48fab25 | ||
|
|
f50766c684 | ||
|
|
6dc597f826 | ||
|
|
509f132bc8 | ||
|
|
096e063754 | ||
|
|
5e621eb0fb | ||
|
|
4e5edc834f | ||
|
|
4de1ac6e40 | ||
|
|
9d2aa62785 | ||
|
|
917c2a345f | ||
|
|
6932fe4ab4 | ||
|
|
332890d92b | ||
|
|
39abdcb90f | ||
|
|
4e11b5bf37 | ||
|
|
d446541f34 | ||
|
|
0a9fe818dc | ||
|
|
d26437ccd5 | ||
|
|
54e9b2e1c1 | ||
|
|
3d030cb6b0 | ||
|
|
56db4aa038 | ||
|
|
0acfdec238 | ||
|
|
86b4ce6243 | ||
|
|
7436c398f8 | ||
|
|
3c4494a14f | ||
|
|
345f515372 | ||
|
|
b6b660ec06 | ||
|
|
f9596ec2c1 | ||
|
|
df9fa9ebad | ||
|
|
8a6c43ee69 | ||
|
|
c4b2a66152 | ||
|
|
c8dadca564 | ||
|
|
4ea3e8de8b | ||
|
|
8c55946cf0 | ||
|
|
f4265e1d73 | ||
|
|
96c2272b03 | ||
|
|
7b7684f0af | ||
|
|
bff3dbd777 | ||
|
|
0fc2b18f68 | ||
|
|
e5dff4322a | ||
|
|
167944e8ed | ||
|
|
1af94c9c21 | ||
|
|
63df9a4d8f | ||
|
|
24c45c8539 | ||
|
|
d1d3974610 | ||
|
|
e6cd505767 | ||
|
|
2d68e27d3d | ||
|
|
05cc248417 | ||
|
|
10bff4c4fd | ||
|
|
b53da45a15 | ||
|
|
67a7dcdc4b | ||
|
|
f87f10f332 | ||
|
|
3d47b30193 | ||
|
|
1370b200bb | ||
|
|
2f249d557e | ||
|
|
ce17fff1ac | ||
|
|
2d55da309b | ||
|
|
761207155d | ||
|
|
456a879181 | ||
|
|
2e02e70916 | ||
|
|
dbc803a0d9 | ||
|
|
fdccafaa68 | ||
|
|
deebd82ecd | ||
|
|
0906abdea9 | ||
|
|
da94fe4f6f | ||
|
|
79672a28ee | ||
|
|
e052a4b261 | ||
|
|
425d4e8fed | ||
|
|
d2a2e2304d | ||
|
|
e7157a64ed | ||
|
|
245a995203 | ||
|
|
c29d7fb6a2 | ||
|
|
8cada6d0a2 | ||
|
|
d03446beef | ||
|
|
f62c0b4ca8 | ||
|
|
c046056736 | ||
|
|
e63cbf94d0 | ||
|
|
d48247b7c6 | ||
|
|
695dcd5de7 | ||
|
|
5e35985a3f | ||
|
|
d9325819fd | ||
|
|
f960238b47 | ||
|
|
d0aef5b683 | ||
|
|
c69fc95126 | ||
|
|
51cb41975b | ||
|
|
0debbb83b1 | ||
|
|
fbfe2b0a31 | ||
|
|
a719a83bce | ||
|
|
d353a9cb9d | ||
|
|
ee2e07a9a3 | ||
|
|
f6689043c7 | ||
|
|
45531dc54a | ||
|
|
0a26c192fe | ||
|
|
281cfb74d9 | ||
|
|
0d03eeb5bd | ||
|
|
36e669d729 | ||
|
|
b1f55d7cfe | ||
|
|
9aa8c46560 | ||
|
|
2ed00ed02d | ||
|
|
5d56f5beb6 | ||
|
|
1b937dfb06 | ||
|
|
42be5330fe | ||
|
|
be8949157f | ||
|
|
93b2a4e07a | ||
|
|
ada1195a26 | ||
|
|
93563f68e0 | ||
|
|
3faa0e83cc | ||
|
|
1985e2af72 | ||
|
|
3f03d36ad6 | ||
|
|
8359deb8eb | ||
|
|
e1f2330f95 | ||
|
|
87014c4db2 | ||
|
|
c9eb9b1938 | ||
|
|
28cb2e1301 | ||
|
|
277999112e | ||
|
|
a7fdf3d325 | ||
|
|
54ae332364 | ||
|
|
76075ffec4 | ||
|
|
ed448146f7 | ||
|
|
638e9c1a8b | ||
|
|
1624cffb2a | ||
|
|
f391a6521d | ||
|
|
02ae2e7ca0 | ||
|
|
40bd84a09c | ||
|
|
0c0fb1c4c5 | ||
|
|
ab39bd1667 | ||
|
|
b41636a208 | ||
|
|
0902de821a | ||
|
|
8a6265658e | ||
|
|
7750a49e65 | ||
|
|
b75b9781c1 | ||
|
|
2687c02e31 | ||
|
|
71b65e03d6 | ||
|
|
e09ee27219 | ||
|
|
5a3428d9b0 | ||
|
|
ed109977f8 | ||
|
|
d6c6f177e8 | ||
|
|
97f2cee1ae | ||
|
|
4fb8a27a78 | ||
|
|
79b825aaad | ||
|
|
28fedafb59 | ||
|
|
d9bff68555 | ||
|
|
cef3a5fc77 | ||
|
|
9956f43fd9 | ||
|
|
2b84593bde | ||
|
|
4e728fd387 | ||
|
|
438ade1106 | ||
|
|
fe54f4ec66 | ||
|
|
fe86b4c593 | ||
|
|
a583afeb60 | ||
|
|
a585d3cf16 | ||
|
|
3db757193e | ||
|
|
bac1d6fd83 | ||
|
|
39ee8a9cde | ||
|
|
1263b3af81 | ||
|
|
dafa29d8a3 | ||
|
|
2bc6fe89ad | ||
|
|
8439216233 | ||
|
|
aab616d184 | ||
|
|
70c3a38c49 | ||
|
|
c64294ac3e | ||
|
|
82330db871 | ||
|
|
c54a721f9a | ||
|
|
355bbb5459 | ||
|
|
63daa0f121 | ||
|
|
50885d5c7c | ||
|
|
4d68818ec5 | ||
|
|
6fb20dd509 | ||
|
|
2bb87dfa96 | ||
|
|
3e374a927c | ||
|
|
84ac6d88f5 | ||
|
|
72f6ee6477 | ||
|
|
a3cfcb1131 | ||
|
|
d7d8d21ba4 | ||
|
|
ef0425e2b1 | ||
|
|
df1fd6d0b3 | ||
|
|
2fa04d7b7c | ||
|
|
a15acd64c8 | ||
|
|
5b18eff01a | ||
|
|
47133c6f31 | ||
|
|
09ba4f5129 | ||
|
|
20d4047bed | ||
|
|
56b71ef7d9 | ||
|
|
091e62057d | ||
|
|
824bd9ea64 | ||
|
|
697a791593 | ||
|
|
7462a887b3 | ||
|
|
3535e83d7d | ||
|
|
cf0b4accb3 | ||
|
|
a63bcfbaa2 | ||
|
|
5c4bf2a207 | ||
|
|
c1611a12ed | ||
|
|
0983120712 | ||
|
|
ce12af8495 | ||
|
|
dc117c8415 | ||
|
|
06e526a961 | ||
|
|
2e343a951f | ||
|
|
141ffcf656 | ||
|
|
d61e5c5a08 | ||
|
|
6a15fa132a | ||
|
|
902b29ee0a | ||
|
|
995bba616f | ||
|
|
f39b7b047f | ||
|
|
72e52df4e0 | ||
|
|
8018e9485e | ||
|
|
e0ae50378f | ||
|
|
a9c2b0fc57 | ||
|
|
dc58ba434a | ||
|
|
34af306309 | ||
|
|
21d70b5ae4 | ||
|
|
e90880ac9a | ||
|
|
66faa13f40 | ||
|
|
8a4a29b4d1 | ||
|
|
8c8db84a4a | ||
|
|
a499a3c80b | ||
|
|
6a3ccf2b48 | ||
|
|
fcfcffe9cb | ||
|
|
363ed4ac4b | ||
|
|
1f73a08e09 | ||
|
|
fe0a34907f | ||
|
|
461b11700f | ||
|
|
24bfbb59a4 | ||
|
|
4476558e9c | ||
|
|
560171832c | ||
|
|
6e93d40e51 | ||
|
|
79b819bca6 | ||
|
|
a18c406cf0 | ||
|
|
6730a83cac | ||
|
|
3b3ebd2196 | ||
|
|
505b6542c7 | ||
|
|
31368f0cba | ||
|
|
5b5dd756b1 | ||
|
|
f6ebbb23d1 | ||
|
|
3f0373b08f | ||
|
|
4c3c60060d | ||
|
|
28f275c22d | ||
|
|
24df3c3809 | ||
|
|
034a667e07 | ||
|
|
008e3e3b05 | ||
|
|
94a5bf7596 | ||
|
|
e8db836eff | ||
|
|
429b26f3d8 | ||
|
|
3ae8327300 | ||
|
|
df7e9a0af1 | ||
|
|
93d3eca0ab | ||
|
|
7753d1f0e7 | ||
|
|
d7c6c24932 | ||
|
|
1a75f23081 | ||
|
|
f071efe1b9 | ||
|
|
a8ad335aed | ||
|
|
7022a80c95 | ||
|
|
9a2f602d6c | ||
|
|
c78a4aa241 | ||
|
|
975ce4d973 | ||
|
|
1e6ff0d969 | ||
|
|
69e133d561 | ||
|
|
20e55eddf8 | ||
|
|
0fdcdc816a | ||
|
|
b7506d97a9 | ||
|
|
4ad7481dc7 | ||
|
|
bc815405d2 | ||
|
|
9c06e762c3 | ||
|
|
1ac87dd32f | ||
|
|
e0ce7ce2ec | ||
|
|
3d951a9d7b | ||
|
|
cec3d984b0 | ||
|
|
392e474cfa | ||
|
|
41fb0d51a4 | ||
|
|
aa9fef2967 | ||
|
|
adc9c02564 | ||
|
|
ace64117a2 | ||
|
|
fb4db2506b | ||
|
|
1076d971ae | ||
|
|
eed1b1cff0 | ||
|
|
f5cb82e21e | ||
|
|
67661f114b | ||
|
|
8a3e09764a | ||
|
|
eb3cfd6e6a | ||
|
|
4d1727d0e9 | ||
|
|
a51d853d1c | ||
|
|
d0039466f7 | ||
|
|
5c959989a2 | ||
|
|
6283d2df3d | ||
|
|
a9e0dfdaf8 | ||
|
|
45ca7e9e47 | ||
|
|
034b5c2718 | ||
|
|
e188649c79 | ||
|
|
1468c6ec90 | ||
|
|
07ba4eb537 | ||
|
|
414bbef1a7 | ||
|
|
e2b94ff6ef | ||
|
|
41f8a9faca | ||
|
|
1d9252e974 | ||
|
|
80780eef3c | ||
|
|
87ff33956b | ||
|
|
1804b98f05 | ||
|
|
847c6813cc | ||
|
|
1dde5ff6e7 | ||
|
|
76c9a19428 | ||
|
|
25ee0519e1 | ||
|
|
c184089c35 | ||
|
|
d2bcc47857 | ||
|
|
34629a69ea | ||
|
|
92c87f7b84 | ||
|
|
0dd96635ac | ||
|
|
048c44a6e4 | ||
|
|
06910ad1f4 | ||
|
|
02a0f3acc6 | ||
|
|
851f9240b7 | ||
|
|
99fce8d0b7 | ||
|
|
bf05c59c3b | ||
|
|
3dcebb1e1f | ||
|
|
fe3efdf610 | ||
|
|
5f4ae46f82 | ||
|
|
deef325319 | ||
|
|
fbe00a8fe3 | ||
|
|
dc87dade43 | ||
|
|
ba1625b5ad | ||
|
|
f6b126415e | ||
|
|
9147e1c08b | ||
|
|
6c18103662 | ||
|
|
6fc343ea12 | ||
|
|
d304d66cdd | ||
|
|
2ce9143b85 | ||
|
|
1c54e4f4ad | ||
|
|
9fd6f2ecae | ||
|
|
0d9f8eefc0 | ||
|
|
40a1530f19 | ||
|
|
0477a0a2e3 | ||
|
|
b77d4b5ae2 | ||
|
|
7b6c5318c5 | ||
|
|
6006d65ce0 | ||
|
|
2b01b76926 | ||
|
|
dcea9e21f0 | ||
|
|
78645ecdf6 | ||
|
|
91646dd93d | ||
|
|
fca146e939 | ||
|
|
62aa3ccc7f | ||
|
|
c0f4a2b0d3 | ||
|
|
68ee89af98 | ||
|
|
6deb30307e | ||
|
|
7357829741 | ||
|
|
4bd04150c1 | ||
|
|
cf35772c18 | ||
|
|
b0fd226c4c | ||
|
|
0d188d1c0c | ||
|
|
c6016ec7b2 | ||
|
|
e8719a1f9b | ||
|
|
27baf78029 | ||
|
|
bf5ce9a3a5 | ||
|
|
bcfe040784 | ||
|
|
d9b88ad1b7 | ||
|
|
e66e5b1d96 | ||
|
|
588166dce9 |
6
.gitignore
vendored
6
.gitignore
vendored
@@ -11,3 +11,9 @@
|
||||
.classpath
|
||||
target/
|
||||
test-output/
|
||||
|
||||
# IntelliJ Settings Files #
|
||||
.idea/
|
||||
out/
|
||||
.idea_modules/
|
||||
*.iws
|
||||
|
||||
61
.travis.yml
61
.travis.yml
@@ -1,48 +1,33 @@
|
||||
sudo: required
|
||||
|
||||
dist: trusty
|
||||
|
||||
language: java
|
||||
|
||||
sudo: required
|
||||
dist: trusty
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.m2
|
||||
env:
|
||||
global:
|
||||
- secure: "Lgj042RD0X3rB8VZVZLWP1GetLhjd3PqI5JbJMlzgHJpDI6RkFIBLN9SWAGmkLPCehIp2zA5tu9+UVy0NNMxm9xz6SyjMCaxS28/fnYEXaNmwwDSF6O6gLUbdxyzoYIFPYOPmFxpzhebqnNIsxaM29oZpgRgUGqosCczQxiB+Ng=" #coveralls
|
||||
- secure: "IfYURwZaDWuBDvyn47n0k1Zod/IQw1FF+CS5nnV08Q+NfC3vGGJMwV8m59XnbfwnWGxwvCaAbk4qP6s6+ijgZNKkvgfFMo3rfTok5zt43bIqgaFOANYV+OC/1c59gYD6ZUxhW5iNgMgU3qdsRtJuwSmfkVv/jKyLGfAbS4kN8BA=" #coverity
|
||||
|
||||
before_install: "curl -L --cookie 'oraclelicense=accept-securebackup-cookie;' http://download.oracle.com/otn-pub/java/jce/8/jce_policy-8.zip -o /tmp/policy.zip && sudo unzip -j -o /tmp/policy.zip *.jar -d `jdk_switcher home oraclejdk8`/jre/lib/security && rm /tmp/policy.zip"
|
||||
|
||||
script: mvn -fmain/pom.xml clean test
|
||||
|
||||
after_success: mvn -fmain/pom.xml -Ptest-coverage clean test jacoco:report-aggregate coveralls:report
|
||||
|
||||
notifications:
|
||||
webhooks:
|
||||
urls:
|
||||
- https://webhooks.gitter.im/e/7d429ab35361726e26f2
|
||||
on_success: change
|
||||
on_failure: always
|
||||
on_start: false
|
||||
slack:
|
||||
rooms:
|
||||
secure: "lngJ/HEAFBbD5AdiO9avMqptKpZHdmEwOzS9FabZjkdFh7yAYueTk5RniPUvShjsKtThYm7cJ8AtDMDwc07NvPrzbMBRtUJGwuDT+7c7YFALGFJ1NYi+emkC9x1oafvmPgEYSE+tMKzNcwrHi3ytGgKdIotsKwaF35QNXYA9aMs="
|
||||
on_success: change
|
||||
on_failure: always
|
||||
|
||||
before_deploy: mvn -fmain/pom.xml -Prelease clean package -DskipTests
|
||||
|
||||
- secure: "IfYURwZaDWuBDvyn47n0k1Zod/IQw1FF+CS5nnV08Q+NfC3vGGJMwV8m59XnbfwnWGxwvCaAbk4qP6s6+ijgZNKkvgfFMo3rfTok5zt43bIqgaFOANYV+OC/1c59gYD6ZUxhW5iNgMgU3qdsRtJuwSmfkVv/jKyLGfAbS4kN8BA=" # COVERITY_SCAN_TOKEN
|
||||
- secure: "lV9OwUbHMrMpLUH1CY+Z4puLDdFXytudyPlG1eGRsesdpuG6KM3uQVz6uAtf6lrU8DRbMM/T7ML+PmvQ4UoPPYLdLxESLLBat2qUPOIVBOhTSlCc7I0DmGy04CSvkeMy8dPaQC0ukgNiR7zwoNzfcpGRN/U9S8tziDruuHoZSrg=" # BINTRAY_API_KEY
|
||||
- secure: "oWFgRTVP6lyTa7qVxlvkpm20MtVc3BtmsNXQJS6bfg2A0o/iCQMNx7OD59BaafCLGRKvCcJVESiC8FlSylVMS7CDSyYu0gg70NUiIuHp4NBM5inFWYCy/PdQsCTzr5uvNG+rMFQpMFRaCV0FrfM3tLondcVkhsHL68l93Xoexx4=" # CODACY_PROJECT_TOKEN
|
||||
addons:
|
||||
coverity_scan:
|
||||
project:
|
||||
name: "cryptomator/cryptomator"
|
||||
notification_email: sebastian.stenzel@cryptomator.org
|
||||
build_command: "mvn -fmain/pom.xml clean test -DskipTests"
|
||||
branch_pattern: coverity_scan
|
||||
|
||||
branch_pattern: release.*
|
||||
install:
|
||||
# "clean" needed until https://bugs.openjdk.java.net/browse/JDK-8067747 is resolved.
|
||||
- mvn -fmain/pom.xml clean package -DskipTests dependency:go-offline -Pcoverage
|
||||
- mvn -fmain/pom.xml clean package -DskipTests dependency:go-offline -Prelease
|
||||
script:
|
||||
- mvn --update-snapshots -fmain/pom.xml clean test jacoco:report verify -Pcoverage
|
||||
before_deploy:
|
||||
- mvn -fmain/pom.xml -Prelease clean package -DskipTests
|
||||
deploy:
|
||||
provider: releases
|
||||
- provider: releases
|
||||
prerelease: false
|
||||
api_key:
|
||||
secure: "ZjE1j93v3qbPIe2YbmhS319aCbMdLQw0HuymmluTurxXsZtn9D4t2+eTr99vBVxGRuB5lzzGezPR5zjk5W7iHF7xhwrawXrFzr2rPJWzWFt0aM+Ry2njU1ROTGGXGTbv4anWeBlgMxLEInTAy/9ytOGNJlec83yc0THpOY2wxnk="
|
||||
@@ -53,3 +38,13 @@ deploy:
|
||||
on:
|
||||
repo: cryptomator/cryptomator
|
||||
tags: true
|
||||
- provider: script
|
||||
script: "curl -X POST -u cryptobot:${BINTRAY_API_KEY} -H 'Content-Type: application/json' -d '{\"name\": \"${TRAVIS_TAG}\", \"vcs_tag\": \"${TRAVIS_TAG}\"}' https://api.bintray.com/packages/cryptomator/cryptomator/cryptomator-win/versions"
|
||||
on:
|
||||
repo: cryptomator/cryptomator
|
||||
tags: true
|
||||
- provider: script
|
||||
script: "curl -X POST -u cryptobot:${BINTRAY_API_KEY} -H 'Content-Type: application/json' -d '{\"name\": \"${TRAVIS_TAG}\", \"vcs_tag\": \"${TRAVIS_TAG}\"}' https://api.bintray.com/packages/cryptomator/cryptomator/cryptomator-osx/versions"
|
||||
on:
|
||||
repo: cryptomator/cryptomator
|
||||
tags: true
|
||||
|
||||
661
3RD PARTY LICENSES/AGPLv3.txt
Normal file
661
3RD PARTY LICENSES/AGPLv3.txt
Normal file
@@ -0,0 +1,661 @@
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU Affero General Public License from time to time. Such new versions
|
||||
will be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU Affero General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU Affero General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU Affero General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
502
3RD PARTY LICENSES/LGPLv2.1.txt
Normal file
502
3RD PARTY LICENSES/LGPLv2.1.txt
Normal file
@@ -0,0 +1,502 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
88
3RD PARTY LICENSES/_NOTICE.md
Normal file
88
3RD PARTY LICENSES/_NOTICE.md
Normal file
@@ -0,0 +1,88 @@
|
||||
# Third party softwares
|
||||
Cryptomator uses third party libraries and fonts that may be licensed under different licenses.
|
||||
|
||||
## AquaFX
|
||||
The ProgressIndicator in ui/src/main/resource/css/mac_theme.css contains code from the AquaFX project.
|
||||
|
||||
Copyright Claudine Zillmann (http://aquafx-project.com/)
|
||||
|
||||
Licensed under the accompanying Modified BSD license file.
|
||||
|
||||
## Apache Commons + Apache HttpComponents + Jackrabbit WebDAV Library
|
||||
Copyright The Apache Software Foundation
|
||||
|
||||
Licensed under the Apache License, Version 2.0
|
||||
|
||||
### Commons Codec
|
||||
|
||||
src/test/org/apache/commons/codec/language/DoubleMetaphoneTest.java contains test data
|
||||
from http://aspell.net/test/orig/batch0.tab. Copyright (C) 2002 Kevin Atkinson (kevina@gnu.org)
|
||||
|
||||
### Commons Lang
|
||||
|
||||
This product includes software from the Spring Framework,
|
||||
under the Apache License 2.0 (see: StringUtils.containsWhitespace())
|
||||
|
||||
### Jackrabbit WebDAV Library
|
||||
|
||||
Based on source code originally developed by
|
||||
Day Software (http://www.day.com/).
|
||||
|
||||
## CryptoLib + CryptoFS
|
||||
Copyright 2016, 2017 Skymatic UG (haftungsbeschränkt)
|
||||
|
||||
Licensed under the GNU Affero General Public License, Version 3
|
||||
|
||||
## Dagger 2
|
||||
Copyright 2014 Google, Inc.
|
||||
Copyright 2012 Square, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0
|
||||
|
||||
## EasyBind
|
||||
Copyright (c) 2014, TomasMikula
|
||||
|
||||
Licensed under the accompanying simplified BSD license.
|
||||
|
||||
|
||||
## GSON + Guava
|
||||
Copyright Google, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0
|
||||
|
||||
## Jetty
|
||||
Copyright 1995-2017 Mort Bay Consulting Pty Ltd.
|
||||
|
||||
The UnixCrypt.java code implements the one way cryptography used by
|
||||
Unix systems for simple password protection. Copyright 1996 Aki Yoshida,
|
||||
modified April 2001 by Iris Van den Broeke, Daniel Deville.
|
||||
Permission to use, copy, modify and distribute UnixCrypt
|
||||
for non-commercial or commercial purposes and without fee is
|
||||
granted provided that the copyright notice appears in all copies.
|
||||
|
||||
Licensed under the Apache License, Version 2.0
|
||||
|
||||
|
||||
## Logback
|
||||
Copyright (C) 1999-2017, QOS.ch. All rights reserved.
|
||||
|
||||
Licensed under the GNU Lesser General Public License, Version 2.1
|
||||
|
||||
## SIV-Mode
|
||||
Copyright (c) Sebastian Stenzel
|
||||
|
||||
Licensed under the MIT / X11 License
|
||||
|
||||
## SLF4J
|
||||
Copyright (c) 2004-2017 QOS.ch
|
||||
|
||||
Licensed under the MIT / X11 License
|
||||
|
||||
|
||||
# Other third party assets
|
||||
Non-software work included in Cryptomator
|
||||
|
||||
## Ionicons
|
||||
Copyright (c) 2016 Drifty (http://drifty.com/)
|
||||
|
||||
ionicons.ttf Licensed under the accompanying MIT license
|
||||
@@ -3,8 +3,8 @@
|
||||
## Did you find a bug?
|
||||
|
||||
- Ensure you're running the latest version of Cryptomator.
|
||||
- Ensure the bug is related to the desktop version of Cryptomator. Bugs concerning the Cryptomator iOS app can be reported on the [Cryptomator for iOS issues list](https://github.com/cryptomator/cryptomator-ios/issues).
|
||||
- Ensure the bug was not [already reported](https://github.com/cryptomator/cryptomator/issues). You can also check out our [FAQ](https://cryptomator.org/faq/) and our [Wiki](https://github.com/cryptomator/cryptomator/wiki).
|
||||
- Ensure the bug is related to the desktop version of Cryptomator. Bugs concerning the Cryptomator iOS and Android app can be reported on the [Cryptomator for iOS issues list](https://github.com/cryptomator/cryptomator-ios/issues) and [Cryptomator for Android issues list](https://github.com/cryptomator/cryptomator-android/issues) respectively.
|
||||
- Ensure the bug was not [already reported](https://github.com/cryptomator/cryptomator/issues). You can also check out our [knowledge base](https://cryptomator.freshdesk.com/support/solutions) and our [Wiki](https://github.com/cryptomator/cryptomator/wiki).
|
||||
- If you're unable to find an open issue addressing the problem, [submit a new one](https://github.com/cryptomator/cryptomator/issues/new).
|
||||
|
||||
## Do you have questions?
|
||||
@@ -13,6 +13,11 @@
|
||||
- [Contact us](https://cryptomator.org/contact/) directly by writing an email. Wir sprechen auch Deutsch!
|
||||
- Have a chat with us on [Gitter](https://gitter.im/cryptomator/cryptomator).
|
||||
|
||||
## Do you miss a feature?
|
||||
|
||||
- Ensure the feature was not [already requested](https://github.com/cryptomator/cryptomator/issues).
|
||||
- You're welcome to suggest a feature by [submitting a new issue](https://github.com/cryptomator/cryptomator/issues/new).
|
||||
|
||||
## Did you write a patch that fixes a bug?
|
||||
|
||||
- Open a new pull request with the patch.
|
||||
|
||||
@@ -1,19 +1,38 @@
|
||||
### Basic Info
|
||||
To tick a checkbox replace [ ] with [x]. Make sure to replace placeholders (…) accordingly.
|
||||
|
||||
- I'm running Cryptomator on: [Windows, OS X, and/or Debian (or other Linux Distribution), don't forget the version]
|
||||
- I'm using Cryptomator in version: [you can check the version in the settings of Cryptomator]
|
||||
## Issue Checklist
|
||||
|
||||
### Description
|
||||
Before creating a new issue make sure that you
|
||||
- [ ] searched [existing (and closed) issues](https://github.com/cryptomator/cryptomator/issues).
|
||||
- [ ] searched the [knowledge base](https://cryptomator.freshdesk.com/support/solutions).
|
||||
- [ ] have read the [contribution guide](https://github.com/cryptomator/cryptomator/blob/master/CONTRIBUTING.md).
|
||||
- [ ] have read the [Code of Conduct](https://github.com/cryptomator/cryptomator/blob/master/CODE_OF_CONDUCT.md).
|
||||
|
||||
[description of the bug, question or feature - what did you do? what problem occurred? etc.]
|
||||
## Basic Info
|
||||
|
||||
### Log File (optional)
|
||||
This is a
|
||||
- [ ] bug report.
|
||||
- [ ] feature request.
|
||||
- [ ] question or something else.
|
||||
|
||||
```
|
||||
[insert relevant parts of the log file here if applicable,
|
||||
don't forget to redact sensitive information
|
||||
I'm using
|
||||
- [ ] Windows in version: …
|
||||
- [ ] macOS in version: …
|
||||
- [ ] Linux in version: …
|
||||
|
||||
on Windows: %appdata%/Cryptomator/cryptomator.log
|
||||
on OS X: ~/Library/Logs/Cryptomator/cryptomator.log
|
||||
on Debian: ~/.Cryptomator/cryptomator.log]
|
||||
```
|
||||
I'm running Cryptomator in version: …
|
||||
(You can check the version in the Cryptomator settings.)
|
||||
|
||||
## Description
|
||||
|
||||
…
|
||||
(Please describe in detail what you did, what you expected, and what really happened.)
|
||||
|
||||
## Attachments (optional)
|
||||
|
||||
If you want to add the log file or screenshots, please add them as attachments. If your log file seems empty and doesn't show any errors, you may enable the [debug mode](https://cryptomator.freshdesk.com/support/solutions/articles/16000046480) first and reproduce the problem to ensure all important information is contained in there. You may use test data or redact sensitive information from the log file.
|
||||
|
||||
You can find the log file
|
||||
- on Windows: %appdata%/Cryptomator/cryptomator.log
|
||||
- on macOS: ~/Library/Logs/Cryptomator/cryptomator.log
|
||||
- on Linux: ~/.Cryptomator/cryptomator.log
|
||||
|
||||
674
LICENSE.txt
Normal file
674
LICENSE.txt
Normal file
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
115
NOTICE.md
115
NOTICE.md
@@ -1,115 +0,0 @@
|
||||
# CRYPTOMATOR
|
||||
Copyright (c) 2014, Sebastian Stenzel
|
||||
|
||||
Cryptomator is licensed under the MIT license. The details can be found in the accompanying license file.
|
||||
|
||||
## Third party softwares
|
||||
Cryptomator uses third party libraries and fonts that may be licensed under different licenses.
|
||||
|
||||
### AquaFX
|
||||
The ProgressIndicator in ui/src/main/resource/css/mac_theme.css contains code from the AquaFX project.
|
||||
|
||||
Copyright 2013 Claudine Zillmann (http://aquafx-project.com/)
|
||||
|
||||
Licensed under the accompanying BSD license file.
|
||||
|
||||
### Apache Commons Collections
|
||||
Copyright 2001-2013 The Apache Software Foundation
|
||||
|
||||
This product includes software developed at The Apache Software Foundation (http://www.apache.org/).
|
||||
|
||||
### Apache Commons Codec
|
||||
Copyright 2002-2013 The Apache Software Foundation
|
||||
|
||||
This product includes software developed at The Apache Software Foundation (http://www.apache.org/).
|
||||
|
||||
src/test/org/apache/commons/codec/language/DoubleMetaphoneTest.java contains test data
|
||||
from http://aspell.net/test/orig/batch0.tab. Copyright (C) 2002 Kevin Atkinson (kevina@gnu.org)
|
||||
|
||||
### Apache Commons IO
|
||||
Copyright 2002-2012 The Apache Software Foundation
|
||||
|
||||
This product includes software developed by The Apache Software Foundation (http://www.apache.org/).
|
||||
|
||||
### Apache Commons Lang
|
||||
Copyright 2001-2011 The Apache Software Foundation
|
||||
|
||||
This product includes software developed by The Apache Software Foundation (http://www.apache.org/).
|
||||
|
||||
This product includes software from the Spring Framework,
|
||||
under the Apache License 2.0 (see: StringUtils.containsWhitespace())
|
||||
|
||||
### ControlsFX
|
||||
Copyright (c) 2013, ControlsFX
|
||||
|
||||
Licensed under the accompanying BSD license file.
|
||||
|
||||
### Dagger 2
|
||||
Copyright 2014 Google, Inc.
|
||||
Copyright 2012 Square, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0
|
||||
|
||||
### EasyBind
|
||||
Copyright (c) 2014, TomasMikula
|
||||
|
||||
Licensed under the accompanying BSD simplified license.
|
||||
|
||||
### Apache Jakarta HttpClient
|
||||
Copyright 1999-2007 The Apache Software Foundation
|
||||
|
||||
This product includes software developed by The Apache Software Foundation (http://www.apache.org/).
|
||||
|
||||
### Apache Log4j
|
||||
Copyright 1999-2012 Apache Software Foundation
|
||||
|
||||
This product includes software developed at The Apache Software Foundation (http://www.apache.org/).
|
||||
|
||||
ResolverUtil.java Copyright 2005-2006 Tim Fennell
|
||||
|
||||
### Ionicons
|
||||
Copyright (c) 2016 Drifty (http://drifty.com/)
|
||||
|
||||
ionicons.ttf Licensed under the accompanying MIT license
|
||||
|
||||
### Jackrabbit WebDAV Library
|
||||
Copyright 2004-2014 The Apache Software Foundation
|
||||
|
||||
This product includes software developed at The Apache Software Foundation (http://www.apache.org/).
|
||||
|
||||
Based on source code originally developed by Day Software (http://www.day.com/).
|
||||
|
||||
### Jackson
|
||||
Jackson is a high-performance, Free/Open Source JSON processing library.
|
||||
It was originally written by Tatu Saloranta (tatu.saloranta@iki.fi), and has
|
||||
been in development since 2007.
|
||||
It is currently developed by a community of developers, as well as supported
|
||||
commercially by FasterXML.com.
|
||||
|
||||
**Licensing:** Jackson core and extension components may licensed under different licenses.
|
||||
To find the details that apply to this artifact see the accompanying Apache 2.0 license file.
|
||||
For more information, including possible other licensing options, contact
|
||||
FasterXML.com (http://fasterxml.com).
|
||||
|
||||
**Credits:** A list of contributors may be found from CREDITS file, which is included
|
||||
in some artifacts (usually source distributions); but is always available
|
||||
from the source code management (SCM) system project uses.
|
||||
|
||||
### Jetty
|
||||
Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
|
||||
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are made available under the terms of the Eclipse Public License v1.0
|
||||
and Apache License v2.0 which accompanies this distribution.
|
||||
|
||||
The UnixCrypt.java code implements the one way cryptography used by
|
||||
Unix systems for simple password protection. Copyright 1996 Aki Yoshida,
|
||||
modified April 2001 by Iris Van den Broeke, Daniel Deville.
|
||||
Permission to use, copy, modify and distribute UnixCrypt
|
||||
for non-commercial or commercial purposes and without fee is
|
||||
granted provided that the copyright notice appears in all copies.
|
||||
|
||||
### JUnit
|
||||
Copyright (c) 2000-2006, www.hamcrest.org
|
||||
|
||||
Licensed under the accompanying BSD license file.
|
||||
20
README.md
20
README.md
@@ -2,10 +2,10 @@
|
||||
|
||||
[](https://travis-ci.org/cryptomator/cryptomator)
|
||||
[](https://scan.coverity.com/projects/cryptomator-cryptomator)
|
||||
[](https://coveralls.io/github/cryptomator/cryptomator?branch=master)
|
||||
[](https://gitter.im/cryptomator/cryptomator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://www.codacy.com/app/cryptomator/cryptomator?utm_source=github.com&utm_medium=referral&utm_content=cryptomator/cryptomator&utm_campaign=Badge_Grade)
|
||||
[](http://twitter.com/Cryptomator)
|
||||
[](https://poeditor.com/join/project/bHwbvJmx0E)
|
||||
[](https://github.com/cryptomator/cryptomator/releases/latest)
|
||||
|
||||
Multi-platform transparent client-side encryption of your files in the cloud.
|
||||
|
||||
@@ -13,12 +13,13 @@ Download native binaries of Cryptomator on [cryptomator.org](https://cryptomator
|
||||
|
||||
## Features
|
||||
|
||||
- Works with Dropbox, Google Drive, OneDrive, and any other cloud storage service that synchronizes with a local directory
|
||||
- Works with Dropbox, Google Drive, OneDrive, Nextcloud and any other cloud storage service which synchronizes with a local directory
|
||||
- Open Source means: No backdoors, control is better than trust
|
||||
- Client-side: No accounts, no data shared with any online service
|
||||
- Totally transparent: Just work on the virtual drive as if it were a USB flash drive
|
||||
- AES encryption with 256-bit key length
|
||||
- Filenames get encrypted, too
|
||||
- File names get encrypted
|
||||
- Folder structure gets obfuscated
|
||||
- Use as many vaults in your Dropbox as you want, each having individual passwords
|
||||
|
||||
### Privacy
|
||||
@@ -43,17 +44,20 @@ For more information on the security details visit [cryptomator.org](https://cry
|
||||
|
||||
### Dependencies
|
||||
|
||||
* Java 8 + JCE unlimited strength policy files (needed for 256-bit keys)
|
||||
* Java 8 (min. 8u51, we recommend to use the current version)
|
||||
* [JCE unlimited strength policy files](http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html) (needed for 256-bit keys)
|
||||
* Maven 3
|
||||
* Optional: OS-dependent build tools for native packaging (see [Windows](https://github.com/cryptomator/cryptomator-win), [OS X](https://github.com/cryptomator/cryptomator-osx), [Debian](https://github.com/cryptomator/cryptomator-deb))
|
||||
* Optional: OS-dependent build tools for native packaging (see [Windows](https://github.com/cryptomator/cryptomator-win), [OS X](https://github.com/cryptomator/cryptomator-osx), [Linux](https://github.com/cryptomator/builder-containers))
|
||||
|
||||
### Run Maven
|
||||
|
||||
```
|
||||
cd main
|
||||
mvn clean install
|
||||
mvn clean install -Prelease
|
||||
```
|
||||
|
||||
An executable jar file will be created inside `main/uber-jar/target`.
|
||||
|
||||
## Contributing to Cryptomator
|
||||
|
||||
Please read our [contribution guide](https://github.com/cryptomator/cryptomator/blob/master/CONTRIBUTING.md), if you would like to report a bug, ask a question or help us with coding.
|
||||
@@ -64,4 +68,4 @@ Help us keep Cryptomator open and inclusive. Please read and follow our [Code of
|
||||
|
||||
## License
|
||||
|
||||
Distributed under the MIT X Consortium license. See the `LICENSES/MIT-X-Consortium-License.txt` file for more info.
|
||||
This project is dual-licensed under the GPLv3 for FOSS projects as well as a commercial license for independent software vendors and resellers. If you want to modify this application under different conditions, feel free to contact our support team.
|
||||
|
||||
@@ -14,6 +14,12 @@
|
||||
</includes>
|
||||
<outputDirectory>libs</outputDirectory>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>target/fixed-binaries</directory>
|
||||
<filtered>false</filtered>
|
||||
<outputDirectory>fixed-binaries</outputDirectory>
|
||||
<fileMode>755</fileMode>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>target/package</directory>
|
||||
<filtered>false</filtered>
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2016 Sebastian Stenzel
|
||||
This file is licensed under the terms of the MIT license.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.0.4</version>
|
||||
<version>1.3.1</version>
|
||||
</parent>
|
||||
<artifactId>ant-kit</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
@@ -18,7 +14,7 @@
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>ui</artifactId>
|
||||
<artifactId>launcher</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -44,7 +40,7 @@
|
||||
<!-- copy resources to target/: -->
|
||||
<plugin>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>2.7</version>
|
||||
<version>3.0.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-resources</id>
|
||||
@@ -60,6 +56,16 @@
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
<excludes>
|
||||
<exclude>fixed-binaries/**</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>false</filtering>
|
||||
<includes>
|
||||
<include>fixed-binaries/**</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
@@ -69,8 +75,8 @@
|
||||
|
||||
<!-- create antkit.tar.gz: -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
<taskdef uri="javafx:com.sun.javafx.tools.ant" resource="com/sun/javafx/tools/ant/antlib.xml" classpath="\${java.class.path}:\${java.home}/../lib/ant-javafx.jar:." />
|
||||
|
||||
<!-- Define application to build -->
|
||||
<fx:application id="Cryptomator" name="Cryptomator" version="${project.version}" mainClass="org.cryptomator.ui.Cryptomator" />
|
||||
<fx:application id="Cryptomator" name="Cryptomator" version="${project.version}" mainClass="org.cryptomator.launcher.Cryptomator" />
|
||||
|
||||
<!-- Create main application jar -->
|
||||
<target name="create-jar">
|
||||
<fx:jar destfile="antbuild/Cryptomator-${project.version}.jar">
|
||||
<fx:application refid="Cryptomator" />
|
||||
<fx:fileset dir="libs" includes="ui-${project.version}.jar" />
|
||||
<fx:fileset dir="libs" includes="launcher-${project.version}.jar" />
|
||||
<fx:resources>
|
||||
<fx:fileset dir="libs" type="jar" includes="*.jar" excludes="ui-${project.version}.jar" />
|
||||
<fx:fileset dir="libs" type="jar" includes="*.jar" excludes="launcher-${project.version}.jar" />
|
||||
</fx:resources>
|
||||
<fx:manifest>
|
||||
<fx:attribute name="Implementation-Vendor" value="cryptomator.org" />
|
||||
@@ -21,21 +21,6 @@
|
||||
</fx:jar>
|
||||
</target>
|
||||
|
||||
<!-- Create native image -->
|
||||
<target name="create-linux-image-with-jvm" depends="create-jar">
|
||||
<fx:deploy nativeBundles="image" outdir="antbuild" outfile="Cryptomator-${project.version}" verbose="true">
|
||||
<fx:application refid="Cryptomator" />
|
||||
<fx:platform j2se="8.0">
|
||||
<fx:property name="cryptomator.logPath" value="~/.Cryptomator/cryptomator.log" />
|
||||
<fx:jvmarg value="-Xmx512m"/>
|
||||
</fx:platform>
|
||||
<fx:resources>
|
||||
<fx:fileset dir="antbuild" type="jar" includes="Cryptomator-${project.version}.jar" />
|
||||
<fx:fileset dir="libs" type="jar" includes="*.jar" excludes="ui-${project.version}.jar"/>
|
||||
</fx:resources>
|
||||
</fx:deploy>
|
||||
</target>
|
||||
|
||||
<!-- Create Debian package -->
|
||||
<target name="deb" depends="create-jar">
|
||||
<fx:deploy nativeBundles="deb" outdir="antbuild" outfile="Cryptomator-${project.version}" verbose="true">
|
||||
@@ -44,12 +29,17 @@
|
||||
<fx:association mimetype="application/x-vnd.cryptomator-vault-metadata" extension="cryptomator" description="Cryptomator Vault Metadata" />
|
||||
</fx:info>
|
||||
<fx:platform j2se="8.0">
|
||||
<fx:property name="cryptomator.logPath" value="~/.Cryptomator/cryptomator.log" />
|
||||
<fx:jvmarg value="-Xmx1048m"/>
|
||||
<fx:property name="logback.configurationFile" value="logback.xml" />
|
||||
<fx:property name="cryptomator.settingsPath" value="~/.Cryptomator/settings.json" />
|
||||
<fx:property name="cryptomator.ipcPortPath" value="~/.Cryptomator/ipcPort.bin" />
|
||||
<fx:jvmarg value="-Xss2m"/>
|
||||
<fx:jvmarg value="-Xmx512m"/>
|
||||
</fx:platform>
|
||||
<fx:resources>
|
||||
<fx:fileset dir="." type="data" includes="logback.xml" />
|
||||
<fx:fileset dir="antbuild" type="jar" includes="Cryptomator-${project.version}.jar" />
|
||||
<fx:fileset dir="libs" type="jar" includes="*.jar" excludes="ui-${project.version}.jar"/>
|
||||
<fx:fileset dir="libs" type="jar" includes="*.jar" excludes="launcher-${project.version}.jar"/>
|
||||
<fx:fileset dir="fixed-binaries" type="data" includes="linux-launcher-*" arch=""/>
|
||||
</fx:resources>
|
||||
<fx:permissions elevated="false" />
|
||||
<fx:preferences install="true" />
|
||||
@@ -64,12 +54,17 @@
|
||||
<fx:association mimetype="application/x-vnd.cryptomator-vault-metadata" extension="cryptomator" description="Cryptomator Vault Metadata" />
|
||||
</fx:info>
|
||||
<fx:platform j2se="8.0">
|
||||
<fx:property name="cryptomator.logPath" value="~/.Cryptomator/cryptomator.log" />
|
||||
<fx:jvmarg value="-Xmx1048m"/>
|
||||
<fx:property name="logback.configurationFile" value="logback.xml" />
|
||||
<fx:property name="cryptomator.settingsPath" value="~/.Cryptomator/settings.json" />
|
||||
<fx:property name="cryptomator.ipcPortPath" value="~/.Cryptomator/ipcPort.bin" />
|
||||
<fx:jvmarg value="-Xss2m"/>
|
||||
<fx:jvmarg value="-Xmx512m"/>
|
||||
</fx:platform>
|
||||
<fx:resources>
|
||||
<fx:fileset dir="." type="data" includes="logback.xml" />
|
||||
<fx:fileset dir="antbuild" type="jar" includes="Cryptomator-${project.version}.jar" />
|
||||
<fx:fileset dir="libs" type="jar" includes="*.jar" excludes="ui-${project.version}.jar"/>
|
||||
<fx:fileset dir="libs" type="jar" includes="*.jar" excludes="launcher-${project.version}.jar"/>
|
||||
<fx:fileset dir="fixed-binaries" type="data" includes="linux-launcher-*" arch=""/>
|
||||
</fx:resources>
|
||||
<fx:permissions elevated="false" />
|
||||
<fx:preferences install="true" />
|
||||
|
||||
Binary file not shown.
Binary file not shown.
44
main/ant-kit/src/main/resources/logback.xml
Normal file
44
main/ant-kit/src/main/resources/logback.xml
Normal file
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE xml>
|
||||
<configuration scan="true" debug="true">
|
||||
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${user.home}/.Cryptomator/cryptomator.log</file>
|
||||
<append>false</append>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
|
||||
<fileNamePattern>${user.home}/.Cryptomator/cryptomator%i.log</fileNamePattern>
|
||||
<minIndex>0</minIndex>
|
||||
<maxIndex>9</maxIndex>
|
||||
</rollingPolicy>
|
||||
<triggeringPolicy class="org.cryptomator.logging.LaunchBasedTriggeringPolicy" />
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="UPGRADE_FILE" class="ch.qos.logback.core.FileAppender">
|
||||
<file>${user.home}/.Cryptomator/upgrade.log</file>
|
||||
<append>true</append>
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="org.cryptomator" level="INFO" />
|
||||
<logger name="org.eclipse.jetty.server.HttpChannel" level="INFO" />
|
||||
<logger name="org.cryptomator.ui.model" level="INFO">
|
||||
<appender-ref ref="UPGRADE_FILE" />
|
||||
</logger>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
<appender-ref ref="FILE" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
@@ -9,7 +9,7 @@ Priority: optional
|
||||
Architecture: APPLICATION_ARCH
|
||||
Provides: APPLICATION_PACKAGE
|
||||
Installed-Size: APPLICATION_INSTALLED_SIZE
|
||||
Depends: gvfs-bin, gvfs-backends, gvfs-fuse, xdg-utils
|
||||
Depends: gvfs-bin, gvfs-backends, gvfs-fuse
|
||||
Description: Multi-platform client-side encryption of your cloud files.
|
||||
Cryptomator provides free client-side AES encryption for your cloud files.
|
||||
Create encrypted vaults, which get mounted as virtual volumes. Whatever
|
||||
|
||||
51
main/ant-kit/src/main/resources/package/linux/postinst
Normal file
51
main/ant-kit/src/main/resources/package/linux/postinst
Normal file
@@ -0,0 +1,51 @@
|
||||
#!/bin/sh
|
||||
# postinst script for APPLICATION_NAME
|
||||
#
|
||||
# see: dh_installdeb(1)
|
||||
|
||||
set -e
|
||||
|
||||
# summary of how this script can be called:
|
||||
# * <postinst> `configure' <most-recently-configured-version>
|
||||
# * <old-postinst> `abort-upgrade' <new version>
|
||||
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
|
||||
# <new-version>
|
||||
# * <postinst> `abort-remove'
|
||||
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
|
||||
# <failed-install-package> <version> `removing'
|
||||
# <conflicting-package> <version>
|
||||
# for details, see http://www.debian.org/doc/debian-policy/ or
|
||||
# the debian-policy package
|
||||
|
||||
case "$1" in
|
||||
configure)
|
||||
echo Adding shortcut to the menu
|
||||
SECONDARY_LAUNCHERS_INSTALL
|
||||
APP_CDS_CACHE
|
||||
mkdir -pm 644 /usr/share/desktop-directories
|
||||
xdg-desktop-menu install --novendor /opt/APPLICATION_FS_NAME/APPLICATION_LAUNCHER_FILENAME.desktop
|
||||
FILE_ASSOCIATION_INSTALL
|
||||
|
||||
rm /opt/APPLICATION_FS_NAME/APPLICATION_LAUNCHER_FILENAME
|
||||
if [ $(uname -m) = "x86_64" ]; then
|
||||
mv /opt/APPLICATION_FS_NAME/app/linux-launcher-x64 /opt/APPLICATION_FS_NAME/APPLICATION_LAUNCHER_FILENAME
|
||||
else
|
||||
mv /opt/APPLICATION_FS_NAME/app/linux-launcher-x86 /opt/APPLICATION_FS_NAME/APPLICATION_LAUNCHER_FILENAME
|
||||
fi
|
||||
;;
|
||||
|
||||
abort-upgrade|abort-remove|abort-deconfigure)
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "postinst called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# dh_installdeb will replace this with shell code automatically
|
||||
# generated by other debhelper scripts.
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
exit 0
|
||||
54
main/ant-kit/src/main/resources/package/linux/spec
Normal file
54
main/ant-kit/src/main/resources/package/linux/spec
Normal file
@@ -0,0 +1,54 @@
|
||||
Summary: APPLICATION_SUMMARY
|
||||
Name: APPLICATION_PACKAGE
|
||||
Version: APPLICATION_VERSION
|
||||
Release: 1
|
||||
License: APPLICATION_LICENSE_TYPE
|
||||
Vendor: APPLICATION_VENDOR
|
||||
Prefix: /opt
|
||||
Provides: APPLICATION_PACKAGE
|
||||
Requires: ld-linux.so.2 libX11.so.6 libXext.so.6 libXi.so.6 libXrender.so.1 libXtst.so.6 libasound.so.2 libc.so.6 libdl.so.2 libgcc_s.so.1 libm.so.6 libpthread.so.0 libthread_db.so.1
|
||||
Autoprov: 0
|
||||
Autoreq: 0
|
||||
|
||||
#avoid ARCH subfolder
|
||||
%define _rpmfilename %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm
|
||||
|
||||
#comment line below to enable effective jar compression
|
||||
#it could easily get your package size from 40 to 15Mb but
|
||||
#build time will substantially increase and it may require unpack200/system java to install
|
||||
%define __jar_repack %{nil}
|
||||
|
||||
%description
|
||||
APPLICATION_DESCRIPTION
|
||||
|
||||
%prep
|
||||
|
||||
%build
|
||||
|
||||
%install
|
||||
rm -rf %{buildroot}
|
||||
mkdir -p %{buildroot}/opt
|
||||
cp -r %{_sourcedir}/APPLICATION_FS_NAME %{buildroot}/opt
|
||||
|
||||
%files
|
||||
APPLICATION_LICENSE_FILE
|
||||
/opt/APPLICATION_FS_NAME
|
||||
|
||||
%post
|
||||
SECONDARY_LAUNCHERS_INSTALL
|
||||
APP_CDS_CACHE
|
||||
xdg-desktop-menu install --novendor /opt/APPLICATION_FS_NAME/APPLICATION_LAUNCHER_FILENAME.desktop
|
||||
FILE_ASSOCIATION_INSTALL
|
||||
rm /opt/APPLICATION_FS_NAME/APPLICATION_LAUNCHER_FILENAME
|
||||
if [ $(uname -m) = "x86_64" ]; then
|
||||
mv /opt/APPLICATION_FS_NAME/app/linux-launcher-x64 /opt/APPLICATION_FS_NAME/APPLICATION_LAUNCHER_FILENAME
|
||||
else
|
||||
mv /opt/APPLICATION_FS_NAME/app/linux-launcher-x86 /opt/APPLICATION_FS_NAME/APPLICATION_LAUNCHER_FILENAME
|
||||
fi
|
||||
|
||||
%preun
|
||||
SECONDARY_LAUNCHERS_REMOVE
|
||||
xdg-desktop-menu uninstall --novendor /opt/APPLICATION_FS_NAME/APPLICATION_LAUNCHER_FILENAME.desktop
|
||||
FILE_ASSOCIATION_REMOVE
|
||||
|
||||
%clean
|
||||
1
main/commons-test/.gitignore
vendored
1
main/commons-test/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
/target/
|
||||
@@ -1,39 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2015 Markus Kreusch
|
||||
This file is licensed under the terms of the MIT license.
|
||||
See the LICENSE.txt file for more info.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.0.4</version>
|
||||
</parent>
|
||||
<artifactId>commons-test</artifactId>
|
||||
<name>Cryptomator common test dependencies</name>
|
||||
<description>Shared utilities for tests</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.bechte.junit</groupId>
|
||||
<artifactId>junit-hierarchicalcontextrunner</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-all</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>commons</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -1,73 +0,0 @@
|
||||
package org.cryptomator.common.test;
|
||||
|
||||
import static java.nio.file.Files.walkFileTree;
|
||||
import static java.util.Collections.synchronizedSet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.FileVisitor;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class TempFilesRemovedOnShutdown {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TempFilesRemovedOnShutdown.class);
|
||||
|
||||
private static final Set<Path> PATHS_TO_REMOVE_ON_SHUTDOWN = synchronizedSet(new HashSet<>());
|
||||
private static final Thread ON_SHUTDOWN_DELETER = new Thread(TempFilesRemovedOnShutdown::removeAll);
|
||||
|
||||
static {
|
||||
Runtime.getRuntime().addShutdownHook(ON_SHUTDOWN_DELETER);
|
||||
}
|
||||
|
||||
public static Path createTempDirectory(String prefix) throws IOException {
|
||||
Path path = Files.createTempDirectory(prefix);
|
||||
PATHS_TO_REMOVE_ON_SHUTDOWN.add(path);
|
||||
return path;
|
||||
}
|
||||
|
||||
private static void removeAll() {
|
||||
PATHS_TO_REMOVE_ON_SHUTDOWN.forEach(TempFilesRemovedOnShutdown::remove);
|
||||
}
|
||||
|
||||
private static void remove(Path path) {
|
||||
try {
|
||||
tryRemove(path);
|
||||
} catch (Throwable e) {
|
||||
LOG.debug("Failed to remove " + path, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void tryRemove(Path path) throws IOException {
|
||||
walkFileTree(path, new FileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||
Files.delete(file);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
|
||||
Files.delete(dir);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package org.cryptomator.common.test.matcher;
|
||||
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.Matchers;
|
||||
|
||||
/**
|
||||
* Wraps hamcrest contains and containsInAnyOrder matcher factory methods to
|
||||
* avoid problems due to incorrect / inconsistent handling of generics by
|
||||
* several java compilers.
|
||||
*
|
||||
* @author Markus Kreusch
|
||||
*/
|
||||
public class ContainsMatcher {
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
@SafeVarargs
|
||||
public static <T> Matcher<Iterable<? super T>> containsInAnyOrder(Matcher<? extends T>... matchers) {
|
||||
return Matchers.containsInAnyOrder((Matcher[]) matchers);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
@SafeVarargs
|
||||
public static <T> Matcher<Iterable<? super T>> contains(Matcher<? extends T>... matchers) {
|
||||
return Matchers.contains((Matcher[]) matchers);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
package org.cryptomator.common.test.matcher;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.hamcrest.Description;
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.TypeSafeDiagnosingMatcher;
|
||||
|
||||
public class ExceptionMatcher<T extends Throwable> extends TypeSafeDiagnosingMatcher<T> {
|
||||
|
||||
public static <T extends Throwable> ExceptionMatcher<T> ofType(Class<T> exceptionType) {
|
||||
return new ExceptionMatcher<>(exceptionType);
|
||||
}
|
||||
|
||||
private final Class<T> exceptionType;
|
||||
private final Optional<Matcher<T>> subMatcher;
|
||||
|
||||
private ExceptionMatcher(Class<T> exceptionType) {
|
||||
super(exceptionType);
|
||||
this.exceptionType = exceptionType;
|
||||
this.subMatcher = Optional.empty();
|
||||
}
|
||||
|
||||
private ExceptionMatcher(Class<T> exceptionType, Matcher<T> subMatcher) {
|
||||
super(exceptionType);
|
||||
this.exceptionType = exceptionType;
|
||||
this.subMatcher = Optional.of(subMatcher);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
subMatcher.ifPresent(description::appendDescriptionOf);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean matchesSafely(T item, Description mismatchDescription) {
|
||||
if (subMatcher.map(matcher -> !matcher.matches(item)).orElse(false)) {
|
||||
subMatcher.get().describeMismatch(item, mismatchDescription);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public Matcher<T> withCauseThat(Matcher<? super Throwable> matcher) {
|
||||
return new ExceptionMatcher<T>(exceptionType, new PropertyMatcher<>(exceptionType, Throwable::getCause, "cause", matcher));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package org.cryptomator.common.test.matcher;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.hamcrest.Description;
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.TypeSafeDiagnosingMatcher;
|
||||
|
||||
public class OptionalMatcher {
|
||||
|
||||
public static <T> Matcher<Optional<T>> presentOptionalWithValueThat(Matcher<? super T> valueMatcher) {
|
||||
return new TypeSafeDiagnosingMatcher<Optional<T>>(Optional.class) {
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
description //
|
||||
.appendText("a present Optional with a value that ") //
|
||||
.appendDescriptionOf(valueMatcher);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean matchesSafely(Optional<T> item, Description mismatchDescription) {
|
||||
if (item.isPresent()) {
|
||||
if (valueMatcher.matches(item.get())) {
|
||||
return true;
|
||||
} else {
|
||||
mismatchDescription.appendText("a present Optional with value that ");
|
||||
valueMatcher.describeMismatch(item, mismatchDescription);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
mismatchDescription.appendText("an empty Optional");
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public static <T> Matcher<Optional<T>> emptyOptional() {
|
||||
return new TypeSafeDiagnosingMatcher<Optional<T>>(Optional.class) {
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
description.appendText("an empty Optional");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean matchesSafely(Optional<T> item, Description mismatchDescription) {
|
||||
if (item.isPresent()) {
|
||||
mismatchDescription.appendText("a present Optional of ").appendValue(item.get());
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Markus Kreusch
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
******************************************************************************/
|
||||
package org.cryptomator.common.test.matcher;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.hamcrest.Description;
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.TypeSafeDiagnosingMatcher;
|
||||
|
||||
public class PropertyMatcher<T, P> extends TypeSafeDiagnosingMatcher<T> {
|
||||
|
||||
private final Class<T> expectedType;
|
||||
private final Function<? super T, P> getter;
|
||||
private final String name;
|
||||
private final Matcher<? super P> subMatcher;
|
||||
|
||||
public PropertyMatcher(Class<T> type, Function<? super T, P> getter, String name, Matcher<? super P> subMatcher) {
|
||||
super(type);
|
||||
this.expectedType = type;
|
||||
this.getter = getter;
|
||||
this.name = name;
|
||||
this.subMatcher = subMatcher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
description.appendText("a ") //
|
||||
.appendText(expectedType.getSimpleName()) //
|
||||
.appendText(" with a ") //
|
||||
.appendText(name) //
|
||||
.appendText(" that ") //
|
||||
.appendDescriptionOf(subMatcher);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean matchesSafely(T item, Description mismatchDescription) {
|
||||
P propertyValue = getter.apply(item);
|
||||
if (subMatcher.matches(propertyValue)) {
|
||||
return true;
|
||||
} else {
|
||||
mismatchDescription.appendText("a ") //
|
||||
.appendText(expectedType.getSimpleName()) //
|
||||
.appendText(" with a ") //
|
||||
.appendText(name) //
|
||||
.appendText(" that ");
|
||||
subMatcher.describeMismatch(propertyValue, mismatchDescription);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package org.cryptomator.common.test.mockito;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
public class Answers {
|
||||
|
||||
public static <T> Answer<T> collectParameters(Answer<T> answer, Consumer<?>... parameterConsumers) {
|
||||
return new Answer<T>() {
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
@Override
|
||||
public T answer(InvocationOnMock invocation) throws Throwable {
|
||||
for (int i = 0; i < invocation.getArguments().length; i++) {
|
||||
if (parameterConsumers.length > i) {
|
||||
((Consumer) parameterConsumers[i]).accept(invocation.getArguments()[i]);
|
||||
}
|
||||
}
|
||||
return answer.answer(invocation);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> Answer<T> consecutiveAnswers(Answer<T>... answers) {
|
||||
if (answers == null || answers.length == 0) {
|
||||
throw new IllegalArgumentException("Required at least one answer");
|
||||
}
|
||||
if (asList(answers).contains(null)) {
|
||||
throw new IllegalArgumentException("No answers must be null");
|
||||
}
|
||||
return new Answer<T>() {
|
||||
private int nextIndex = 0;
|
||||
|
||||
@Override
|
||||
public T answer(InvocationOnMock invocation) throws Throwable {
|
||||
try {
|
||||
return answers[nextIndex].answer(invocation);
|
||||
} finally {
|
||||
nextIndex = (nextIndex + 1) % answers.length;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public static <T> Answer<T> value(T value) {
|
||||
return new Answer<T>() {
|
||||
@Override
|
||||
public T answer(InvocationOnMock invocation) throws Throwable {
|
||||
return value;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,19 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2015 Markus Kreusch
|
||||
This file is licensed under the terms of the MIT license.
|
||||
See the LICENSE.txt file for more info.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.0.4</version>
|
||||
<version>1.3.1</version>
|
||||
</parent>
|
||||
<artifactId>commons</artifactId>
|
||||
<name>Cryptomator common</name>
|
||||
<name>Cryptomator Commons</name>
|
||||
<description>Shared utilities</description>
|
||||
|
||||
<dependencies>
|
||||
@@ -26,42 +20,26 @@
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.fxmisc.easybind</groupId>
|
||||
<artifactId>easybind</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- DI -->
|
||||
<dependency>
|
||||
<groupId>com.google.dagger</groupId>
|
||||
<artifactId>dagger</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Logging -->
|
||||
<dependency>
|
||||
<groupId>com.google.dagger</groupId>
|
||||
<artifactId>dagger-compiler</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Test -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.bechte.junit</groupId>
|
||||
<artifactId>junit-hierarchicalcontextrunner</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-all</artifactId>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
package org.cryptomator.common;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class CachingSupplier<T> implements Supplier<T> {
|
||||
|
||||
public static <T> Supplier<T> from(Supplier<T> delegate) {
|
||||
return new CachingSupplier<>(delegate);
|
||||
}
|
||||
|
||||
private Supplier<T> delegate;
|
||||
|
||||
private CachingSupplier(Supplier<T> delegate) {
|
||||
this.delegate = () -> {
|
||||
T result = delegate.get();
|
||||
CachingSupplier.this.delegate = () -> result;
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get() {
|
||||
return delegate.get();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,3 +1,8 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.common;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.common;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ConsumerThrowingException<T, E extends Exception> {
|
||||
public interface ConsumerThrowingException<T, E extends Throwable> {
|
||||
|
||||
void accept(T t) throws E;
|
||||
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
package org.cryptomator.common;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class Holder<V> implements Supplier<V>, Consumer<V> {
|
||||
|
||||
private final V initial;
|
||||
|
||||
private V value;
|
||||
|
||||
public <W extends V> Holder(W initial) {
|
||||
this.initial = initial;
|
||||
reset();
|
||||
}
|
||||
|
||||
public V get() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void set(V value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
set(initial);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(V value) {
|
||||
set(value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,15 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.common;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
|
||||
public final class LazyInitializer {
|
||||
|
||||
@@ -9,7 +17,7 @@ public final class LazyInitializer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Threadsafe lazy initialization pattern as proposed on http://stackoverflow.com/a/30247202/4014509
|
||||
* Same as {@link #initializeLazily(AtomicReference, SupplierThrowingException, Class)} except that no checked exception may be thrown by the factory function.
|
||||
*
|
||||
* @param <T> Type of the value
|
||||
* @param reference A reference to a maybe not yet initialized value.
|
||||
@@ -17,17 +25,55 @@ public final class LazyInitializer {
|
||||
* @return The initialized value
|
||||
*/
|
||||
public static <T> T initializeLazily(AtomicReference<T> reference, Supplier<T> factory) {
|
||||
final T existingInstance = reference.get();
|
||||
if (existingInstance != null) {
|
||||
return existingInstance;
|
||||
SupplierThrowingException<T, RuntimeException> factoryThrowingRuntimeExceptions = () -> factory.get();
|
||||
return initializeLazily(reference, factoryThrowingRuntimeExceptions, RuntimeException.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Threadsafe lazy initialization pattern as proposed on http://stackoverflow.com/a/30247202/4014509
|
||||
*
|
||||
* @param <T> Type of the value
|
||||
* @param <E> Type of the any expected exception that may occur during initialization
|
||||
* @param reference A reference to a maybe not yet initialized value.
|
||||
* @param factory A factory providing a value for the reference, if it doesn't exist yet. The factory may be invoked multiple times, but only one result will survive.
|
||||
* @param exceptionType Expected exception type.
|
||||
* @return The initialized value
|
||||
* @throws E Exception thrown by the factory function.
|
||||
*/
|
||||
public static <T, E extends Exception> T initializeLazily(AtomicReference<T> reference, SupplierThrowingException<T, E> factory, Class<E> exceptionType) throws E {
|
||||
final T existing = reference.get();
|
||||
if (existing != null) {
|
||||
return existing;
|
||||
} else {
|
||||
final T newInstance = factory.get();
|
||||
if (reference.compareAndSet(null, newInstance)) {
|
||||
return newInstance;
|
||||
} else {
|
||||
return reference.get();
|
||||
try {
|
||||
return reference.updateAndGet(invokeFactoryIfNull(factory));
|
||||
} catch (InitializationException e) {
|
||||
Throwables.throwIfUnchecked(e.getCause());
|
||||
Throwables.throwIfInstanceOf(e.getCause(), exceptionType);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static <T, E extends Exception> UnaryOperator<T> invokeFactoryIfNull(SupplierThrowingException<T, E> factory) throws InitializationException {
|
||||
return currentValue -> {
|
||||
if (currentValue == null) {
|
||||
try {
|
||||
return factory.get();
|
||||
} catch (Exception e) {
|
||||
throw new InitializationException(e);
|
||||
}
|
||||
} else {
|
||||
return currentValue;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static class InitializationException extends RuntimeException {
|
||||
|
||||
public InitializationException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,28 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.common;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
public final class Optionals {
|
||||
|
||||
private Optionals() {
|
||||
}
|
||||
|
||||
public static <T, E extends Exception> void ifPresent(Optional<T> optional, ConsumerThrowingException<T, E> consumer) throws E {
|
||||
final T t = optional.orElse(null);
|
||||
if (t != null) {
|
||||
consumer.accept(t);
|
||||
}
|
||||
/**
|
||||
* Returns a function that is equivalent to the input function but immediately gets the value of the returned optional when invoked.
|
||||
*
|
||||
* @param <T> the type of the input to the function
|
||||
* @param <R> the type of the result of the function
|
||||
* @param function An {@code Optional}-bearing input function {@code Function<Foo, Optional<Bar>>}
|
||||
* @return A {@code Function<Foo, Bar>}, that may throw a NoSuchElementException, if the original function returns an empty optional.
|
||||
*/
|
||||
public static <T, R> Function<T, R> unwrap(Function<T, Optional<R>> function) {
|
||||
return t -> function.apply(t).get();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.common;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface RunnableThrowingException<T extends Exception> {
|
||||
public interface RunnableThrowingException<T extends Throwable> {
|
||||
|
||||
void run() throws T;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
* Copyright (c) 2016, 2017 Sebastian Stenzel and others.
|
||||
* All rights reserved.
|
||||
* This program and the accompanying materials are made available under the terms of the accompanying LICENSE file.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
@@ -12,12 +12,51 @@ import java.util.Comparator;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* Compares version strings according to <a href="http://semver.org/spec/v2.0.0.html">SemVer 2.0.0</a>.
|
||||
*/
|
||||
public class SemVerComparator implements Comparator<String> {
|
||||
|
||||
private static final char VERSION_SEP = '.'; // http://semver.org/spec/v2.0.0.html#spec-item-2
|
||||
private static final String PRE_RELEASE_SEP = "-"; // http://semver.org/spec/v2.0.0.html#spec-item-9
|
||||
private static final String BUILD_SEP = "+"; // http://semver.org/spec/v2.0.0.html#spec-item-10
|
||||
|
||||
@Override
|
||||
public int compare(String version1, String version2) {
|
||||
final String[] vComps1 = StringUtils.split(version1, '.');
|
||||
final String[] vComps2 = StringUtils.split(version2, '.');
|
||||
// "Build metadata SHOULD be ignored when determining version precedence.
|
||||
// Thus two versions that differ only in the build metadata, have the same precedence."
|
||||
String v1WithoutBuildMetadata = StringUtils.substringBefore(version1, BUILD_SEP);
|
||||
String v2WithoutBuildMetadata = StringUtils.substringBefore(version2, BUILD_SEP);
|
||||
|
||||
if (v1WithoutBuildMetadata.equals(v2WithoutBuildMetadata)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
String v1MajorMinorPatch = StringUtils.substringBefore(v1WithoutBuildMetadata, PRE_RELEASE_SEP);
|
||||
String v2MajorMinorPatch = StringUtils.substringBefore(v2WithoutBuildMetadata, PRE_RELEASE_SEP);
|
||||
String v1PreReleaseVersion = StringUtils.substringAfter(v1WithoutBuildMetadata, PRE_RELEASE_SEP);
|
||||
String v2PreReleaseVersion = StringUtils.substringAfter(v2WithoutBuildMetadata, PRE_RELEASE_SEP);
|
||||
return compare(v1MajorMinorPatch, v1PreReleaseVersion, v2MajorMinorPatch, v2PreReleaseVersion);
|
||||
}
|
||||
|
||||
private int compare(String v1MajorMinorPatch, String v1PreReleaseVersion, String v2MajorMinorPatch, String v2PreReleaseVersion) {
|
||||
int comparisonResult = compareNumericallyThenLexicographically(v1MajorMinorPatch, v2MajorMinorPatch);
|
||||
if (comparisonResult == 0) {
|
||||
if (v1PreReleaseVersion.isEmpty()) {
|
||||
return 1; // 1.0.0 > 1.0.0-BETA
|
||||
} else if (v2PreReleaseVersion.isEmpty()) {
|
||||
return -1; // 1.0.0-BETA < 1.0.0
|
||||
} else {
|
||||
return compareNumericallyThenLexicographically(v1PreReleaseVersion, v2PreReleaseVersion);
|
||||
}
|
||||
} else {
|
||||
return comparisonResult;
|
||||
}
|
||||
}
|
||||
|
||||
private int compareNumericallyThenLexicographically(String version1, String version2) {
|
||||
final String[] vComps1 = StringUtils.split(version1, VERSION_SEP);
|
||||
final String[] vComps2 = StringUtils.split(version2, VERSION_SEP);
|
||||
final int commonCompCount = Math.min(vComps1.length, vComps2.length);
|
||||
|
||||
for (int i = 0; i < commonCompCount; i++) {
|
||||
@@ -35,7 +74,7 @@ public class SemVerComparator implements Comparator<String> {
|
||||
}
|
||||
}
|
||||
|
||||
// all in common so far? longest version string wins:
|
||||
// all in common so far? longest version string is considered the higher version:
|
||||
return vComps1.length - vComps2.length;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.common;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface SupplierThrowingException<T, E extends Throwable> {
|
||||
|
||||
T get() throws E;
|
||||
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
package org.cryptomator.common;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.util.concurrent.ExecutionError;
|
||||
import com.google.common.util.concurrent.UncheckedExecutionException;
|
||||
|
||||
public class WeakValuedCache<Key, Value> {
|
||||
|
||||
private final LoadingCache<Key, Value> delegate;
|
||||
|
||||
private WeakValuedCache(Function<Key, Value> loader) {
|
||||
delegate = CacheBuilder.newBuilder() //
|
||||
.weakValues() //
|
||||
.build(new CacheLoader<Key, Value>() {
|
||||
@Override
|
||||
public Value load(Key key) {
|
||||
return loader.apply(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static <Key, Value> WeakValuedCache<Key, Value> usingLoader(Function<Key, Value> loader) {
|
||||
return new WeakValuedCache<>(loader);
|
||||
}
|
||||
|
||||
public Value get(Key key) {
|
||||
try {
|
||||
return delegate.get(key);
|
||||
} catch (ExecutionException e) {
|
||||
throw new IllegalStateException("No checked exception can be thrown by loader", e);
|
||||
} catch (UncheckedExecutionException e) {
|
||||
throw (RuntimeException) e.getCause();
|
||||
} catch (ExecutionError e) {
|
||||
throw (Error) e.getCause();
|
||||
}
|
||||
}
|
||||
|
||||
public void forEach(BiConsumer<Key, Value> function) {
|
||||
delegate.asMap().forEach(function);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2014, 2017 Sebastian Stenzel
|
||||
* All rights reserved.
|
||||
* This program and the accompanying materials are made available under the terms of the accompanying LICENSE file.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
******************************************************************************/
|
||||
package org.cryptomator.common.settings;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
|
||||
public class Settings {
|
||||
|
||||
public static final int MIN_PORT = 1024;
|
||||
public static final int MAX_PORT = 65535;
|
||||
public static final boolean DEFAULT_CHECK_FOR_UDPATES = true;
|
||||
public static final int DEFAULT_PORT = 42427;
|
||||
public static final int DEFAULT_NUM_TRAY_NOTIFICATIONS = 3;
|
||||
public static final String DEFAULT_GVFS_SCHEME = "dav";
|
||||
public static final boolean DEFAULT_DEBUG_MODE = false;
|
||||
|
||||
private final ObservableList<VaultSettings> directories = FXCollections.observableArrayList(VaultSettings::observables);
|
||||
private final BooleanProperty checkForUpdates = new SimpleBooleanProperty(DEFAULT_CHECK_FOR_UDPATES);
|
||||
private final IntegerProperty port = new SimpleIntegerProperty(DEFAULT_PORT);
|
||||
private final IntegerProperty numTrayNotifications = new SimpleIntegerProperty(DEFAULT_NUM_TRAY_NOTIFICATIONS);
|
||||
private final StringProperty preferredGvfsScheme = new SimpleStringProperty(DEFAULT_GVFS_SCHEME);
|
||||
private final BooleanProperty debugMode = new SimpleBooleanProperty(DEFAULT_DEBUG_MODE);
|
||||
private Consumer<Settings> saveCmd;
|
||||
|
||||
/**
|
||||
* Package-private constructor; use {@link SettingsProvider}.
|
||||
*/
|
||||
Settings() {
|
||||
directories.addListener((ListChangeListener.Change<? extends VaultSettings> change) -> this.save());
|
||||
checkForUpdates.addListener(this::somethingChanged);
|
||||
port.addListener(this::somethingChanged);
|
||||
numTrayNotifications.addListener(this::somethingChanged);
|
||||
preferredGvfsScheme.addListener(this::somethingChanged);
|
||||
debugMode.addListener(this::somethingChanged);
|
||||
}
|
||||
|
||||
void setSaveCmd(Consumer<Settings> saveCmd) {
|
||||
this.saveCmd = saveCmd;
|
||||
}
|
||||
|
||||
private void somethingChanged(ObservableValue<?> observable, Object oldValue, Object newValue) {
|
||||
this.save();
|
||||
}
|
||||
|
||||
void save() {
|
||||
if (saveCmd != null) {
|
||||
saveCmd.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
/* Getter/Setter */
|
||||
|
||||
public ObservableList<VaultSettings> getDirectories() {
|
||||
return directories;
|
||||
}
|
||||
|
||||
public BooleanProperty checkForUpdates() {
|
||||
return checkForUpdates;
|
||||
}
|
||||
|
||||
public IntegerProperty port() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public IntegerProperty numTrayNotifications() {
|
||||
return numTrayNotifications;
|
||||
}
|
||||
|
||||
public StringProperty preferredGvfsScheme() {
|
||||
return preferredGvfsScheme;
|
||||
}
|
||||
|
||||
public BooleanProperty debugMode() {
|
||||
return debugMode;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.common.settings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
public class SettingsJsonAdapter extends TypeAdapter<Settings> {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SettingsJsonAdapter.class);
|
||||
|
||||
private final VaultSettingsJsonAdapter vaultSettingsJsonAdapter = new VaultSettingsJsonAdapter();
|
||||
|
||||
@Override
|
||||
public void write(JsonWriter out, Settings value) throws IOException {
|
||||
out.beginObject();
|
||||
out.name("directories");
|
||||
writeVaultSettingsArray(out, value.getDirectories());
|
||||
out.name("checkForUpdatesEnabled").value(value.checkForUpdates().get());
|
||||
out.name("port").value(value.port().get());
|
||||
out.name("numTrayNotifications").value(value.numTrayNotifications().get());
|
||||
out.name("preferredGvfsScheme").value(value.preferredGvfsScheme().get());
|
||||
out.name("debugMode").value(value.debugMode().get());
|
||||
out.endObject();
|
||||
}
|
||||
|
||||
private void writeVaultSettingsArray(JsonWriter out, Iterable<VaultSettings> vaultSettings) throws IOException {
|
||||
out.beginArray();
|
||||
for (VaultSettings value : vaultSettings) {
|
||||
vaultSettingsJsonAdapter.write(out, value);
|
||||
}
|
||||
out.endArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Settings read(JsonReader in) throws IOException {
|
||||
Settings settings = new Settings();
|
||||
|
||||
in.beginObject();
|
||||
while (in.hasNext()) {
|
||||
String name = in.nextName();
|
||||
switch (name) {
|
||||
case "directories":
|
||||
settings.getDirectories().addAll(readVaultSettingsArray(in));
|
||||
break;
|
||||
case "checkForUpdatesEnabled":
|
||||
settings.checkForUpdates().set(in.nextBoolean());
|
||||
break;
|
||||
case "port":
|
||||
settings.port().set(in.nextInt());
|
||||
break;
|
||||
case "numTrayNotifications":
|
||||
settings.numTrayNotifications().set(in.nextInt());
|
||||
break;
|
||||
case "preferredGvfsScheme":
|
||||
settings.preferredGvfsScheme().set(in.nextString());
|
||||
break;
|
||||
case "debugMode":
|
||||
settings.debugMode().set(in.nextBoolean());
|
||||
break;
|
||||
default:
|
||||
LOG.warn("Unsupported vault setting found in JSON: " + name);
|
||||
in.skipValue();
|
||||
}
|
||||
}
|
||||
in.endObject();
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
private List<VaultSettings> readVaultSettingsArray(JsonReader in) throws IOException {
|
||||
List<VaultSettings> result = new ArrayList<>();
|
||||
in.beginArray();
|
||||
while (!JsonToken.END_ARRAY.equals(in.peek())) {
|
||||
result.add(vaultSettingsJsonAdapter.read(in));
|
||||
}
|
||||
in.endArray();
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016, 2017 Sebastian Stenzel and others.
|
||||
* All rights reserved.
|
||||
* This program and the accompanying materials are made available under the terms of the accompanying LICENSE file.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.common.settings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.LazyInitializer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
@Singleton
|
||||
public class SettingsProvider implements Provider<Settings> {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SettingsProvider.class);
|
||||
private static final Path DEFAULT_SETTINGS_PATH;
|
||||
private static final long SAVE_DELAY_MS = 1000;
|
||||
|
||||
static {
|
||||
final FileSystem fs = FileSystems.getDefault();
|
||||
if (SystemUtils.IS_OS_WINDOWS) {
|
||||
DEFAULT_SETTINGS_PATH = fs.getPath(SystemUtils.USER_HOME, "AppData/Roaming/Cryptomator/settings.json");
|
||||
} else if (SystemUtils.IS_OS_MAC_OSX) {
|
||||
DEFAULT_SETTINGS_PATH = fs.getPath(SystemUtils.USER_HOME, "Library/Application Support/Cryptomator/settings.json");
|
||||
} else {
|
||||
DEFAULT_SETTINGS_PATH = fs.getPath(SystemUtils.USER_HOME, ".Cryptomator/settings.json");
|
||||
}
|
||||
}
|
||||
|
||||
private final ScheduledExecutorService saveScheduler = Executors.newSingleThreadScheduledExecutor();
|
||||
private final AtomicReference<ScheduledFuture<?>> scheduledSaveCmd = new AtomicReference<>();
|
||||
private final AtomicReference<Settings> settings = new AtomicReference<>();
|
||||
private final SettingsJsonAdapter settingsJsonAdapter = new SettingsJsonAdapter();
|
||||
private final Gson gson;
|
||||
|
||||
@Inject
|
||||
public SettingsProvider() {
|
||||
this.gson = new GsonBuilder() //
|
||||
.setPrettyPrinting().setLenient().disableHtmlEscaping() //
|
||||
.registerTypeAdapter(Settings.class, settingsJsonAdapter) //
|
||||
.create();
|
||||
}
|
||||
|
||||
private Path getSettingsPath() {
|
||||
final String settingsPathProperty = System.getProperty("cryptomator.settingsPath");
|
||||
return Optional.ofNullable(settingsPathProperty).filter(StringUtils::isNotBlank).map(this::replaceHomeDir).map(FileSystems.getDefault()::getPath).orElse(DEFAULT_SETTINGS_PATH);
|
||||
}
|
||||
|
||||
private String replaceHomeDir(String path) {
|
||||
if (path.startsWith("~/")) {
|
||||
return SystemUtils.USER_HOME + path.substring(1);
|
||||
} else {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Settings get() {
|
||||
return LazyInitializer.initializeLazily(settings, this::load);
|
||||
}
|
||||
|
||||
private Settings load() {
|
||||
Settings settings;
|
||||
final Path settingsPath = getSettingsPath();
|
||||
try (InputStream in = Files.newInputStream(settingsPath, StandardOpenOption.READ); //
|
||||
Reader reader = new InputStreamReader(in, StandardCharsets.UTF_8)) {
|
||||
settings = gson.fromJson(reader, Settings.class);
|
||||
if (settings == null) {
|
||||
throw new IOException("Unexpected EOF");
|
||||
}
|
||||
LOG.info("Settings loaded from " + settingsPath);
|
||||
} catch (IOException e) {
|
||||
LOG.info("Failed to load settings, creating new one.");
|
||||
settings = new Settings();
|
||||
}
|
||||
settings.setSaveCmd(this::scheduleSave);
|
||||
return settings;
|
||||
}
|
||||
|
||||
private void scheduleSave(Settings settings) {
|
||||
if (settings == null) {
|
||||
return;
|
||||
}
|
||||
ScheduledFuture<?> saveCmd = saveScheduler.schedule(() -> {
|
||||
this.save(settings);
|
||||
}, SAVE_DELAY_MS, TimeUnit.MILLISECONDS);
|
||||
ScheduledFuture<?> previousSaveCmd = scheduledSaveCmd.getAndSet(saveCmd);
|
||||
if (previousSaveCmd != null) {
|
||||
previousSaveCmd.cancel(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void save(Settings settings) {
|
||||
assert settings != null : "method should only be invoked by #scheduleSave, which checks for null";
|
||||
final Path settingsPath = getSettingsPath();
|
||||
try {
|
||||
Files.createDirectories(settingsPath.getParent());
|
||||
try (OutputStream out = Files.newOutputStream(settingsPath, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); //
|
||||
Writer writer = new OutputStreamWriter(out, StandardCharsets.UTF_8)) {
|
||||
gson.toJson(settings, writer);
|
||||
LOG.info("Settings saved to " + settingsPath);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOG.error("Failed to save settings.", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.common.settings;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Base64;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
|
||||
import javafx.beans.Observable;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
|
||||
public class VaultSettings {
|
||||
|
||||
public static final boolean DEFAULT_UNLOCK_AFTER_STARTUP = false;
|
||||
public static final boolean DEFAULT_MOUNT_AFTER_UNLOCK = true;
|
||||
public static final boolean DEFAULT_REAVEAL_AFTER_MOUNT = true;
|
||||
|
||||
private final String id;
|
||||
private final ObjectProperty<Path> path = new SimpleObjectProperty<>();
|
||||
private final StringProperty mountName = new SimpleStringProperty();
|
||||
private final StringProperty winDriveLetter = new SimpleStringProperty();
|
||||
private final BooleanProperty unlockAfterStartup = new SimpleBooleanProperty(DEFAULT_UNLOCK_AFTER_STARTUP);
|
||||
private final BooleanProperty mountAfterUnlock = new SimpleBooleanProperty(DEFAULT_MOUNT_AFTER_UNLOCK);
|
||||
private final BooleanProperty revealAfterMount = new SimpleBooleanProperty(DEFAULT_REAVEAL_AFTER_MOUNT);
|
||||
|
||||
public VaultSettings(String id) {
|
||||
this.id = Objects.requireNonNull(id);
|
||||
|
||||
EasyBind.subscribe(path, this::deriveMountNameFromPath);
|
||||
}
|
||||
|
||||
Observable[] observables() {
|
||||
return new Observable[] {path, mountName, winDriveLetter, unlockAfterStartup, mountAfterUnlock, revealAfterMount};
|
||||
}
|
||||
|
||||
private void deriveMountNameFromPath(Path path) {
|
||||
if (path != null && StringUtils.isBlank(mountName.get())) {
|
||||
mountName.set(normalizeMountName(path.getFileName().toString()));
|
||||
}
|
||||
}
|
||||
|
||||
public static VaultSettings withRandomId() {
|
||||
return new VaultSettings(generateId());
|
||||
}
|
||||
|
||||
private static String generateId() {
|
||||
return asBase64String(nineBytesFrom(UUID.randomUUID()));
|
||||
}
|
||||
|
||||
private static String asBase64String(byte[] bytes) {
|
||||
byte[] base64Bytes = Base64.getUrlEncoder().encode(bytes);
|
||||
return new String(base64Bytes, StandardCharsets.US_ASCII);
|
||||
}
|
||||
|
||||
private static byte[] nineBytesFrom(UUID uuid) {
|
||||
ByteBuffer uuidBuffer = ByteBuffer.allocate(9);
|
||||
uuidBuffer.putLong(uuid.getMostSignificantBits());
|
||||
uuidBuffer.put((byte) (uuid.getLeastSignificantBits() & 0xFF));
|
||||
uuidBuffer.flip();
|
||||
return uuidBuffer.array();
|
||||
}
|
||||
|
||||
public static String normalizeMountName(String mountName) {
|
||||
String normalizedMountName = StringUtils.stripAccents(mountName);
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (char c : normalizedMountName.toCharArray()) {
|
||||
if (Character.isWhitespace(c)) {
|
||||
if (builder.length() == 0 || builder.charAt(builder.length() - 1) != '_') {
|
||||
builder.append('_');
|
||||
}
|
||||
} else if (c < 127 && Character.isLetterOrDigit(c)) {
|
||||
builder.append(c);
|
||||
} else {
|
||||
if (builder.length() == 0 || builder.charAt(builder.length() - 1) != '_') {
|
||||
builder.append('_');
|
||||
}
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/* Getter/Setter */
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public ObjectProperty<Path> path() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public StringProperty mountName() {
|
||||
return mountName;
|
||||
}
|
||||
|
||||
public StringProperty winDriveLetter() {
|
||||
return winDriveLetter;
|
||||
}
|
||||
|
||||
public BooleanProperty unlockAfterStartup() {
|
||||
return unlockAfterStartup;
|
||||
}
|
||||
|
||||
public BooleanProperty mountAfterUnlock() {
|
||||
return mountAfterUnlock;
|
||||
}
|
||||
|
||||
public BooleanProperty revealAfterMount() {
|
||||
return revealAfterMount;
|
||||
}
|
||||
|
||||
/* Hashcode/Equals */
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof VaultSettings && obj.getClass().equals(this.getClass())) {
|
||||
VaultSettings other = (VaultSettings) obj;
|
||||
return Objects.equals(this.id, other.id);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.common.settings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
class VaultSettingsJsonAdapter {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(VaultSettingsJsonAdapter.class);
|
||||
|
||||
public void write(JsonWriter out, VaultSettings value) throws IOException {
|
||||
out.beginObject();
|
||||
out.name("id").value(value.getId());
|
||||
out.name("path").value(value.path().get().toString());
|
||||
out.name("mountName").value(value.mountName().get());
|
||||
out.name("winDriveLetter").value(value.winDriveLetter().get());
|
||||
out.name("unlockAfterStartup").value(value.unlockAfterStartup().get());
|
||||
out.name("mountAfterUnlock").value(value.mountAfterUnlock().get());
|
||||
out.name("revealAfterMount").value(value.revealAfterMount().get());
|
||||
out.endObject();
|
||||
}
|
||||
|
||||
public VaultSettings read(JsonReader in) throws IOException {
|
||||
String id = null;
|
||||
String path = null;
|
||||
String mountName = null;
|
||||
String winDriveLetter = null;
|
||||
boolean unlockAfterStartup = VaultSettings.DEFAULT_UNLOCK_AFTER_STARTUP;
|
||||
boolean mountAfterUnlock = VaultSettings.DEFAULT_MOUNT_AFTER_UNLOCK;
|
||||
boolean revealAfterMount = VaultSettings.DEFAULT_REAVEAL_AFTER_MOUNT;
|
||||
|
||||
in.beginObject();
|
||||
while (in.hasNext()) {
|
||||
String name = in.nextName();
|
||||
switch (name) {
|
||||
case "id":
|
||||
id = in.nextString();
|
||||
break;
|
||||
case "path":
|
||||
path = in.nextString();
|
||||
break;
|
||||
case "mountName":
|
||||
mountName = in.nextString();
|
||||
break;
|
||||
case "winDriveLetter":
|
||||
winDriveLetter = in.nextString();
|
||||
break;
|
||||
case "unlockAfterStartup":
|
||||
unlockAfterStartup = in.nextBoolean();
|
||||
break;
|
||||
case "mountAfterUnlock":
|
||||
mountAfterUnlock = in.nextBoolean();
|
||||
break;
|
||||
case "revealAfterMount":
|
||||
revealAfterMount = in.nextBoolean();
|
||||
break;
|
||||
default:
|
||||
LOG.warn("Unsupported vault setting found in JSON: " + name);
|
||||
in.skipValue();
|
||||
}
|
||||
}
|
||||
in.endObject();
|
||||
|
||||
VaultSettings vaultSettings = (id == null) ? VaultSettings.withRandomId() : new VaultSettings(id);
|
||||
vaultSettings.mountName().set(mountName);
|
||||
vaultSettings.path().set(Paths.get(path));
|
||||
vaultSettings.winDriveLetter().set(winDriveLetter);
|
||||
vaultSettings.unlockAfterStartup().set(unlockAfterStartup);
|
||||
vaultSettings.mountAfterUnlock().set(mountAfterUnlock);
|
||||
vaultSettings.revealAfterMount().set(revealAfterMount);
|
||||
return vaultSettings;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,178 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import static org.cryptomator.common.streams.AutoClosingStreamFactory.AUTO_CLOSING_STREAM_FACTORY;
|
||||
|
||||
import java.util.DoubleSummaryStatistics;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.DoubleBinaryOperator;
|
||||
import java.util.function.DoubleConsumer;
|
||||
import java.util.function.DoublePredicate;
|
||||
import java.util.function.ObjDoubleConsumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.DoubleStream;
|
||||
|
||||
public class AutoClosingDoubleStream extends DelegatingDoubleStream {
|
||||
|
||||
public static DoubleStream from(DoubleStream delegate) {
|
||||
return new AutoClosingDoubleStream(delegate);
|
||||
}
|
||||
|
||||
public AutoClosingDoubleStream(DoubleStream delegate) {
|
||||
super(delegate, AUTO_CLOSING_STREAM_FACTORY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(DoubleConsumer action) {
|
||||
try {
|
||||
super.forEach(action);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachOrdered(DoubleConsumer action) {
|
||||
try {
|
||||
super.forEachOrdered(action);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] toArray() {
|
||||
try {
|
||||
return super.toArray();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double reduce(double identity, DoubleBinaryOperator op) {
|
||||
try {
|
||||
return super.reduce(identity, op);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalDouble reduce(DoubleBinaryOperator op) {
|
||||
try {
|
||||
return super.reduce(op);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> R collect(Supplier<R> supplier, ObjDoubleConsumer<R> accumulator, BiConsumer<R, R> combiner) {
|
||||
try {
|
||||
return super.collect(supplier, accumulator, combiner);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double sum() {
|
||||
try {
|
||||
return super.sum();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalDouble min() {
|
||||
try {
|
||||
return super.min();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalDouble max() {
|
||||
try {
|
||||
return super.max();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long count() {
|
||||
try {
|
||||
return super.count();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalDouble average() {
|
||||
try {
|
||||
return super.average();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DoubleSummaryStatistics summaryStatistics() {
|
||||
try {
|
||||
return super.summaryStatistics();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean anyMatch(DoublePredicate predicate) {
|
||||
try {
|
||||
return super.anyMatch(predicate);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allMatch(DoublePredicate predicate) {
|
||||
try {
|
||||
return super.allMatch(predicate);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean noneMatch(DoublePredicate predicate) {
|
||||
try {
|
||||
return super.noneMatch(predicate);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalDouble findFirst() {
|
||||
try {
|
||||
return super.findFirst();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalDouble findAny() {
|
||||
try {
|
||||
return super.findAny();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,179 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import static org.cryptomator.common.streams.AutoClosingStreamFactory.AUTO_CLOSING_STREAM_FACTORY;
|
||||
|
||||
import java.util.IntSummaryStatistics;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.IntBinaryOperator;
|
||||
import java.util.function.IntConsumer;
|
||||
import java.util.function.IntPredicate;
|
||||
import java.util.function.ObjIntConsumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class AutoClosingIntStream extends DelegatingIntStream {
|
||||
|
||||
public static IntStream from(IntStream delegate) {
|
||||
return new AutoClosingIntStream(delegate);
|
||||
}
|
||||
|
||||
public AutoClosingIntStream(IntStream delegate) {
|
||||
super(delegate, AUTO_CLOSING_STREAM_FACTORY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(IntConsumer action) {
|
||||
try {
|
||||
super.forEach(action);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachOrdered(IntConsumer action) {
|
||||
try {
|
||||
super.forEachOrdered(action);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] toArray() {
|
||||
try {
|
||||
return super.toArray();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int reduce(int identity, IntBinaryOperator op) {
|
||||
try {
|
||||
return super.reduce(identity, op);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalInt reduce(IntBinaryOperator op) {
|
||||
try {
|
||||
return super.reduce(op);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> R collect(Supplier<R> supplier, ObjIntConsumer<R> accumulator, BiConsumer<R, R> combiner) {
|
||||
try {
|
||||
return super.collect(supplier, accumulator, combiner);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int sum() {
|
||||
try {
|
||||
return super.sum();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalInt min() {
|
||||
try {
|
||||
return super.min();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalInt max() {
|
||||
try {
|
||||
return super.max();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long count() {
|
||||
try {
|
||||
return super.count();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalDouble average() {
|
||||
try {
|
||||
return super.average();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntSummaryStatistics summaryStatistics() {
|
||||
try {
|
||||
return super.summaryStatistics();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean anyMatch(IntPredicate predicate) {
|
||||
try {
|
||||
return super.anyMatch(predicate);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allMatch(IntPredicate predicate) {
|
||||
try {
|
||||
return super.allMatch(predicate);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean noneMatch(IntPredicate predicate) {
|
||||
try {
|
||||
return super.noneMatch(predicate);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalInt findFirst() {
|
||||
try {
|
||||
return super.findFirst();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalInt findAny() {
|
||||
try {
|
||||
return super.findAny();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,179 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import static org.cryptomator.common.streams.AutoClosingStreamFactory.AUTO_CLOSING_STREAM_FACTORY;
|
||||
|
||||
import java.util.LongSummaryStatistics;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.OptionalLong;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.LongBinaryOperator;
|
||||
import java.util.function.LongConsumer;
|
||||
import java.util.function.LongPredicate;
|
||||
import java.util.function.ObjLongConsumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.LongStream;
|
||||
|
||||
public class AutoClosingLongStream extends DelegatingLongStream {
|
||||
|
||||
public static LongStream from(LongStream delegate) {
|
||||
return new AutoClosingLongStream(delegate);
|
||||
}
|
||||
|
||||
public AutoClosingLongStream(LongStream delegate) {
|
||||
super(delegate, AUTO_CLOSING_STREAM_FACTORY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(LongConsumer action) {
|
||||
try {
|
||||
super.forEach(action);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachOrdered(LongConsumer action) {
|
||||
try {
|
||||
super.forEachOrdered(action);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long[] toArray() {
|
||||
try {
|
||||
return super.toArray();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long reduce(long identity, LongBinaryOperator op) {
|
||||
try {
|
||||
return super.reduce(identity, op);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalLong reduce(LongBinaryOperator op) {
|
||||
try {
|
||||
return super.reduce(op);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> R collect(Supplier<R> supplier, ObjLongConsumer<R> accumulator, BiConsumer<R, R> combiner) {
|
||||
try {
|
||||
return super.collect(supplier, accumulator, combiner);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long sum() {
|
||||
try {
|
||||
return super.sum();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalLong min() {
|
||||
try {
|
||||
return super.min();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalLong max() {
|
||||
try {
|
||||
return super.max();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long count() {
|
||||
try {
|
||||
return super.count();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalDouble average() {
|
||||
try {
|
||||
return super.average();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LongSummaryStatistics summaryStatistics() {
|
||||
try {
|
||||
return super.summaryStatistics();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean anyMatch(LongPredicate predicate) {
|
||||
try {
|
||||
return super.anyMatch(predicate);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allMatch(LongPredicate predicate) {
|
||||
try {
|
||||
return super.allMatch(predicate);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean noneMatch(LongPredicate predicate) {
|
||||
try {
|
||||
return super.noneMatch(predicate);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalLong findFirst() {
|
||||
try {
|
||||
return super.findFirst();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalLong findAny() {
|
||||
try {
|
||||
return super.findAny();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,173 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import static org.cryptomator.common.streams.AutoClosingStreamFactory.AUTO_CLOSING_STREAM_FACTORY;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.BinaryOperator;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* A Stream which is automatically closed after execution of a terminal operation.
|
||||
* <p>
|
||||
* Streams returned by intermediate operations are also auto closing.
|
||||
* <p>
|
||||
* <b>Note:</b> When using {@link #iterator()} or {@link #spliterator()} auto closing does not occur.
|
||||
*
|
||||
* @author Markus Kreusch
|
||||
*/
|
||||
public class AutoClosingStream<T> extends DelegatingStream<T> {
|
||||
|
||||
public static <T> Stream<T> from(Stream<T> delegate) {
|
||||
return new AutoClosingStream<>(delegate);
|
||||
}
|
||||
|
||||
private AutoClosingStream(Stream<T> delegate) {
|
||||
super(delegate, AUTO_CLOSING_STREAM_FACTORY);
|
||||
}
|
||||
|
||||
public void forEach(Consumer<? super T> action) {
|
||||
try {
|
||||
super.forEach(action);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public void forEachOrdered(Consumer<? super T> action) {
|
||||
try {
|
||||
super.forEachOrdered(action);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public Object[] toArray() {
|
||||
try {
|
||||
return super.toArray();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public <A> A[] toArray(IntFunction<A[]> generator) {
|
||||
try {
|
||||
return super.toArray(generator);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public T reduce(T identity, BinaryOperator<T> accumulator) {
|
||||
try {
|
||||
return super.reduce(identity, accumulator);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<T> reduce(BinaryOperator<T> accumulator) {
|
||||
try {
|
||||
return super.reduce(accumulator);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public <U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner) {
|
||||
try {
|
||||
return super.reduce(identity, accumulator, combiner);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public <R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner) {
|
||||
try {
|
||||
return super.collect(supplier, accumulator, combiner);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public <R, A> R collect(Collector<? super T, A, R> collector) {
|
||||
try {
|
||||
return super.collect(collector);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<T> min(Comparator<? super T> comparator) {
|
||||
try {
|
||||
return super.min(comparator);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<T> max(Comparator<? super T> comparator) {
|
||||
try {
|
||||
return super.max(comparator);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public long count() {
|
||||
try {
|
||||
return super.count();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean anyMatch(Predicate<? super T> predicate) {
|
||||
try {
|
||||
return super.anyMatch(predicate);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean allMatch(Predicate<? super T> predicate) {
|
||||
try {
|
||||
return super.allMatch(predicate);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean noneMatch(Predicate<? super T> predicate) {
|
||||
try {
|
||||
return super.noneMatch(predicate);
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<T> findFirst() {
|
||||
try {
|
||||
return super.findFirst();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<T> findAny() {
|
||||
try {
|
||||
return super.findAny();
|
||||
} finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import java.util.stream.DoubleStream;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
class AutoClosingStreamFactory implements DelegatingStreamFactory {
|
||||
|
||||
public static final DelegatingStreamFactory AUTO_CLOSING_STREAM_FACTORY = new AutoClosingStreamFactory();
|
||||
|
||||
private AutoClosingStreamFactory() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S> Stream<S> from(Stream<S> other) {
|
||||
if (AutoClosingStream.class.isInstance(other)) {
|
||||
return other;
|
||||
} else {
|
||||
return AutoClosingStream.from(other);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntStream from(IntStream other) {
|
||||
if (AutoClosingIntStream.class.isInstance(other)) {
|
||||
return other;
|
||||
} else {
|
||||
return AutoClosingIntStream.from(other);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LongStream from(LongStream other) {
|
||||
if (AutoClosingLongStream.class.isInstance(other)) {
|
||||
return other;
|
||||
} else {
|
||||
return AutoClosingLongStream.from(other);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DoubleStream from(DoubleStream other) {
|
||||
if (AutoClosingDoubleStream.class.isInstance(other)) {
|
||||
return other;
|
||||
} else {
|
||||
return AutoClosingDoubleStream.from(other);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,179 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import java.util.DoubleSummaryStatistics;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.PrimitiveIterator.OfDouble;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.DoubleBinaryOperator;
|
||||
import java.util.function.DoubleConsumer;
|
||||
import java.util.function.DoubleFunction;
|
||||
import java.util.function.DoublePredicate;
|
||||
import java.util.function.DoubleToIntFunction;
|
||||
import java.util.function.DoubleToLongFunction;
|
||||
import java.util.function.DoubleUnaryOperator;
|
||||
import java.util.function.ObjDoubleConsumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.DoubleStream;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
abstract class DelegatingDoubleStream implements DoubleStream {
|
||||
|
||||
private final DoubleStream delegate;
|
||||
private final DelegatingStreamFactory wrapper;
|
||||
|
||||
public DelegatingDoubleStream(DoubleStream delegate, DelegatingStreamFactory wrapper) {
|
||||
this.delegate = delegate;
|
||||
this.wrapper = wrapper;
|
||||
}
|
||||
|
||||
public DoubleStream filter(DoublePredicate predicate) {
|
||||
return wrapper.from(delegate.filter(predicate));
|
||||
}
|
||||
|
||||
public boolean isParallel() {
|
||||
return delegate.isParallel();
|
||||
}
|
||||
|
||||
public DoubleStream map(DoubleUnaryOperator mapper) {
|
||||
return wrapper.from(delegate.map(mapper));
|
||||
}
|
||||
|
||||
public <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper) {
|
||||
return wrapper.from(delegate.mapToObj(mapper));
|
||||
}
|
||||
|
||||
public DoubleStream unordered() {
|
||||
return wrapper.from(delegate.unordered());
|
||||
}
|
||||
|
||||
public DoubleStream onClose(Runnable closeHandler) {
|
||||
return wrapper.from(delegate.onClose(closeHandler));
|
||||
}
|
||||
|
||||
public IntStream mapToInt(DoubleToIntFunction mapper) {
|
||||
return wrapper.from(delegate.mapToInt(mapper));
|
||||
}
|
||||
|
||||
public LongStream mapToLong(DoubleToLongFunction mapper) {
|
||||
return wrapper.from(delegate.mapToLong(mapper));
|
||||
}
|
||||
|
||||
public void close() {
|
||||
delegate.close();
|
||||
}
|
||||
|
||||
public DoubleStream flatMap(DoubleFunction<? extends DoubleStream> mapper) {
|
||||
return wrapper.from(delegate.flatMap(mapper));
|
||||
}
|
||||
|
||||
public DoubleStream distinct() {
|
||||
return wrapper.from(delegate.distinct());
|
||||
}
|
||||
|
||||
public DoubleStream sorted() {
|
||||
return wrapper.from(delegate.sorted());
|
||||
}
|
||||
|
||||
public DoubleStream peek(DoubleConsumer action) {
|
||||
return wrapper.from(delegate.peek(action));
|
||||
}
|
||||
|
||||
public DoubleStream limit(long maxSize) {
|
||||
return wrapper.from(delegate.limit(maxSize));
|
||||
}
|
||||
|
||||
public DoubleStream skip(long n) {
|
||||
return wrapper.from(delegate.skip(n));
|
||||
}
|
||||
|
||||
public void forEach(DoubleConsumer action) {
|
||||
delegate.forEach(action);
|
||||
}
|
||||
|
||||
public void forEachOrdered(DoubleConsumer action) {
|
||||
delegate.forEachOrdered(action);
|
||||
}
|
||||
|
||||
public double[] toArray() {
|
||||
return delegate.toArray();
|
||||
}
|
||||
|
||||
public double reduce(double identity, DoubleBinaryOperator op) {
|
||||
return delegate.reduce(identity, op);
|
||||
}
|
||||
|
||||
public OptionalDouble reduce(DoubleBinaryOperator op) {
|
||||
return delegate.reduce(op);
|
||||
}
|
||||
|
||||
public <R> R collect(Supplier<R> supplier, ObjDoubleConsumer<R> accumulator, BiConsumer<R, R> combiner) {
|
||||
return delegate.collect(supplier, accumulator, combiner);
|
||||
}
|
||||
|
||||
public double sum() {
|
||||
return delegate.sum();
|
||||
}
|
||||
|
||||
public OptionalDouble min() {
|
||||
return delegate.min();
|
||||
}
|
||||
|
||||
public OptionalDouble max() {
|
||||
return delegate.max();
|
||||
}
|
||||
|
||||
public long count() {
|
||||
return delegate.count();
|
||||
}
|
||||
|
||||
public OptionalDouble average() {
|
||||
return delegate.average();
|
||||
}
|
||||
|
||||
public DoubleSummaryStatistics summaryStatistics() {
|
||||
return delegate.summaryStatistics();
|
||||
}
|
||||
|
||||
public boolean anyMatch(DoublePredicate predicate) {
|
||||
return delegate.anyMatch(predicate);
|
||||
}
|
||||
|
||||
public boolean allMatch(DoublePredicate predicate) {
|
||||
return delegate.allMatch(predicate);
|
||||
}
|
||||
|
||||
public boolean noneMatch(DoublePredicate predicate) {
|
||||
return delegate.noneMatch(predicate);
|
||||
}
|
||||
|
||||
public OptionalDouble findFirst() {
|
||||
return delegate.findFirst();
|
||||
}
|
||||
|
||||
public OptionalDouble findAny() {
|
||||
return delegate.findAny();
|
||||
}
|
||||
|
||||
public Stream<Double> boxed() {
|
||||
return wrapper.from(delegate.boxed());
|
||||
}
|
||||
|
||||
public DoubleStream sequential() {
|
||||
return wrapper.from(delegate.sequential());
|
||||
}
|
||||
|
||||
public DoubleStream parallel() {
|
||||
return wrapper.from(delegate.parallel());
|
||||
}
|
||||
|
||||
public OfDouble iterator() {
|
||||
return delegate.iterator();
|
||||
}
|
||||
|
||||
public java.util.Spliterator.OfDouble spliterator() {
|
||||
return delegate.spliterator();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,188 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import java.util.IntSummaryStatistics;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.PrimitiveIterator.OfInt;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.IntBinaryOperator;
|
||||
import java.util.function.IntConsumer;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.function.IntPredicate;
|
||||
import java.util.function.IntToDoubleFunction;
|
||||
import java.util.function.IntToLongFunction;
|
||||
import java.util.function.IntUnaryOperator;
|
||||
import java.util.function.ObjIntConsumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.DoubleStream;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
abstract class DelegatingIntStream implements IntStream {
|
||||
|
||||
private final IntStream delegate;
|
||||
private final DelegatingStreamFactory wrapper;
|
||||
|
||||
public DelegatingIntStream(IntStream delegate, DelegatingStreamFactory wrapper) {
|
||||
this.delegate = delegate;
|
||||
this.wrapper = wrapper;
|
||||
}
|
||||
|
||||
public IntStream filter(IntPredicate predicate) {
|
||||
return wrapper.from(delegate.filter(predicate));
|
||||
}
|
||||
|
||||
public boolean isParallel() {
|
||||
return delegate.isParallel();
|
||||
}
|
||||
|
||||
public IntStream map(IntUnaryOperator mapper) {
|
||||
return wrapper.from(delegate.map(mapper));
|
||||
}
|
||||
|
||||
public <U> Stream<U> mapToObj(IntFunction<? extends U> mapper) {
|
||||
return wrapper.from(delegate.mapToObj(mapper));
|
||||
}
|
||||
|
||||
public IntStream unordered() {
|
||||
return wrapper.from(delegate.unordered());
|
||||
}
|
||||
|
||||
public LongStream mapToLong(IntToLongFunction mapper) {
|
||||
return wrapper.from(delegate.mapToLong(mapper));
|
||||
}
|
||||
|
||||
public IntStream onClose(Runnable closeHandler) {
|
||||
return wrapper.from(delegate.onClose(closeHandler));
|
||||
}
|
||||
|
||||
public DoubleStream mapToDouble(IntToDoubleFunction mapper) {
|
||||
return wrapper.from(delegate.mapToDouble(mapper));
|
||||
}
|
||||
|
||||
public void close() {
|
||||
delegate.close();
|
||||
}
|
||||
|
||||
public IntStream flatMap(IntFunction<? extends IntStream> mapper) {
|
||||
return wrapper.from(delegate.flatMap(mapper));
|
||||
}
|
||||
|
||||
public IntStream distinct() {
|
||||
return wrapper.from(delegate.distinct());
|
||||
}
|
||||
|
||||
public IntStream sorted() {
|
||||
return wrapper.from(delegate.sorted());
|
||||
}
|
||||
|
||||
public IntStream peek(IntConsumer action) {
|
||||
return wrapper.from(delegate.peek(action));
|
||||
}
|
||||
|
||||
public IntStream limit(long maxSize) {
|
||||
return wrapper.from(delegate.limit(maxSize));
|
||||
}
|
||||
|
||||
public IntStream skip(long n) {
|
||||
return wrapper.from(delegate.skip(n));
|
||||
}
|
||||
|
||||
public void forEach(IntConsumer action) {
|
||||
delegate.forEach(action);
|
||||
}
|
||||
|
||||
public void forEachOrdered(IntConsumer action) {
|
||||
delegate.forEachOrdered(action);
|
||||
}
|
||||
|
||||
public int[] toArray() {
|
||||
return delegate.toArray();
|
||||
}
|
||||
|
||||
public int reduce(int identity, IntBinaryOperator op) {
|
||||
return delegate.reduce(identity, op);
|
||||
}
|
||||
|
||||
public OptionalInt reduce(IntBinaryOperator op) {
|
||||
return delegate.reduce(op);
|
||||
}
|
||||
|
||||
public <R> R collect(Supplier<R> supplier, ObjIntConsumer<R> accumulator, BiConsumer<R, R> combiner) {
|
||||
return delegate.collect(supplier, accumulator, combiner);
|
||||
}
|
||||
|
||||
public int sum() {
|
||||
return delegate.sum();
|
||||
}
|
||||
|
||||
public OptionalInt min() {
|
||||
return delegate.min();
|
||||
}
|
||||
|
||||
public OptionalInt max() {
|
||||
return delegate.max();
|
||||
}
|
||||
|
||||
public long count() {
|
||||
return delegate.count();
|
||||
}
|
||||
|
||||
public OptionalDouble average() {
|
||||
return delegate.average();
|
||||
}
|
||||
|
||||
public IntSummaryStatistics summaryStatistics() {
|
||||
return delegate.summaryStatistics();
|
||||
}
|
||||
|
||||
public boolean anyMatch(IntPredicate predicate) {
|
||||
return delegate.anyMatch(predicate);
|
||||
}
|
||||
|
||||
public boolean allMatch(IntPredicate predicate) {
|
||||
return delegate.allMatch(predicate);
|
||||
}
|
||||
|
||||
public boolean noneMatch(IntPredicate predicate) {
|
||||
return delegate.noneMatch(predicate);
|
||||
}
|
||||
|
||||
public OptionalInt findFirst() {
|
||||
return delegate.findFirst();
|
||||
}
|
||||
|
||||
public OptionalInt findAny() {
|
||||
return delegate.findAny();
|
||||
}
|
||||
|
||||
public LongStream asLongStream() {
|
||||
return wrapper.from(delegate.asLongStream());
|
||||
}
|
||||
|
||||
public DoubleStream asDoubleStream() {
|
||||
return wrapper.from(delegate.asDoubleStream());
|
||||
}
|
||||
|
||||
public Stream<Integer> boxed() {
|
||||
return wrapper.from(delegate.boxed());
|
||||
}
|
||||
|
||||
public IntStream sequential() {
|
||||
return wrapper.from(delegate.sequential());
|
||||
}
|
||||
|
||||
public IntStream parallel() {
|
||||
return wrapper.from(delegate.parallel());
|
||||
}
|
||||
|
||||
public OfInt iterator() {
|
||||
return delegate.iterator();
|
||||
}
|
||||
|
||||
public java.util.Spliterator.OfInt spliterator() {
|
||||
return delegate.spliterator();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import java.util.LongSummaryStatistics;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.OptionalLong;
|
||||
import java.util.PrimitiveIterator.OfLong;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.LongBinaryOperator;
|
||||
import java.util.function.LongConsumer;
|
||||
import java.util.function.LongFunction;
|
||||
import java.util.function.LongPredicate;
|
||||
import java.util.function.LongToDoubleFunction;
|
||||
import java.util.function.LongToIntFunction;
|
||||
import java.util.function.LongUnaryOperator;
|
||||
import java.util.function.ObjLongConsumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.DoubleStream;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
abstract class DelegatingLongStream implements LongStream {
|
||||
|
||||
private final LongStream delegate;
|
||||
private final DelegatingStreamFactory wrapper;
|
||||
|
||||
public DelegatingLongStream(LongStream delegate, DelegatingStreamFactory wrapper) {
|
||||
this.delegate = delegate;
|
||||
this.wrapper = wrapper;
|
||||
}
|
||||
|
||||
public LongStream filter(LongPredicate predicate) {
|
||||
return wrapper.from(delegate.filter(predicate));
|
||||
}
|
||||
|
||||
public boolean isParallel() {
|
||||
return delegate.isParallel();
|
||||
}
|
||||
|
||||
public LongStream map(LongUnaryOperator mapper) {
|
||||
return wrapper.from(delegate.map(mapper));
|
||||
}
|
||||
|
||||
public <U> Stream<U> mapToObj(LongFunction<? extends U> mapper) {
|
||||
return wrapper.from(delegate.mapToObj(mapper));
|
||||
}
|
||||
|
||||
public LongStream unordered() {
|
||||
return wrapper.from(delegate.unordered());
|
||||
}
|
||||
|
||||
public LongStream onClose(Runnable closeHandler) {
|
||||
return wrapper.from(delegate.onClose(closeHandler));
|
||||
}
|
||||
|
||||
public IntStream mapToInt(LongToIntFunction mapper) {
|
||||
return wrapper.from(delegate.mapToInt(mapper));
|
||||
}
|
||||
|
||||
public DoubleStream mapToDouble(LongToDoubleFunction mapper) {
|
||||
return wrapper.from(delegate.mapToDouble(mapper));
|
||||
}
|
||||
|
||||
public void close() {
|
||||
delegate.close();
|
||||
}
|
||||
|
||||
public LongStream flatMap(LongFunction<? extends LongStream> mapper) {
|
||||
return wrapper.from(delegate.flatMap(mapper));
|
||||
}
|
||||
|
||||
public LongStream distinct() {
|
||||
return wrapper.from(delegate.distinct());
|
||||
}
|
||||
|
||||
public LongStream sorted() {
|
||||
return wrapper.from(delegate.sorted());
|
||||
}
|
||||
|
||||
public LongStream peek(LongConsumer action) {
|
||||
return wrapper.from(delegate.peek(action));
|
||||
}
|
||||
|
||||
public LongStream limit(long maxSize) {
|
||||
return wrapper.from(delegate.limit(maxSize));
|
||||
}
|
||||
|
||||
public LongStream skip(long n) {
|
||||
return wrapper.from(delegate.skip(n));
|
||||
}
|
||||
|
||||
public void forEach(LongConsumer action) {
|
||||
delegate.forEach(action);
|
||||
}
|
||||
|
||||
public void forEachOrdered(LongConsumer action) {
|
||||
delegate.forEachOrdered(action);
|
||||
}
|
||||
|
||||
public long[] toArray() {
|
||||
return delegate.toArray();
|
||||
}
|
||||
|
||||
public long reduce(long identity, LongBinaryOperator op) {
|
||||
return delegate.reduce(identity, op);
|
||||
}
|
||||
|
||||
public OptionalLong reduce(LongBinaryOperator op) {
|
||||
return delegate.reduce(op);
|
||||
}
|
||||
|
||||
public <R> R collect(Supplier<R> supplier, ObjLongConsumer<R> accumulator, BiConsumer<R, R> combiner) {
|
||||
return delegate.collect(supplier, accumulator, combiner);
|
||||
}
|
||||
|
||||
public long sum() {
|
||||
return delegate.sum();
|
||||
}
|
||||
|
||||
public OptionalLong min() {
|
||||
return delegate.min();
|
||||
}
|
||||
|
||||
public OptionalLong max() {
|
||||
return delegate.max();
|
||||
}
|
||||
|
||||
public long count() {
|
||||
return delegate.count();
|
||||
}
|
||||
|
||||
public OptionalDouble average() {
|
||||
return delegate.average();
|
||||
}
|
||||
|
||||
public LongSummaryStatistics summaryStatistics() {
|
||||
return delegate.summaryStatistics();
|
||||
}
|
||||
|
||||
public boolean anyMatch(LongPredicate predicate) {
|
||||
return delegate.anyMatch(predicate);
|
||||
}
|
||||
|
||||
public boolean allMatch(LongPredicate predicate) {
|
||||
return delegate.allMatch(predicate);
|
||||
}
|
||||
|
||||
public boolean noneMatch(LongPredicate predicate) {
|
||||
return delegate.noneMatch(predicate);
|
||||
}
|
||||
|
||||
public OptionalLong findFirst() {
|
||||
return delegate.findFirst();
|
||||
}
|
||||
|
||||
public OptionalLong findAny() {
|
||||
return delegate.findAny();
|
||||
}
|
||||
|
||||
public DoubleStream asDoubleStream() {
|
||||
return wrapper.from(delegate.asDoubleStream());
|
||||
}
|
||||
|
||||
public Stream<Long> boxed() {
|
||||
return wrapper.from(delegate.boxed());
|
||||
}
|
||||
|
||||
public LongStream sequential() {
|
||||
return wrapper.from(delegate.sequential());
|
||||
}
|
||||
|
||||
public LongStream parallel() {
|
||||
return wrapper.from(delegate.parallel());
|
||||
}
|
||||
|
||||
public OfLong iterator() {
|
||||
return delegate.iterator();
|
||||
}
|
||||
|
||||
public java.util.Spliterator.OfLong spliterator() {
|
||||
return delegate.spliterator();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,194 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.Optional;
|
||||
import java.util.Spliterator;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.BinaryOperator;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.function.ToDoubleFunction;
|
||||
import java.util.function.ToIntFunction;
|
||||
import java.util.function.ToLongFunction;
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.DoubleStream;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
abstract class DelegatingStream<T> implements Stream<T> {
|
||||
|
||||
private final Stream<T> delegate;
|
||||
private final DelegatingStreamFactory wrapper;
|
||||
|
||||
protected DelegatingStream(Stream<T> delegate, DelegatingStreamFactory wrapper) {
|
||||
this.delegate = delegate;
|
||||
this.wrapper = wrapper;
|
||||
}
|
||||
|
||||
public Iterator<T> iterator() {
|
||||
return delegate.iterator();
|
||||
}
|
||||
|
||||
public Spliterator<T> spliterator() {
|
||||
return delegate.spliterator();
|
||||
}
|
||||
|
||||
public boolean isParallel() {
|
||||
return delegate.isParallel();
|
||||
}
|
||||
|
||||
public Stream<T> sequential() {
|
||||
return wrapper.from(delegate.sequential());
|
||||
}
|
||||
|
||||
public Stream<T> parallel() {
|
||||
return wrapper.from(delegate.parallel());
|
||||
}
|
||||
|
||||
public Stream<T> unordered() {
|
||||
return wrapper.from(delegate.unordered());
|
||||
}
|
||||
|
||||
public Stream<T> onClose(Runnable closeHandler) {
|
||||
return wrapper.from(delegate.onClose(closeHandler));
|
||||
}
|
||||
|
||||
public void close() {
|
||||
delegate.close();
|
||||
}
|
||||
|
||||
public Stream<T> filter(Predicate<? super T> predicate) {
|
||||
return wrapper.from(delegate.filter(predicate));
|
||||
}
|
||||
|
||||
public <R> Stream<R> map(Function<? super T, ? extends R> mapper) {
|
||||
return wrapper.from(delegate.map(mapper));
|
||||
}
|
||||
|
||||
public IntStream mapToInt(ToIntFunction<? super T> mapper) {
|
||||
return wrapper.from(delegate.mapToInt(mapper));
|
||||
}
|
||||
|
||||
public LongStream mapToLong(ToLongFunction<? super T> mapper) {
|
||||
return wrapper.from(delegate.mapToLong(mapper));
|
||||
}
|
||||
|
||||
public DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper) {
|
||||
return wrapper.from(delegate.mapToDouble(mapper));
|
||||
}
|
||||
|
||||
public <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper) {
|
||||
return wrapper.from(delegate.flatMap(mapper));
|
||||
}
|
||||
|
||||
public IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper) {
|
||||
return wrapper.from(delegate.flatMapToInt(mapper));
|
||||
}
|
||||
|
||||
public LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper) {
|
||||
return wrapper.from(delegate.flatMapToLong(mapper));
|
||||
}
|
||||
|
||||
public DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper) {
|
||||
return wrapper.from(delegate.flatMapToDouble(mapper));
|
||||
}
|
||||
|
||||
public Stream<T> distinct() {
|
||||
return wrapper.from(delegate.distinct());
|
||||
}
|
||||
|
||||
public Stream<T> sorted() {
|
||||
return wrapper.from(delegate.sorted());
|
||||
}
|
||||
|
||||
public Stream<T> sorted(Comparator<? super T> comparator) {
|
||||
return wrapper.from(delegate.sorted(comparator));
|
||||
}
|
||||
|
||||
public Stream<T> peek(Consumer<? super T> action) {
|
||||
return wrapper.from(delegate.peek(action));
|
||||
}
|
||||
|
||||
public Stream<T> limit(long maxSize) {
|
||||
return wrapper.from(delegate.limit(maxSize));
|
||||
}
|
||||
|
||||
public Stream<T> skip(long n) {
|
||||
return wrapper.from(delegate.skip(n));
|
||||
}
|
||||
|
||||
public void forEach(Consumer<? super T> action) {
|
||||
delegate.forEach(action);
|
||||
}
|
||||
|
||||
public void forEachOrdered(Consumer<? super T> action) {
|
||||
delegate.forEachOrdered(action);
|
||||
}
|
||||
|
||||
public Object[] toArray() {
|
||||
return delegate.toArray();
|
||||
}
|
||||
|
||||
public <A> A[] toArray(IntFunction<A[]> generator) {
|
||||
return delegate.toArray(generator);
|
||||
}
|
||||
|
||||
public T reduce(T identity, BinaryOperator<T> accumulator) {
|
||||
return delegate.reduce(identity, accumulator);
|
||||
}
|
||||
|
||||
public Optional<T> reduce(BinaryOperator<T> accumulator) {
|
||||
return delegate.reduce(accumulator);
|
||||
}
|
||||
|
||||
public <U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner) {
|
||||
return delegate.reduce(identity, accumulator, combiner);
|
||||
}
|
||||
|
||||
public <R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner) {
|
||||
return delegate.collect(supplier, accumulator, combiner);
|
||||
}
|
||||
|
||||
public <R, A> R collect(Collector<? super T, A, R> collector) {
|
||||
return delegate.collect(collector);
|
||||
}
|
||||
|
||||
public Optional<T> min(Comparator<? super T> comparator) {
|
||||
return delegate.min(comparator);
|
||||
}
|
||||
|
||||
public Optional<T> max(Comparator<? super T> comparator) {
|
||||
return delegate.max(comparator);
|
||||
}
|
||||
|
||||
public long count() {
|
||||
return delegate.count();
|
||||
}
|
||||
|
||||
public boolean anyMatch(Predicate<? super T> predicate) {
|
||||
return delegate.anyMatch(predicate);
|
||||
}
|
||||
|
||||
public boolean allMatch(Predicate<? super T> predicate) {
|
||||
return delegate.allMatch(predicate);
|
||||
}
|
||||
|
||||
public boolean noneMatch(Predicate<? super T> predicate) {
|
||||
return delegate.noneMatch(predicate);
|
||||
}
|
||||
|
||||
public Optional<T> findFirst() {
|
||||
return delegate.findFirst();
|
||||
}
|
||||
|
||||
public Optional<T> findAny() {
|
||||
return delegate.findAny();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import java.util.stream.DoubleStream;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public interface DelegatingStreamFactory {
|
||||
|
||||
<S> Stream<S> from(Stream<S> other);
|
||||
|
||||
IntStream from(IntStream other);
|
||||
|
||||
LongStream from(LongStream other);
|
||||
|
||||
DoubleStream from(DoubleStream other);
|
||||
|
||||
public interface ObjectStreamWrapper {
|
||||
<S> Stream<S> from(Stream<S> other);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package org.cryptomator.common;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class CachingSupplierTest {
|
||||
|
||||
@Test
|
||||
public void testInvokingGetInvokesDelegate() {
|
||||
@SuppressWarnings("unchecked")
|
||||
Supplier<Object> delegate = mock(Supplier.class);
|
||||
Object expectedResult = new Object();
|
||||
when(delegate.get()).thenReturn(expectedResult);
|
||||
Supplier<Object> inTest = CachingSupplier.from(delegate);
|
||||
|
||||
Object result = inTest.get();
|
||||
|
||||
assertThat(result, is(expectedResult));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvokingGetTwiceDoesNotInvokeDelegateTwice() {
|
||||
@SuppressWarnings("unchecked")
|
||||
Supplier<Object> delegate = mock(Supplier.class);
|
||||
Object expectedResult = new Object();
|
||||
when(delegate.get()).thenReturn(expectedResult);
|
||||
Supplier<Object> inTest = CachingSupplier.from(delegate);
|
||||
|
||||
inTest.get();
|
||||
Object result = inTest.get();
|
||||
|
||||
assertThat(result, is(expectedResult));
|
||||
verify(delegate).get();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package org.cryptomator.common;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class HolderTest {
|
||||
|
||||
private static final Object INITIAL = new Object();
|
||||
private static final Object VALUE = new Object();
|
||||
|
||||
private Holder<Object> inTest = new Holder<>(INITIAL);
|
||||
|
||||
@Test
|
||||
public void testInitialValueIsInitial() {
|
||||
assertThat(inTest.get(), is(INITIAL));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetChangesValue() {
|
||||
inTest.set(VALUE);
|
||||
|
||||
assertThat(inTest.get(), is(VALUE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptChangesValue() {
|
||||
inTest.accept(VALUE);
|
||||
|
||||
assertThat(inTest.get(), is(VALUE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResetChangesValueToInitial() {
|
||||
inTest.set(VALUE);
|
||||
inTest.reset();
|
||||
|
||||
assertThat(inTest.get(), is(INITIAL));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
* Copyright (c) 2016, 2017 Sebastian Stenzel and others.
|
||||
* All rights reserved.
|
||||
* This program and the accompanying materials are made available under the terms of the accompanying LICENSE file.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
@@ -10,7 +10,6 @@ package org.cryptomator.common;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.cryptomator.common.SemVerComparator;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -22,8 +21,10 @@ public class SemVerComparatorTest {
|
||||
|
||||
@Test
|
||||
public void compareEqualVersions() {
|
||||
final int comparisonResult = semVerComparator.compare("1.23.4", "1.23.4");
|
||||
Assert.assertEquals(0, Integer.signum(comparisonResult));
|
||||
Assert.assertEquals(0, Integer.signum(semVerComparator.compare("1.23.4", "1.23.4")));
|
||||
Assert.assertEquals(0, Integer.signum(semVerComparator.compare("1.23.4-alpha", "1.23.4-alpha")));
|
||||
Assert.assertEquals(0, Integer.signum(semVerComparator.compare("1.23.4+20170101", "1.23.4+20171231")));
|
||||
Assert.assertEquals(0, Integer.signum(semVerComparator.compare("1.23.4-alpha+20170101", "1.23.4-alpha+20171231")));
|
||||
}
|
||||
|
||||
// newer versions in first argument
|
||||
@@ -33,7 +34,11 @@ public class SemVerComparatorTest {
|
||||
Assert.assertEquals(1, Integer.signum(semVerComparator.compare("1.23.5", "1.23.4")));
|
||||
Assert.assertEquals(1, Integer.signum(semVerComparator.compare("1.24.4", "1.23.4")));
|
||||
Assert.assertEquals(1, Integer.signum(semVerComparator.compare("1.23.4", "1.23")));
|
||||
Assert.assertEquals(1, Integer.signum(semVerComparator.compare("1.23.4a", "1.23.4")));
|
||||
Assert.assertEquals(1, Integer.signum(semVerComparator.compare("1.23.4", "1.23.4-SNAPSHOT")));
|
||||
Assert.assertEquals(1, Integer.signum(semVerComparator.compare("1.23.4", "1.23.4-56.78")));
|
||||
Assert.assertEquals(1, Integer.signum(semVerComparator.compare("1.23.4-beta", "1.23.4-alpha")));
|
||||
Assert.assertEquals(1, Integer.signum(semVerComparator.compare("1.23.4-alpha.1", "1.23.4-alpha")));
|
||||
Assert.assertEquals(1, Integer.signum(semVerComparator.compare("1.23.4-56.79", "1.23.4-56.78")));
|
||||
}
|
||||
|
||||
// newer versions in second argument
|
||||
@@ -43,7 +48,11 @@ public class SemVerComparatorTest {
|
||||
Assert.assertEquals(-1, Integer.signum(semVerComparator.compare("1.23.4", "1.23.5")));
|
||||
Assert.assertEquals(-1, Integer.signum(semVerComparator.compare("1.23.4", "1.24.4")));
|
||||
Assert.assertEquals(-1, Integer.signum(semVerComparator.compare("1.23", "1.23.4")));
|
||||
Assert.assertEquals(-1, Integer.signum(semVerComparator.compare("1.23.4", "1.23.4a")));
|
||||
Assert.assertEquals(-1, Integer.signum(semVerComparator.compare("1.23.4-SNAPSHOT", "1.23.4")));
|
||||
Assert.assertEquals(-1, Integer.signum(semVerComparator.compare("1.23.4-56.78", "1.23.4")));
|
||||
Assert.assertEquals(-1, Integer.signum(semVerComparator.compare("1.23.4-alpha", "1.23.4-beta")));
|
||||
Assert.assertEquals(-1, Integer.signum(semVerComparator.compare("1.23.4-alpha", "1.23.4-alpha.1")));
|
||||
Assert.assertEquals(-1, Integer.signum(semVerComparator.compare("1.23.4-56.78", "1.23.4-56.79")));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,155 +0,0 @@
|
||||
package org.cryptomator.common;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.sameInstance;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.cryptomator.common.WeakValuedCache;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
|
||||
public class WeakValuedCacheTest {
|
||||
|
||||
private final String A_KEY = "aKey";
|
||||
private final String ANOTHER_KEY = "anotherKey";
|
||||
|
||||
private WeakValuedCache<String, Value> inTest;
|
||||
|
||||
private Function<String, Value> loader;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Before
|
||||
public void setup() {
|
||||
loader = Mockito.mock(Function.class);
|
||||
inTest = WeakValuedCache.usingLoader(loader);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResultOfGetIsResultOfLoaderForTheSameKey() {
|
||||
Value theValue = new Value();
|
||||
Value theOtherValue = new Value();
|
||||
when(loader.apply(A_KEY)).thenReturn(theValue);
|
||||
when(loader.apply(ANOTHER_KEY)).thenReturn(theOtherValue);
|
||||
|
||||
Value result = inTest.get(A_KEY);
|
||||
Value anotherResult = inTest.get(ANOTHER_KEY);
|
||||
|
||||
assertThat(result, is(sameInstance(theValue)));
|
||||
assertThat(anotherResult, is(sameInstance(theOtherValue)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCachedResultIsResultOfLoaderForTheSameKey() {
|
||||
Value theValue = new Value();
|
||||
Value theOtherValue = new Value();
|
||||
when(loader.apply(A_KEY)).thenReturn(theValue);
|
||||
when(loader.apply(ANOTHER_KEY)).thenReturn(theOtherValue);
|
||||
|
||||
inTest.get(A_KEY);
|
||||
inTest.get(ANOTHER_KEY);
|
||||
Value result = inTest.get(A_KEY);
|
||||
Value anotherResult = inTest.get(ANOTHER_KEY);
|
||||
|
||||
assertThat(result, is(sameInstance(theValue)));
|
||||
assertThat(anotherResult, is(sameInstance(theOtherValue)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwiceInvocationOfGetDoesNotInvokeLoaderTwice() {
|
||||
Value theValue = new Value();
|
||||
when(loader.apply(A_KEY)).thenReturn(theValue);
|
||||
|
||||
inTest.get(A_KEY);
|
||||
inTest.get(A_KEY);
|
||||
|
||||
verify(loader).apply(A_KEY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSecondInvocationOfGetReturnsTheSameResult() {
|
||||
Value theValue = new Value();
|
||||
when(loader.apply(A_KEY)).thenReturn(theValue);
|
||||
|
||||
inTest.get(A_KEY);
|
||||
Value result = inTest.get(A_KEY);
|
||||
|
||||
assertThat(result, is(sameInstance(theValue)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCacheDoesNotPreventGarbageCollectionOfValues() {
|
||||
when(loader.apply(A_KEY)).thenAnswer(this::createValueUsingMoreThanHalfTheJvmMemory);
|
||||
|
||||
inTest.get(A_KEY);
|
||||
|
||||
// force garbage collection of previously created value by creating an
|
||||
// object so large it can not coexist with the value
|
||||
createObjectUsingMoreThanHalfTheJvmMemory();
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeExceptionThrownInLoader.class)
|
||||
public void testCacheRethrowsRuntimeExceptionsFromLoader() {
|
||||
when(loader.apply(A_KEY)).thenThrow(new RuntimeExceptionThrownInLoader());
|
||||
|
||||
inTest.get(A_KEY);
|
||||
}
|
||||
|
||||
@Test(expected = ErrorThrownInLoader.class)
|
||||
public void testCacheRethrowsErrorsFromLoader() {
|
||||
when(loader.apply(A_KEY)).thenThrow(new ErrorThrownInLoader());
|
||||
|
||||
inTest.get(A_KEY);
|
||||
}
|
||||
|
||||
private Value createValueUsingMoreThanHalfTheJvmMemory(InvocationOnMock invocation) {
|
||||
Object data = createObjectUsingMoreThanHalfTheJvmMemory();
|
||||
Value value = new Value();
|
||||
value.setPayload(data);
|
||||
return value;
|
||||
}
|
||||
|
||||
private Object createObjectUsingMoreThanHalfTheJvmMemory() {
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
long moreThanHalfTheJvmMemory = maxMemory / 2 + 1;
|
||||
return createObjectUsingAtLeast(moreThanHalfTheJvmMemory);
|
||||
}
|
||||
|
||||
private Object createObjectUsingAtLeast(long minMemory) {
|
||||
if (minMemory <= Integer.MAX_VALUE) {
|
||||
return new byte[(int) minMemory];
|
||||
} else if ((minMemory / Integer.MAX_VALUE) <= Integer.MAX_VALUE) {
|
||||
int numberOfArraysWithMaxIntSize = (int) (minMemory / Integer.MAX_VALUE);
|
||||
int numberOfRemainingBytes = (int) (minMemory - Integer.MAX_VALUE * numberOfArraysWithMaxIntSize);
|
||||
return new byte[][][] { //
|
||||
new byte[numberOfArraysWithMaxIntSize][Integer.MAX_VALUE], //
|
||||
new byte[1][numberOfRemainingBytes] //
|
||||
};
|
||||
} else {
|
||||
throw new IllegalArgumentException(format("Can not create object with more than 3.999999996 Exabyte"));
|
||||
}
|
||||
}
|
||||
|
||||
private static class RuntimeExceptionThrownInLoader extends RuntimeException {
|
||||
}
|
||||
|
||||
private static class ErrorThrownInLoader extends Error {
|
||||
}
|
||||
|
||||
private static class Value {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private Object payload;
|
||||
|
||||
public void setPayload(Object payload) {
|
||||
this.payload = payload;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.common.settings;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class SettingsJsonAdapterTest {
|
||||
|
||||
private final SettingsJsonAdapter adapter = new SettingsJsonAdapter();
|
||||
|
||||
@Test
|
||||
public void testDeserialize() throws IOException {
|
||||
String vault1Json = "{\"id\": \"1\", \"path\": \"/vault1\", \"mountName\": \"vault1\", \"winDriveLetter\": \"X\"}";
|
||||
String vault2Json = "{\"id\": \"2\", \"path\": \"/vault2\", \"mountName\": \"vault2\", \"winDriveLetter\": \"Y\"}";
|
||||
String json = "{\"directories\": [" + vault1Json + "," + vault2Json + "]," //
|
||||
+ "\"checkForUpdatesEnabled\": true,"//
|
||||
+ "\"port\": 8080,"//
|
||||
+ "\"useIpv6\": true,"//
|
||||
+ "\"numTrayNotifications\": 42}";
|
||||
|
||||
Settings settings = adapter.fromJson(json);
|
||||
|
||||
Assert.assertTrue(settings.checkForUpdates().get());
|
||||
Assert.assertEquals(2, settings.getDirectories().size());
|
||||
Assert.assertEquals(8080, settings.port().get());
|
||||
// Assert.assertTrue(settings.useIpv6().get()); temporarily ignored
|
||||
Assert.assertEquals(42, settings.numTrayNotifications().get());
|
||||
Assert.assertEquals("dav", settings.preferredGvfsScheme().get());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.common.settings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
public class SettingsTest {
|
||||
|
||||
@Test
|
||||
public void testAutoSave() throws IOException {
|
||||
@SuppressWarnings("unchecked")
|
||||
Consumer<Settings> changeListener = Mockito.mock(Consumer.class);
|
||||
Settings settings = new Settings();
|
||||
settings.setSaveCmd(changeListener);
|
||||
VaultSettings vaultSettings = VaultSettings.withRandomId();
|
||||
Mockito.verify(changeListener, Mockito.times(0)).accept(settings);
|
||||
|
||||
// first change (to property):
|
||||
settings.preferredGvfsScheme().set("asd");
|
||||
Mockito.verify(changeListener, Mockito.times(1)).accept(settings);
|
||||
|
||||
// second change (to list):
|
||||
settings.getDirectories().add(vaultSettings);
|
||||
Mockito.verify(changeListener, Mockito.times(2)).accept(settings);
|
||||
|
||||
// third change (to property of list item):
|
||||
vaultSettings.mountName().set("asd");
|
||||
Mockito.verify(changeListener, Mockito.times(3)).accept(settings);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.common.settings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.gson.stream.JsonReader;
|
||||
|
||||
public class VaultSettingsJsonAdapterTest {
|
||||
|
||||
private final VaultSettingsJsonAdapter adapter = new VaultSettingsJsonAdapter();
|
||||
|
||||
@Test
|
||||
public void testDeserialize() throws IOException {
|
||||
String json = "{\"id\": \"foo\", \"path\": \"/foo/bar\", \"mountName\": \"test\", \"winDriveLetter\": \"X\", \"shouldBeIgnored\": true}";
|
||||
JsonReader jsonReader = new JsonReader(new StringReader(json));
|
||||
|
||||
VaultSettings vaultSettings = adapter.read(jsonReader);
|
||||
Assert.assertEquals("foo", vaultSettings.getId());
|
||||
Assert.assertEquals(Paths.get("/foo/bar"), vaultSettings.path().get());
|
||||
Assert.assertEquals("test", vaultSettings.mountName().get());
|
||||
Assert.assertEquals("X", vaultSettings.winDriveLetter().get());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016, 2017 Sebastian Stenzel and others.
|
||||
* All rights reserved.
|
||||
* This program and the accompanying materials are made available under the terms of the accompanying LICENSE file.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.common.settings;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class VaultSettingsTest {
|
||||
|
||||
@Test
|
||||
public void testNormalize() throws Exception {
|
||||
assertEquals("_", VaultSettings.normalizeMountName(" "));
|
||||
assertEquals("a", VaultSettings.normalizeMountName("ä"));
|
||||
assertEquals("C", VaultSettings.normalizeMountName("Ĉ"));
|
||||
assertEquals("_", VaultSettings.normalizeMountName(":"));
|
||||
assertEquals("_", VaultSettings.normalizeMountName("汉语"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,227 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.anyOf;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.DoubleSummaryStatistics;
|
||||
import java.util.List;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.DoubleBinaryOperator;
|
||||
import java.util.function.DoubleConsumer;
|
||||
import java.util.function.DoubleFunction;
|
||||
import java.util.function.DoublePredicate;
|
||||
import java.util.function.DoubleToIntFunction;
|
||||
import java.util.function.DoubleToLongFunction;
|
||||
import java.util.function.DoubleUnaryOperator;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.ObjDoubleConsumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.BaseStream;
|
||||
import java.util.stream.DoubleStream;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.hamcrest.Matcher;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.experimental.theories.DataPoints;
|
||||
import org.junit.experimental.theories.FromDataPoints;
|
||||
import org.junit.experimental.theories.Theories;
|
||||
import org.junit.experimental.theories.Theory;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InOrder;
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
@RunWith(Theories.class)
|
||||
public class AutoClosingDoubleStreamTest {
|
||||
|
||||
private static final DoublePredicate A_DOUBLE_PREDICATE = any -> true;
|
||||
private static final DoubleFunction A_DOUBLE_FUNCTION = i -> null;
|
||||
private static final BiConsumer A_BICONSUMER = (a, b) -> {
|
||||
};
|
||||
private static final Supplier A_SUPPLIER = () -> null;
|
||||
|
||||
@DataPoints("intermediateOperations")
|
||||
public static final List<DoubleermediateOperation<?>> INTERMEDIATE_OPERATIONS = new ArrayList<>();
|
||||
|
||||
@DataPoints("terminalOperations")
|
||||
public static final List<TerminalOperation<?>> TERMINAL_OPERATIONS = new ArrayList<>();
|
||||
private static final DoubleUnaryOperator A_DOUBLE_UNARY_OPERATOR = i -> 3;
|
||||
private static final DoubleToLongFunction A_DOUBLE_TO_LONG_FUNCTION = i -> 3L;
|
||||
private static final DoubleToIntFunction A_DOUBLE_TO_INT_FUNCTION = i -> 5;
|
||||
private static final DoubleConsumer A_DOUBLE_CONSUMER = i -> {
|
||||
};
|
||||
private static final ObjDoubleConsumer AN_OBJ_DOUBLE_CONSUMER = (a, b) -> {
|
||||
};
|
||||
private static final DoubleBinaryOperator A_DOUBLE_BINARY_OPERATOR = (a, b) -> a;
|
||||
|
||||
static {
|
||||
// define intermediate operations
|
||||
test(DoubleStream.class, DoubleStream::distinct);
|
||||
test(DoubleStream.class, stream -> stream.filter(A_DOUBLE_PREDICATE));
|
||||
test(DoubleStream.class, stream -> stream.flatMap(A_DOUBLE_FUNCTION));
|
||||
test(DoubleStream.class, stream -> stream.limit(5));
|
||||
test(DoubleStream.class, stream -> stream.map(A_DOUBLE_UNARY_OPERATOR));
|
||||
test(LongStream.class, stream -> stream.mapToLong(A_DOUBLE_TO_LONG_FUNCTION));
|
||||
test(Stream.class, stream -> stream.mapToObj(A_DOUBLE_FUNCTION));
|
||||
test(IntStream.class, stream -> stream.mapToInt(A_DOUBLE_TO_INT_FUNCTION));
|
||||
test(DoubleStream.class, DoubleStream::parallel);
|
||||
test(DoubleStream.class, stream -> stream.peek(A_DOUBLE_CONSUMER));
|
||||
test(DoubleStream.class, DoubleStream::sequential);
|
||||
test(DoubleStream.class, stream -> stream.skip(5));
|
||||
test(DoubleStream.class, DoubleStream::sorted);
|
||||
test(DoubleStream.class, DoubleStream::unordered);
|
||||
test(Stream.class, DoubleStream::boxed);
|
||||
|
||||
// define terminal operations
|
||||
test(stream -> stream.allMatch(A_DOUBLE_PREDICATE), true);
|
||||
test(stream -> stream.anyMatch(A_DOUBLE_PREDICATE), true);
|
||||
test(stream -> stream.collect(A_SUPPLIER, AN_OBJ_DOUBLE_CONSUMER, A_BICONSUMER), 7d);
|
||||
test(DoubleStream::count, 3L);
|
||||
test(DoubleStream::findAny, OptionalDouble.of(3));
|
||||
test(DoubleStream::findFirst, OptionalDouble.of(3));
|
||||
test(stream -> stream.forEach(A_DOUBLE_CONSUMER));
|
||||
test(stream -> stream.forEachOrdered(A_DOUBLE_CONSUMER));
|
||||
test(stream -> stream.max(), OptionalDouble.of(3));
|
||||
test(stream -> stream.min(), OptionalDouble.of(3));
|
||||
test(stream -> stream.noneMatch(A_DOUBLE_PREDICATE), true);
|
||||
test(stream -> stream.reduce(A_DOUBLE_BINARY_OPERATOR), OptionalDouble.of(3));
|
||||
test(stream -> stream.reduce(1, A_DOUBLE_BINARY_OPERATOR), 3d);
|
||||
test(DoubleStream::toArray, new double[1]);
|
||||
test(DoubleStream::sum, 1d);
|
||||
test(DoubleStream::average, OptionalDouble.of(3d));
|
||||
test(DoubleStream::summaryStatistics, new DoubleSummaryStatistics());
|
||||
}
|
||||
|
||||
private static <T> void test(Consumer<DoubleStream> consumer) {
|
||||
TERMINAL_OPERATIONS.add(new TerminalOperation<T>() {
|
||||
@Override
|
||||
public T result() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(DoubleStream stream) {
|
||||
consumer.accept(stream);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static <T> void test(Function<DoubleStream, T> function, T result) {
|
||||
TERMINAL_OPERATIONS.add(new TerminalOperation<T>() {
|
||||
@Override
|
||||
public T result() {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(DoubleStream stream) {
|
||||
return function.apply(stream);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static <T extends BaseStream> void test(Class<? extends T> type, Function<DoubleStream, T> function) {
|
||||
INTERMEDIATE_OPERATIONS.add(new DoubleermediateOperation<T>() {
|
||||
@Override
|
||||
public Class<? extends T> type() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(DoubleStream stream) {
|
||||
return function.apply(stream);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
private DoubleStream delegate;
|
||||
private DoubleStream inTest;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
delegate = mock(DoubleStream.class);
|
||||
inTest = AutoClosingDoubleStream.from(delegate);
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testIntermediateOperationReturnsNewAutoClosingStream(@FromDataPoints("intermediateOperations") DoubleermediateOperation intermediateOperation) {
|
||||
BaseStream newDelegate = (BaseStream) mock(intermediateOperation.type());
|
||||
when(intermediateOperation.apply(delegate)).thenReturn(newDelegate);
|
||||
|
||||
BaseStream result = intermediateOperation.apply(inTest);
|
||||
|
||||
assertThat(result, isAutoClosing());
|
||||
verifyDelegate(result, newDelegate);
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testTerminalOperationDelegatesToAndClosesDelegate(@FromDataPoints("terminalOperations") TerminalOperation terminalOperation) {
|
||||
Object expectedResult = terminalOperation.result();
|
||||
if (expectedResult != null) {
|
||||
when(terminalOperation.apply(delegate)).thenReturn(expectedResult);
|
||||
}
|
||||
|
||||
Object result = terminalOperation.apply(inTest);
|
||||
|
||||
InOrder inOrder = inOrder(delegate);
|
||||
assertThat(result, is(expectedResult));
|
||||
inOrder.verify(delegate).close();
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testTerminalOperationClosesDelegateEvenOnException(@FromDataPoints("terminalOperations") TerminalOperation terminalOperation) {
|
||||
RuntimeException exception = new RuntimeException();
|
||||
terminalOperation.apply(doThrow(exception).when(delegate));
|
||||
|
||||
thrown.expect(is(exception));
|
||||
|
||||
try {
|
||||
terminalOperation.apply(inTest);
|
||||
} finally {
|
||||
verify(delegate).close();
|
||||
}
|
||||
}
|
||||
|
||||
private Matcher<BaseStream> isAutoClosing() {
|
||||
return is(anyOf(instanceOf(AutoClosingStream.class), instanceOf(AutoClosingDoubleStream.class), instanceOf(AutoClosingIntStream.class), instanceOf(AutoClosingLongStream.class)));
|
||||
}
|
||||
|
||||
private void verifyDelegate(BaseStream result, BaseStream newDelegate) {
|
||||
result.close();
|
||||
verify(newDelegate).close();
|
||||
}
|
||||
|
||||
private interface TerminalOperation<T> {
|
||||
|
||||
T result();
|
||||
|
||||
T apply(DoubleStream stream);
|
||||
|
||||
}
|
||||
|
||||
private interface DoubleermediateOperation<T extends BaseStream> {
|
||||
|
||||
Class<? extends T> type();
|
||||
|
||||
T apply(DoubleStream stream);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,228 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.anyOf;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.IntSummaryStatistics;
|
||||
import java.util.List;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.IntBinaryOperator;
|
||||
import java.util.function.IntConsumer;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.function.IntPredicate;
|
||||
import java.util.function.IntToDoubleFunction;
|
||||
import java.util.function.IntToLongFunction;
|
||||
import java.util.function.IntUnaryOperator;
|
||||
import java.util.function.ObjIntConsumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.BaseStream;
|
||||
import java.util.stream.DoubleStream;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.hamcrest.Matcher;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.experimental.theories.DataPoints;
|
||||
import org.junit.experimental.theories.FromDataPoints;
|
||||
import org.junit.experimental.theories.Theories;
|
||||
import org.junit.experimental.theories.Theory;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InOrder;
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
@RunWith(Theories.class)
|
||||
public class AutoClosingIntStreamTest {
|
||||
|
||||
private static final IntPredicate AN_INT_PREDICATE = any -> true;
|
||||
private static final IntFunction AN_INT_FUNCTION = i -> null;
|
||||
private static final BiConsumer A_BICONSUMER = (a, b) -> {
|
||||
};
|
||||
private static final Supplier A_SUPPLIER = () -> null;
|
||||
|
||||
@DataPoints("intermediateOperations")
|
||||
public static final List<IntermediateOperation<?>> INTERMEDIATE_OPERATIONS = new ArrayList<>();
|
||||
|
||||
@DataPoints("terminalOperations")
|
||||
public static final List<TerminalOperation<?>> TERMINAL_OPERATIONS = new ArrayList<>();
|
||||
private static final IntUnaryOperator AN_INT_UNARY_OPERATOR = i -> 3;
|
||||
private static final IntToDoubleFunction AN_INT_TO_DOUBLE_FUNCTION = i -> 3d;
|
||||
private static final IntToLongFunction AN_INT_TO_LONG_FUNCTION = i -> 5L;
|
||||
private static final IntConsumer AN_INT_CONSUMER = i -> {
|
||||
};
|
||||
private static final ObjIntConsumer AN_OBJ_INT_CONSUMER = (a, b) -> {
|
||||
};
|
||||
private static final IntBinaryOperator AN_INT_BINARY_OPERATOR = (a, b) -> a;
|
||||
|
||||
static {
|
||||
// define intermediate operations
|
||||
test(IntStream.class, IntStream::distinct);
|
||||
test(IntStream.class, stream -> stream.filter(AN_INT_PREDICATE));
|
||||
test(IntStream.class, stream -> stream.flatMap(AN_INT_FUNCTION));
|
||||
test(IntStream.class, stream -> stream.limit(5));
|
||||
test(IntStream.class, stream -> stream.map(AN_INT_UNARY_OPERATOR));
|
||||
test(DoubleStream.class, stream -> stream.mapToDouble(AN_INT_TO_DOUBLE_FUNCTION));
|
||||
test(Stream.class, stream -> stream.mapToObj(AN_INT_FUNCTION));
|
||||
test(LongStream.class, stream -> stream.mapToLong(AN_INT_TO_LONG_FUNCTION));
|
||||
test(IntStream.class, IntStream::parallel);
|
||||
test(IntStream.class, stream -> stream.peek(AN_INT_CONSUMER));
|
||||
test(IntStream.class, IntStream::sequential);
|
||||
test(IntStream.class, stream -> stream.skip(5));
|
||||
test(IntStream.class, IntStream::sorted);
|
||||
test(IntStream.class, IntStream::unordered);
|
||||
test(Stream.class, IntStream::boxed);
|
||||
|
||||
// define terminal operations
|
||||
test(stream -> stream.allMatch(AN_INT_PREDICATE), true);
|
||||
test(stream -> stream.anyMatch(AN_INT_PREDICATE), true);
|
||||
test(stream -> stream.collect(A_SUPPLIER, AN_OBJ_INT_CONSUMER, A_BICONSUMER), 7);
|
||||
test(IntStream::count, 3L);
|
||||
test(IntStream::findAny, OptionalInt.of(3));
|
||||
test(IntStream::findFirst, OptionalInt.of(3));
|
||||
test(stream -> stream.forEach(AN_INT_CONSUMER));
|
||||
test(stream -> stream.forEachOrdered(AN_INT_CONSUMER));
|
||||
test(stream -> stream.max(), OptionalInt.of(3));
|
||||
test(stream -> stream.min(), OptionalInt.of(3));
|
||||
test(stream -> stream.noneMatch(AN_INT_PREDICATE), true);
|
||||
test(stream -> stream.reduce(AN_INT_BINARY_OPERATOR), OptionalInt.of(3));
|
||||
test(stream -> stream.reduce(1, AN_INT_BINARY_OPERATOR), 3);
|
||||
test(IntStream::toArray, new int[1]);
|
||||
test(IntStream::sum, 1);
|
||||
test(IntStream::average, OptionalDouble.of(3d));
|
||||
test(IntStream::summaryStatistics, new IntSummaryStatistics());
|
||||
}
|
||||
|
||||
private static <T> void test(Consumer<IntStream> consumer) {
|
||||
TERMINAL_OPERATIONS.add(new TerminalOperation<T>() {
|
||||
@Override
|
||||
public T result() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(IntStream stream) {
|
||||
consumer.accept(stream);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static <T> void test(Function<IntStream, T> function, T result) {
|
||||
TERMINAL_OPERATIONS.add(new TerminalOperation<T>() {
|
||||
@Override
|
||||
public T result() {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(IntStream stream) {
|
||||
return function.apply(stream);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static <T extends BaseStream> void test(Class<? extends T> type, Function<IntStream, T> function) {
|
||||
INTERMEDIATE_OPERATIONS.add(new IntermediateOperation<T>() {
|
||||
@Override
|
||||
public Class<? extends T> type() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(IntStream stream) {
|
||||
return function.apply(stream);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
private IntStream delegate;
|
||||
private IntStream inTest;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
delegate = mock(IntStream.class);
|
||||
inTest = AutoClosingIntStream.from(delegate);
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testIntermediateOperationReturnsNewAutoClosingStream(@FromDataPoints("intermediateOperations") IntermediateOperation intermediateOperation) {
|
||||
BaseStream newDelegate = (BaseStream) mock(intermediateOperation.type());
|
||||
when(intermediateOperation.apply(delegate)).thenReturn(newDelegate);
|
||||
|
||||
BaseStream result = intermediateOperation.apply(inTest);
|
||||
|
||||
assertThat(result, isAutoClosing());
|
||||
verifyDelegate(result, newDelegate);
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testTerminalOperationDelegatesToAndClosesDelegate(@FromDataPoints("terminalOperations") TerminalOperation terminalOperation) {
|
||||
Object expectedResult = terminalOperation.result();
|
||||
if (expectedResult != null) {
|
||||
when(terminalOperation.apply(delegate)).thenReturn(expectedResult);
|
||||
}
|
||||
|
||||
Object result = terminalOperation.apply(inTest);
|
||||
|
||||
InOrder inOrder = inOrder(delegate);
|
||||
assertThat(result, is(expectedResult));
|
||||
inOrder.verify(delegate).close();
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testTerminalOperationClosesDelegateEvenOnException(@FromDataPoints("terminalOperations") TerminalOperation terminalOperation) {
|
||||
RuntimeException exception = new RuntimeException();
|
||||
terminalOperation.apply(doThrow(exception).when(delegate));
|
||||
|
||||
thrown.expect(is(exception));
|
||||
|
||||
try {
|
||||
terminalOperation.apply(inTest);
|
||||
} finally {
|
||||
verify(delegate).close();
|
||||
}
|
||||
}
|
||||
|
||||
private Matcher<BaseStream> isAutoClosing() {
|
||||
return is(anyOf(instanceOf(AutoClosingStream.class), instanceOf(AutoClosingDoubleStream.class), instanceOf(AutoClosingIntStream.class), instanceOf(AutoClosingLongStream.class)));
|
||||
}
|
||||
|
||||
private void verifyDelegate(BaseStream result, BaseStream newDelegate) {
|
||||
result.close();
|
||||
verify(newDelegate).close();
|
||||
}
|
||||
|
||||
private interface TerminalOperation<T> {
|
||||
|
||||
T result();
|
||||
|
||||
T apply(IntStream stream);
|
||||
|
||||
}
|
||||
|
||||
private interface IntermediateOperation<T extends BaseStream> {
|
||||
|
||||
Class<? extends T> type();
|
||||
|
||||
T apply(IntStream stream);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,228 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.anyOf;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.LongSummaryStatistics;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.OptionalLong;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.LongBinaryOperator;
|
||||
import java.util.function.LongConsumer;
|
||||
import java.util.function.LongFunction;
|
||||
import java.util.function.LongPredicate;
|
||||
import java.util.function.LongToDoubleFunction;
|
||||
import java.util.function.LongToIntFunction;
|
||||
import java.util.function.LongUnaryOperator;
|
||||
import java.util.function.ObjLongConsumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.BaseStream;
|
||||
import java.util.stream.DoubleStream;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.hamcrest.Matcher;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.experimental.theories.DataPoints;
|
||||
import org.junit.experimental.theories.FromDataPoints;
|
||||
import org.junit.experimental.theories.Theories;
|
||||
import org.junit.experimental.theories.Theory;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InOrder;
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
@RunWith(Theories.class)
|
||||
public class AutoClosingLongStreamTest {
|
||||
|
||||
private static final LongPredicate AN_LONG_PREDICATE = any -> true;
|
||||
private static final LongFunction AN_LONG_FUNCTION = i -> null;
|
||||
private static final BiConsumer A_BICONSUMER = (a, b) -> {
|
||||
};
|
||||
private static final Supplier A_SUPPLIER = () -> null;
|
||||
|
||||
@DataPoints("intermediateOperations")
|
||||
public static final List<LongermediateOperation<?>> INTERMEDIATE_OPERATIONS = new ArrayList<>();
|
||||
|
||||
@DataPoints("terminalOperations")
|
||||
public static final List<TerminalOperation<?>> TERMINAL_OPERATIONS = new ArrayList<>();
|
||||
private static final LongUnaryOperator AN_LONG_UNARY_OPERATOR = i -> 3;
|
||||
private static final LongToDoubleFunction AN_LONG_TO_DOUBLE_FUNCTION = i -> 3d;
|
||||
private static final LongToIntFunction AN_LONG_TO_INT_FUNCTION = i -> 5;
|
||||
private static final LongConsumer AN_LONG_CONSUMER = i -> {
|
||||
};
|
||||
private static final ObjLongConsumer AN_OBJ_LONG_CONSUMER = (a, b) -> {
|
||||
};
|
||||
private static final LongBinaryOperator AN_LONG_BINARY_OPERATOR = (a, b) -> a;
|
||||
|
||||
static {
|
||||
// define intermediate operations
|
||||
test(LongStream.class, LongStream::distinct);
|
||||
test(LongStream.class, stream -> stream.filter(AN_LONG_PREDICATE));
|
||||
test(LongStream.class, stream -> stream.flatMap(AN_LONG_FUNCTION));
|
||||
test(LongStream.class, stream -> stream.limit(5));
|
||||
test(LongStream.class, stream -> stream.map(AN_LONG_UNARY_OPERATOR));
|
||||
test(DoubleStream.class, stream -> stream.mapToDouble(AN_LONG_TO_DOUBLE_FUNCTION));
|
||||
test(Stream.class, stream -> stream.mapToObj(AN_LONG_FUNCTION));
|
||||
test(IntStream.class, stream -> stream.mapToInt(AN_LONG_TO_INT_FUNCTION));
|
||||
test(LongStream.class, LongStream::parallel);
|
||||
test(LongStream.class, stream -> stream.peek(AN_LONG_CONSUMER));
|
||||
test(LongStream.class, LongStream::sequential);
|
||||
test(LongStream.class, stream -> stream.skip(5));
|
||||
test(LongStream.class, LongStream::sorted);
|
||||
test(LongStream.class, LongStream::unordered);
|
||||
test(Stream.class, LongStream::boxed);
|
||||
|
||||
// define terminal operations
|
||||
test(stream -> stream.allMatch(AN_LONG_PREDICATE), true);
|
||||
test(stream -> stream.anyMatch(AN_LONG_PREDICATE), true);
|
||||
test(stream -> stream.collect(A_SUPPLIER, AN_OBJ_LONG_CONSUMER, A_BICONSUMER), 7L);
|
||||
test(LongStream::count, 3L);
|
||||
test(LongStream::findAny, OptionalLong.of(3));
|
||||
test(LongStream::findFirst, OptionalLong.of(3));
|
||||
test(stream -> stream.forEach(AN_LONG_CONSUMER));
|
||||
test(stream -> stream.forEachOrdered(AN_LONG_CONSUMER));
|
||||
test(stream -> stream.max(), OptionalLong.of(3));
|
||||
test(stream -> stream.min(), OptionalLong.of(3));
|
||||
test(stream -> stream.noneMatch(AN_LONG_PREDICATE), true);
|
||||
test(stream -> stream.reduce(AN_LONG_BINARY_OPERATOR), OptionalLong.of(3));
|
||||
test(stream -> stream.reduce(1, AN_LONG_BINARY_OPERATOR), 3L);
|
||||
test(LongStream::toArray, new long[1]);
|
||||
test(LongStream::sum, 1L);
|
||||
test(LongStream::average, OptionalDouble.of(3d));
|
||||
test(LongStream::summaryStatistics, new LongSummaryStatistics());
|
||||
}
|
||||
|
||||
private static <T> void test(Consumer<LongStream> consumer) {
|
||||
TERMINAL_OPERATIONS.add(new TerminalOperation<T>() {
|
||||
@Override
|
||||
public T result() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(LongStream stream) {
|
||||
consumer.accept(stream);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static <T> void test(Function<LongStream, T> function, T result) {
|
||||
TERMINAL_OPERATIONS.add(new TerminalOperation<T>() {
|
||||
@Override
|
||||
public T result() {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(LongStream stream) {
|
||||
return function.apply(stream);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static <T extends BaseStream> void test(Class<? extends T> type, Function<LongStream, T> function) {
|
||||
INTERMEDIATE_OPERATIONS.add(new LongermediateOperation<T>() {
|
||||
@Override
|
||||
public Class<? extends T> type() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(LongStream stream) {
|
||||
return function.apply(stream);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
private LongStream delegate;
|
||||
private LongStream inTest;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
delegate = mock(LongStream.class);
|
||||
inTest = AutoClosingLongStream.from(delegate);
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testIntermediateOperationReturnsNewAutoClosingStream(@FromDataPoints("intermediateOperations") LongermediateOperation intermediateOperation) {
|
||||
BaseStream newDelegate = (BaseStream) mock(intermediateOperation.type());
|
||||
when(intermediateOperation.apply(delegate)).thenReturn(newDelegate);
|
||||
|
||||
BaseStream result = intermediateOperation.apply(inTest);
|
||||
|
||||
assertThat(result, isAutoClosing());
|
||||
verifyDelegate(result, newDelegate);
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testTerminalOperationDelegatesToAndClosesDelegate(@FromDataPoints("terminalOperations") TerminalOperation terminalOperation) {
|
||||
Object expectedResult = terminalOperation.result();
|
||||
if (expectedResult != null) {
|
||||
when(terminalOperation.apply(delegate)).thenReturn(expectedResult);
|
||||
}
|
||||
|
||||
Object result = terminalOperation.apply(inTest);
|
||||
|
||||
InOrder inOrder = inOrder(delegate);
|
||||
assertThat(result, is(expectedResult));
|
||||
inOrder.verify(delegate).close();
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testTerminalOperationClosesDelegateEvenOnException(@FromDataPoints("terminalOperations") TerminalOperation terminalOperation) {
|
||||
RuntimeException exception = new RuntimeException();
|
||||
terminalOperation.apply(doThrow(exception).when(delegate));
|
||||
|
||||
thrown.expect(is(exception));
|
||||
|
||||
try {
|
||||
terminalOperation.apply(inTest);
|
||||
} finally {
|
||||
verify(delegate).close();
|
||||
}
|
||||
}
|
||||
|
||||
private Matcher<BaseStream> isAutoClosing() {
|
||||
return is(anyOf(instanceOf(AutoClosingStream.class), instanceOf(AutoClosingDoubleStream.class), instanceOf(AutoClosingIntStream.class), instanceOf(AutoClosingLongStream.class)));
|
||||
}
|
||||
|
||||
private void verifyDelegate(BaseStream result, BaseStream newDelegate) {
|
||||
result.close();
|
||||
verify(newDelegate).close();
|
||||
}
|
||||
|
||||
private interface TerminalOperation<T> {
|
||||
|
||||
T result();
|
||||
|
||||
T apply(LongStream stream);
|
||||
|
||||
}
|
||||
|
||||
private interface LongermediateOperation<T extends BaseStream> {
|
||||
|
||||
Class<? extends T> type();
|
||||
|
||||
T apply(LongStream stream);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,231 +0,0 @@
|
||||
package org.cryptomator.common.streams;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.anyOf;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BinaryOperator;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.function.ToDoubleFunction;
|
||||
import java.util.function.ToIntFunction;
|
||||
import java.util.function.ToLongFunction;
|
||||
import java.util.stream.BaseStream;
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.DoubleStream;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.LongStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.hamcrest.Matcher;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.experimental.theories.DataPoints;
|
||||
import org.junit.experimental.theories.FromDataPoints;
|
||||
import org.junit.experimental.theories.Theories;
|
||||
import org.junit.experimental.theories.Theory;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InOrder;
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
@RunWith(Theories.class)
|
||||
public class AutoClosingStreamTest {
|
||||
|
||||
private static final Predicate A_PREDICATE = any -> true;
|
||||
private static final Function A_FUNCTION = any -> null;
|
||||
private static final ToDoubleFunction A_TO_DOUBLE_FUNCTION = any -> 0d;
|
||||
private static final ToIntFunction A_TO_INT_FUNCTION = any -> 1;
|
||||
private static final ToLongFunction A_TO_LONG_FUNCTION = any -> 1L;
|
||||
private static final Consumer A_CONSUMER = any -> {
|
||||
};
|
||||
private static final Comparator A_COMPARATOR = (left, right) -> 0;
|
||||
private static final Collector A_COLLECTOR = mock(Collector.class);
|
||||
private static final BinaryOperator A_BINARY_OPERATOR = (left, right) -> null;
|
||||
private static final Object AN_OBJECT = new Object();
|
||||
private static final IntFunction AN_INT_FUNCTION = i -> null;
|
||||
private static final BiConsumer A_BICONSUMER = (a, b) -> {
|
||||
};
|
||||
private static final Supplier A_SUPPLIER = () -> null;
|
||||
|
||||
@DataPoints("intermediateOperations")
|
||||
public static final List<IntermediateOperation<?>> INTERMEDIATE_OPERATIONS = new ArrayList<>();
|
||||
|
||||
@DataPoints("terminalOperations")
|
||||
public static final List<TerminalOperation<?>> TERMINAL_OPERATIONS = new ArrayList<>();
|
||||
|
||||
static {
|
||||
// define intermediate operations
|
||||
test(Stream.class, Stream::distinct);
|
||||
test(Stream.class, stream -> stream.filter(A_PREDICATE));
|
||||
test(Stream.class, stream -> stream.flatMap(A_FUNCTION));
|
||||
test(DoubleStream.class, stream -> stream.flatMapToDouble(A_FUNCTION));
|
||||
test(IntStream.class, stream -> stream.flatMapToInt(A_FUNCTION));
|
||||
test(LongStream.class, stream -> stream.flatMapToLong(A_FUNCTION));
|
||||
test(Stream.class, stream -> stream.limit(5));
|
||||
test(Stream.class, stream -> stream.map(A_FUNCTION));
|
||||
test(DoubleStream.class, stream -> stream.mapToDouble(A_TO_DOUBLE_FUNCTION));
|
||||
test(IntStream.class, stream -> stream.mapToInt(A_TO_INT_FUNCTION));
|
||||
test(LongStream.class, stream -> stream.mapToLong(A_TO_LONG_FUNCTION));
|
||||
test(Stream.class, Stream::parallel);
|
||||
test(Stream.class, stream -> stream.peek(A_CONSUMER));
|
||||
test(Stream.class, Stream::sequential);
|
||||
test(Stream.class, stream -> stream.skip(5));
|
||||
test(Stream.class, Stream::sorted);
|
||||
test(Stream.class, stream -> stream.sorted(A_COMPARATOR));
|
||||
test(Stream.class, Stream::unordered);
|
||||
|
||||
// define terminal operations
|
||||
test(stream -> stream.allMatch(A_PREDICATE), true);
|
||||
test(stream -> stream.anyMatch(A_PREDICATE), true);
|
||||
test(stream -> stream.collect(A_COLLECTOR), new Object());
|
||||
test(stream -> stream.collect(A_SUPPLIER, A_BICONSUMER, A_BICONSUMER), new Object());
|
||||
test(Stream::count, 3L);
|
||||
test(Stream::findAny, Optional.of(new Object()));
|
||||
test(Stream::findFirst, Optional.of(new Object()));
|
||||
test(stream -> stream.forEach(A_CONSUMER));
|
||||
test(stream -> stream.forEachOrdered(A_CONSUMER));
|
||||
test(stream -> stream.max(A_COMPARATOR), Optional.of(new Object()));
|
||||
test(stream -> stream.min(A_COMPARATOR), Optional.of(new Object()));
|
||||
test(stream -> stream.noneMatch(A_PREDICATE), true);
|
||||
test(stream -> stream.reduce(A_BINARY_OPERATOR), Optional.of(new Object()));
|
||||
test(stream -> stream.reduce(AN_OBJECT, A_BINARY_OPERATOR), Optional.of(new Object()));
|
||||
test(stream -> stream.reduce(AN_OBJECT, A_BINARY_OPERATOR, A_BINARY_OPERATOR), Optional.of(new Object()));
|
||||
test(Stream::toArray, new Object[1]);
|
||||
test(stream -> stream.toArray(AN_INT_FUNCTION), new Object[1]);
|
||||
}
|
||||
|
||||
private static <T> void test(Consumer<Stream> consumer) {
|
||||
TERMINAL_OPERATIONS.add(new TerminalOperation<T>() {
|
||||
@Override
|
||||
public T result() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(Stream stream) {
|
||||
consumer.accept(stream);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static <T> void test(Function<Stream, T> function, T result) {
|
||||
TERMINAL_OPERATIONS.add(new TerminalOperation<T>() {
|
||||
@Override
|
||||
public T result() {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(Stream stream) {
|
||||
return function.apply(stream);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static <T extends BaseStream> void test(Class<? extends T> type, Function<Stream, T> function) {
|
||||
INTERMEDIATE_OPERATIONS.add(new IntermediateOperation<T>() {
|
||||
@Override
|
||||
public Class<? extends T> type() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(Stream stream) {
|
||||
return function.apply(stream);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
private Stream<Object> delegate;
|
||||
private Stream<Object> inTest;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
delegate = mock(Stream.class);
|
||||
inTest = AutoClosingStream.from(delegate);
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testIntermediateOperationReturnsNewAutoClosingStream(@FromDataPoints("intermediateOperations") IntermediateOperation intermediateOperation) {
|
||||
BaseStream newDelegate = (BaseStream) mock(intermediateOperation.type());
|
||||
when(intermediateOperation.apply(delegate)).thenReturn(newDelegate);
|
||||
|
||||
BaseStream result = intermediateOperation.apply(inTest);
|
||||
|
||||
assertThat(result, isAutoClosing());
|
||||
verifyDelegate(result, newDelegate);
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testTerminalOperationDelegatesToAndClosesDelegate(@FromDataPoints("terminalOperations") TerminalOperation terminalOperation) {
|
||||
Object expectedResult = terminalOperation.result();
|
||||
if (expectedResult != null) {
|
||||
when(terminalOperation.apply(delegate)).thenReturn(expectedResult);
|
||||
}
|
||||
|
||||
Object result = terminalOperation.apply(inTest);
|
||||
|
||||
InOrder inOrder = inOrder(delegate);
|
||||
assertThat(result, is(expectedResult));
|
||||
inOrder.verify(delegate).close();
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void testTerminalOperationClosesDelegateEvenOnException(@FromDataPoints("terminalOperations") TerminalOperation terminalOperation) {
|
||||
RuntimeException exception = new RuntimeException();
|
||||
terminalOperation.apply(doThrow(exception).when(delegate));
|
||||
|
||||
thrown.expect(is(exception));
|
||||
|
||||
try {
|
||||
terminalOperation.apply(inTest);
|
||||
} finally {
|
||||
verify(delegate).close();
|
||||
}
|
||||
}
|
||||
|
||||
private Matcher<BaseStream> isAutoClosing() {
|
||||
return is(anyOf(instanceOf(AutoClosingStream.class), instanceOf(AutoClosingDoubleStream.class), instanceOf(AutoClosingIntStream.class), instanceOf(AutoClosingLongStream.class)));
|
||||
}
|
||||
|
||||
private void verifyDelegate(BaseStream result, BaseStream newDelegate) {
|
||||
result.close();
|
||||
verify(newDelegate).close();
|
||||
}
|
||||
|
||||
private interface TerminalOperation<T> {
|
||||
|
||||
T result();
|
||||
|
||||
T apply(Stream stream);
|
||||
|
||||
}
|
||||
|
||||
private interface IntermediateOperation<T extends BaseStream> {
|
||||
|
||||
Class<? extends T> type();
|
||||
|
||||
T apply(Stream stream);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
2
main/filesystem-api/.gitignore
vendored
2
main/filesystem-api/.gitignore
vendored
@@ -1,2 +0,0 @@
|
||||
/target/
|
||||
/target/
|
||||
@@ -1,55 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.filesystem;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
|
||||
import com.google.common.io.ByteStreams;
|
||||
|
||||
class Copier {
|
||||
|
||||
public static void copy(Folder source, Folder destination) {
|
||||
assertFoldersAreNotNested(source, destination);
|
||||
|
||||
destination.delete();
|
||||
destination.create();
|
||||
|
||||
source.files().forEach(sourceFile -> {
|
||||
File destinationFile = destination.file(sourceFile.name());
|
||||
sourceFile.copyTo(destinationFile);
|
||||
});
|
||||
|
||||
source.folders().forEach(sourceFolder -> {
|
||||
Folder destinationFolder = destination.folder(sourceFolder.name());
|
||||
sourceFolder.copyTo(destinationFolder);
|
||||
});
|
||||
}
|
||||
|
||||
public static void copy(File source, File destination) {
|
||||
try (OpenFiles openFiles = DeadlockSafeFileOpener.withReadable(source).andWritable(destination).open()) {
|
||||
ReadableFile readable = openFiles.readable(source);
|
||||
WritableFile writable = openFiles.writable(destination);
|
||||
writable.truncate();
|
||||
ByteStreams.copy(readable, writable);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertFoldersAreNotNested(Folder source, Folder destination) {
|
||||
if (source.isAncestorOf(destination)) {
|
||||
throw new IllegalArgumentException("Can not copy parent to child directory (src: " + source + ", dst: " + destination + ")");
|
||||
}
|
||||
if (destination.isAncestorOf(source)) {
|
||||
throw new IllegalArgumentException("Can not copy child to parent directory (src: " + source + ", dst: " + destination + ")");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.filesystem;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class DeadlockSafeFileOpener {
|
||||
|
||||
public static DeadlockSafeFileOpener withReadable(File file) {
|
||||
return new DeadlockSafeFileOpener().andReadable(file);
|
||||
}
|
||||
|
||||
public static DeadlockSafeFileOpener withWritable(File file) {
|
||||
return new DeadlockSafeFileOpener().andWritable(file);
|
||||
}
|
||||
|
||||
private final SortedMap<File, Consumer<File>> filesWithOperation = new TreeMap<>();
|
||||
|
||||
private final Map<File, ReadableFile> readableFiles = new HashMap<>();
|
||||
private final Map<File, WritableFile> writableFiles = new HashMap<>();
|
||||
|
||||
private DeadlockSafeFileOpener() {
|
||||
}
|
||||
|
||||
public DeadlockSafeFileOpener andReadable(File file) {
|
||||
if (filesWithOperation.put(file, this::openReadable) != null) {
|
||||
throw new IllegalArgumentException(format("File %s already marked for opening", file));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public DeadlockSafeFileOpener andWritable(File file) {
|
||||
if (filesWithOperation.put(file, this::openWritable) != null) {
|
||||
throw new IllegalArgumentException(format("File %s already marked for opening", file));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private void openReadable(File file) {
|
||||
readableFiles.put(file, file.openReadable());
|
||||
}
|
||||
|
||||
private void openWritable(File file) {
|
||||
writableFiles.put(file, file.openWritable());
|
||||
}
|
||||
|
||||
public OpenFiles open() {
|
||||
try {
|
||||
filesWithOperation.forEach((file, openAction) -> openAction.accept(file));
|
||||
} catch (RuntimeException e) {
|
||||
OpenFiles.cleanup(readableFiles.values(), writableFiles.values());
|
||||
throw e;
|
||||
}
|
||||
return new OpenFiles(readableFiles, writableFiles);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package org.cryptomator.filesystem;
|
||||
|
||||
public class Deleter {
|
||||
|
||||
/**
|
||||
* Deletes all and only the content of a given {@link Folder} but <b>not</b> the folder itself.
|
||||
*/
|
||||
public static void deleteContent(Folder folder) {
|
||||
if (folder.exists()) {
|
||||
folder.folders().forEach(Folder::delete);
|
||||
folder.files().forEach(File::delete);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Markus Kreusch
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
******************************************************************************/
|
||||
package org.cryptomator.filesystem;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
|
||||
/**
|
||||
* A {@link File} in a {@link FileSystem}.
|
||||
*
|
||||
* @author Markus Kreusch
|
||||
*/
|
||||
public interface File extends Node, Comparable<File> {
|
||||
|
||||
static final int EOF = -1;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Opens this file for reading.
|
||||
* <p>
|
||||
* An implementation guarantees, that per {@link FileSystem} and
|
||||
* {@code File} while a {@code ReadableFile} is open no {@link WritableFile}
|
||||
* can be open and vice versa. A {@link ReadableFile} is open when returned
|
||||
* from this method and not yet closed using {@link ReadableFile#close()}.
|
||||
* <br>
|
||||
* A limitation to the number of {@code ReadableFiles} is in general not
|
||||
* required but may be set by a specific implementation.
|
||||
* <p>
|
||||
* If a {@link WritableFile} for this {@code File} is open the invocation of
|
||||
* this method will block regarding the specified timeout.<br>
|
||||
* In addition implementations may block to lock the required IO resources
|
||||
* to read the file.
|
||||
*
|
||||
* @return a {@link ReadableFile} to work with
|
||||
* @throws UncheckedIOException
|
||||
* if an {@link IOException} occurs while opening the file, the
|
||||
* file does not exist or is a directory
|
||||
*/
|
||||
|
||||
ReadableFile openReadable() throws UncheckedIOException;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Opens this file for writing.
|
||||
* <p>
|
||||
* If the file does not exist a new empty file is created.
|
||||
* <p>
|
||||
* An implementation guarantees, that per {@link FileSystem} and
|
||||
* {@code File} only one {@link WritableFile} is open at a time. A
|
||||
* {@code WritableFile} is open when returned from this method and not yet
|
||||
* closed using {@link WritableFile#close()} or
|
||||
* {@link WritableFile#delete()}.<br>
|
||||
* In addition while a {@code WritableFile} is open no {@link ReadableFile}
|
||||
* can be open and vice versa.
|
||||
* <p>
|
||||
* If a {@code Readable-} or {@code WritableFile} for this {@code File} is
|
||||
* open the invocation of this method will block regarding the specified
|
||||
* timeout.<br>
|
||||
* In addition implementations may block to lock the required IO resources
|
||||
* to read the file.
|
||||
*
|
||||
* @return a {@link WritableFile} to work with
|
||||
* @throws UncheckedIOException
|
||||
* if an {@link IOException} occurs while opening the file or
|
||||
* the file is a directory
|
||||
*/
|
||||
WritableFile openWritable() throws UncheckedIOException;
|
||||
|
||||
default void copyTo(File destination) {
|
||||
Copier.copy(this, destination);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves this file including content to a new location specified by <code>destination</code>.
|
||||
*/
|
||||
void moveTo(File destination) throws UncheckedIOException;
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Markus Kreusch
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
******************************************************************************/
|
||||
package org.cryptomator.filesystem;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* The root folder of a file system.
|
||||
*
|
||||
* @author Markus Kreusch
|
||||
*/
|
||||
public interface FileSystem extends Folder {
|
||||
|
||||
/**
|
||||
* @return an empty {@link Optional} because a {@link FileSystem} represents
|
||||
* the root {@link Folder} and thus does not have a parent
|
||||
*/
|
||||
@Override
|
||||
default Optional<? extends Folder> parent() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
Optional<Long> quotaUsedBytes();
|
||||
|
||||
Optional<Long> quotaAvailableBytes();
|
||||
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Markus Kreusch
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
******************************************************************************/
|
||||
package org.cryptomator.filesystem;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* A {@link Folder} in a {@link FileSystem}.
|
||||
*
|
||||
* @author Markus Kreusch
|
||||
*/
|
||||
public interface Folder extends Node {
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Creates a {@link Stream} over all child nodes of this {@code Folder}.
|
||||
* <p>
|
||||
* <b>Note:</b> The {@link Stream} may be lazily populated and thus
|
||||
* {@link IOException IOExceptions} may occurs after this method returned.
|
||||
* In this case implementors should throw a {@link UncheckedIOException}
|
||||
* from any method that produces an {@link IOException}. Thus users should
|
||||
* expect {@link UncheckedIOException UncheckedIOExceptions} when invoking
|
||||
* methods on the returned {@code Stream}.
|
||||
*
|
||||
* @return the created {@code Stream}
|
||||
* @throws UncheckedIOException
|
||||
* if an {@link IOException} occurs while initializing the
|
||||
* stream or the {@code Folder} does not exist
|
||||
*/
|
||||
Stream<? extends Node> children() throws UncheckedIOException;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Returns the child {@link Node} in this directory of type {@link File}
|
||||
* with the specified name.
|
||||
* <p>
|
||||
* This operation always returns a {@link File} without checking if the file
|
||||
* exists or is a {@link Folder} instead.
|
||||
*/
|
||||
File file(String name) throws UncheckedIOException;
|
||||
|
||||
/**
|
||||
* Returns a file by resolving a path relative to this folder.
|
||||
*
|
||||
* @param path A unix-style path, which is always relative to this folder, no matter if it starts with a slash or not. Path must not be empty.
|
||||
* @return File with the given path relative to this folder
|
||||
* @throws IllegalArgumentException
|
||||
* if relativePath is empty
|
||||
*/
|
||||
default File resolveFile(String relativePath) throws UncheckedIOException, IllegalArgumentException {
|
||||
return PathResolver.resolveFile(this, relativePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Returns the child {@link Node} in this directory of type {@link Folder}
|
||||
* with the specified name.
|
||||
* <p>
|
||||
* This operation always returns a {@link Folder} without checking if the
|
||||
* folder exists or is a {@link File} instead.
|
||||
*/
|
||||
Folder folder(String name) throws UncheckedIOException;
|
||||
|
||||
/**
|
||||
* Returns a folder by resolving a path relative to this folder.
|
||||
*
|
||||
* @param path A unix-style path, which is always relative to this folder, no matter if it starts with a slash or not. Path may be empty.
|
||||
* @return Folder with the given path relative to this folder. Returns <code>this</code> if path is empty.
|
||||
*/
|
||||
default Folder resolveFolder(String relativePath) throws UncheckedIOException {
|
||||
return PathResolver.resolveFolder(this, relativePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the directory including all parent directories, if it doesn't
|
||||
* exist yet. No effect, if folder already exists.
|
||||
*
|
||||
* @throws UncheckedIOException
|
||||
* if an {@link IOException} occurs while creating the folder or
|
||||
* one of its parents
|
||||
*/
|
||||
void create() throws UncheckedIOException;
|
||||
|
||||
/**
|
||||
* Recusively copies this directory and all its contents to (not into) the
|
||||
* given destination, creating nonexisting parent directories. If the target
|
||||
* exists it is deleted before performing the copy.
|
||||
*
|
||||
* @param target
|
||||
* Destination folder. Must not be a descendant of this folder.
|
||||
*/
|
||||
default void copyTo(Folder target) throws UncheckedIOException {
|
||||
Copier.copy(this, target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves this directory and its contents to the given destination. If the
|
||||
* target exists it is deleted before performing the move.
|
||||
*/
|
||||
void moveTo(Folder target);
|
||||
|
||||
/**
|
||||
* @return the result of {@link #children()} filtered to contain only
|
||||
* {@link File Files}
|
||||
*/
|
||||
default Stream<? extends File> files() throws UncheckedIOException {
|
||||
return children() //
|
||||
.filter(File.class::isInstance) //
|
||||
.map(File.class::cast);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the result of {@link #children()} filtered to contain only
|
||||
* {@link Folder Folders}
|
||||
*/
|
||||
default Stream<? extends Folder> folders() throws UncheckedIOException {
|
||||
return children() //
|
||||
.filter(Folder.class::isInstance) //
|
||||
.map(Folder.class::cast);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively checks whether this folder or any subfolder contains the
|
||||
* given node.
|
||||
*
|
||||
* @param node
|
||||
* Potential child, grandchild, ...
|
||||
* @return <code>true</code> if this folder is an ancestor of the node.
|
||||
*/
|
||||
default boolean isAncestorOf(Node node) {
|
||||
if (!node.parent().isPresent()) {
|
||||
return false;
|
||||
} else if (node.parent().get().equals(this)) {
|
||||
return true;
|
||||
} else {
|
||||
return this.isAncestorOf(node.parent().get());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.filesystem;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class FolderVisitor {
|
||||
|
||||
private final Consumer<Folder> beforeFolderVisitor;
|
||||
private final Consumer<Folder> afterFolderVisitor;
|
||||
private final Consumer<File> fileVisitor;
|
||||
private final Consumer<Node> nodeVisitor;
|
||||
private final int maxDepth;
|
||||
|
||||
public FolderVisitor(FolderVisitorBuilder builder) {
|
||||
this.beforeFolderVisitor = builder.beforeFolderVisitor;
|
||||
this.afterFolderVisitor = builder.afterFolderVisitor;
|
||||
this.fileVisitor = builder.fileVisitor;
|
||||
this.nodeVisitor = builder.nodeVisitor;
|
||||
this.maxDepth = builder.maxDepth;
|
||||
}
|
||||
|
||||
public static FolderVisitorBuilder folderVisitor() {
|
||||
return new FolderVisitorBuilder();
|
||||
}
|
||||
|
||||
public FolderVisitor visit(Folder folder) {
|
||||
return visit(folder, 0);
|
||||
}
|
||||
|
||||
public FolderVisitor visit(File file) {
|
||||
return visit(file, 0);
|
||||
}
|
||||
|
||||
private FolderVisitor visit(Folder folder, int depth) {
|
||||
beforeFolderVisitor.accept(folder);
|
||||
nodeVisitor.accept(folder);
|
||||
final int childDepth = depth + 1;
|
||||
if (childDepth <= maxDepth) {
|
||||
folder.folders().forEach(childFolder -> visit(childFolder, childDepth));
|
||||
folder.files().forEach(childFile -> visit(childFile, childDepth));
|
||||
}
|
||||
afterFolderVisitor.accept(folder);
|
||||
return this;
|
||||
}
|
||||
|
||||
private FolderVisitor visit(File file, int depth) {
|
||||
nodeVisitor.accept(file);
|
||||
fileVisitor.accept(file);
|
||||
return this;
|
||||
}
|
||||
|
||||
public static class FolderVisitorBuilder {
|
||||
|
||||
private Consumer<Folder> beforeFolderVisitor = noOp();
|
||||
private Consumer<Folder> afterFolderVisitor = noOp();
|
||||
private Consumer<File> fileVisitor = noOp();
|
||||
private Consumer<Node> nodeVisitor = noOp();
|
||||
private int maxDepth = Integer.MAX_VALUE;
|
||||
|
||||
private FolderVisitorBuilder() {
|
||||
}
|
||||
|
||||
public FolderVisitorBuilder beforeFolder(Consumer<Folder> beforeFolderVisitor) {
|
||||
if (beforeFolderVisitor == null) {
|
||||
throw new IllegalArgumentException("Vistior may not be null");
|
||||
}
|
||||
this.beforeFolderVisitor = beforeFolderVisitor;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FolderVisitorBuilder afterFolder(Consumer<Folder> afterFolderVisitor) {
|
||||
if (afterFolderVisitor == null) {
|
||||
throw new IllegalArgumentException("Vistior may not be null");
|
||||
}
|
||||
this.afterFolderVisitor = afterFolderVisitor;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FolderVisitorBuilder forEachFile(Consumer<File> fileVisitor) {
|
||||
if (fileVisitor == null) {
|
||||
throw new IllegalArgumentException("Vistior may not be null");
|
||||
}
|
||||
this.fileVisitor = fileVisitor;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FolderVisitorBuilder forEachNode(Consumer<Node> nodeVisitor) {
|
||||
if (nodeVisitor == null) {
|
||||
throw new IllegalArgumentException("Vistior may not be null");
|
||||
}
|
||||
this.nodeVisitor = nodeVisitor;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FolderVisitorBuilder withMaxDepth(int maxDepth) {
|
||||
if (maxDepth < 0) {
|
||||
throw new IllegalArgumentException(format("maxDepth must not be smaller 0 but was %d", maxDepth));
|
||||
}
|
||||
this.maxDepth = maxDepth;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FolderVisitor visit(Folder folder) {
|
||||
return build().visit(folder);
|
||||
}
|
||||
|
||||
public FolderVisitor visit(File file) {
|
||||
return build().visit(file);
|
||||
}
|
||||
|
||||
public FolderVisitor build() {
|
||||
return new FolderVisitor(this);
|
||||
}
|
||||
|
||||
private static <T> Consumer<T> noOp() {
|
||||
return ignoredParameter -> {
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Markus Kreusch
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
******************************************************************************/
|
||||
package org.cryptomator.filesystem;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.time.Instant;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Represents a node, namely a {@link File} or {@link Folder}, in a
|
||||
* {@link FileSystem}.
|
||||
* <p>
|
||||
* A node's identity (i.e. {@link #hashCode()} and {@link #equals(Object)}) depends on its parent node and its name (forming the node's path).
|
||||
* These properties are meant to be immutable. This means that e.g. moving a node doesn't modify the node's identity but rather transfers properties to the destination node.
|
||||
*
|
||||
* @author Markus Kreusch
|
||||
* @see Folder
|
||||
* @see File
|
||||
*/
|
||||
public interface Node {
|
||||
|
||||
String name() throws UncheckedIOException;
|
||||
|
||||
/**
|
||||
* @return Optional parent folder. No parent is present for the root node (see {@link FileSystem#parent()}).
|
||||
*/
|
||||
Optional<? extends Folder> parent() throws UncheckedIOException;
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if the node exists.
|
||||
*/
|
||||
boolean exists() throws UncheckedIOException;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Deletes the node if it exists.
|
||||
* <p>
|
||||
* Does nothing if the node does not exist.
|
||||
*/
|
||||
void delete() throws UncheckedIOException;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Determines the last modified date of this node.
|
||||
*
|
||||
* @returns the last modified date of the file
|
||||
*/
|
||||
Instant lastModified() throws UncheckedIOException;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Sets the last modified date of the file.
|
||||
*
|
||||
* @param lastModified the time to set as creation time
|
||||
*/
|
||||
void setLastModified(Instant lastModified) throws UncheckedIOException;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Determines the creation time of this node.
|
||||
* <p>
|
||||
* Note: Getting the creation time may not be supported by all {@link FileSystem FileSystems}.
|
||||
*
|
||||
* @returns the creation time of the file or {@link Optional#empty()} if not supported
|
||||
*/
|
||||
default Optional<Instant> creationTime() throws UncheckedIOException {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Sets the creation time of this node.
|
||||
* <p>
|
||||
* Setting the creation time may not be supported by all {@link FileSystem FileSystems}. If the {@code FileSystem} this {@code Node} belongs to does not support the
|
||||
* setting the creation time the behavior of this method is unspecified.
|
||||
*
|
||||
* @param creationTime the time to set as creation time
|
||||
*/
|
||||
default void setCreationTime(Instant creationTime) throws UncheckedIOException {
|
||||
throw new UncheckedIOException(new IOException("CreationTime not supported"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link FileSystem} this Node belongs to
|
||||
*/
|
||||
default FileSystem fileSystem() {
|
||||
return parent() //
|
||||
.map(Node::fileSystem) //
|
||||
.orElseGet(() -> (FileSystem) this);
|
||||
}
|
||||
|
||||
default boolean belongsToSameFilesystem(Node other) {
|
||||
return fileSystem() == other.fileSystem();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.filesystem;
|
||||
|
||||
import java.io.UncheckedIOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class OpenFiles implements AutoCloseable {
|
||||
|
||||
private final static Logger LOG = LoggerFactory.getLogger(OpenFiles.class);
|
||||
|
||||
private final Map<File, ReadableFile> readableFiles;
|
||||
private final Map<File, WritableFile> writableFiles;
|
||||
|
||||
public OpenFiles(Map<File, ReadableFile> readableFiles, Map<File, WritableFile> writableFiles) {
|
||||
this.readableFiles = readableFiles;
|
||||
this.writableFiles = writableFiles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws UncheckedIOException {
|
||||
OpenFiles.cleanup(readableFiles.values(), writableFiles.values());
|
||||
}
|
||||
|
||||
public ReadableFile readable(File file) {
|
||||
return readableFiles.computeIfAbsent(file, fileNotOpenForReading -> {
|
||||
throw new IllegalArgumentException(String.format("File %s is not open for reading", fileNotOpenForReading));
|
||||
});
|
||||
}
|
||||
|
||||
public WritableFile writable(File file) {
|
||||
return writableFiles.computeIfAbsent(file, fileNotOpenForWriting -> {
|
||||
throw new IllegalArgumentException(String.format("File %s is not open for writing", fileNotOpenForWriting));
|
||||
});
|
||||
}
|
||||
|
||||
static void cleanup(Collection<ReadableFile> readableFiles, Collection<WritableFile> writableFiles) {
|
||||
Iterator<? extends AutoCloseable> iterator = Stream.concat(readableFiles.stream(), writableFiles.stream()).iterator();
|
||||
UncheckedIOException firstException = null;
|
||||
while (iterator.hasNext()) {
|
||||
AutoCloseable openFile = iterator.next();
|
||||
try {
|
||||
openFile.close();
|
||||
} catch (UncheckedIOException e) {
|
||||
if (firstException == null) {
|
||||
firstException = e;
|
||||
} else {
|
||||
firstException.addSuppressed(e);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.error("Unexpected exception during close on " + openFile.getClass().getSimpleName(), e);
|
||||
}
|
||||
}
|
||||
if (firstException != null) {
|
||||
throw firstException;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
package org.cryptomator.filesystem;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
final class PathResolver {
|
||||
|
||||
private static final String DOT = ".";
|
||||
private static final String DOTDOT = "..";
|
||||
|
||||
private PathResolver() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a relative path (separated by '/') to a folder, e.g.
|
||||
* <!-- @formatter:off -->
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr>
|
||||
* <th>dir</th>
|
||||
* <th>path</th>
|
||||
* <th>result</th>
|
||||
* </tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr>
|
||||
* <td>/foo/bar</td>
|
||||
* <td>foo/bar</td>
|
||||
* <td>/foo/bar/foo/bar</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>/foo/bar</td>
|
||||
* <td>../baz</td>
|
||||
* <td>/foo/baz</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>/foo/bar</td>
|
||||
* <td>./foo/..</td>
|
||||
* <td>/foo/bar</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>/foo/bar</td>
|
||||
* <td>/</td>
|
||||
* <td>/foo/bar</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>/foo/bar</td>
|
||||
* <td></td>
|
||||
* <td>/foo/bar</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>/foo/bar</td>
|
||||
* <td>../../..</td>
|
||||
* <td>Exception</td>
|
||||
* </tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
*
|
||||
* @param dir The directory from which to resolve the path.
|
||||
* @param relativePath The path relative to a given directory.
|
||||
* @return The folder with the given path relative to the given dir.
|
||||
*/
|
||||
public static Folder resolveFolder(Folder dir, String relativePath) {
|
||||
final String[] fragments = StringUtils.split(relativePath, '/');
|
||||
if (ArrayUtils.isEmpty(fragments)) {
|
||||
return dir;
|
||||
}
|
||||
return resolveFolder(dir, Arrays.stream(fragments).iterator());
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a relative path (separated by '/') to a file. Besides returning a File, this method is identical to {@link #resolveFile(Folder, String)}.
|
||||
*
|
||||
* @param dir The directory from which to resolve the path.
|
||||
* @param relativePath The path relative to a given directory.
|
||||
* @return The file with the given path relative to the given dir.
|
||||
* @throws IllegalArgumentException
|
||||
* if relativePath is empty, as this path would resolve to the directory itself, which obviously can't be a file.
|
||||
*/
|
||||
public static File resolveFile(Folder dir, String relativePath) {
|
||||
final String[] fragments = StringUtils.split(relativePath, '/');
|
||||
if (ArrayUtils.isEmpty(fragments)) {
|
||||
throw new IllegalArgumentException("Empty relativePath");
|
||||
}
|
||||
final Folder folder = resolveFolder(dir, Arrays.stream(fragments).limit(fragments.length - 1).iterator());
|
||||
final String filename = fragments[fragments.length - 1];
|
||||
return folder.file(filename);
|
||||
}
|
||||
|
||||
private static Folder resolveFolder(Folder dir, Iterator<String> remainingPathFragments) {
|
||||
if (!remainingPathFragments.hasNext()) {
|
||||
return dir;
|
||||
}
|
||||
final String fragment = remainingPathFragments.next();
|
||||
assert fragment.length() > 0 : "iterator must not contain empty fragments";
|
||||
if (DOT.equals(fragment)) {
|
||||
return resolveFolder(dir, remainingPathFragments);
|
||||
} else if (DOTDOT.equals(fragment) && dir.parent().isPresent()) {
|
||||
return resolveFolder(dir.parent().get(), remainingPathFragments);
|
||||
} else if (DOTDOT.equals(fragment) && !dir.parent().isPresent()) {
|
||||
throw new UncheckedIOException(new FileNotFoundException("Unresolvable path"));
|
||||
} else {
|
||||
return resolveFolder(dir.folder(fragment), remainingPathFragments);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Markus Kreusch
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
******************************************************************************/
|
||||
package org.cryptomator.filesystem;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
|
||||
public interface ReadableFile extends ReadableByteChannel {
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Tries to fill the remaining space in the given byte buffer with data from
|
||||
* this readable bytes from the current position.
|
||||
* <p>
|
||||
* May read less bytes if the end of this readable bytes has been reached.
|
||||
*
|
||||
* @param target
|
||||
* the byte buffer to fill
|
||||
* @return the number of bytes actually read, or {@code -1} if the end of
|
||||
* file has been reached
|
||||
* @throws UncheckedIOException
|
||||
* if an {@link IOException} occurs while reading from this
|
||||
* {@code ReadableBytes}
|
||||
*/
|
||||
@Override
|
||||
int read(ByteBuffer target) throws UncheckedIOException;
|
||||
|
||||
/**
|
||||
* @return The current size of the file. This value is a snapshot and might have been changed by concurrent modifications.
|
||||
* @throws UncheckedIOException
|
||||
* if an {@link IOException} occurs
|
||||
*/
|
||||
long size() throws UncheckedIOException;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Fast-forwards or rewinds the file to the specified position.
|
||||
* <p>
|
||||
* Consecutive reads on the file will begin at the new position.
|
||||
*
|
||||
* @param position
|
||||
* the position to set the file to
|
||||
* @throws UncheckedIOException
|
||||
* if an {@link IOException} occurs
|
||||
*
|
||||
*/
|
||||
void position(long position) throws UncheckedIOException;
|
||||
|
||||
@Override
|
||||
void close() throws UncheckedIOException;
|
||||
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Markus Kreusch
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
******************************************************************************/
|
||||
package org.cryptomator.filesystem;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
|
||||
public interface WritableFile extends WritableByteChannel {
|
||||
|
||||
void truncate() throws UncheckedIOException;
|
||||
|
||||
/**
|
||||
* Writes the data in the given byte buffer to this readable bytes at the
|
||||
* current position.
|
||||
*
|
||||
* @param source
|
||||
* the byte buffer to use
|
||||
* @return the number of bytes written, always equal to
|
||||
* {@code source.remaining()}
|
||||
* @throws UncheckedIOException
|
||||
* if an {@link IOException} occurs while writing
|
||||
*/
|
||||
@Override
|
||||
int write(ByteBuffer source) throws UncheckedIOException;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Fast-forwards or rewinds the file to the specified position.
|
||||
* <p>
|
||||
* Consecutive writes on the file will begin at the new position.
|
||||
* <p>
|
||||
* If the position is set to a value greater than the current end of file
|
||||
* consecutive writes will write data to the given position. The value of
|
||||
* all bytes between this position and the previous end of file will be
|
||||
* unspecified.
|
||||
*
|
||||
* @param position
|
||||
* the position to set the file to
|
||||
* @throws UncheckedIOException
|
||||
* if an {@link IOException} occurs
|
||||
*/
|
||||
void position(long position) throws UncheckedIOException;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Closes this {@code WritableFile} which finally commits all operations
|
||||
* performed on it to the underlying file system.
|
||||
* <p>
|
||||
* After a {@code WritableFile} has been closed all other operations will
|
||||
* throw an {@link UncheckedIOException}.
|
||||
* <p>
|
||||
* Invoking this method on a {@link WritableFile} which has already been
|
||||
* closed does nothing.
|
||||
*/
|
||||
@Override
|
||||
void close() throws UncheckedIOException;
|
||||
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.filesystem.delegating;
|
||||
|
||||
import java.io.UncheckedIOException;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.cryptomator.filesystem.File;
|
||||
import org.cryptomator.filesystem.ReadableFile;
|
||||
import org.cryptomator.filesystem.WritableFile;
|
||||
|
||||
public abstract class DelegatingFile<D extends DelegatingFolder<D, ?>> extends DelegatingNode<File>implements File {
|
||||
|
||||
private final D parent;
|
||||
|
||||
public DelegatingFile(D parent, File delegate) {
|
||||
super(delegate);
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<D> parent() throws UncheckedIOException {
|
||||
return Optional.of(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadableFile openReadable() throws UncheckedIOException {
|
||||
return delegate.openReadable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public WritableFile openWritable() throws UncheckedIOException {
|
||||
return delegate.openWritable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyTo(File destination) {
|
||||
if (getClass().equals(destination.getClass())) {
|
||||
final File delegateDest = ((DelegatingFile<?>) destination).delegate;
|
||||
delegate.copyTo(delegateDest);
|
||||
} else {
|
||||
delegate.copyTo(destination);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveTo(File destination) {
|
||||
if (getClass().equals(destination.getClass())) {
|
||||
final File delegateDest = ((DelegatingFile<?>) destination).delegate;
|
||||
delegate.moveTo(delegateDest);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Can only move DelegatingFile to other DelegatingFile.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete() throws UncheckedIOException {
|
||||
delegate.delete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(File o) {
|
||||
if (getClass().equals(o.getClass())) {
|
||||
final File delegateOther = ((DelegatingFile<?>) o).delegate;
|
||||
return delegate.compareTo(delegateOther);
|
||||
} else {
|
||||
return delegate.compareTo(o);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package org.cryptomator.filesystem.delegating;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.cryptomator.filesystem.FileSystem;
|
||||
import org.cryptomator.filesystem.Folder;
|
||||
|
||||
public interface DelegatingFileSystem extends FileSystem {
|
||||
|
||||
Folder getDelegate();
|
||||
|
||||
@Override
|
||||
default Optional<Long> quotaUsedBytes() {
|
||||
return getDelegate().fileSystem().quotaUsedBytes();
|
||||
}
|
||||
|
||||
@Override
|
||||
default Optional<Long> quotaAvailableBytes() {
|
||||
return getDelegate().fileSystem().quotaAvailableBytes();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.filesystem.delegating;
|
||||
|
||||
import java.io.UncheckedIOException;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.cryptomator.common.WeakValuedCache;
|
||||
import org.cryptomator.common.streams.AutoClosingStream;
|
||||
import org.cryptomator.filesystem.File;
|
||||
import org.cryptomator.filesystem.Folder;
|
||||
import org.cryptomator.filesystem.Node;
|
||||
|
||||
public abstract class DelegatingFolder<D extends DelegatingFolder<D, F>, F extends DelegatingFile<D>> extends DelegatingNode<Folder>implements Folder {
|
||||
|
||||
private final D parent;
|
||||
private final WeakValuedCache<Folder, D> folders = WeakValuedCache.usingLoader(this::newFolder);
|
||||
private final WeakValuedCache<File, F> files = WeakValuedCache.usingLoader(this::newFile);
|
||||
|
||||
public DelegatingFolder(D parent, Folder delegate) {
|
||||
super(delegate);
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<D> parent() throws UncheckedIOException {
|
||||
return Optional.ofNullable(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<? extends Node> children() throws UncheckedIOException {
|
||||
return AutoClosingStream.from(Stream.concat(folders(), files()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<D> folders() {
|
||||
return delegate.folders().map(folders::get);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<F> files() throws UncheckedIOException {
|
||||
return delegate.files().map(files::get);
|
||||
}
|
||||
|
||||
@Override
|
||||
public F file(String name) throws UncheckedIOException {
|
||||
return files.get(delegate.file(name));
|
||||
}
|
||||
|
||||
protected abstract F newFile(File delegate);
|
||||
|
||||
@Override
|
||||
public D folder(String name) throws UncheckedIOException {
|
||||
return folders.get(delegate.folder(name));
|
||||
}
|
||||
|
||||
protected abstract D newFolder(Folder delegate);
|
||||
|
||||
@Override
|
||||
public void create() throws UncheckedIOException {
|
||||
if (exists()) {
|
||||
return;
|
||||
}
|
||||
parent().ifPresent(p -> p.create());
|
||||
delegate.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete() {
|
||||
delegate.delete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyTo(Folder destination) throws UncheckedIOException {
|
||||
if (destination instanceof DelegatingFolder) {
|
||||
final Folder delegateDest = ((DelegatingFolder<?, ?>) destination).delegate;
|
||||
delegate.copyTo(delegateDest);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Can only copy DelegatingFolder to other DelegatingFolder.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveTo(Folder destination) {
|
||||
if (getClass().equals(destination.getClass())) {
|
||||
final Folder delegateDest = ((DelegatingFolder<?, ?>) destination).delegate;
|
||||
delegate.moveTo(delegateDest);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Can only move DelegatingFolder to other DelegatingFolder.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.filesystem.delegating;
|
||||
|
||||
import java.io.UncheckedIOException;
|
||||
import java.time.Instant;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.cryptomator.filesystem.Node;
|
||||
|
||||
public abstract class DelegatingNode<T extends Node> implements Node {
|
||||
|
||||
protected final T delegate;
|
||||
|
||||
public DelegatingNode(T delegate) {
|
||||
if (delegate == null) {
|
||||
throw new IllegalArgumentException("Delegate must not be null");
|
||||
}
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() throws UncheckedIOException {
|
||||
return delegate.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() throws UncheckedIOException {
|
||||
return delegate.exists();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instant lastModified() throws UncheckedIOException {
|
||||
return delegate.lastModified();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLastModified(Instant instant) throws UncheckedIOException {
|
||||
delegate.setLastModified(instant);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Instant> creationTime() throws UncheckedIOException {
|
||||
return delegate.creationTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCreationTime(Instant instant) throws UncheckedIOException {
|
||||
delegate.setCreationTime(instant);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return delegate.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof DelegatingNode) {
|
||||
DelegatingNode<?> other = (DelegatingNode<?>) obj;
|
||||
return this.delegate.equals(other.delegate);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Delegate[" + delegate + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.filesystem.delegating;
|
||||
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.cryptomator.filesystem.ReadableFile;
|
||||
|
||||
public class DelegatingReadableFile implements ReadableFile {
|
||||
|
||||
private final ReadableFile delegate;
|
||||
|
||||
public DelegatingReadableFile(ReadableFile delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return delegate.isOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(ByteBuffer target) throws UncheckedIOException {
|
||||
return delegate.read(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long size() throws UncheckedIOException {
|
||||
return delegate.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void position(long position) throws UncheckedIOException {
|
||||
delegate.position(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws UncheckedIOException {
|
||||
delegate.close();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.filesystem.delegating;
|
||||
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.cryptomator.filesystem.WritableFile;
|
||||
|
||||
public class DelegatingWritableFile implements WritableFile {
|
||||
|
||||
final WritableFile delegate;
|
||||
|
||||
public DelegatingWritableFile(WritableFile delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return delegate.isOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void truncate() throws UncheckedIOException {
|
||||
delegate.truncate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int write(ByteBuffer source) throws UncheckedIOException {
|
||||
return delegate.write(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void position(long position) throws UncheckedIOException {
|
||||
delegate.position(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws UncheckedIOException {
|
||||
delegate.close();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* Defines a file system abstraction to allow access to real and virtual file
|
||||
* systems through a common API.
|
||||
*/
|
||||
package org.cryptomator.filesystem;
|
||||
@@ -1,35 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.io;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public final class ByteBuffers {
|
||||
|
||||
private ByteBuffers() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies as many bytes as possible from the given source to the destination buffer.
|
||||
* The position of both buffers will be incremented by as many bytes as have been copied.
|
||||
*
|
||||
* @param source ByteBuffer from which bytes are read
|
||||
* @param destination ByteBuffer into which bytes are written
|
||||
* @return number of bytes copied, i.e. {@link ByteBuffer#remaining() source.remaining()} or {@link ByteBuffer#remaining() destination.remaining()}, whatever is less.
|
||||
*/
|
||||
public static int copy(ByteBuffer source, ByteBuffer destination) {
|
||||
final int numBytes = Math.min(source.remaining(), destination.remaining());
|
||||
final ByteBuffer tmp = source.asReadOnlyBuffer();
|
||||
tmp.limit(tmp.position() + numBytes);
|
||||
destination.put(tmp);
|
||||
source.position(tmp.position()); // until now only tmp pos has been incremented, so we need to adjust the position
|
||||
return numBytes;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
package org.cryptomator.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.cryptomator.filesystem.File;
|
||||
import org.cryptomator.filesystem.WritableFile;
|
||||
|
||||
public final class FileContents {
|
||||
|
||||
public static final FileContents UTF_8 = FileContents.withCharset(StandardCharsets.UTF_8);
|
||||
|
||||
private final Charset charset;
|
||||
|
||||
private FileContents(Charset charset) {
|
||||
this.charset = charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the whole content from the given file.
|
||||
*
|
||||
* @param file File whose content should be read.
|
||||
* @return The file's content interpreted in this FileContents' charset.
|
||||
*/
|
||||
public String readContents(File file) {
|
||||
try (Reader reader = Channels.newReader(file.openReadable(), charset.newDecoder(), -1)) {
|
||||
return IOUtils.toString(reader);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the string into the file encoded with this FileContents' charset.
|
||||
* This methods replaces any previously existing content, i.e. the string will be the sole content.
|
||||
*
|
||||
* @param file File whose content should be written.
|
||||
* @param content The new content.
|
||||
*/
|
||||
public void writeContents(File file, String content) {
|
||||
try (WritableFile writable = file.openWritable()) {
|
||||
writable.truncate();
|
||||
writable.write(charset.encode(content));
|
||||
}
|
||||
}
|
||||
|
||||
public static FileContents withCharset(Charset charset) {
|
||||
return new FileContents(charset);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package org.cryptomator.filesystem;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.hamcrest.Description;
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.TypeSafeDiagnosingMatcher;
|
||||
|
||||
public class ByteBufferMatcher {
|
||||
|
||||
public static Matcher<ByteBuffer> byteBufferFilledWith(int value) {
|
||||
if (((byte) value) != value) {
|
||||
throw new IllegalArgumentException("Invalid byte value");
|
||||
}
|
||||
return new TypeSafeDiagnosingMatcher<ByteBuffer>(ByteBuffer.class) {
|
||||
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
description.appendText("a byte buffer filled with " + value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean matchesSafely(ByteBuffer item, Description mismatchDescription) {
|
||||
while (item.hasRemaining()) {
|
||||
byte currentValue = item.get();
|
||||
if (currentValue != value) {
|
||||
mismatchDescription.appendText("a byte buffer containing also " + currentValue);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,227 +0,0 @@
|
||||
package org.cryptomator.filesystem;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.cryptomator.common.test.matcher.ContainsMatcher.contains;
|
||||
import static org.cryptomator.common.test.mockito.Answers.collectParameters;
|
||||
import static org.cryptomator.common.test.mockito.Answers.consecutiveAnswers;
|
||||
import static org.cryptomator.common.test.mockito.Answers.value;
|
||||
import static org.cryptomator.filesystem.File.EOF;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import de.bechte.junit.runners.context.HierarchicalContextRunner;
|
||||
|
||||
@RunWith(HierarchicalContextRunner.class)
|
||||
public class CopierTest {
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
@Rule
|
||||
public MockitoRule mockitoRule = MockitoJUnit.rule();
|
||||
|
||||
public class CopyFiles {
|
||||
|
||||
@Mock
|
||||
private File source;
|
||||
|
||||
@Mock
|
||||
private File destination;
|
||||
|
||||
@Mock
|
||||
private ReadableFile readable;
|
||||
|
||||
@Mock
|
||||
private WritableFile writable;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
when(source.openReadable()).thenReturn(readable);
|
||||
when(destination.openWritable()).thenReturn(writable);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopyFileOpensFilesInSortedOrderIfSourceIsSmallerDestination() {
|
||||
mockCompareToWithOrder(source, destination);
|
||||
when(readable.read(any())).thenReturn(EOF);
|
||||
|
||||
Copier.copy(source, destination);
|
||||
|
||||
InOrder inOrder = inOrder(source, destination);
|
||||
inOrder.verify(source).openReadable();
|
||||
inOrder.verify(destination).openWritable();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopyFileOpensFilesInSortedOrderIfDestinationIsSmallerSource() {
|
||||
mockCompareToWithOrder(destination, source);
|
||||
when(readable.read(any())).thenReturn(EOF);
|
||||
|
||||
Copier.copy(source, destination);
|
||||
|
||||
InOrder inOrder = inOrder(source, destination);
|
||||
inOrder.verify(destination).openWritable();
|
||||
inOrder.verify(source).openReadable();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopyFileReadsAndWritesReadableSourceAndWritableDestintationUntilEof() {
|
||||
int irrelevantValue = 0;
|
||||
Collection<byte[]> written = new ArrayList<>();
|
||||
mockCompareToWithOrder(source, destination);
|
||||
byte[] read1 = {1, 48, 32, 33, 22};
|
||||
byte[] read2 = {4, 3, 1, -2, -8};
|
||||
when(readable.read(any())).then(consecutiveAnswers(fillBufferWith(read1), fillBufferWith(read2), value(EOF)));
|
||||
when(writable.write(any())).then(collectParameters(value(irrelevantValue), (ByteBuffer buffer) -> {
|
||||
byte[] data = new byte[buffer.remaining()];
|
||||
buffer.get(data);
|
||||
written.add(data);
|
||||
}));
|
||||
|
||||
Copier.copy(source, destination);
|
||||
|
||||
InOrder inOrder = inOrder(readable, writable);
|
||||
inOrder.verify(writable).truncate();
|
||||
inOrder.verify(readable).read(any());
|
||||
inOrder.verify(writable).write(any());
|
||||
inOrder.verify(readable).read(any());
|
||||
inOrder.verify(writable).write(any());
|
||||
inOrder.verify(readable).read(any());
|
||||
inOrder.verify(readable).close();
|
||||
inOrder.verify(writable).close();
|
||||
|
||||
assertThat(written, contains(is(read1), is(read2)));
|
||||
}
|
||||
|
||||
private Answer<Integer> fillBufferWith(byte[] data) {
|
||||
return new Answer<Integer>() {
|
||||
@Override
|
||||
public Integer answer(InvocationOnMock invocation) throws Throwable {
|
||||
ByteBuffer buffer = invocation.getArgumentAt(0, ByteBuffer.class);
|
||||
for (byte value : data) {
|
||||
buffer.put(value);
|
||||
}
|
||||
return data.length;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
private void mockCompareToWithOrder(File first, File last) {
|
||||
when(first.compareTo(last)).thenReturn(-1);
|
||||
when(last.compareTo(first)).thenReturn(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class CopyFolders {
|
||||
|
||||
@Mock
|
||||
private Folder source;
|
||||
|
||||
@Mock
|
||||
private Folder destination;
|
||||
|
||||
@Test
|
||||
public void testCopyFolderDeletesAndCreatesDestinationBeforeIteratingOverTheFilesAndFoldersInSource() {
|
||||
when(source.files()).thenReturn(Stream.empty());
|
||||
when(source.folders()).thenReturn(Stream.empty());
|
||||
|
||||
Copier.copy(source, destination);
|
||||
|
||||
InOrder inOrder = inOrder(source, destination);
|
||||
inOrder.verify(destination).delete();
|
||||
inOrder.verify(destination).create();
|
||||
inOrder.verify(source).files();
|
||||
inOrder.verify(source).folders();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public void testCopyFolderInvokesCopyToOnAllFilesInSourceWithFileWithSameNameFromDestination() {
|
||||
String filename1 = "nameOfFile1";
|
||||
String filename2 = "nameOfFile2";
|
||||
File file1 = mock(File.class);
|
||||
File file2 = mock(File.class);
|
||||
File destinationFile1 = mock(File.class);
|
||||
File destinationFile2 = mock(File.class);
|
||||
when(source.files()).thenReturn((Stream) asList(file1, file2).stream());
|
||||
when(source.folders()).thenReturn(Stream.empty());
|
||||
when(destination.file(filename1)).thenReturn(destinationFile1);
|
||||
when(destination.file(filename2)).thenReturn(destinationFile2);
|
||||
when(file1.name()).thenReturn(filename1);
|
||||
when(file2.name()).thenReturn(filename2);
|
||||
|
||||
Copier.copy(source, destination);
|
||||
|
||||
verify(file1).copyTo(destinationFile1);
|
||||
verify(file2).copyTo(destinationFile2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public void testCopyFolderInvokesCopyToOnAllFoldersInSourceWithFolderWithSameNameFromDestination() {
|
||||
String folderName1 = "nameOfFolder1";
|
||||
String folderName2 = "nameOfFolder2";
|
||||
Folder folder1 = mock(Folder.class);
|
||||
Folder folder2 = mock(Folder.class);
|
||||
Folder destinationfolder1 = mock(Folder.class);
|
||||
Folder destinationfolder2 = mock(Folder.class);
|
||||
when(source.folders()).thenReturn((Stream) asList(folder1, folder2).stream());
|
||||
when(source.files()).thenReturn(Stream.empty());
|
||||
when(destination.folder(folderName1)).thenReturn(destinationfolder1);
|
||||
when(destination.folder(folderName2)).thenReturn(destinationfolder2);
|
||||
when(folder1.name()).thenReturn(folderName1);
|
||||
when(folder2.name()).thenReturn(folderName2);
|
||||
|
||||
Copier.copy(source, destination);
|
||||
|
||||
verify(folder1).copyTo(destinationfolder1);
|
||||
verify(folder2).copyTo(destinationfolder2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopyFolderFailsWithIllegalArgumentExceptionIfSourceIsNestedInDestination() {
|
||||
when(source.isAncestorOf(destination)).thenReturn(false);
|
||||
when(destination.isAncestorOf(source)).thenReturn(true);
|
||||
|
||||
thrown.expect(IllegalArgumentException.class);
|
||||
|
||||
Copier.copy(source, destination);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopyFolderFailsWithIllegalArgumentExceptionIfDestinationIsNestedInSource() {
|
||||
when(source.isAncestorOf(destination)).thenReturn(true);
|
||||
when(destination.isAncestorOf(source)).thenReturn(false);
|
||||
|
||||
thrown.expect(IllegalArgumentException.class);
|
||||
|
||||
Copier.copy(source, destination);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
package org.cryptomator.filesystem;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
public class PathResolverTest {
|
||||
|
||||
private final Folder root = Mockito.mock(Folder.class);
|
||||
private final Folder foo = Mockito.mock(Folder.class);
|
||||
private final Folder bar = Mockito.mock(Folder.class);
|
||||
private final File baz = Mockito.mock(File.class);
|
||||
|
||||
@Before
|
||||
public void configureMocks() throws IOException {
|
||||
Mockito.doReturn(Optional.empty()).when(root).parent();
|
||||
Mockito.doReturn(Optional.of(root)).when(foo).parent();
|
||||
Mockito.doReturn(Optional.of(foo)).when(bar).parent();
|
||||
|
||||
Mockito.doReturn(foo).when(root).folder("foo");
|
||||
Mockito.doReturn(bar).when(foo).folder("bar");
|
||||
Mockito.doReturn(baz).when(bar).file("baz");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveSameFolder() {
|
||||
Assert.assertEquals(foo, PathResolver.resolveFolder(foo, ""));
|
||||
Assert.assertEquals(foo, PathResolver.resolveFolder(foo, "/"));
|
||||
Assert.assertEquals(foo, PathResolver.resolveFolder(foo, "///"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveChildFolder() {
|
||||
Assert.assertEquals(bar, PathResolver.resolveFolder(root, "foo/bar"));
|
||||
Assert.assertEquals(bar, PathResolver.resolveFolder(root, "foo/./bar"));
|
||||
Assert.assertEquals(bar, PathResolver.resolveFolder(root, "./foo/././bar"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveParentFolder() {
|
||||
Assert.assertEquals(foo, PathResolver.resolveFolder(bar, ".."));
|
||||
Assert.assertEquals(root, PathResolver.resolveFolder(bar, "../.."));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveSiblingFolder() {
|
||||
Assert.assertEquals(foo, PathResolver.resolveFolder(bar, "../../foo"));
|
||||
}
|
||||
|
||||
@Test(expected = UncheckedIOException.class)
|
||||
public void testResolveUnresolvableFolder() {
|
||||
PathResolver.resolveFolder(root, "..");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testResolveFileWithEmptyPath() {
|
||||
PathResolver.resolveFile(root, "");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveFile() {
|
||||
Assert.assertEquals(baz, PathResolver.resolveFile(foo, "../foo/bar/./baz"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package org.cryptomator.filesystem.delegating;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.cryptomator.filesystem.FileSystem;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
public class DelegatingFileSystemTest {
|
||||
|
||||
@Test
|
||||
public void testQuotaAvailableBytes() {
|
||||
FileSystem mockFs = Mockito.mock(FileSystem.class);
|
||||
Mockito.when(mockFs.fileSystem()).thenReturn(mockFs);
|
||||
Mockito.when(mockFs.quotaAvailableBytes()).thenReturn(Optional.of(42l));
|
||||
|
||||
DelegatingFileSystem delegatingFs = TestDelegatingFileSystem.withRoot(mockFs);
|
||||
Assert.assertEquals(mockFs.quotaAvailableBytes(), delegatingFs.quotaAvailableBytes());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQuotaUsedBytes() {
|
||||
FileSystem mockFs = Mockito.mock(FileSystem.class);
|
||||
Mockito.when(mockFs.fileSystem()).thenReturn(mockFs);
|
||||
Mockito.when(mockFs.quotaUsedBytes()).thenReturn(Optional.of(23l));
|
||||
|
||||
DelegatingFileSystem delegatingFs = TestDelegatingFileSystem.withRoot(mockFs);
|
||||
Assert.assertEquals(mockFs.quotaUsedBytes(), delegatingFs.quotaUsedBytes());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.filesystem.delegating;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.cryptomator.filesystem.File;
|
||||
import org.cryptomator.filesystem.Folder;
|
||||
import org.cryptomator.filesystem.ReadableFile;
|
||||
import org.cryptomator.filesystem.WritableFile;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
public class DelegatingFileTest {
|
||||
|
||||
@Test
|
||||
public void testName() {
|
||||
File mockFile = Mockito.mock(File.class);
|
||||
DelegatingFile<?> delegatingFile = new TestDelegatingFile(null, mockFile);
|
||||
|
||||
Mockito.when(mockFile.name()).thenReturn("Test");
|
||||
Assert.assertEquals(mockFile.name(), delegatingFile.name());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParent() {
|
||||
Folder mockFolder = Mockito.mock(Folder.class);
|
||||
File mockFile = Mockito.mock(File.class);
|
||||
|
||||
TestDelegatingFileSystem delegatingParent = TestDelegatingFileSystem.withRoot(mockFolder);
|
||||
DelegatingFile<?> delegatingFile = new TestDelegatingFile(delegatingParent, mockFile);
|
||||
Assert.assertEquals(delegatingParent, delegatingFile.parent().get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExists() {
|
||||
File mockFile = Mockito.mock(File.class);
|
||||
DelegatingFile<?> delegatingFile = new TestDelegatingFile(null, mockFile);
|
||||
|
||||
Mockito.when(mockFile.exists()).thenReturn(true);
|
||||
Assert.assertTrue(delegatingFile.exists());
|
||||
|
||||
Mockito.when(mockFile.exists()).thenReturn(false);
|
||||
Assert.assertFalse(delegatingFile.exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLastModified() {
|
||||
File mockFile = Mockito.mock(File.class);
|
||||
DelegatingFile<?> delegatingFile = new TestDelegatingFile(null, mockFile);
|
||||
|
||||
Instant now = Instant.now();
|
||||
Mockito.when(mockFile.lastModified()).thenReturn(now);
|
||||
Assert.assertEquals(now, delegatingFile.lastModified());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetLastModified() {
|
||||
File mockFile = Mockito.mock(File.class);
|
||||
DelegatingFile<?> delegatingFile = new TestDelegatingFile(null, mockFile);
|
||||
|
||||
Instant now = Instant.now();
|
||||
delegatingFile.setLastModified(now);
|
||||
Mockito.verify(mockFile).setLastModified(now);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreationTime() {
|
||||
File mockFile = Mockito.mock(File.class);
|
||||
DelegatingFile<?> delegatingFile = new TestDelegatingFile(null, mockFile);
|
||||
|
||||
Instant now = Instant.now();
|
||||
Mockito.when(mockFile.creationTime()).thenReturn(Optional.of(now));
|
||||
Assert.assertEquals(now, delegatingFile.creationTime().get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetCreationTime() {
|
||||
File mockFile = Mockito.mock(File.class);
|
||||
DelegatingFile<?> delegatingFile = new TestDelegatingFile(null, mockFile);
|
||||
|
||||
Instant now = Instant.now();
|
||||
delegatingFile.setCreationTime(now);
|
||||
Mockito.verify(mockFile).setCreationTime(now);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOpenReadable() {
|
||||
File mockFile = Mockito.mock(File.class);
|
||||
ReadableFile mockReadableFile = Mockito.mock(ReadableFile.class);
|
||||
|
||||
Mockito.when(mockFile.openReadable()).thenReturn(mockReadableFile);
|
||||
DelegatingFile<?> delegatingFile = new TestDelegatingFile(null, mockFile);
|
||||
Assert.assertNotNull(delegatingFile.openReadable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOpenWritable() {
|
||||
File mockFile = Mockito.mock(File.class);
|
||||
WritableFile mockWritableFile = Mockito.mock(WritableFile.class);
|
||||
|
||||
Mockito.when(mockFile.openWritable()).thenReturn(mockWritableFile);
|
||||
DelegatingFile<?> delegatingFile = new TestDelegatingFile(null, mockFile);
|
||||
Assert.assertNotNull(delegatingFile.openWritable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveTo() {
|
||||
File mockFile1 = Mockito.mock(File.class);
|
||||
File mockFile2 = Mockito.mock(File.class);
|
||||
DelegatingFile<?> delegatingFile1 = new TestDelegatingFile(null, mockFile1);
|
||||
DelegatingFile<?> delegatingFile2 = new TestDelegatingFile(null, mockFile2);
|
||||
|
||||
delegatingFile1.moveTo(delegatingFile2);
|
||||
Mockito.verify(mockFile1).moveTo(mockFile2);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testMoveToDestinationFromDifferentLayer() {
|
||||
File mockFile1 = Mockito.mock(File.class);
|
||||
File mockFile2 = Mockito.mock(File.class);
|
||||
DelegatingFile<?> delegatingFile1 = new TestDelegatingFile(null, mockFile1);
|
||||
|
||||
delegatingFile1.moveTo(mockFile2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopyTo() {
|
||||
File mockFile1 = Mockito.mock(File.class);
|
||||
File mockFile2 = Mockito.mock(File.class);
|
||||
DelegatingFile<?> delegatingFile1 = new TestDelegatingFile(null, mockFile1);
|
||||
DelegatingFile<?> delegatingFile2 = new TestDelegatingFile(null, mockFile2);
|
||||
|
||||
delegatingFile1.copyTo(delegatingFile2);
|
||||
Mockito.verify(mockFile1).copyTo(mockFile2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopyToDestinationFromDifferentLayer() {
|
||||
File mockFile1 = Mockito.mock(File.class);
|
||||
File mockFile2 = Mockito.mock(File.class);
|
||||
DelegatingFile<?> delegatingFile1 = new TestDelegatingFile(null, mockFile1);
|
||||
|
||||
delegatingFile1.copyTo(mockFile2);
|
||||
Mockito.verify(mockFile1).copyTo(mockFile2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelete() {
|
||||
File mockFile = Mockito.mock(File.class);
|
||||
DelegatingFile<?> delegatingFile = new TestDelegatingFile(null, mockFile);
|
||||
|
||||
delegatingFile.delete();
|
||||
Mockito.verify(mockFile).delete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompareTo() {
|
||||
File mockFile1 = Mockito.mock(File.class);
|
||||
File mockFile2 = Mockito.mock(File.class);
|
||||
|
||||
Mockito.when(mockFile1.compareTo(mockFile2)).thenReturn(-1);
|
||||
DelegatingFile<?> delegatingFile1 = new TestDelegatingFile(null, mockFile1);
|
||||
DelegatingFile<?> delegatingFile2 = new TestDelegatingFile(null, mockFile2);
|
||||
Assert.assertEquals(-1, delegatingFile1.compareTo(delegatingFile2));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,206 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.filesystem.delegating;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.cryptomator.filesystem.File;
|
||||
import org.cryptomator.filesystem.Folder;
|
||||
import org.cryptomator.filesystem.Node;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
public class DelegatingFolderTest {
|
||||
|
||||
@Test
|
||||
public void testName() {
|
||||
Folder mockFolder = Mockito.mock(Folder.class);
|
||||
DelegatingFolder<?, ?> delegatingFolder = new TestDelegatingFolder(null, mockFolder);
|
||||
|
||||
Mockito.when(mockFolder.name()).thenReturn("Test");
|
||||
Assert.assertEquals(mockFolder.name(), delegatingFolder.name());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParent() {
|
||||
Folder mockFolder1 = Mockito.mock(Folder.class);
|
||||
Folder mockFolder2 = Mockito.mock(Folder.class);
|
||||
|
||||
TestDelegatingFileSystem delegatingParent = TestDelegatingFileSystem.withRoot(mockFolder1);
|
||||
DelegatingFolder<?, ?> delegatingFolder = new TestDelegatingFolder(delegatingParent, mockFolder2);
|
||||
Assert.assertEquals(delegatingParent, delegatingFolder.parent().get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExists() {
|
||||
Folder mockFolder = Mockito.mock(Folder.class);
|
||||
DelegatingFolder<?, ?> delegatingFolder = new TestDelegatingFolder(null, mockFolder);
|
||||
|
||||
Mockito.when(mockFolder.exists()).thenReturn(true);
|
||||
Assert.assertTrue(delegatingFolder.exists());
|
||||
|
||||
Mockito.when(mockFolder.exists()).thenReturn(false);
|
||||
Assert.assertFalse(delegatingFolder.exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLastModified() {
|
||||
Folder mockFolder = Mockito.mock(Folder.class);
|
||||
DelegatingFolder<?, ?> delegatingFolder = new TestDelegatingFolder(null, mockFolder);
|
||||
|
||||
Instant now = Instant.now();
|
||||
Mockito.when(mockFolder.lastModified()).thenReturn(now);
|
||||
Assert.assertEquals(now, delegatingFolder.lastModified());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetLastModified() {
|
||||
Folder mockFolder = Mockito.mock(Folder.class);
|
||||
DelegatingFolder<?, ?> delegatingFolder = new TestDelegatingFolder(null, mockFolder);
|
||||
|
||||
Instant now = Instant.now();
|
||||
delegatingFolder.setLastModified(now);
|
||||
Mockito.verify(mockFolder).setLastModified(now);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreationTime() {
|
||||
Folder mockFolder = Mockito.mock(Folder.class);
|
||||
DelegatingFolder<?, ?> delegatingFolder = new TestDelegatingFolder(null, mockFolder);
|
||||
|
||||
Instant now = Instant.now();
|
||||
Mockito.when(mockFolder.creationTime()).thenReturn(Optional.of(now));
|
||||
Assert.assertEquals(now, delegatingFolder.creationTime().get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetCreationTime() {
|
||||
Folder mockFolder = Mockito.mock(Folder.class);
|
||||
DelegatingFolder<?, ?> delegatingFolder = new TestDelegatingFolder(null, mockFolder);
|
||||
|
||||
Instant now = Instant.now();
|
||||
delegatingFolder.setCreationTime(now);
|
||||
Mockito.verify(mockFolder).setCreationTime(now);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChildren() {
|
||||
Folder mockFolder = Mockito.mock(Folder.class);
|
||||
TestDelegatingFileSystem delegatingFolder = TestDelegatingFileSystem.withRoot(mockFolder);
|
||||
|
||||
Folder subFolder1 = Mockito.mock(Folder.class);
|
||||
TestDelegatingFolder delegatingSubFolder1 = new TestDelegatingFolder(delegatingFolder, subFolder1);
|
||||
File subFile1 = Mockito.mock(File.class);
|
||||
TestDelegatingFile delegatingSubFile1 = new TestDelegatingFile(delegatingFolder, subFile1);
|
||||
|
||||
/* folders */
|
||||
Mockito.when(mockFolder.folder("subFolder1")).thenReturn(subFolder1);
|
||||
Assert.assertEquals(delegatingSubFolder1, delegatingFolder.folder("subFolder1"));
|
||||
|
||||
Mockito.<Stream<? extends Folder>>when(mockFolder.folders()).thenAnswer((invocation) -> {
|
||||
return Arrays.stream(new Folder[] {subFolder1});
|
||||
});
|
||||
List<TestDelegatingFolder> subFolders = delegatingFolder.folders().collect(Collectors.toList());
|
||||
Assert.assertThat(subFolders, Matchers.containsInAnyOrder(delegatingSubFolder1));
|
||||
|
||||
/* files */
|
||||
Mockito.when(mockFolder.file("subFile1")).thenReturn(subFile1);
|
||||
Assert.assertEquals(delegatingSubFile1, delegatingFolder.file("subFile1"));
|
||||
|
||||
Mockito.<Stream<? extends File>>when(mockFolder.files()).thenAnswer((invocation) -> {
|
||||
return Arrays.stream(new File[] {subFile1});
|
||||
});
|
||||
List<TestDelegatingFile> subFiles = delegatingFolder.files().collect(Collectors.toList());
|
||||
Assert.assertThat(subFiles, Matchers.containsInAnyOrder(delegatingSubFile1));
|
||||
|
||||
/* files and folders */
|
||||
List<Node> children = delegatingFolder.children().collect(Collectors.toList());
|
||||
DelegatingNode<?>[] expectedChildren = new DelegatingNode[] {delegatingSubFolder1, delegatingSubFile1};
|
||||
Assert.assertThat(children, Matchers.containsInAnyOrder(expectedChildren));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveTo() {
|
||||
Folder mockFolder1 = Mockito.mock(Folder.class);
|
||||
Folder mockFolder2 = Mockito.mock(Folder.class);
|
||||
DelegatingFolder<?, ?> delegatingFolder1 = new TestDelegatingFolder(null, mockFolder1);
|
||||
DelegatingFolder<?, ?> delegatingFolder2 = new TestDelegatingFolder(null, mockFolder2);
|
||||
|
||||
delegatingFolder1.moveTo(delegatingFolder2);
|
||||
Mockito.verify(mockFolder1).moveTo(mockFolder2);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testMoveToDestinationFromDifferentLayer() {
|
||||
Folder mockFolder1 = Mockito.mock(Folder.class);
|
||||
Folder mockFolder2 = Mockito.mock(Folder.class);
|
||||
DelegatingFolder<?, ?> delegatingFolder1 = new TestDelegatingFolder(null, mockFolder1);
|
||||
|
||||
delegatingFolder1.moveTo(mockFolder2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopyTo() {
|
||||
Folder mockFolder1 = Mockito.mock(Folder.class);
|
||||
Folder mockFolder2 = Mockito.mock(Folder.class);
|
||||
DelegatingFolder<?, ?> delegatingFolder1 = new TestDelegatingFolder(null, mockFolder1);
|
||||
DelegatingFolder<?, ?> delegatingFolder2 = new TestDelegatingFolder(null, mockFolder2);
|
||||
|
||||
delegatingFolder1.copyTo(delegatingFolder2);
|
||||
Mockito.verify(mockFolder1).copyTo(mockFolder2);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testCopyToDestinationFromDifferentLayer() {
|
||||
Folder mockFolder1 = Mockito.mock(Folder.class);
|
||||
Folder mockFolder2 = Mockito.mock(Folder.class);
|
||||
DelegatingFolder<?, ?> delegatingFolder1 = new TestDelegatingFolder(null, mockFolder1);
|
||||
|
||||
delegatingFolder1.copyTo(mockFolder2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreate() {
|
||||
Folder mockFolder = Mockito.mock(Folder.class);
|
||||
DelegatingFolder<?, ?> delegatingFolder = new TestDelegatingFolder(null, mockFolder);
|
||||
|
||||
delegatingFolder.create();
|
||||
Mockito.verify(mockFolder).create();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelete() {
|
||||
Folder mockFolder = Mockito.mock(Folder.class);
|
||||
DelegatingFolder<?, ?> delegatingFolder = new TestDelegatingFolder(null, mockFolder);
|
||||
|
||||
delegatingFolder.delete();
|
||||
Mockito.verify(mockFolder).delete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubresourcesAreSameInstance() {
|
||||
Folder mockFolder = Mockito.mock(Folder.class);
|
||||
Folder mockSubFolder = Mockito.mock(Folder.class);
|
||||
File mockSubFile = Mockito.mock(File.class);
|
||||
Mockito.when(mockFolder.folder("mockSubFolder")).thenReturn(mockSubFolder);
|
||||
Mockito.when(mockFolder.file("mockSubFile")).thenReturn(mockSubFile);
|
||||
|
||||
DelegatingFolder<?, ?> delegatingFolder = new TestDelegatingFolder(null, mockFolder);
|
||||
Assert.assertSame(delegatingFolder.folder("mockSubFolder"), delegatingFolder.folder("mockSubFolder"));
|
||||
Assert.assertSame(delegatingFolder.file("mockSubFile"), delegatingFolder.file("mockSubFile"));
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.filesystem.delegating;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.cryptomator.filesystem.ReadableFile;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
public class DelegatingReadableFileTest {
|
||||
|
||||
@Test
|
||||
public void testIsOpen() {
|
||||
ReadableFile mockReadableFile = Mockito.mock(ReadableFile.class);
|
||||
@SuppressWarnings("resource")
|
||||
DelegatingReadableFile delegatingReadableFile = new DelegatingReadableFile(mockReadableFile);
|
||||
|
||||
Mockito.when(mockReadableFile.isOpen()).thenReturn(true);
|
||||
Assert.assertTrue(delegatingReadableFile.isOpen());
|
||||
|
||||
Mockito.when(mockReadableFile.isOpen()).thenReturn(false);
|
||||
Assert.assertFalse(delegatingReadableFile.isOpen());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRead() {
|
||||
ReadableFile mockReadableFile = Mockito.mock(ReadableFile.class);
|
||||
@SuppressWarnings("resource")
|
||||
DelegatingReadableFile delegatingReadableFile = new DelegatingReadableFile(mockReadableFile);
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocate(4);
|
||||
Mockito.when(mockReadableFile.read(buf)).thenReturn(4);
|
||||
Assert.assertEquals(4, delegatingReadableFile.read(buf));
|
||||
Mockito.verify(mockReadableFile).read(buf);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSize() {
|
||||
ReadableFile mockReadableFile = Mockito.mock(ReadableFile.class);
|
||||
@SuppressWarnings("resource")
|
||||
DelegatingReadableFile delegatingReadableFile = new DelegatingReadableFile(mockReadableFile);
|
||||
|
||||
Mockito.when(mockReadableFile.size()).thenReturn(42l);
|
||||
Assert.assertEquals(42l, delegatingReadableFile.size());
|
||||
Mockito.verify(mockReadableFile).size();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPosition() {
|
||||
ReadableFile mockReadableFile = Mockito.mock(ReadableFile.class);
|
||||
@SuppressWarnings("resource")
|
||||
DelegatingReadableFile delegatingReadableFile = new DelegatingReadableFile(mockReadableFile);
|
||||
|
||||
delegatingReadableFile.position(42);
|
||||
Mockito.verify(mockReadableFile).position(42);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClose() {
|
||||
ReadableFile mockReadableFile = Mockito.mock(ReadableFile.class);
|
||||
DelegatingReadableFile delegatingReadableFile = new DelegatingReadableFile(mockReadableFile);
|
||||
|
||||
delegatingReadableFile.close();
|
||||
Mockito.verify(mockReadableFile).close();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.filesystem.delegating;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.cryptomator.filesystem.WritableFile;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
public class DelegatingWritableFileTest {
|
||||
|
||||
@Test
|
||||
public void testIsOpen() {
|
||||
WritableFile mockWritableFile = Mockito.mock(WritableFile.class);
|
||||
@SuppressWarnings("resource")
|
||||
DelegatingWritableFile delegatingWritableFile = new DelegatingWritableFile(mockWritableFile);
|
||||
|
||||
Mockito.when(mockWritableFile.isOpen()).thenReturn(true);
|
||||
Assert.assertTrue(delegatingWritableFile.isOpen());
|
||||
|
||||
Mockito.when(mockWritableFile.isOpen()).thenReturn(false);
|
||||
Assert.assertFalse(delegatingWritableFile.isOpen());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTruncate() {
|
||||
WritableFile mockWritableFile = Mockito.mock(WritableFile.class);
|
||||
@SuppressWarnings("resource")
|
||||
DelegatingWritableFile delegatingWritableFile = new DelegatingWritableFile(mockWritableFile);
|
||||
|
||||
delegatingWritableFile.truncate();
|
||||
Mockito.verify(mockWritableFile).truncate();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWrite() {
|
||||
WritableFile mockWritableFile = Mockito.mock(WritableFile.class);
|
||||
@SuppressWarnings("resource")
|
||||
DelegatingWritableFile delegatingWritableFile = new DelegatingWritableFile(mockWritableFile);
|
||||
|
||||
ByteBuffer buf = ByteBuffer.allocate(4);
|
||||
Mockito.when(mockWritableFile.write(buf)).thenReturn(4);
|
||||
Assert.assertEquals(4, delegatingWritableFile.write(buf));
|
||||
Mockito.verify(mockWritableFile).write(buf);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPosition() {
|
||||
WritableFile mockWritableFile = Mockito.mock(WritableFile.class);
|
||||
@SuppressWarnings("resource")
|
||||
DelegatingWritableFile delegatingWritableFile = new DelegatingWritableFile(mockWritableFile);
|
||||
|
||||
delegatingWritableFile.position(42);
|
||||
Mockito.verify(mockWritableFile).position(42);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClose() {
|
||||
WritableFile mockWritableFile = Mockito.mock(WritableFile.class);
|
||||
DelegatingWritableFile delegatingWritableFile = new DelegatingWritableFile(mockWritableFile);
|
||||
|
||||
delegatingWritableFile.close();
|
||||
Mockito.verify(mockWritableFile).close();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package org.cryptomator.filesystem.delegating;
|
||||
|
||||
import org.cryptomator.filesystem.File;
|
||||
|
||||
class TestDelegatingFile extends DelegatingFile<TestDelegatingFolder> {
|
||||
|
||||
public TestDelegatingFile(TestDelegatingFolder parent, File delegate) {
|
||||
super(parent, delegate);
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user