diff --git a/.gitignore b/.gitignore index 06c8c148f1e9f45493f574a11c6789398246defd..c30895c42d4a4bae9f1bea8750f63899102b2fa9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +# -*- mode:conf; -*- + # configuration files /conf/ext/* !/conf/core/*.template @@ -11,8 +13,11 @@ *.jks # typical build dirs +build/ bin/ target/ +_apidoc/ + # But include server-side scripting !/scripting/bin @@ -29,6 +34,7 @@ log/ OUTBOX ConsistencyTest.xml testlog/ +authtoken/ # python __pycache__ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8587b4072e1d7485406cd432aff9034e6c2e6b84..0cf07b5cc6c376d27df7f1956af2e5ec8639be10 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -37,17 +37,19 @@ build-testenv: tags: [ cached-dind ] image: docker:19.03 stage: setup + timeout: 3h only: - schedules script: - cd src/test/docker + - time docker load < /image-cache/caosdb-server-testenv.tar || true - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY # use here general latest or specific branch latest... - - docker pull $CI_REGISTRY_IMAGE || true - docker build --pull - --cache-from $CI_REGISTRY_IMAGE -t $CI_REGISTRY_IMAGE . + - docker save $CI_REGISTRY_IMAGE > image.tar; + mv image.tar /image-cache/caosdb-server-testenv.tar; - docker push $CI_REGISTRY_IMAGE # Test: run unit tests of the server @@ -60,7 +62,6 @@ test: - make easy-units - mvn antlr4:antlr4 - mvn compile - - echo "defaultRealm = CaosDB" > conf/ext/usersources.ini - mvn test # Deploy: Trigger building of server image and integration tests @@ -75,3 +76,21 @@ trigger_build: -F "variables[TriggerdBy]=SERVER" -F "variables[TriggerdByHash]=$CI_COMMIT_SHORT_SHA" -F ref=$DEPLOY_REF https://gitlab.indiscale.com/api/v4/projects/14/trigger/pipeline + +# Build the sphinx documentation and make it ready for deployment by Gitlab Pages +# documentation: +# stage: deploy + +# Special job for serving a static website. See https://docs.gitlab.com/ee/ci/yaml/README.html#pages +pages: + tags: [ cached-dind ] + stage: deploy + only: + - dev + script: + - echo "Deploying" + - make doc + - cp -r build/doc/html public + artifacts: + paths: + - public diff --git a/CHANGELOG.md b/CHANGELOG.md index 27382acd3b6ac4e94224186a6e89664470c20cad..9997cd81461632727647bab467779089789dfb93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,51 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +* New version history feature. The "H" container flag retrieves the full + version history during a transaction (e.g. during Retrievals) and constructs + a tree of successors and predecessors of the requested entity version. +* New query functionality: `ANY VERSION OF` modifier. E.g. `FIND ANY VERSION OF + RECORD WITH pname=val` returns all current and old versions of records where + `pname=val`. For further information, examples and limitations see the wiki + page on [CQL](https://gitlab.com/caosdb/caosdb/-/wikis/manuals/CQL/CaosDB%20Query%20Language) +* New server property `SERVER_SIDE_SCRIPTING_BIN_DIRS` which accepts a comma or + space separated list as values. The server looks for scripts in all + directories in the order or the list and uses the first matching file. +* Automated documentation builds: `make doc` + +### Changed + +### Deprecated + +* `SERVER_SIDE_SCRIPTING_BIN_DIR` property is deprecated. + `SERVER_SIDE_SCRIPTING_BIN_DIRS` should be used instead (note the plural + form!) + +### Removed + +### Fixed + +* Bug: When the user password is updated the user is deactivated. +* Semi-fixed a bug which occurs when retrieving old versions of entities which + reference entities which have been deleted in the mean time. The current fix + adds a warning message to the reference property in question and sets the + value to NULL. This might even be desired behavior, however this would have + to finally specified during the Delete/Forget phase of the implementation of + the versioning. +- Inheritance job cannot handle inheritance from same container (!54) +* Bug in the query parser (MR!56) - The parser would throw an error when the + query contains a conjunction or disjunction filter with a first element which + is another disjunction or conjunction and being wrapped into parenthesis. + +### Security + +## [0.2] - 2020-09-02 + +### Added + +- Support for deeply nested selectors in SELECT queries. +- One-time Authentication Tokens for login without credentials and login with + particular permissions and roles for the course of the session. - `Entity/names` resource for retrieving all known entity names. - Scripting is simplified by adding a `home` directory, of which a copy is created for each called script and set as the `HOME` environment variable. @@ -21,21 +66,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [README.md](misc/move_files/README.md). - LDAP server may now be given and may be different from LDAP domain. See `misc/pam_authentication/ldap.conf` +- #47 - Sub-properties can now be queried, such as in + `SELECT window.width FROM house`. +- Added support for versioning, if it is enabled on the backend. + ### Changed -- The sever by default now only serves TLS 1.2 and 1.3, all previous versions +* All caosdb server java classes moved from `caosdb.[...]` to + `org.caosdb.[...]` because the new root package is compliant with the java + package naming conventions while the old was not. This has some implications + for configuring the server. See [README_SETUP.md](./README_SETUP.md), section + "Migration" for additional information. +- The server by default now only serves TLS 1.2 and 1.3, all previous versions have been disabled in the default settings. Make sure that your clients (especially the Python client) are up to date. ### Deprecated -- +- CaosDBTerminal ### Removed -- - ### Fixed * #51 - name queries (e.g. `FIND ENTITY WITH name = ...`) @@ -48,6 +100,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 returned without ID but with a notice now. - #11 - pam_authentication leaks the password to unprivileged processes on the same machine. +- #39 - quotes around datetimes in queries +- #99 - Checksum updating resulted in infinite loop on server. ### Security (in case of vulnerabilities) @@ -56,7 +110,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 processes on the same machine. - #68 - Shadow sensitive information when logging for debugging purposes. - ## [0.1.0] - 2018-10-09 Tag `v0.1` - Commit 3b17b49 diff --git a/makefile b/Makefile similarity index 85% rename from makefile rename to Makefile index 55631222cbb0613e6ccd634a609b594a50ff0951..d73f140f065ca0b3db62651e40162194f4ffb4eb 100644 --- a/makefile +++ b/Makefile @@ -23,39 +23,47 @@ # ** end header # +CAOSDB_SERVER_VERSION ?= $(shell mvn org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate -Dexpression=project.version -q -DforceStdout) SHELL:=/bin/bash JPDA_PORT ?= 9000 JMX_PORT ?= 9090 -compile: easy-units +compile: print-version easy-units mvn compile -runserver: +print-version: + @echo "This is CaosDB $(CAOSDB_SERVER_VERSION)" + +runserver: print-version mvn exec:java@run run: compile mvn exec:java@run run-debug: jar - java -Xrunjdwp:transport=dt_socket,address=0.0.0.0:$(JPDA_PORT),server=y,suspend=n -Dcaosdb.debug=true -jar target/caosdb-server-0.1-SNAPSHOT-jar-with-dependencies.jar + java -Xrunjdwp:transport=dt_socket,address=0.0.0.0:$(JPDA_PORT),server=y,suspend=n -Dcaosdb.debug=true -jar target/caosdb-server.jar run-debug-single: - java -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=$(JMX_PORT) -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Xrunjdwp:transport=dt_socket,address=0.0.0.0:$(JPDA_PORT),server=y,suspend=n -Dcaosdb.debug=true -jar target/caosdb-server-0.1-SNAPSHOT-jar-with-dependencies.jar + java -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=$(JMX_PORT) -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Xrunjdwp:transport=dt_socket,address=0.0.0.0:$(JPDA_PORT),server=y,suspend=n -Dcaosdb.debug=true -jar target/caosdb-server.jar run-single: - java -jar target/caosdb-server-0.1-SNAPSHOT-jar-with-dependencies.jar + java -jar target/caosdb-server.jar formatting: mvn fmt:format + autopep8 -ari scripting/ # Compile into a standalone jar file -jar: easy-units +jar: print-version easy-units mvn package -DskipTests + @pushd target ; \ + ln -s caosdb-server-$(CAOSDB_SERVER_VERSION)-jar-with-dependencies.jar caosdb-server.jar; \ + popd antlr: mvn antlr4:antlr4 -test: easy-units +test: print-version easy-units MAVEN_DEBUG_OPTS="-Xdebug -Xnoagent -Djava.compiler=NONE -Dcaosdb.debug=true -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=0.0.0.0:9000" mvn test -X @@ -120,3 +128,8 @@ stop-debug-screen: easy-units: .m2-local mvn clean mvn deploy:deploy-file -DgroupId=de.timmfitschen -DartifactId=easy-units -Dversion=0.0.1-SNAPSHOT -Durl=file:./.m2-local/ -DrepositoryId=local-maven-repo -DupdateReleaseInfo=true -Dfile=./lib/easy-units-0.0.1-SNAPSHOT-jar-with-dependencies.jar + +# Compile the standalone documentation +.PHONY: doc +doc: + $(MAKE) -C src/doc html diff --git a/README_CONFIGURATION.md b/README_CONFIGURATION.md index 55b47175762f15266e66bcca8d3b17143baaf578..27045eea4523c5009e246fe506ec6319965d8e9f 100644 --- a/README_CONFIGURATION.md +++ b/README_CONFIGURATION.md @@ -13,3 +13,9 @@ The default configuration can be overriden by in this order. +# One-time Authentication Tokens + +One-time Authentication Tokens can be configure to be issued for special purposes (e.g. a call of a server-side script) or to be written to a file on a regular basis. + +An example of a configuration is located at `./conf/core/authtoken.example.yaml`. + diff --git a/README_SETUP.md b/README_SETUP.md index 19a62bda4144550d18f2cd40ea43bbc8431ca903..5cbd85ab73bc200fe8534508be1f4538ac1dad88 100644 --- a/README_SETUP.md +++ b/README_SETUP.md @@ -1,19 +1,28 @@ -# Requirements - -## Software -* >=Java 8 -* >=Apache Maven 3.0.4 -* >=Python 3.4 -* >=pip 9.0.1 -* >=git 1.9.1 -* >=Make 3.81 -* >=Screen 4.01 -* >=MySQL 5.5 (better >=5.6) or >=MariaDB 10.1 -* libpam (if PAM authentication is required) -* unzip -* openpyxl (for XLS/ODS export) - -### Install the requirements on Debian +# Getting Started with the CaosDB Server +Here, you find information on requirements, the installation, configuration and more. + +## Requirements + +### CaosDB Packages + +* caosdb-webui=0.2.1 +* caosdb-mysqlbackend=3.0 + +### Third-party Software +* `>=Java 8` +* `>=Apache Maven 3.0.4` +* `>=Python 3.4` +* `>=pip 9.0.1` +* `>=git 1.9.1` +* `>=Make 3.81` +* `>=Screen 4.01` +* `>=MySQL 5.5` (better `>=5.6`) or `>=MariaDB 10.1` +* `libpam` (if PAM authentication is required) +* `unzip` +* `openpyxl` (for XLS/ODS export) +* `openssl` (if a custom TLS certificate is required) + +#### Install the requirements on Debian On Debian, the required packages can be installed with: apt-get install git make mariadb-server maven openjdk-11-jdk-headless \ @@ -22,21 +31,21 @@ On Debian, the required packages can be installed with: Note that installing MariaDB will uninstall existing MySQL packages and vice versa. -## System +### System -* >=Linux 4.0.0, x86\_64, e.g. Ubuntu 14.04.1 +* `>=Linux 4.0.0`, `x86_64`, e.g. Ubuntu 18.04 * Mounted filesytem(s) with enough space * Working internet connection (for up-to-date python and java libraries) -## Extensions ## +### Extensions ## -### Web UI ### +#### Web UI ### - If the WebUI shall run, check out the respective submodule: `git submodule update --init caosdb-webui` - Then configure and compile it according to its - [documentation](caosdb-webui/README_SETUP.md). + [documentation](https://http://caosdb.gitlab.io/caosdb-webui/getting_started.html). -### PAM ### +#### PAM ### Authentication via PAM is possible, for this the PAM development library must be installed and the pam user tool must be compiled: @@ -46,14 +55,14 @@ installed and the pam user tool must be compiled: should print `[FAILED]` and return with a non-zero exit code. Unless there is a user `asdf` with password `ghjk` on your system, of course. -#### Troubleshooting #### +##### Troubleshooting #### If `make` fails with `pam_authentication.c:4:31: fatal error: security/pam_appl.h: No such file or directory` the header files are probably not installed. You can do so under Debian and Ubuntu with `apt-get install libpam0g-dev`. Then try again. -# First Setup +## First Setup After a fresh clone of the repository, this is what you need to setup the server: @@ -62,37 +71,54 @@ server: needs to be an internet connection as packages are downloaded to be integrated in the java file. 1. It is recommended to run the unit tests with `make test`. It may take a - while. + while. 2. Create an SSL certificate somewhere with a `Java Key Store` file. For self-signed certificates (not recommended for production use) you can do: - `mkdir certificates; cd certificates` - - `keytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.jks -validity 375 -keysize 2048 -ext san=dns:localhost` + - `keytool -genkey -keyalg RSA -alias selfsigned -keystore caosdb.jks -validity 375 -keysize 2048 -ext san=dns:localhost` Replace `localhost` by your host name, if you want. - - `keytool -importkeystore -srckeystore keystore.jks -destkeystore keystore.p12 -deststoretype PKCS12 -srcalias selfsigned` - - `openssl pkcs12 -in keystore.p12 -nokeys -out cert.pem` + - `keytool -importkeystore -srckeystore caosdb.jks -destkeystore caosdb.p12 -deststoretype PKCS12 -srcalias selfsigned` + - Export the public part only: `openssl pkcs12 -in caosdb.p12 -nokeys -out cert.pem`. + The resulting ``cert.pem` can safely be given to users to allow ssl verification. - You can check the content of the certificate with `openssl x509 -in cert.pem -text` -3. Copy `conf/core/server.conf` to `conf/ext/server.conf` and change it + + Alternatively, you can create a keystore from certificate files that you already have: + - `openssl pkcs12 -export -inkey privkey.pem -in fullchain.pem -out all-certs.pkcs12` + - `keytool -importkeystore -srckeystore all-certs.pkcs12 -srcstoretype PKCS12 -deststoretype pkcs12 -destkeystore caosdb.jks` +3. Install/configure the MySQL back-end: see the `README_SETUP.md` of the + `caosdb-mysqlbackend` repository +4. Create an authtoken config (e.g. copy `conf/core/authtoken.example.yaml` to `conf/ext/authtoken.yml` and change it) +5. Copy `conf/core/server.conf` to `conf/ext/server.conf` and change it appropriately: - * Setup for MySQL back-end: Assuming that the mysql back-end is installed - (see the `README_SETUP.md` of the `caosdb-mysqlbackend` repository), + * Setup for MySQL back-end: specify the fields `MYSQL_USER_NAME`, `MYSQL_USER_PASSWORD`, - `MYSQL_DATABASE_NAME`, and `MYSQL_HOST`. + `MYSQL_DATABASE_NAME`, and `MYSQL_HOST`. * Choose the ports under which CaosDB will be accessible. * Setup the SSL certificate: Assuming that there is an appropriate `Java Key Store` file (see above), change the fields `CERTIFICATES_KEY_PASSWORD`, `CERTIFICATES_KEY_STORE_PATH`, and `CERTIFICATES_KEY_STORE_PASSWORD`. Make sure that the conf file is not readable by other users because the certificate passwords are stored in plaintext. + - Set the path to the authtoken config (see step 4) * Set the file system paths: - - `FILE_SYSTEM_ROOT`: The root for all the files managed by CaosDB. - - `DROP_OFF_BOX`: Files can be put here for insertion into CaosDB. - - `TMP_FILES`: Temporary files go here, for example during script execution - or when uploading or moving files. - - `SHARED_FOLDER`: Folder for sharing files via cryptographic tokens, also - those created by scripts. + - `FILE_SYSTEM_ROOT`: The root for all the files managed by CaosDB. + - `DROP_OFF_BOX`: Files can be put here for insertion into CaosDB. + - `TMP_FILES`: Temporary files go here, for example during script + execution or when uploading or moving files. + - `SHARED_FOLDER`: Folder for sharing files via cryptographic tokens, + also those created by scripts. + - `SERVER_SIDE_SCRIPTING_BIN_DIRS`: A comma or white space separated list + of directories (relative or absolute) where the server will be looking + for executables which are then callable as server-side scripts. By + default this list only contains `./scripting/bin`. If you want to + include e.g. scripts which are maintained as part of the caosdb-webui + repository (because they are intended for usage by the webui), you + should add `./caosdb-webui/sss_bin/` as well. + - `INSERT_FILES_IN_DIR_ALLOWED_DIRS`: add mounted filesystems here that + shall be accessible by CaosDB * Maybe set another `SESSION_TIMEOUT_MS`. * See also [README_CONFIGURATION.md](README_CONFIGURATION.md) -4. Copy `conf/core/usersources.ini.template` to `conf/ext/usersources.ini`. +6. Copy `conf/core/usersources.ini.template` to `conf/ext/usersources.ini`. * Define the users/groups who you want to include/exclude. * Assign at least one user the `administration` role. * For example, if the admin user is called `caosdb`, there should be the @@ -105,27 +131,28 @@ server: Especially that there are no `properties` (aka `keys`) without a `value`. An emtpy value can be represented by `""`. Comments are everything from `#` or `;` to the end of the line. -5. Install the pam caller in `misc/pam_authentication/`. See - [the pam authentication README](misc/pam_authentication/README.md) +7. Possibly install the PAM caller in `misc/pam_authentication/` if you have + not do so already. See above. + Done! -# Start Server +## Start Server `$ make run` -This can take a while. Once you see `Starting caosdb.server.CaosDBServer +This can take a while. Once you see `Starting org.caosdb.server.CaosDBServer application` the server is ready and you can try it out by connecting with a client, e.g. the web client, if you installed it. Typically, you just need to type `https://localhost:10443` in your Browser, assuming you used 10443 as port. Note, that you will get a security warning if you are using a self-signed certificate. -# Run Unit Tests +## Run Unit Tests `$ make test` -# Setup Eclipse +## Setup Eclipse 1. Open Eclipse (recommended version: Oxygen.1a Release (4.7.1a)) 2. `File > New > Java Project`: Choose a project name and specify the location @@ -143,3 +170,39 @@ certificate. Build Project`. Done! + +## Migration + +### From 0.1 to 0.2 + +A major change in the code is the renaming of the java packages (from +`caosdb.[...]` to `org.caosdb.[...]`). + +This makes its necessary to change some of your config files as well. Whenever +you configured a class (e.g. the `EMAIL_HANDLER`, or the realms in your +`usersources.ini`) you would need to reconfigure it there. + +The following `sed` command could be useful. However, use it with care and backup +before you execute it. + +```sh +sed -i.bak -e "s/\(\s*\)\([^.]\)caosdb\.server/\1\2org.caosdb.server/g" FILE_TO_BE_CHANGED +``` + +## Build the documentation # + +Stand-alone documentation is built using Sphinx: `make doc` + +### Requirements ## + +- sphinx +- javasphinx :: `pip3 install --user javasphinx` + - Alternative, if javasphinx fails because python3-sphinx is too recent: + (`l_` not found): + +```sh +git clone git@github.com:simgrid/javasphinx.git +cd javasphinx +git checkout 659209069603a +pip3 install . +``` diff --git a/caosdb-webui b/caosdb-webui index 136582641fb1b675d9630b4eacea54fbf7765eea..82315e1199bd5adcf584f61bfde167bd05624172 160000 --- a/caosdb-webui +++ b/caosdb-webui @@ -1 +1 @@ -Subproject commit 136582641fb1b675d9630b4eacea54fbf7765eea +Subproject commit 82315e1199bd5adcf584f61bfde167bd05624172 diff --git a/conf/core/authtoken.example.yaml b/conf/core/authtoken.example.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4d57c919ef122a7786850f4feddf2ac5d98e7e67 --- /dev/null +++ b/conf/core/authtoken.example.yaml @@ -0,0 +1,94 @@ +# OneTimeAuthenticationToken Config +# +# One-Time Authentication (OTA) Tokens are a means to authenticate a client +# without a password. +# +# This example config file illustrates several use cases of One-Time +# Authentication Tokens. +# +# This yaml file contains an array of configuration objects which may have the +# properties that are defined by the org.caosdb.server.accessControl.Config class. +# +# These properties are: +# +# - expiresAfter:: An integer timespan in milliseconds after the OTA Token was +# generated by the server when the token expires. So the token will not be +# valid after <creationDate> + <expiresAfter>. +# - expiresAfterSeconds:: A convenient option which has the same meaning as +# expiresAfter but measured in seconds instead of milliseconds. +# - roles:: A list of strings which are the user roles that the client has when +# it authenticates with this token. This is a way to give a client a set of +# roles which it wouldn't have otherwise. Consequently, the client also has +# all permissions of its roles. +# - permissions:: A list of string which are the permissions that the client has +# when it authenticates with this token. This is another way to give a +# client permissions which it wouldn't have otherwise. +# - maxReplays:: Normally a One-Time token can be used exactly once and +# invalidates the moment when the server recognizes that a client uses it. +# However, when a network connection is unreliable, it should be possible to +# attempt another login with the same token for a few times. And in another +# use case, it might be practical to authenticate several clients at the +# same time with the same authentication token. The maxReplays value is the +# number of times that a server accepts an OTA token as valid. The default +# is, of course, 1. +# - replayTimeout:: An integer timespan in milliseconds. Because replays are a +# possible attack vector, the time span in which the same token may be used +# is limited by this value. The default value is configured by the server +# property 'ONE_TIME_TOKEN_REPLAYS_TIMEOUT_MS' which has a default of 30000, +# which is 30 seconds. +# - replayTimeoutSeconds:: A convenient option which has the same meaning as +# replayTimeout but measured in seconds instead of milliseconds. +# - output:: Defines how the OTA token is output by the server. If this property +# is not present the OTA is not output in any way but only used internally +# (see purpose). The 'output' object has the following properties: +# - file:: An absolute or relative path in the server's file system. This +# property means that the OTA is written to that file on server start. +# - schedule:: A string formatted according to the Quartz[1] library +# indicating when the OTA is renewed and the file is being overridden +# with the new OTA. +# - purpose:: A string which is used (only internally so far) to generate an OTA +# for a special purpose, e.g. the execution of a server-side script with +# particular permissions. This way, an otherwise unprivileged client may +# execute a server-side script with all necessary permissions, if the client +# has the "SCRIPTING:EXECUTE:<script-path>" permission and this config file +# has a configuration with "purpose: SCRIPTING:EXECUTE:<script-path>" +# (case-sensitive). +# +# [1] http://www.quartz-scheduler.org/api/2.3.0/org/quartz/CronExpression.html +# +# +# Examples: +# +# 1. Every client with the SCRIPTING:EXECUTE:administration/diagnostics.py +# permission can execute the administration/diagnostics.py script with the +# administration role (and not the client's roles). +- purpose: SCRIPTING:EXECUTE:administration/diagnostics.py + roles: + - administration +# 2. The server writes an OTA token with the administration role to +# "authtoken/admin_token_crud.txt" and refreshes that token every 10 seconds. +- roles: + - administration + output: + file: "authtoken/admin_token_crud.txt" + schedule: "0/10 * * ? * * *" + +# 3. The server writes an OTA token with the administration role to +# "authtoken/admin_token_3_attempts.txt" which can be replayed 3 times in 10 +# seconds. The OTA token is refreshed every 10 seconds. +- roles: + - administration + output: + file: "authtoken/admin_token_3_attempts.txt" + schedule: "0/10 * * ? * * *" + maxReplays: 3 + replayTimeout: 10000 + +# 4. The server writes an OTA token with the administration role to +# "authtoken/admin_token_expired.txt" which expires immediately. Of course +# this is only useful for testing. +- roles: + - administration + output: + file: "authtoken/admin_token_expired.txt" + expiresAfterSeconds: 0 diff --git a/conf/core/cache.ccf b/conf/core/cache.ccf index 821e5d7862efb21e0aa13f8410886c6c14b10a7c..b6a50bee08fdd8598dac3c9f3d7aa70f43190127 100644 --- a/conf/core/cache.ccf +++ b/conf/core/cache.ccf @@ -1,3 +1,8 @@ +# -*- mode:conf-javaprop; -*- + +# Configuration for the Java Caching System (JCS) which is used by the server. Please look at +# http://commons.apache.org/proper/commons-jcs/getting_started/intro.html for further information. + # default caching options jcs.default.cacheattributes=org.apache.commons.jcs.engine.CompositeCacheAttributes jcs.default.cacheattributes.MaxObjects=1000 @@ -28,6 +33,8 @@ jcs.region.BACKEND_JobRules.cacheattributes.MaxObjects=103 jcs.region.BACKEND_SparseEntities jcs.region.BACKEND_SparseEntities.cacheattributes.MaxObjects=1002 +jcs.region.BACKEND_RetrieveVersionHistory +jcs.region.BACKEND_RetrieveVersionHistory.cacheattributes.MaxObjects=1006 # PAM UserSource Caching: Cached Items expire after 60 seconds if they are not requested (idle) and after 600 seconds max. # PAM_UnixUserGroups diff --git a/conf/core/global_entity_permissions.xml b/conf/core/global_entity_permissions.xml index 3cebb79bd1c40564c99219519aa92b59a92e9dcd..3b0cf1b5ccb3f50c73f7a0ad8f4a2651c2dad221 100644 --- a/conf/core/global_entity_permissions.xml +++ b/conf/core/global_entity_permissions.xml @@ -1,4 +1,10 @@ <globalPermissions> + <!-- + 4-store for permissions, implemented as a mapping: + {Grant/Deny, priority, role} -> List of permissions + + Please look at the permission documentation for more information. + --> <Grant priority="false" role="?OWNER?"><Permission name="*"/></Grant> <Grant priority="false" role="?OTHER?"><Permission name="RETRIEVE:*"/></Grant> <Grant priority="false" role="?OTHER?"><Permission name="USE:*"/></Grant> diff --git a/conf/core/log4j2-debug.properties b/conf/core/log4j2-debug.properties index 5d6b5fa1e7fe7770a77d0048e419c1c834fbc7c5..3ae3ed266ef865fcffde45c21458650dc5ccc0c1 100644 --- a/conf/core/log4j2-debug.properties +++ b/conf/core/log4j2-debug.properties @@ -1,8 +1,10 @@ +# This log4j2-debug.properties file is only loaded when the server runs in debug mode. + # override location of log files for debugging and testing property.LOG_DIR = testlog # for unit testing -logger.caosdb_server_logging.name = caosdb.server.logging +logger.caosdb_server_logging.name = org.caosdb.server.logging logger.caosdb_server_logging.level = TRACE # ${LOG_DIR}/debug.log diff --git a/conf/core/log4j2-default.properties b/conf/core/log4j2-default.properties index b1697a73fe6703850865406e1441947614d00f47..974ce34df0f8290d763bf6a993554dab0ec7eeb2 100644 --- a/conf/core/log4j2-default.properties +++ b/conf/core/log4j2-default.properties @@ -1,3 +1,6 @@ +# This log4j2-default.properties file describes the logging settings. See +# https://logging.apache.org/log4j/2.x/ for more information. + name = base_configuration status = TRACE verbose = true diff --git a/conf/core/server.conf b/conf/core/server.conf index 358f6b5c14106b87d7a676e2262474772ae98512..039284de44da219837e522b6f9282327562eb1f0 100644 --- a/conf/core/server.conf +++ b/conf/core/server.conf @@ -12,9 +12,10 @@ SERVER_NAME=CaosDB Server # The following paths are relative to the working directory of the server. # -------------------------------------------------- -# The location of the server side scripting binaries. +# The location(s) of the server side scripting binaries. # Put your executable python scripts here, if they need to be called from the scripting API. -SERVER_SIDE_SCRIPTING_BIN_DIR=./scripting/bin/ +# The value is a comma or space separated list or a single directory +SERVER_SIDE_SCRIPTING_BIN_DIRS=./scripting/bin/ # Working directory of the server side scripting API. # On execution of binaries and scripts the server will create a corresponding working directory in this folder. @@ -67,7 +68,7 @@ MYSQL_USER_NAME=caosdb # Password for the user MYSQL_USER_PASSWORD=caosdb # Schema of mysql procedures and tables which is required by this CaosDB instance -MYSQL_SCHEMA_VERSION=v3.0.0-rc1 +MYSQL_SCHEMA_VERSION=v4.0.0-rc2 # -------------------------------------------------- @@ -114,10 +115,21 @@ CERTIFICATES_KEY_STORE_PASSWORD= # 10 min SESSION_TIMEOUT_MS=600000 -# Time after which activation tokens for the activation of new users (internal -# user sources) expire. +# Time after which one-time tokens expire. +# This is only a default value. The actual timeout of tokens can be +# configured otherwise, for example in authtoken.yml. # 7days -ACTIVATION_TIMEOUT_MS=604800000 +ONE_TIME_TOKEN_EXPIRES_MS=604800000 + +# Path to config file for one time tokens, see authtoken.example.yml. +AUTHTOKEN_CONFIG= + +# Timeout after which a one-time token expires once it has been first consumed, +# regardless of the maximum of replays that are allowed for that token. This is +# only a default value. The actual timeout of tokens can be configured +# otherwise. +# 30 s +ONE_TIME_TOKEN_REPLAYS_TIMEOUT_MS=30000 # The value for the HTTP cache directive "max-age" WEBUI_HTTP_HEADER_CACHE_MAX_AGE=28800 @@ -127,13 +139,13 @@ WEBUI_HTTP_HEADER_CACHE_MAX_AGE=28800 # -------------------------------------------------- # The handler that treats sent mails. # The default handler pipes mails to a file. -MAIL_HANDLER_CLASS=caosdb.server.utils.mail.ToFileHandler +MAIL_HANDLER_CLASS=org.caosdb.server.utils.mail.ToFileHandler # The file were the ToFileHanlder pipes messages to. MAIL_TO_FILE_HANDLER_LOC=./ # -------------------------------------------------- # Admin settings -# # -------------------------------------------------- +# -------------------------------------------------- # Name of the administrator of this instance ADMIN_NAME=CaosDB Admin # Email of the administrator of this instance @@ -170,3 +182,9 @@ CHECK_ENTITY_ACL_ROLES_MODE=MUST # part of any Entity ACL. GLOBAL_ENTITY_PERMISSIONS_FILE=./conf/core/global_entity_permissions.xml +# -------------------------------------------------- +# Extensions +# -------------------------------------------------- + +# If set to true, versioning of entities' history is enabled. +ENTITY_VERSIONING_ENABLED=true diff --git a/conf/core/usersources.ini.template b/conf/core/usersources.ini.template index 14ad63428550e2548c688b95b66024b800a4db31..9053093eba21af0adcc5846112932a8a84b8250c 100644 --- a/conf/core/usersources.ini.template +++ b/conf/core/usersources.ini.template @@ -1,4 +1,5 @@ -# +# -*- mode:conf; -*- + # ** header v3.0 # This file is a part of the CaosDB Project. # @@ -20,17 +21,30 @@ # # ** end header # + +# `realms` is a comma and/or space separated list of realms which users can use for authentication realms = PAM + +# This is the default realm, to be used when no other realms is specified defaultRealm = PAM +# Each realm has one section with specific options. The options for a specific realm can be looked +# up in that realm's documentation. +# +# Hint: Realms are implemented by classes which are typically in the +# org.caosdb.server.accessControl.Pam package and implement the UserSource interface. + +# Options for authentication against Linux' PAM. [PAM] -class = caosdb.server.accessControl.Pam +class = org.caosdb.server.accessControl.Pam +# The script which does the actual checking. ; pam_script = ./misc/pam_authentication/pam_authentication.sh default_status = ACTIVE +# Only users which fulfill these criteria are accepted. ;include.user = [uncomment and put your users here] ;include.group = [uncomment and put your groups here] ;exclude.user = [uncomment and put excluded users here] ;exclude.group = [uncomment and put excluded groups here] -;it is necessary to add at least one admin +# It is typically necessary to add at least one admin ;user.[uncomment a set a username here].roles = administration diff --git a/doc/devel/Benchmarking.md b/doc/devel/Benchmarking.md index 7800d568b3cb80bb61281281fcb86d5d4a2d2a33..e07f6f8973784bfe3d77191f6730662d261f73fb 100644 --- a/doc/devel/Benchmarking.md +++ b/doc/devel/Benchmarking.md @@ -9,13 +9,13 @@ one can then connect to the CaosDB server and profile execution times. In the sampler settings, you may want to add these expressions to the blocked packages: `org.restlet.**, com.mysql.**`. Branches on the call tree which are entirely inside the blacklist, will become leaves. Alternatively, specify a -whitelist, for example with `caosdb.server.database.backend.implementation.**`, +whitelist, for example with `org.caosdb.server.database.backend.implementation.**`, if you only want to see the time spent for certain MySQL calls. # Manual Java-side benchmarking # Benchmarking can be done using the `TransactionBenchmark` class (in package -`caosdb.server.database.misc`). +`org.caosdb.server.database.misc`). - Single timings can be added to instances of that class via the `addBenchmark(object, time)` method. Multiple benchmarks for the same object diff --git a/pom.xml b/pom.xml index 00e5919bad540f4fa41e2526ced885263e61a419..0474d444d9a004fed909b8462a9cd91d0536a1d5 100644 --- a/pom.xml +++ b/pom.xml @@ -1,344 +1,375 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- * ** header v3.0 * This file is a part of the CaosDB Project. * * Copyright - (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics - and Self-Organization Göttingen * * 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 <https://www.gnu.org/licenses/>. * - * ** end header --> -<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> - <groupId>bmp.ds.mpg.de</groupId> - <artifactId>caosdb-server</artifactId> - <version>0.1-SNAPSHOT</version> - <packaging>jar</packaging> - <name>CaosDB Server</name> - <properties> - <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> - <project.build.testSourceDirectory>src/test/java</project.build.testSourceDirectory> - <protobuf.version>3.12.3</protobuf.version> - <grpc.version>1.30.2</grpc.version> - </properties> - <repositories> - <repository> - <id>maven-central</id> - <url>http://central.maven.org/maven2/</url> - <name>Maven Central</name> - </repository> - <repository> - <id>maven-restlet</id> - <name>Public online Restlet repository</name> - <url>http://maven.restlet.com</url> - </repository> - <repository> - <id>local-maven-repo</id> - <url>file:///${project.basedir}/.m2-local</url> - </repository> - </repositories> - <dependencies> - <dependency> - <groupId>de.timmfitschen</groupId> - <artifactId>easy-units</artifactId> - <version>0.0.1-SNAPSHOT</version> - </dependency> - <dependency> - <groupId>org.apache.shiro</groupId> - <artifactId>shiro-core</artifactId> - <version>1.4.1</version> - </dependency> - <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <version>4.12</version> - <scope>test</scope> - </dependency> - <dependency> - <!-- preventing parallel execution of some test classes --> - <groupId>com.github.stephenc.jcip</groupId> - <artifactId>jcip-annotations</artifactId> - <version>1.0-1</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.jdom</groupId> - <artifactId>jdom2</artifactId> - <version>2.0.6</version> - </dependency> - <dependency> - <groupId>org.restlet.jse</groupId> - <artifactId>org.restlet</artifactId> - <version>2.3.12</version> - </dependency> - <dependency> - <groupId>org.restlet.jse</groupId> - <artifactId>org.restlet.ext.fileupload</artifactId> - <version>2.3.12</version> - </dependency> - <dependency> - <groupId>mysql</groupId> - <artifactId>mysql-connector-java</artifactId> - <version>6.0.6</version> - </dependency> - <dependency> - <groupId>org.xerial</groupId> - <artifactId>sqlite-jdbc</artifactId> - <version>3.16.1</version> - </dependency> - <dependency> - <groupId>net.snaq</groupId> - <artifactId>dbpool</artifactId> - <version>7.0.1</version> - </dependency> - <dependency> - <groupId>org.reflections</groupId> - <artifactId>reflections</artifactId> - <version>0.9.11</version> - </dependency> - <dependency> - <groupId>com.googlecode.lanterna</groupId> - <artifactId>lanterna</artifactId> - <version>2.1.9</version> - </dependency> - <dependency> - <groupId>org.antlr</groupId> - <artifactId>antlr4</artifactId> - <version>4.8-1</version> - </dependency> - <dependency> - <groupId>org.restlet.jse</groupId> - <artifactId>org.restlet.ext.jetty</artifactId> - <version>2.3.12</version> - </dependency> - <dependency> - <groupId>org.apache.commons</groupId> - <artifactId>commons-math</artifactId> - <version>2.2</version> - </dependency> - <dependency> - <groupId>commons-codec</groupId> - <artifactId>commons-codec</artifactId> - <version>1.12</version> - </dependency> - <dependency> - <groupId>com.sun.mail</groupId> - <artifactId>javax.mail</artifactId> - <version>1.6.0-rc1</version> - </dependency> - <dependency> - <groupId>org.apache.commons</groupId> - <artifactId>commons-jcs-core</artifactId> - <version>2.1</version> - </dependency> - <dependency> - <groupId>org.kohsuke</groupId> - <artifactId>libpam4j</artifactId> - <version>1.8</version> - </dependency> - <dependency> - <groupId>org.eclipse.jetty</groupId> - <artifactId>jetty-util-ajax</artifactId> - <version>9.2.14.v20151106</version> - </dependency> - <dependency> - <groupId>org.apache.logging.log4j</groupId> - <artifactId>log4j-slf4j-impl</artifactId> - <version>2.11.1</version> - </dependency> - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-api</artifactId> - <version>1.7.21</version> - </dependency> - <dependency> - <groupId>org.apache.logging.log4j</groupId> - <artifactId>log4j-api</artifactId> - <version>2.11.1</version> - </dependency> - <dependency> - <groupId>org.apache.logging.log4j</groupId> - <artifactId>log4j-core</artifactId> - <version>2.11.1</version> - </dependency> - <dependency> - <groupId>io.grpc</groupId> - <artifactId>grpc-netty</artifactId> - <version>${grpc.version}</version> - </dependency> - <dependency> - <groupId>io.grpc</groupId> - <artifactId>grpc-protobuf</artifactId> - <version>${grpc.version}</version> - </dependency> - <dependency> - <groupId>io.grpc</groupId> - <artifactId>grpc-stub</artifactId> - <version>${grpc.version}</version> - </dependency> - <dependency> - <groupId>javax.annotation</groupId> - <artifactId>javax.annotation-api</artifactId> - <version>1.3.2</version> - </dependency> - </dependencies> - <build> - <extensions> - <extension> - <groupId>kr.motd.maven</groupId> - <artifactId>os-maven-plugin</artifactId> - <version>1.6.2</version> - </extension> - </extensions> - <sourceDirectory>${basedir}/src/main/java</sourceDirectory> - <scriptSourceDirectory>${basedir}/src/main/scripts</scriptSourceDirectory> - <testSourceDirectory>${basedir}/src/test/java</testSourceDirectory> - <outputDirectory>${basedir}/target/classes</outputDirectory> - <testOutputDirectory>${basedir}/target/test-classes</testOutputDirectory> - <plugins> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-shade-plugin</artifactId> - <version>2.4.3</version> - <executions> - <execution> - <phase>package</phase> - <goals> - <goal>shade</goal> - </goals> - <configuration> - <finalName>${project.artifactId}-${project.version}-jar-with-dependencies</finalName> - <transformers> - <transformer - implementation="com.github.edwgiz.mavenShadePlugin.log4j2CacheTransformer.PluginsCacheFileTransformer"></transformer> - <transformer - implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> - <mainClass>caosdb.server.CaosDBServer</mainClass> - </transformer> - </transformers> - </configuration> - </execution> - </executions> - <dependencies> - <dependency> - <groupId>com.github.edwgiz</groupId> - <artifactId>maven-shade-plugin.log4j2-cachefile-transformer</artifactId> - <version>2.8.1</version> - </dependency> - </dependencies> - </plugin> - <plugin> - <groupId>org.antlr</groupId> - <artifactId>antlr4-maven-plugin</artifactId> - <version>4.8-1</version> - <configuration> - <sourceDirectory>${basedir}/src/main/java</sourceDirectory> - </configuration> - <executions> - <execution> - <goals> - <goal>antlr4</goal> - </goals> - </execution> - </executions> - </plugin> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-compiler-plugin</artifactId> - <version>3.8.1</version> - <configuration> - <source>11</source> - <target>11</target> - </configuration> - </plugin> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-surefire-plugin</artifactId> - <version>3.0.0-M3</version> - <configuration> - <includes> - <include>**/*.java</include> - </includes> - <systemPropertyVariables> - <caosdb.debug>true</caosdb.debug> - <log4j2.debug>true</log4j2.debug> - </systemPropertyVariables> - <reuseForks>false</reuseForks> - <!-- Start 0.5 JVMs per CPU core Higher numbers *seem* to lead to higher - failure rates... :-/ --> - <forkCount>0.5C</forkCount> - </configuration> - </plugin> - <plugin> - <groupId>org.codehaus.mojo</groupId> - <artifactId>exec-maven-plugin</artifactId> - <version>1.6.0</version> - <executions> - <execution> - <id>run</id> - <goals> - <goal>java</goal> - </goals> - <configuration> - <mainClass>caosdb.server.CaosDBServer</mainClass> - <arguments> - <argument>silent</argument> - </arguments> - </configuration> - </execution> - <execution> - <id>run-debug</id> - <goals> - <goal>java</goal> - </goals> - <configuration> - <mainClass>caosdb.server.CaosDBServer</mainClass> - <arguments> - <argument>silent</argument> - </arguments> - <systemProperties> - <systemProperty> - <key>caosdb.debug</key> - <value>true</value> - </systemProperty> - </systemProperties> - </configuration> - </execution> - </executions> - </plugin> - <plugin> - <groupId>com.coveo</groupId> - <artifactId>fmt-maven-plugin</artifactId> - <version>2.5.1</version> - <configuration> - <skip> - <!-- Set skip to `true` to prevent auto-formatting while coding. --> - false - </skip> - </configuration> - <executions> - <execution> - <goals> - <goal>format</goal> - </goals> - </execution> - </executions> - </plugin> - <!-- Remove easy-units from classpath generation because of https://github.com/jdee-emacs/jdee/issues/125 - (no sources inside easy-units) --> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-dependency-plugin</artifactId> - <configuration> - <excludeArtifactIds>easy-units</excludeArtifactIds> - </configuration> - </plugin> - <plugin> +<!-- + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2018 Research Group Biomedical Physics, + * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * + * 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 <https://www.gnu.org/licenses/>. + * + * ** end header +--> +<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> + <groupId>org.caosdb</groupId> + <artifactId>caosdb-server</artifactId> + <version>0.3-SNAPSHOT</version> + <packaging>jar</packaging> + <name>CaosDB Server</name> + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <project.build.testSourceDirectory>src/test/java</project.build.testSourceDirectory> + <protobuf.version>3.14.0</protobuf.version> + <grpc.version>1.35.0</grpc.version> + </properties> + <repositories> + <repository> + <id>maven-central</id> + <url>https://repo1.maven.org/maven2/</url> + <name>Maven Central</name> + </repository> + <repository> + <id>maven-restlet</id> + <name>Public online Restlet repository</name> + <url>https://maven.restlet.com</url> + </repository> + <repository> + <id>local-maven-repo</id> + <url>file:///${project.basedir}/.m2-local</url> + </repository> + </repositories> + <dependencies> + <dependency> + <groupId>de.timmfitschen</groupId> + <artifactId>easy-units</artifactId> + <version>0.0.1-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>org.quartz-scheduler</groupId> + <artifactId>quartz</artifactId> + <version>2.3.2</version> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.dataformat</groupId> + <artifactId>jackson-dataformat-yaml</artifactId> + <version>2.11.0</version> + </dependency> + <dependency> + <groupId>org.apache.shiro</groupId> + <artifactId>shiro-core</artifactId> + <version>1.5.3</version> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.12</version> + <scope>test</scope> + </dependency> + <dependency> + <!-- preventing parallel execution of some test classes --> + <groupId>com.github.stephenc.jcip</groupId> + <artifactId>jcip-annotations</artifactId> + <version>1.0-1</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.jdom</groupId> + <artifactId>jdom2</artifactId> + <version>2.0.6</version> + </dependency> + <dependency> + <groupId>org.restlet.jse</groupId> + <artifactId>org.restlet</artifactId> + <version>2.3.12</version> + </dependency> + <dependency> + <groupId>org.restlet.jse</groupId> + <artifactId>org.restlet.ext.fileupload</artifactId> + <version>2.3.12</version> + </dependency> + <dependency> + <groupId>mysql</groupId> + <artifactId>mysql-connector-java</artifactId> + <version>8.0.19</version> + </dependency> + <dependency> + <groupId>org.xerial</groupId> + <artifactId>sqlite-jdbc</artifactId> + <version>3.16.1</version> + </dependency> + <dependency> + <groupId>net.snaq</groupId> + <artifactId>dbpool</artifactId> + <version>7.0.1</version> + </dependency> + <dependency> + <groupId>org.reflections</groupId> + <artifactId>reflections</artifactId> + <version>0.9.11</version> + </dependency> + <dependency> + <groupId>com.googlecode.lanterna</groupId> + <artifactId>lanterna</artifactId> + <version>2.1.9</version> + </dependency> + <dependency> + <groupId>org.antlr</groupId> + <artifactId>antlr4</artifactId> + <version>4.8-1</version> + </dependency> + <dependency> + <groupId>org.restlet.jse</groupId> + <artifactId>org.restlet.ext.jetty</artifactId> + <version>2.3.12</version> + </dependency> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-math</artifactId> + <version>2.2</version> + </dependency> + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + <version>1.12</version> + </dependency> + <dependency> + <groupId>com.sun.mail</groupId> + <artifactId>javax.mail</artifactId> + <version>1.6.0-rc1</version> + </dependency> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-jcs-core</artifactId> + <version>2.2.1</version> + </dependency> + <dependency> + <groupId>org.kohsuke</groupId> + <artifactId>libpam4j</artifactId> + <version>1.8</version> + </dependency> + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-util-ajax</artifactId> + <version>9.2.14.v20151106</version> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-slf4j-impl</artifactId> + <version>2.11.1</version> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>1.7.21</version> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-api</artifactId> + <version>2.11.1</version> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-core</artifactId> + <version>2.11.1</version> + </dependency> + <dependency> + <groupId>io.grpc</groupId> + <artifactId>grpc-netty</artifactId> + <version>${grpc.version}</version> + </dependency> + <dependency> + <groupId>io.grpc</groupId> + <artifactId>grpc-protobuf</artifactId> + <version>${grpc.version}</version> + </dependency> + <dependency> + <groupId>io.grpc</groupId> + <artifactId>grpc-stub</artifactId> + <version>${grpc.version}</version> + </dependency> + <dependency> + <groupId>javax.annotation</groupId> + <artifactId>javax.annotation-api</artifactId> + <version>1.3.2</version> + </dependency> + <dependency> + <groupId>com.google.protobuf</groupId> + <artifactId>protobuf-java</artifactId> + <version>${protobuf.version}</version> +</dependency> + + </dependencies> + <build> + <sourceDirectory>${basedir}/src/main/java</sourceDirectory> + <scriptSourceDirectory>${basedir}/src/main/scripts</scriptSourceDirectory> + <testSourceDirectory>${basedir}/src/test/java</testSourceDirectory> + <outputDirectory>${basedir}/target/classes</outputDirectory> + <testOutputDirectory>${basedir}/target/test-classes</testOutputDirectory> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <version>2.4.3</version> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + <configuration> + <finalName>${project.artifactId}-${project.version}-jar-with-dependencies</finalName> + <transformers> + <transformer implementation="com.github.edwgiz.mavenShadePlugin.log4j2CacheTransformer.PluginsCacheFileTransformer"></transformer> + <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> + <mainClass>org.caosdb.server.CaosDBServer</mainClass> + </transformer> + </transformers> + </configuration> + </execution> + </executions> + <dependencies> + <dependency> + <groupId>com.github.edwgiz</groupId> + <artifactId>maven-shade-plugin.log4j2-cachefile-transformer</artifactId> + <version>2.8.1</version> + </dependency> + </dependencies> + </plugin> + <plugin> + <groupId>org.antlr</groupId> + <artifactId>antlr4-maven-plugin</artifactId> + <version>4.8-1</version> + <configuration> + <sourceDirectory>${basedir}/src/main/java</sourceDirectory> + </configuration> + <executions> + <execution> + <goals> + <goal>antlr4</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.8.1</version> + <configuration> + <source>11</source> + <target>11</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>3.0.0-M3</version> + <configuration> + <includes> + <include>**/*.java</include> + </includes> + <systemPropertyVariables> + <caosdb.debug>true</caosdb.debug> + <log4j2.debug>true</log4j2.debug> + </systemPropertyVariables> + <reuseForks>false</reuseForks> + <!-- Start 0.5 JVMs per CPU core + Higher numbers *seem* to lead to higher failure rates... :-/ --> + <forkCount>0.5C</forkCount> + </configuration> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>exec-maven-plugin</artifactId> + <version>1.6.0</version> + <executions> + <execution> + <id>run</id> + <goals> + <goal>java</goal> + </goals> + <configuration> + <mainClass>org.caosdb.server.CaosDBServer</mainClass> + <arguments> + <argument>silent</argument> + </arguments> + </configuration> + </execution> + <execution> + <id>run-debug</id> + <goals> + <goal>java</goal> + </goals> + <configuration> + <mainClass>org.caosdb.server.CaosDBServer</mainClass> + <arguments> + <argument>silent</argument> + </arguments> + <systemProperties> + <systemProperty> + <key>caosdb.debug</key> + <value>true</value> + </systemProperty> + </systemProperties> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>com.coveo</groupId> + <artifactId>fmt-maven-plugin</artifactId> + <version>2.5.1</version> + <configuration> + <skip> + <!-- Set skip to `true` to prevent auto-formatting while coding. --> + false + </skip> + </configuration> + <executions> + <execution> + <goals> + <goal>format</goal> + </goals> + </execution> + </executions> + </plugin> + <!-- Remove easy-units from classpath generation because of https://github.com/jdee-emacs/jdee/issues/125 + (no sources inside easy-units) --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <configuration> + <excludeArtifactIds>easy-units</excludeArtifactIds> + </configuration> + </plugin> + + <plugin> + <groupId>kr.motd.maven</groupId> + <artifactId>os-maven-plugin</artifactId> + <version>1.6.2</version> + <executions> + <execution> + <phase>initialize</phase> + <goals> + <goal>detect</goal> + </goals> + </execution> + </executions> + </plugin> + + <!-- code generation protobuf/grpc --> + <plugin> <groupId>org.xolstice.maven.plugins</groupId> <artifactId>protobuf-maven-plugin</artifactId> <version>0.6.1</version> @@ -356,9 +387,8 @@ </execution> </executions> </plugin> - - </plugins> - - </build> - <url>bmp.ds.mpg.de</url> + + </plugins> + </build> + <url>caosdb.org</url> </project> diff --git a/scripting/bin/administration/diagnostics.py b/scripting/bin/administration/diagnostics.py new file mode 100755 index 0000000000000000000000000000000000000000..ccecbd583ffdaf5f941a2df873ac10982560af31 --- /dev/null +++ b/scripting/bin/administration/diagnostics.py @@ -0,0 +1,149 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# ** header v3.0 +# This file is a part of the CaosDB Project. +# +# Copyright (C) 2018 Research Group Biomedical Physics, +# Max-Planck-Institute for Dynamics and Self-Organization Göttingen +# Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> +# Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> +# +# 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 <https://www.gnu.org/licenses/>. +# +# ** end header +# +"""diagnostics.py + +A script which returns a json representation of various parameters which might +be interesting for debugging the server-side scripting functionality and which +should not be executable for non-admin users. +""" + +import sys + +TEST_MODULES = [ + "caosdb", + "numpy", + "pandas", + "validate_email" +] + + +def get_files(): + from os import walk + from os.path import join + result = [] + for p, dirs, files in walk("."): + for f in files: + result.append(join(p, f)) + for d in dirs: + result.append(join(p, d)) + return result + + +def get_option(name, default=None): + for arg in sys.argv: + if arg.startswith("--{}=".format(name)): + index = len(name) + 3 + return arg[index:] + return default + + +def get_exit_code(): + return int(get_option("exit", 0)) + + +def get_auth_token(): + return get_option("auth-token") + + +def get_query(): + return get_option("query") + + +def get_caosdb_info(auth_token): + import caosdb as db + result = dict() + result["version"] = db.version.version + + try: + db.configure_connection( + auth_token=auth_token, + password_method="auth_token") + + info = db.Info() + + result["info"] = str(info) + result["username"] = info.user_info.name + result["realm"] = info.user_info.realm + result["roles"] = info.user_info.roles + + # execute a query and return the results + query = get_query() + if query is not None: + query_result = db.execute_query(query) + result["query"] = (query, str(query_result)) + + except Exception as e: + result["exception"] = str(e) + return result + + +def test_imports(modules): + result = dict() + for m in modules: + try: + i = __import__(m) + if hasattr(i, "__version__") and i.__version__ is not None: + v = i.__version__ + else: + v = "unknown version" + result[m] = (True, v) + except ImportError as e: + result[m] = (False, str(e)) + return result + + +def main(): + try: + import json + except ImportError: + print('{{"python_version":"{v}",' + '"python_path":["{p}"]}}'.format(v=sys.version, + p='","'.join(sys.path))) + raise + + try: + diagnostics = dict() + diagnostics["python_version"] = sys.version + diagnostics["python_path"] = sys.path + diagnostics["call"] = sys.argv + diagnostics["import"] = test_imports(TEST_MODULES) + diagnostics["files"] = get_files() + + auth_token = get_auth_token() + diagnostics["auth_token"] = auth_token + + if diagnostics["import"]["caosdb"][0] is True: + diagnostics["caosdb"] = get_caosdb_info(auth_token) + + finally: + json.dump(diagnostics, sys.stdout) + + sys.exit(get_exit_code()) + + +if __name__ == "__main__": + main() diff --git a/scripting/bin/xls_from_csv.py b/scripting/bin/xls_from_csv.py index 38dfbc1c9392ce60d338b102f9b9fd05309919d3..73bb6b0ac23fc2df093bd6797e864aad1f2d5592 100755 --- a/scripting/bin/xls_from_csv.py +++ b/scripting/bin/xls_from_csv.py @@ -93,7 +93,8 @@ def _parse_arguments(): parser.add_argument('-t', '--tempdir', required=False, default=tempdir, help="Temporary dir for saving the result.") parser.add_argument('-a', '--auth-token', required=False, - help="An authentication token (not needed, only for compatibility).") + help=("An authentication token (not needed, only for " + "compatibility).")) parser.add_argument('tsv', help="The tsv file.") return parser.parse_args() @@ -104,5 +105,6 @@ def main(): filename = _write_xls(dataframe, directory=args.tempdir) print(filename) + if __name__ == "__main__": main() diff --git a/scripting/home/readme.md b/scripting/home/readme.md index 9c9744a55cec41f33929a3953d9c582fa97f46e0..c79afce2a399089c797e0157d30d9908b33dd23e 100644 --- a/scripting/home/readme.md +++ b/scripting/home/readme.md @@ -1,3 +1,3 @@ # The `home` directory # -This directory will be copied to a temporary directy for each server-side +This directory will be copied to a temporary directly for each server-side scripting invocation and set as the `HOME` environment variable. diff --git a/src/doc/CaosDB-Query-Language.md b/src/doc/CaosDB-Query-Language.md new file mode 100644 index 0000000000000000000000000000000000000000..47a890d716564eb72c70de4f9d39d1cd00d92157 --- /dev/null +++ b/src/doc/CaosDB-Query-Language.md @@ -0,0 +1,377 @@ +# CaosDB Query Language +**WIP This is going to be the specification. CQL tutorials are in the webui** + +## Example queries + +### Simple FIND Query +The following query will return any entity which has the name _ename_ and all its children. +`FIND ename` + +The following queries are equivalent and will return any entity which has the name _ename_ and all its children, but only if they are genuin records. Of course, the returned set of entities (henceforth referred to as _resultset_) can also be restricted to recordtypes, properties and files. + +`FIND RECORD ename` + +`FIND RECORDS ename` + +Wildcards use `*` for any characters or none at all. Wildcards for single characters (like the '_' wildcard from mysql) are not implemented yet. + +`FIND RECORD en*` returns any entity which has a name beginning with _en_. + +Regular expressions must be surrounded by _<<_ and '>>': + +`FIND RECORD <<e[aemn]{2,5}>>` + +`FIND RECORD <<[cC]am_[0-9]*>>` + +*TODO* (Timm): +Describe escape sequences like `\\ `, `\*`, `\<<` and `\>>`. + +Currently, wildcards and regular expressions are only available for the _simple-find-part_ of the query, i. e. no wildcards/regexps for filters. + +### Simple COUNT Query + +This query counts entities which have certain properties. + +`COUNT ename` +will return the number of entities which have the name _ename_ and all their children. + +The syntax of the COUNT queries is equivalent to the FIND queries in any respect (this also applies to wildcards and regular expressions) but one: The prefix is to be `COUNT` instead of `FIND`. + +Unlike the FIND queries, the COUNT queries do not return any entities. The result of the query is the number of entities which _would be_ returned if the query was a FIND query. + +## Filters + +### POV - Property-Operator-Value + +The following queries are equivalent and will restrict the result set to entities which have a property named _pname1_ that has a value _val1_. + +`FIND ename.pname1=val1` + +`FIND ename WITH pname1=val1` + +`FIND ename WHICH HAS A PROPERTY pname1=val1` + +`FIND ename WHICH HAS A pname1=val1` + +Again, the resultset can be restricted to records: + +`FIND RECORD ename WHICH HAS A pname1=val1` + +_currently known operators:_ `=, !=, <=, <, >=, >` (and cf. next paragraphes!) + +#### Special Operator: LIKE + +The _LIKE_ can be used with wildcards. The `*` is a wildcard for any (possibly empty) sequence of characters. Examples: + +`FIND RECORD ename WHICH HAS A pname1 LIKE va*` + +`FIND RECORD ename WHICH HAS A pname1 LIKE va*1` + +`FIND RECORD ename WHICH HAS A pname1 LIKE *al1` + +_Note:_ The _LIKE_ operator is will only produce expectable results with text properties. + +#### Special Case: References + +In general a reference can be addressed just like a POV filter. So + +`FIND ename1.pname1=ename2` + +will also return any entity named _ename1_ which references the entity with name or id _ename2_ via a reference property named _pname1_. However, it will also return any entity with a text property of that name with the string value _ename2_. In order to restrict the result set to reference properties one may make use of special reference operators: + +_reference operators:_ `->, REFERENCES, REFERENCE TO` + + +The query looks like this: + +`FIND ename1 WHICH HAS A pname1 REFERENCE TO ename2` + +`FIND ename1 WHICH HAS A pname1->ename2` + +#### Time Special Case: DateTime + +_DateTime operators:_ `=, !=, <, >, IN, NOT IN` + +##### `d1=d2`: Equivalence relation. +* ''True'' iff d1 and d2 are equal in every respect (same DateTime flavor, same fields are defined/undefined and all defined fields are equal respectively). +* ''False'' iff they have the same DateTime flavor but have different fields defined or fields with differing values. +* ''Undefined'' otherwise. + +Examples: +* `2015-04-03=2015-04-03T00:00:00` is undefined. +* `2015-04-03T00:00:00=2015-04-03T00:00:00.0` is undefined (second precision vs. nanosecond precision). +* `2015-04-03T00:00:00.0=2015-04-03T00:00:00.0` is true. +* `2015-04-03T00:00:00=2015-04-03T00:00:00` is true. +* `2015-04=2015-05` is false. +* `2015-04=2015-04` is true. + +##### `d1!=d2`: Intransitive, symmetric relation. +* ''True'' iff `d1=d2` is false. +* ''False'' iff `d1=d2` is true. +* ''Undefined'' otherwise. + +Examples: +* `2015-04-03!=2015-04-03T00:00:00` is undefined. +* `2015-04-03T00:00:00!=2015-04-03T00:00:00.0` is undefined. +* `2015-04-03T00:00:00.0!=2015-04-03T00:00:00.0` is false. +* `2015-04-03T00:00:00!=2015-04-03T00:00:00` is false. +* `2015-04!=2015-05` is true. +* `2015-04!=2015-04` is false. + +##### `d1>d2`: Transitive, non-symmetric relation. +Semantics depend on the flavors of d1 and d2. If both are... +###### [UTCDateTime](Datatype#datetime) +* ''True'' iff the time of d1 is after the the time of d2 according to [https://en.wikipedia.org/wiki/Coordinated_Universal_Time](UTC) +* ''False'' otherwise. + +###### [SemiCompleteDateTime](Datatype#datetime) +* ''True'' iff `d1.ILB>d2.EUB` is true or `d1.ILB=d2.EUB` is true. +* ''False'' iff `d1.EUB<d2.ILB}} is true or {{{d1.EUB=d2.ILB` is true. +* ''Undefined'' otherwise. + +Examples: +* `2015>2014` is true. +* `2015-04>2014` is true. +* `2015-01-01T20:15.00>2015-01-01T20:14` is true. +* `2015-04>2015` is undefined. +* `2015>2015-04` is undefined. +* `2015-01-01T20:15>2015-01-01T20:15:15` is undefined. +* `2014>2015` is false. +* `2014-04>2015` is false. +* `2014-01-01>2015-01-01T20:15:30` is false. + +##### `d1<d2`: Transitive, non-symmetric relation. +Semantics depend on the flavors of d1 and d2. If both are... +###### [UTCDateTime](Datatype#datetime) +* ''True'' iff the time of d1 is before the the time of d2 according to [UTC](https://en.wikipedia.org/wiki/Coordinated_Universal_Time) +* ''False'' otherwise. + +###### [SemiCompleteDateTime](Datatype#datetime) +* ''True'' iff `d1.EUB<d2.ILB` is true or `d1.EUB=d2.ILB` is true. +* ''False'' iff `d1.ILB>d2.EUB}} is true or {{{d1.ILB=d2.EUB` is true. +* ''Undefined'' otherwise. + +Examples: +* `2014<2015` is true. +* `2014-04<2015` is true. +* `2014-01-01<2015-01-01T20:15:30` is true. +* `2015-04<2015` is undefined. +* `2015<2015-04` is undefined. +* `2015-01-01T20:15<2015-01-01T20:15:15` is undefined. +* `2015<2014` is false. +* `2015-04<2014` is false. +* `2015-01-01T20:15.00<2015-01-01T20:14` is false. + +##### `d1 IN d2`: Transitive, non-symmetric relation. +Semantics depend on the flavors of d1 and d2. If both are... +###### [SemiCompleteDateTime](Datatype#datetime) +* ''True'' iff (`d1.ILB>d2.ILB` is true or `d1.ILB=d2.ILB` is true) and (`d1.EUB<d2.EUB` is true or `d1.EUB=d2.EUB` is true). +* ''False'' otherwise. + +Examples: +* `2015-01-01 IN 2015` is true. +* `2015-01-01T20:15:30 IN 2015-01-01` is true. +* `2015-01-01T20:15:30 IN 2015-01-01T20:15:30` is true. +* `2015 IN 2015-01-01` is false. +* `2015-01-01 IN 2015-01-01T20:15:30` is false. + +##### `d1 NOT IN d2`: Non-symmetric relation. +Semantics depend on the flavors of d1 and d2. If both are... +###### [SemiCompleteDateTime](Datatype#datetime) +* ''True'' iff `d1.ILB IN d2.ILB` is false. +* ''False'' otherwise. + +Examples: +* `2015 NOT IN 2015-01-01` is true. +* `2015-01-01 NOT IN 2015-01-01T20:15:30` is true. +* `2015-01-01 NOT IN 2015` is false. +* `2015-01-01T20:15:30 NOT IN 2015-01-01` is false. +* `2015-01-01T20:15:30 NOT IN 2015-01-01T20:15:30` is false. + +##### Note +These semantics follow a three-valued logic with ''true'', ''false'' and ''undefined'' as truth values. Only ''true'' is truth preserving. I.e. only those expressions which evaluate to ''true'' pass the POV filter. `FIND ... WHICH HAS A somedate=2015-01` only returns entities for which `somedate=2015-01` is true. On the other hand, `FIND ... WHICH DOESN'T HAVE A somedate=2015-01` returns entities for which `somedate=2015-01` is false or undefined. Shortly put, `NOT d1=d2` is not equivalent to `d1!=d2`. The latter assertion is stronger. + +#### Omitting the Property or the Value + +One doesn't have to specify the property or the value at all. The following query filters the result set for entities which have any property with a value greater than _val1_. + +`FIND ename WHICH HAS A PROPERTY > val1` + +`FIND ename . > val1` + +`FIND ename.>val1` + + +And for references... + +`FIND ename1 WHICH HAS A REFERENCE TO ename2` + +`FIND ename1 WHICH REFERENCES ename2` + +`FIND ename1 . -> ename2` + +`FIND ename1.->ename2` + + +The following query returns entities which have a _pname1_ property with any value. + +`FIND ename WHICH HAS A PROPERTY pname1` + +`FIND ename WHICH HAS A pname1` + +`FIND ename WITH pname1` + +`FIND ename . pname1` + +`FIND ename.pname1` + +### TransactionFilter + +*Definition* + + sugar:: `HAS BEEN` | `HAVE BEEN` | `HAD BEEN` | `WAS` | `IS` | + + negated_sugar:: `HAS NOT BEEN` | `HASN'T BEEN` | `WAS NOT` | `WASN'T` | `IS NOT` | `ISN'T` | `HAVN'T BEEN` | +`HAVE NOT BEEN` | `HADN'T BEEN` | `HAD NOT BEEN` + + by_clause:: `BY (ME | username | SOMEONE ELSE (BUT ME)? | SOMEONE ELSE BUT username)` + + date:: A date string of the form `YYYY-MM-DD` + + datetime:: A datetime string of the form `YYYY-MM-DD hh:mm:ss` + + time_clause:: `ON ($date|$datetime) ` Here is plenty of room for more syntactic sugar, e.g. a `TODAY` keyword, and more funcionality, e.g. ranges. + +`FIND ename WHICH ($sugar|$negated_sugar)? (NOT)? (CREATED|INSERTED|UPDATED|DELETED) (by_clause time_clause?| time_clause by_clause?)` + +*Examples* + +`FIND ename WHICH HAS BEEN CREATED BY ME ON 2014-12-24` + +`FIND ename WHICH HAS BEEN CREATED BY SOMEONE ELSE ON 2014-12-24` + +`FIND ename WHICH HAS BEEN CREATED BY erwin ON 2014-12-24` + +`FIND ename WHICH HAS BEEN CREATED BY SOMEONE ELSE BUT erwin ON 2014-12-24` + +`FIND ename WHICH HAS BEEN CREATED BY erwin` + +`FIND ename . CREATED BY erwin ON ` + + + +### File Location + +Search for file objects by their location: + +`FIND FILE WHICH IS STORED AT a/certain/path/` + +#### Wildcards + +_STORED AT_ can be used with wildcards similar to unix wildcards. + * `*` matches any characters or none at all, but not the directory separator `/` + * `**` matches any character or none at all. + * A leading `*` is a shortcut for `/**` + * Asterisks directly between two other asterisks are ignored: `***` is the same as `**`. + * Escape character: `\` (E.g. `\\` is a literal backslash. `\*` is a literal star. But `\\*` is a literal backslash followed by a wildcard.) + +Examples: + +Find any files ending with `.acq`: +`FIND FILE WHICH IS STORED AT *.acq` or +`FIND FILE WHICH IS STORED AT **.acq` or +`FIND FILE WHICH IS STORED AT /**.acq` + +Find files stored one directory below `/data/`, ending with `.acq`: +`FIND FILE WHICH IS STORED AT /data/*/*.acq` + +Find files stored in `/data/`, ending with `.acq`: +`FIND FILE WHICH IS STORED AT /data/*.acq` + +Find files stored in a directory at any depth in the tree below `/data/`, ending with `.acq`: +`FIND FILE WHICH IS STORED AT /data/**.acq` + +Find any file in a directory which begins with `2016-02`: +`FIND FILE WHICH IS STORED AT */2016-02*/*` + + +### Back References + +The back reference filters for entities that are referenced by another entity. The following query returns entities of the type _ename1_ which are referenced by _ename2_ entities via the reference property _pname1_. + +* `FIND ename1 WHICH IS REFERENCED BY ename2 AS A pname1` +* `FIND ename1 WITH @ ename2 / pname1` +* `FIND ename1 . @ ename2 / pname1` + +One may omit the property specification: + +* `FIND ename1 WHICH IS REFERENCED BY ename2` +* `FIND ename1 WHICH HAS A PROPERTY @ ename2` +* `FIND ename1 WITH @ ename2` +* `FIND ename1 . @ ename2` + +### Combining Filters with Propositional Logic + +Any result set can be filtered by logically combining POV filters or back reference filters: + +#### Conjunction (AND) + +* `FIND ename1 WHICH HAS A PROPERTY pname1=val1 AND A PROPERTY pname2=val2 AND A PROPERTY...` +* `FIND ename1 WHICH HAS A PROPERTY pname1=val1 AND A pname2=val2 AND ...` +* `FIND ename1 . pname1=val1 & pname2=val2 & ...` + +#### Disjunction (OR) + +* `FIND ename1 WHICH HAS A PROPERTY pname1=val1 OR A PROPERTY pname2=val2 Or A PROPERTY...` +* `FIND ename1 WHICH HAS A PROPERTY pname1=val1 OR A pname2=val2 OR ...` +* `FIND ename1 . pname1=val1 | pname2=val2 | ...` + +#### Negation (NOT) + +* `FIND ename1 WHICH DOES NOT HAVE A PROPERTY pname1=val1` +* `FIND ename1 WHICH DOESN'T HAVE A pname1=val1` +* `FIND ename1 . NOT pname2=val2` +* `FIND ename1 . !pname2=val2` + +#### ... and combinations with parentheses + +* `FIND ename1 WHICH HAS A pname1=val1 AND DOESN'T HAVE A pname2<val2 AND ((WHICH HAS A pname3=val3 AND A pname4=val4) OR DOES NOT HAVE A (pname5=val5 AND pname6=val6))` +* `FIND ename1 . pname1=val1 & !pname2<val2 & ((pname3=val3 & pname4=val4) | !(pname5=val5 & pname6=val6))` +* `FIND ename1.pname1=val1&!pname2<val2&((pname3=val3&pname4=val4)|!(pname5=val5&pname6=val6))` + +### A Few Important Expressions + +* A:: The indistinct article. This is only syntactic suger. Equivalent expressions: `A, AN` +* AND:: The logical _and_. Equivalent expressions: `AND, &` +* FIND:: The beginning of the query. +* NOT:: The logical negation. Equivalent expressions: `NOT, DOESN'T HAVE A PROPERTY, DOES NOT HAVE A PROPERTY, DOESN'T HAVE A, DOES NOT HAVE A, DOES NOT, DOESN'T, IS NOT, ISN'T, !` +* OR:: The logical _or_. Equivalent expressions: `OR, |` +* RECORD,RECORDTYPE,FILE,PROPERTY:: Role expression for restricting the result set to a specific role. +* WHICH:: The marker for the beginning of the filters. Equivalent expressions: `WHICH, WHICH HAS A, WHICH HAS A PROPERTY, WHERE, WITH, .` +* REFERENCE:: This one is tricky: `REFERENCE TO` expresses a the state of _having_ a reference property. `REFERENCED BY` expresses the state of _being_ referenced by another entity. +* COUNT:: `COUNT` works like `FIND` but doesn't return the entities. + +## Versioning + +Since Caosdb 0.2 entities are optionally version controlled. The query language will be extended to include versioning in the future. A current minimal implementation introduces the `ANY VERSION OF` modifier which can be used to return all matching versions in the results of `COUNT`, `FIND`, and `SELECT` queries. + +### Example + +* `FIND ANY VERSION OF RECORD WITH pname=value` returns the all past and present versions of records with `pname = value`. + +### Scope and current limitations + +* The `ANY VERSION OF` modifier currently the only expression for taking the versioning into account when using the query language. +* Subproperties are not supported yet, e.g. `FIND ANY VERSION OF ENTITY WHICH IS REFERENCED BY ename WITH ...`. This applies to all cases where you specify properties of *referenced* entities or *referencing* entities. + +### Future + +* Add `(LATEST|LAST|OLDEST|NEWEST|FIRST) VERSION OF` modifiers. +* Add `(ANY|LATEST|LAST|OLDEST|NEWEST|FIRST) VERSION (BEFORE|AFTER) (<timestamp>|<transaction id>|<entity@version>) OF` modifier. +* Add support for subproperties, e.g. `FIND ANY VERSION OF ENTITY WHICH IS REFERENCED BY ename WITH ...`. + +## Future + + * *Sub Queries* (or *Sub Properties*): `FIND ename WHICH HAS A pname WHICH HAS A subpname=val`. This is like: `FIND AN experiment WHICH HAS A camera WHICH HAS A 'serial number'= 1234567890` + * *More Logic*, especially `ANY`, `ALL`, `NONE`, and `SUCH THAT` key words (and equivalents) for logical quantisation: `FIND ename1 SUCH THAT ALL ename2 WHICH HAVE A REFERENCE TO ename1 HAVE A pname=val`. This is like `FIND experiment SUCH THAT ALL person WHICH ARE REFERENCED BY THIS experiment AS conductor HAVE AN 'academic title'=professor.` + diff --git a/src/doc/Makefile b/src/doc/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..4f177fd3850423c3005829a75a2b37625dc68a87 --- /dev/null +++ b/src/doc/Makefile @@ -0,0 +1,47 @@ +# ** header v3.0 +# This file is a part of the CaosDB Project. +# +# Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> +# Copyright (C) 2020 Daniel Hornung <d.hornung@indiscale.com> +# +# 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 <https://www.gnu.org/licenses/>. +# +# ** end header + +# This Makefile is a wrapper for sphinx scripts. +# +# It is based upon the autocreated makefile for Sphinx documentation. + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= -a +SPHINXBUILD ?= sphinx-build +SPHINXAPIDOC ?= javasphinx-apidoc +SOURCEDIR = . +BUILDDIR = ../../build/doc + +.PHONY: doc-help Makefile apidoc + +# Put it first so that "make" without argument is like "make help". +doc-help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile apidoc + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) +# sphinx-build -M html . ../../build/doc + +apidoc: + @$(SPHINXAPIDOC) -o _apidoc --update --title="CaosDB Server" ../main/ diff --git a/src/doc/README_SETUP.md b/src/doc/README_SETUP.md new file mode 120000 index 0000000000000000000000000000000000000000..88332e357f5e06f3de522768ccdcd9e513c15f62 --- /dev/null +++ b/src/doc/README_SETUP.md @@ -0,0 +1 @@ +../../README_SETUP.md \ No newline at end of file diff --git a/src/doc/administration/configuration.rst b/src/doc/administration/configuration.rst new file mode 100644 index 0000000000000000000000000000000000000000..4170fd0ed31c7a0ec5c1b4e589ff919267cf7de9 --- /dev/null +++ b/src/doc/administration/configuration.rst @@ -0,0 +1,62 @@ +Configuration +============= + +The server is configured through configuration files. There are two directories with config files: + +``conf/core`` + Upstream defaults are stored here. +``conf/ext`` + User specific configuration should be stored here, settings in ``ext`` override settings in + ``core``. Additionally, configuration files may be stored in ``*.d`` directories here, named + after the original config file name. For example, the general server configuration will be + assembled from ``conf/core/server.conf``, ``conf/ext/server.conf`` and any ``*.conf`` files found + in ``conf/ext/server.conf.d``. + +Configuration files +------------------- + +In each of these directories, the server looks for the following files: + +``server.conf`` + General server configuration options. The possible configuration options are documented inside + the `default file <https://gitlab.com/caosdb/caosdb-server/-/blob/dev/conf/core/server.conf>`_. + +``global_entity_permissions.xml`` + :ref:`Permissions <concepts:Permissions>` which are automatically set, based on user roles. + +``usersources.ini`` + This file defines possible sources which are checked when a user tries to authenticate. Each + defined source has a special section, the possible options are defined separately for each user + source. At the moment the best place to look for this specific documentation is at the API + documentation of :java:type:`UserSource` and its implementing classes. The provided `template + file <https://gitlab.com/caosdb/caosdb-server/-/blob/dev/conf/core/usersources.ini.template>`_ + also has some information. The general concept about authentication realms is described in + :java:type:`UserSources`. + +``authtoken.yaml`` + Configuration for dispensed authentication tokens, which can be used to authenticate to CaosDB + without the need of a user/password combination. Possible use cases are server-side scripts or + initial setup after the server start. There is more documentation inside the `template file + <https://gitlab.com/caosdb/caosdb-server/-/blob/dev/conf/core/authtoken.example.yaml>`_. + +``cache.ccf`` + Configuration for the Java Caching System (JCS) which can be used by the server. More + documentation is `upstream + <http://commons.apache.org/proper/commons-jcs/getting_started/intro.html>`_ and inside `the file + <https://gitlab.com/caosdb/caosdb-server/-/blob/dev/conf/core/cache.ccf>`_. + +``log4j2-default.properties``, ``log4j2-debug.properties`` + Configuration for logging, following the standard described by the `log4j library + <https://logging.apache.org/log4j/2.x/>`_. The ``default`` file is always loaded, in debug mode + the ``debug`` file iss added as well. + + +Changing the configuration at runtime +------------------------------------- + +Remark: + Only when the server is in debug mode, the general configuration can be changed at runtime. + +In the debug case, the server provides the ``_server_properties`` resource which allows the ``GET`` +and ``POST`` methods to access the server's properties. The Python client library conveniently +wraps this in the :any:`caosdb-pylib:caosdb.common.administration` module. diff --git a/src/doc/administration/maintenance.rst b/src/doc/administration/maintenance.rst new file mode 100644 index 0000000000000000000000000000000000000000..8a3397614b409a4ad498d0d8898c79cd0eb69bd6 --- /dev/null +++ b/src/doc/administration/maintenance.rst @@ -0,0 +1,59 @@ + +Maintenance of the CaosDB Server +================================ + +Creating a Backup +----------------- + +In order to create a full backup of CaosDB, the state of the SQL-Backend (MySQL, MariaDB) +has to be saved and the internal file system of CaosDB (symbolic links to +file systems that are mounted and uploaded files) has to be saved. + +You find the documentation on how to backup the SQL-Backend :any:`caosdb-mysqlbackend:Maintenance` + +In order to save the file backend we recommend to tar the file system. However, +you could use other backup methods that allow to restore the file system. +The CaosDB internal file system is located at the path defined by the +``FILE_SYSTEM_ROOT`` configuration variable (see :any:`configuration`). + +The command could look like:: + + tar czvf /path/to/new/backup /path/to/caosdb/filesystem.tar.gz + + +You can also save the content of CaosDB using XML. This is **not recommended** since it is less reliable than a real SQL backup. However there may be cases in which an XML backup is desirable, e.g., when transferring entities between two different CaosDB instances. +Collect the entities that you want to export in a :any:`caosdb-pylib:caosdb.common.models.Container`, here +named ``cont``. Then you can export the XML with:: + + from caosadvancedtools.export_related import invert_ids + from lxml import etree + invert_ids(cont) + xml = etree.tounicode(cont.to_xml( + local_serialization=True), pretty_print=True) + + with open("caosdb_data.xml"), "w") as fi: + fi.write(xml) + + +Restoring a Backup +------------------ + +.. note : + CaosDB should be offline before restoring data. + +If you want to restore the internal file system, simply replace it. E.g. if your +Backup is a tarball:: + + tar xvf /path/to/caosroot.tar.gz + + +You find the documentation on how to restore the data in the SQL-Backend :any:`caosdb-mysqlbackend:Maintenance` + + +If you want to restore the entities exported to XML, you can do:: + + cont = db.Container() + with open("caosdb_data.xml") as fi: + cont = cont.from_xml(fi.read()) + cont.insert() + diff --git a/src/doc/administration/server_side_scripting.rst b/src/doc/administration/server_side_scripting.rst new file mode 100644 index 0000000000000000000000000000000000000000..59bce98682c6d1190fc90681fc8e14fd483e891e --- /dev/null +++ b/src/doc/administration/server_side_scripting.rst @@ -0,0 +1,85 @@ +Server-Side Scripting +===================== + +Introduction +------------ + +Small computation task, like some visualization, might be easily implemented in Python or some other language, but cumbersome to integrate into the server. Furthermore, the CaosDB server should stay a general tool without burden from specific projects. Also, one might want to trigger some standardized processing task from the web interface for convenience. For these situations the "server side scripting" is intended. + +Concepts +------------ + +The basic idea is that a script or program (script in the following) can be called to run on the server (or elsewhere in future) to do some calculations. This triggering of the script is done over the API so it can be done with any client. Input arguments can be passed to the script and the STDOUT and STDERR are returned. + +Each script is executed in a temporary home directory, which is automatically clean up. However, scripts can store files in the "$SHARED" folder and for example provide users a link that allows them to download files. + +Write and Install a Script +-------------------------- + +A server-side script must accept at least the ``--auth-token=AUTH_TOKEN`` option. All other command-line parameters which are passed to the script are not specified by the API and maybe defined by the script itself. + +So a minimal bash script would be + +.. code-block:: sh + + #!/bin/bash + echo Hello, World! + +thereby just ignoring the ``--auth-token`` option. + +The script has to be executable and must be placed somewhere in one of the directory trees which are configured by the server config :doc:`SERVER_SIDE_SCRIPTING_BIN_DIRS <configuration>`. + +Users will need the ``SCRIPTING:EXECUTE:path:to:the:script`` permission. Here the path to the script is of course relativet to the ``SERVER_SIDE_SCRIPTING_BIN_DIRS`` where it is located. + +For more information see the :doc:`specification of the API <../specs/Server-side-scripting>` + +Environment +------------ + +The script is called with several special environment variables to accommodate +for its special location. + +`HOME` +^^^^^^^^^^^^ +To be able to run with reduced privileges, the script has its `HOME` environment +variable set to a special directory with write access. This directory will be +deleted after the script has terminated. Its content is freshly copied for each +script invocation from a skeleton directory, located in the server directory, in +`scripting/home/`. By default, this directory contains the following: + +- `readme.md` :: A small text file describing the purpose of the directory. + +Users of CaosDB are invited to populate the directory with whatever their +scripts need. + +Invocation +------------ + +Server side scripts are triggered by sending a POST to the `/scripting` resource. There are the following arguments that can be provided: + +- `call`: the name of the script to be called +- `-pN`: positional arguments (e.g. `-p0`, `-p1` etc.) +- `-ONAME`: named arguments (e.g. `-Otest`, `-Onumber` etc.) + +The arguments will be passed to the script. + +An invocation via a button in javascript could look like: + +.. code-block:: javascript + + var _make_sss_button = function (entity) { + const script = "script.py"; + + const scripting_form = $(` + <form class="btn-group-xs ${_css_class_export_button}" + method="POST" + action="/scripting"> + <input type="hidden" name="call" value="${script}"/> + <input name="-p0" value=""/> + <button type="submit" class="btn btn-link">Start script</button> + </form>`); + return scripting_form[0]; + } + +For more information see the :doc:`specification of the API <../specs/Server-side-scripting>` + diff --git a/src/doc/concepts.rst b/src/doc/concepts.rst new file mode 100644 index 0000000000000000000000000000000000000000..ec93719548a7d7c577ac62c6615b3fcf24111b42 --- /dev/null +++ b/src/doc/concepts.rst @@ -0,0 +1,29 @@ +=================================== +Basic concepts of the CaosDB server +=================================== + +The CaosDB server provides the HTTP API resources to users and client libraries. It uses a plain +MariaDB/MySQL database as backend for data storage, raw files are stored separately on the file +system. + + +Configuration +------------- + +Administrators may configure the server through :doc:`configuration +files<administration/configuration>`. Additionally, configurations may be set via the API if the +server is in debug mode. + + +Permissions +----------- + +CaosDB has a fine grained role based permission system. Each interaction with the server is +governed by the current rules of the user, by default this is the ``anonymous`` role. The +permissions for an action which involves one or more objects are set either manually or via default +permissions which can be configured. For more detailed information, there is separate +:doc:`documentation of the permission system<permissions>`. + + + + diff --git a/src/doc/conf.py b/src/doc/conf.py new file mode 100644 index 0000000000000000000000000000000000000000..84e676394d19e8ec35f241f1cf3cc202dafa0d4d --- /dev/null +++ b/src/doc/conf.py @@ -0,0 +1,214 @@ +# -*- coding: utf-8 -*- +# +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('../caosdb')) + +import sphinx_rtd_theme + +# -- Project information ----------------------------------------------------- + +project = 'caosdb-server' +copyright = '2020, IndiScale GmbH' +author = 'Daniel Hornung' + +# The short X.Y version +version = '0.2' +# The full version, including alpha/beta/rc tags +release = '0.2' + + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'javasphinx', + 'sphinx.ext.autodoc', + 'sphinx.ext.intersphinx', + 'sphinx.ext.napoleon', # For Google style docstrings + "recommonmark", # For markdown files. + "sphinx.ext.autosectionlabel", # Allow reference sections using its title + "sphinx_rtd_theme", +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = None + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +# html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# The default sidebars (for documents that don't match any pattern) are +# defined by theme itself. Builtin themes are using these templates by +# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', +# 'searchbox.html']``. +# +# html_sidebars = {} + + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = 'caosdb-serverdoc' + + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'caosdb-server.tex', 'caosdb-server Documentation', + 'IndiScale GmbH', 'manual'), +] + + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'caosdb-server', 'caosdb-server Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'caosdb-server', 'caosdb-server Documentation', + author, 'caosdb-server', 'One line description of project.', + 'Miscellaneous'), +] + + +# -- Options for Epub output ------------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = project + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +# +# epub_identifier = '' + +# A unique identification for the text. +# +# epub_uid = '' + +# A list of files that should not be packed into the epub file. +epub_exclude_files = ['search.html'] + + +# -- Extension configuration ------------------------------------------------- + +# -- Options for javasphinx -------------------------------------------------- +# See also https://bronto-javasphinx.readthedocs.io/en/latest/ + +# javadoc_url_map = { +# '<namespace_here>' : ('<base_url_here>', 'javadoc'), +# } + + +# -- Options for intersphinx ------------------------------------------------- + +# https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html#confval-intersphinx_mapping +intersphinx_mapping = { + "python": ("https://docs.python.org/", None), + "caosdb-pylib": ("https://caosdb.gitlab.io/caosdb-pylib/", None), + "caosdb-mysqlbackend": ("https://caosdb.gitlab.io/caosdb-mysqlbackend/", None), +} + + +# -- Options for autodoc ----------------------------------------------------- +# TODO Which options do we want? +autodoc_default_options = { + 'members': None, + 'undoc-members': None, +} + + +# -- Options for autosectionlabel -------------------------------------------- + +autosectionlabel_prefix_document = True diff --git a/src/doc/development/benchmarking.md b/src/doc/development/benchmarking.md new file mode 100644 index 0000000000000000000000000000000000000000..f2d663f6e69799c7a87a28fbdf32f15fab892ac1 --- /dev/null +++ b/src/doc/development/benchmarking.md @@ -0,0 +1,130 @@ + +# Benchmarking CaosDB # + +Benchmarking CaosDB may encompass several distinct areas: How much time is spent in the server's +Java code, how much time is spent inside the SQL backend, are the same costly methods clalled more +than once? This documentation tries to answer some questions connected with these benchmarking +aspects and give you the tools to answer your own questions. + +## Tools for the benchmarking ## + +For averaging over many runs of comparable requests and for putting the database into a +representative state, Python scripts are used. The scripts can be found in the `caosdb-dev-tools` +repository, located at [https://gitlab.indiscale.com/caosdb/src/caosdb-dev-tools](https://gitlab.indiscale.com/caosdb/src/caosdb-dev-tools) in the folder +`benchmarking`: + +### `fill_database.py` ### + +This commandline script is meant for filling the database with enough data to represeny an actual +real-life case, it can easily create hundreds of thousands of Entities. + +The script inserts predefined amounts of randomized Entities into the database, RecordTypes, +Properties and Records. Each Record has a random (but with defined average) number of Properties, +some of which may be references to other Records which have been inserted before. Actual insertion +of the Entities into CaosDB is done in chunks of a defined size. + +Users can tell the script to store times needed for the insertion of each chunk into a tsv file. + +### `measure_execution_time.py` ### + +A somewhat outdated script which executes a given query a number of times and then save statistics +about the `TransactionBenchmark` readings (see below for more information about the transaction +benchmarks) delivered by the server. + +### Benchmarking SQL commands ### + +MariaDB and MySQL have a feature to enable the logging of SQL queries' times. This logging must be +turned on on the SQL server as described in the [upstream documentation](https://mariadb.com/kb/en/general-query-log/). For the Docker +environment LinkAhead, this can conveniently be done with `linkahead mysqllog {on,off,store}`. + +### External JVM profilers ### + +Additionally to the transaction benchmarks, it is possible to benchmark the server execution via +external Java profilers. For example, [VisualVM](https://visualvm.github.io/) can connect to JVMs running locally or remotely +(e.g. in a Docker container). To enable this in LinkAhead's Docker environment, set + +```yaml +devel: + profiler: true +``` + +Most profilers, like as VisualVM, only gather cumulative data for call trees, they do not provide +complete call graphs (as callgrind/kcachegrind would do). They also do not differentiate between +calls with different query strings, as long as the Java process flow is the same (for example, `FIND +Record 1234` and `FIND Record A WHICH HAS A Property B WHICH HAS A Property C>100` would be handled +equally). + +## How to set up a representative database ## +For reproducible results, it makes sense to start off with an empty database and fill it using the +`fill_database.py` script, for example like this: + +```sh +./fill_database.py -t 500 -p 700 -r 10000 -s 100 --clean +``` + +The `--clean` argument is not strictly necessary when the database was empty before, but it may make +sense when there have been previous runs of the command. This example would create 500 RecordTypes, +700 Properties and 10000 Records with randomized properties, everything is inserted in chunks of 100 +Entities. + +## How to measure request times ## + +If the execution of the Java components is of interest, the VisualVM profiler should be started and +connected to the server before any requests to the server are started. + +When doing performance tests which are used for detailed analysis, it is important that + +1. CaosDB is in a reproducible state, which should be documented +2. all measurements are repeated several times to account for inevitable variance in access (for + example file system caching, network variablity etc.) + +### Filling the database ### + +By simply adding the option `-T logfile.tsv` to the `fill_database.py` command above, the times for +inserting the records are stored in a tsv file and can be analyzed later. + +### Obtain statistics about a query ### + +To repeat single queries a number of times, `measure_execution_time.py` can be used, for example: + +```sh +./measure_execution_time.py -n 120 -q "FIND MusicalInstrument WHICH IS REFERENCED BY Analysis" +``` + +This command executes the query 120 times, additional arguments could even plot the +TransactionBenchmark results directly. + +## What is measured ## + +For a consistent interpretation, the exact definitions of the measured times are as follows: + +### SQL logs ### + +As per https://mariadb.com/kb/en/general-query-log, the logs store only the time at which the SQL +server received a query, not the duration of the query. + +#### Possible future enhancements #### + +- The `query_response_time` plugin may be additionally used in the future, see + https://mariadb.com/kb/en/query-response-time-plugin + +### Transaction benchmarks ### + +Transaction benchmarking manually collects timing information for each transaction. At defined +points, different measurements can be made, accumulated and will finally be returned to the client. +Benchmark objects may consist of sub benchmarks and have a number of measurement objects, which +contain the actual statistics. + +Because transaction benchmarks must be manually added to the server code, they only monitor those +code paths where they are added. On the other hand, their manual nature allows for a more +abstracted analysis of performance bottlenecks. + +### Java profiler ### + +VisualVM records for each thread the call tree, specifically which methods were called how often and +how much time was spent inside these methods. + +### Global requests ### + +Python scripts may measure the global time needed for the execution of each request. +`fill_database.py` obtains its numbers this way. diff --git a/src/doc/index.rst b/src/doc/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..e41d318a2dbf7323e5cb327be1c7a3fe0b5d61ad --- /dev/null +++ b/src/doc/index.rst @@ -0,0 +1,29 @@ + +Welcome to caosdb-server's documentation! +========================================= + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + :hidden: + :glob: + + Getting started <README_SETUP> + Concepts <concepts> + Query Language <CaosDB-Query-Language> + administration/* + development/* + API documentation<_apidoc/packages> + +Welcome to the CaosDB, the flexible semantic data management toolkit! + +This documentation helps you to :doc:`get started<getting_started>`, explains the most important +:doc:`concepts<concepts>` and offers a range of :doc:`tutorials<tutorials>`. + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/src/doc/specs/Server-side-scripting.md b/src/doc/specs/Server-side-scripting.md new file mode 100644 index 0000000000000000000000000000000000000000..49f56af66a6b65855e36de12144955b2925a4f51 --- /dev/null +++ b/src/doc/specs/Server-side-scripting.md @@ -0,0 +1,187 @@ +# Server-Side Scripting API (v0.1) + +The CaosDB Server can execute scripts (bash/python/perl) and compiled executables. The scripts can be invoked by a remote-procedure-call (RPC) protocol. Both, the requirements for the scripts and the RPC are described in this document. + +## Configuration of the Server + +* The CaosDB Server has two relevant properties: + 1. `SERVER_SIDE_SCRIPTING_BIN_DIR` is the directory where executable scripts are to be placed. The server will not execute scripts which are out side of this directory. This directory must be readable and executable for the server. But it should not be readable or executable for anyone else. + 2. `SERVER_SIDE_SCRIPTING_WORKING_DIR` is the directory under which the server creates temporary working directories. The server needs writing, reading and executing permissions. The temporary working directories are deleted after the scripts have finished and the server has collected the results of the scripts. + +## Installing a Server-Side Script (SSS) + +* Put your script into the `SERVER_SIDE_SCRIPTING_BIN_DIR` or in any subdirectory and make it executable. Executable files below this directory are called `SSS`. +* All other files in that directory MUST be ignored by the server, i.e. the server will never call them directly. + However, they MAY contain additional data, different implementations, libraries etc. +* A symlink pointing to an executable MUST be treated as SSS, too. + +### Example SERVER\_SIDE\_SCRIPTING\_BIN\_DIR + +``` +/ ++- script1.py (EXECUTABLE) ++- script2.sh (EXECUTABLE) ++- subdir1/ + +-script3.pl (EXECUTABLE) ++- subdir2/ + +- data_for_script2 + +- another_script.py (EXECUTABLE) ++- script4 -> ./subdir2/another_script.py (SIMLINK to EXECUTABLE) ++- script5 -> /usr/local/bin/external (SIMLINK to EXECUTABLE) +``` + +The files `scripts1.py`, `scripts2.sh`, `scripts3.pl` and `another_script.py` are SSS. +Also the `script4` can be called which would result in calling `another_script.py` +The script5 points to an executable which is not stored in the `SSD_DIR`. + +## Calling a Server-Side Script Via Remote Procedure Call + +* Users can invoke scripts via HTTP under the uri `https://$HOST:$HTTPS_PORT/$CONTEXT_ROOT/scripting`. The server accepts POST requests with content types `application/x-www-form-urlencoded` and `multipart/form-data`. +* There are 6 types of form fields which are processed by the server: + 1. A single parameter form field with name="call" (the path to script, relative to the `SERVER_SIDE_SCRIPTING_BIN_DIR`). If there are more than one fields with that name, the behavior is not defined. + 2. Zero or more parameter form fields with a unique name which starts with the string `-O` (command line options). + 3. Zero or more parameter form fields with a unique name which starts with the string `-p` (positional command line arguments). + 4. Zero or more file form fields which have a unique field name and a unique file name (upload files). If the field names or file names are not unique, the behavior is not defined. + 5. A parameter form field with name="timeout" (the request timeout) + 6. A parameter form field with name="auth-token" and a valid CaosDB AuthToken string or "generate" as value. + +## How Does the Server Call the Script? +* The server executes the script in a temporary working directory, called *PWD* (which will be deleted afterwards). +* The form parameter `call`, the options, the arguments and file fields construct the string which is executed in a shell. The value of *call* begins the command line. +* For any option paramter with the name `-Ooption_name` and a value `option_value` a resulting `--option_name=option_value` is appended to the commandLine in no particular order. +* The values of the positional arguments are appended sorted alphabetically by their field name. E.g. a parameter `-p0` with value `v0` and a parameter `-p1` with value `v1` result in appending `v0 v1` to the command line. +* All files will be loaded into the directory `$PWD/.upload_files` with their file name (i.e. the form field property). If the file names contain slashes '/' they will build sub-directories in the `./upload_files`. +* If a file form field has a field name which begins with either `-p` or `-O` the file name with prefix `.upload_files/` is passed as value of an option or as a positional argument to the script. Thus it is possible to distinguish several uploaded files from one another. +* If there is a "auth-token" field present, another command line options `--auth-token=...` is appended. The value is either the string which was submitted with the POST request, or, if the value was "generate", a refreshed, valid AuthToken which authenticates as the user of the request (why? see below). + +### Example HTML Form + +```html +<form action="/scripting" method="post" enctype="multipart/form-data"> +<input type="hidden" name="call" value="my/script.py"/> +<input type="file" name="-Oconfig-file"/> +<input type="file" name="-p1"/> +<input type="text" name="-p0" value="analyze"/> +<input type="text" name="user"/> +<input type="text" name="-Oalgorithm" value="fast"/> +<input type="submit" value="Submit"> +</form> +``` + +where the user uploads `my.conf` as `-Oconfig-file` and `my.input.tsv` as `-p1`, would result in this command line: + +``` +$SERVER_SIDE_SCRIPTING_BIN_DIR/my/script.py --config-file=.upload_files/my.conf --algorithm=fast analyze .upload_files/my.input.tsv +``` +## CaosDB Server Response + +The CaosDB Server responds with an xml document. The root element is the usual `/Response`. If no errors occurred (which would be represented with `/Response/Error` elements) the result of the script execution is represented as a `/Response/script/` element. + +* It has a `code` attribute which contains the exit code value of the execution. +* It has `stdout` and `stderr` children which contain the dump of the stdout and stderr file of the execution environment. +* It has a `call` child which contains the command line which was executed (but without a possible `--auth-token` option and with a relative path to the executable). + +### Example XML Response + +```xml +<Response> +<script code="0"> +<call>my/script.py --config-file=.upload_files/my.conf --algorithm=fast analyze .upload_files/my.input.tsv</call> +<stdout>Result: 0.5</stdout> +<stderr>Warning: 8 Lines did not contain enough columns</stderr> +</Response> +``` + +## CaosDB Clients and Authentication Token + +A special use case for server side scripting is the automated execution of CaosDB clients. These clients need to connect to the CaosDB Server and thus need a way to authenticate themselves. +For this special case the server can pass an Authentication Token which can be used by the script to authenticate itself. If the invocation request send a particulare AuthToken in the form, this AuthToken will be passed to the script with the `--auth-token` option. Otherwise, if the `auth-token` field has "generate" as value, a fresh AuthToken is generated which belongs to the user who requested the script execution. +Thus the script is executed (and connects back to the server) as the user who called the script in the first place. + +A CaosDB client might use the python client library to connect to the server with that AuthToken. + +### Example Script + +```python +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# ** header v3.0 +# This file is a part of the CaosDB Project. +# +# Copyright (C) 2018 Research Group Biomedical Physics, +# Max-Planck-Institute for Dynamics and Self-Organization Göttingen +# +# 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 <https://www.gnu.org/licenses/>. +# +# ** end header +# +"""server_side_script.py. + +An example which implements a minimal server-side script. + +1) This script expects to find a *.txt file in the .upload_files dir which is +printed to stdout. + +2) It executes a "Count stars" query and prints the result to stdout. + +3) It will return with code 0 if everything is ok, or with any code that is +specified with the commandline option --exit +""" + +import sys +from os import listdir +from caosdb import configure_connection, execute_query + + +# parse --auth-token option and configure connection +CODE = 0 +QUERY = "COUNT stars" +for arg in sys.argv: + if arg.startswith("--auth-token="): + auth_token = arg[13:] + configure_connection(auth_token=auth_token) + if arg.startswith("--exit="): + CODE = int(arg[7:]) + if arg.startswith("--query="): + QUERY = arg[8:] + + +############################################################ +# 1 # find and print *.txt file ############################ +############################################################ + +try: + for fname in listdir(".upload_files"): + if fname.endswith(".txt"): + with open(".upload_files/{}".format(fname)) as f: + print(f.read()) +except FileNotFoundError: + pass + + +############################################################ +# 2 # query "COUNT stars" ################################## +############################################################ + +RESULT = execute_query(QUERY) +print(RESULT) + +############################################################ +# 3 ######################################################## +############################################################ + +sys.exit(CODE) +``` + diff --git a/src/main/java/caosdb/server/accessControl/CaosDBAuthorizingRealm.java b/src/main/java/caosdb/server/accessControl/CaosDBAuthorizingRealm.java deleted file mode 100644 index 5cfa425ac235405a0c861e54c9d97ae8ffab58f5..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/accessControl/CaosDBAuthorizingRealm.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * 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 <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package caosdb.server.accessControl; - -import com.google.common.base.Objects; -import java.util.Arrays; -import java.util.List; -import java.util.Set; -import org.apache.shiro.authc.AuthenticationInfo; -import org.apache.shiro.authc.AuthenticationToken; -import org.apache.shiro.authz.AuthorizationInfo; -import org.apache.shiro.authz.SimpleAuthorizationInfo; -import org.apache.shiro.realm.AuthorizingRealm; -import org.apache.shiro.subject.PrincipalCollection; -import org.apache.shiro.subject.SimplePrincipalCollection; - -public class CaosDBAuthorizingRealm extends AuthorizingRealm { - - private static class PermissionPrincipalCollection extends SimplePrincipalCollection { - - private final List<String> permissions; - - public PermissionPrincipalCollection( - final PrincipalCollection principals, final String[] permissions) { - super(principals); - this.permissions = Arrays.asList(permissions); - } - - private static final long serialVersionUID = 5585425107072564933L; - - @Override - public boolean equals(final Object obj) { - if (obj == this) { - return true; - } else if (obj instanceof PermissionPrincipalCollection) { - final PermissionPrincipalCollection that = (PermissionPrincipalCollection) obj; - return Objects.equal(that.permissions, this.permissions) && super.equals(that); - } else { - return false; - } - } - - @Override - public int hashCode() { - return super.hashCode() + 28 * this.permissions.hashCode(); - } - } - - static class PermissionAuthenticationInfo implements AuthenticationInfo { - - private static final long serialVersionUID = -3714484164124767976L; - private final PermissionPrincipalCollection principalCollection; - - public PermissionAuthenticationInfo( - final PrincipalCollection principals, final String... permissions) { - this.principalCollection = new PermissionPrincipalCollection(principals, permissions); - } - - @Override - public PrincipalCollection getPrincipals() { - return this.principalCollection; - } - - @Override - public Object getCredentials() { - return null; - } - - @Override - public boolean equals(final Object obj) { - if (obj == this) { - return true; - } else if (obj instanceof PermissionAuthenticationInfo) { - final PermissionAuthenticationInfo that = (PermissionAuthenticationInfo) obj; - return Objects.equal(that.principalCollection, this.principalCollection); - } else { - return false; - } - } - - @Override - public int hashCode() { - return this.principalCollection.hashCode(); - } - } - - private static final CaosDBRolePermissionResolver role_permission_resolver = - new CaosDBRolePermissionResolver(); - - @Override - protected AuthorizationInfo doGetAuthorizationInfo(final PrincipalCollection principals) { - if (principals instanceof PermissionPrincipalCollection) { - // the PrincialsCollection carries the permissions. - final SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); - info.addStringPermissions(((PermissionPrincipalCollection) principals).permissions); - return info; - } - - final SimpleAuthorizationInfo authzInfo = new SimpleAuthorizationInfo(); - - // find all roles which are associated with this principal in this - // realm. - final Set<String> roles = UserSources.resolve(principals); - if (roles != null) { - authzInfo.setRoles(roles); - - // find all permissions which are associated with these roles. - authzInfo.addObjectPermission(role_permission_resolver.resolvePermissionsInRole(roles)); - } - - return authzInfo; - } - - public CaosDBAuthorizingRealm() { - setCachingEnabled(false); - setAuthorizationCachingEnabled(false); - } - - @Override - public boolean supports(final AuthenticationToken token) { - // this is not an authenticating realm - just for authorizing. - return false; - } - - @Override - protected AuthenticationInfo doGetAuthenticationInfo(final AuthenticationToken token) { - return null; - } -} diff --git a/src/main/java/caosdb/server/accessControl/OneTimeAuthenticationToken.java b/src/main/java/caosdb/server/accessControl/OneTimeAuthenticationToken.java deleted file mode 100644 index ba7dff8d50bd5f77ae4dc035e07caef48d6f3426..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/accessControl/OneTimeAuthenticationToken.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * 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 <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package caosdb.server.accessControl; - -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; -import java.util.UUID; -import org.eclipse.jetty.util.ajax.JSON; - -public class OneTimeAuthenticationToken extends SelfValidatingAuthenticationToken { - - private static final transient String PEPPER = java.util.UUID.randomUUID().toString(); - private final String[] permissions; - - public OneTimeAuthenticationToken( - final Principal principal, - final long date, - final long timeout, - final String salt, - final String curry, - final String checksum, - final String... permissions) { - super(principal, date, timeout, salt, curry, checksum); - this.permissions = permissions; - } - - public OneTimeAuthenticationToken( - final Principal principal, - final long date, - final long timeout, - final String salt, - final String curry, - final String... permissions) { - super( - principal, - date, - timeout, - salt, - curry, - calcChecksum( - principal.getRealm(), - principal.getUsername(), - date, - timeout, - salt, - curry, - calcChecksum((Object[]) permissions), - PEPPER)); - this.permissions = permissions; - } - - private static final long serialVersionUID = -1072740888045267613L; - - public String[] getPermissions() { - return this.permissions; - } - - @Override - public String calcChecksum() { - return calcChecksum( - this.principal.getRealm(), - this.principal.getUsername(), - this.date, - this.timeout, - this.salt, - this.curry, - calcChecksum((Object[]) this.permissions), - PEPPER); - } - - @Override - public String toString() { - return JSON.toString( - new Object[] { - this.principal.getRealm(), - this.principal.getUsername(), - this.date, - this.timeout, - this.salt, - this.permissions, - this.checksum - }); - } - - private static String[] toStringArray(final Object[] array) { - final String[] ret = new String[array.length]; - for (int i = 0; i < ret.length; i++) { - ret[i] = (String) array[i]; - } - return ret; - } - - public static OneTimeAuthenticationToken parse(final String token, final String curry) { - final Object[] array = (Object[]) JSON.parse(token); - final Principal principal = new Principal((String) array[0], (String) array[1]); - final long date = (Long) array[2]; - final long timeout = (Long) array[3]; - final String salt = (String) array[4]; - final String[] permissions = toStringArray((Object[]) array[5]); - final String checksum = (String) array[6]; - return new OneTimeAuthenticationToken( - principal, date, timeout, salt, curry, checksum, permissions); - } - - public static OneTimeAuthenticationToken generate( - final Principal principal, final String curry, final String... permissions) { - return new OneTimeAuthenticationToken( - principal, - System.currentTimeMillis(), - Long.parseLong(CaosDBServer.getServerProperty(ServerProperties.KEY_ACTIVATION_TIMEOUT_MS)), - UUID.randomUUID().toString(), - curry, - permissions); - } -} diff --git a/src/main/java/caosdb/server/accessControl/OneTimeTokenRealm.java b/src/main/java/caosdb/server/accessControl/OneTimeTokenRealm.java deleted file mode 100644 index 468a8d8d212ca5546f1940a4b3de38c1da50b3d8..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/accessControl/OneTimeTokenRealm.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * 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 <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package caosdb.server.accessControl; - -import caosdb.server.accessControl.CaosDBAuthorizingRealm.PermissionAuthenticationInfo; -import org.apache.shiro.authc.AuthenticationException; -import org.apache.shiro.authc.AuthenticationInfo; -import org.apache.shiro.authc.AuthenticationToken; -import org.apache.shiro.authc.credential.AllowAllCredentialsMatcher; - -public class OneTimeTokenRealm extends SessionTokenRealm { - - @Override - protected AuthenticationInfo doGetAuthenticationInfo(final AuthenticationToken token) - throws AuthenticationException { - - final AuthenticationInfo info = super.doGetAuthenticationInfo(token); - if (info != null) { - return new PermissionAuthenticationInfo( - info.getPrincipals(), ((OneTimeAuthenticationToken) token).getPermissions()); - } - - return null; - } - - public OneTimeTokenRealm() { - setAuthenticationTokenClass(OneTimeAuthenticationToken.class); - setCredentialsMatcher(new AllowAllCredentialsMatcher()); - setCachingEnabled(false); - setAuthenticationCachingEnabled(false); - // setAuthorizationCachingEnabled(false); - } -} diff --git a/src/main/java/caosdb/server/accessControl/SelfValidatingAuthenticationToken.java b/src/main/java/caosdb/server/accessControl/SelfValidatingAuthenticationToken.java deleted file mode 100644 index 079f592ea7911f974bf4a64c9c5f1674e64a09a5..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/accessControl/SelfValidatingAuthenticationToken.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * 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 <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package caosdb.server.accessControl; - -import caosdb.server.utils.Utils; -import org.apache.shiro.authc.AuthenticationToken; - -public abstract class SelfValidatingAuthenticationToken implements AuthenticationToken { - - private static final long serialVersionUID = -7212039848895531161L; - protected final long date; - protected final long timeout; - protected final String checksum; - protected final Principal principal; - protected final String curry; - protected final String salt; - - public SelfValidatingAuthenticationToken( - final Principal principal, - final long date, - final long timeout, - final String salt, - final String curry, - final String checksum) { - this.date = date; - this.timeout = timeout; - this.principal = principal; - this.salt = salt; - this.curry = curry; - this.checksum = checksum; - } - - public SelfValidatingAuthenticationToken( - final Principal principal, - final long date, - final long timeout, - final String salt, - final String curry) { - this.date = date; - this.timeout = timeout; - this.principal = principal; - this.salt = salt; - this.curry = curry; - this.checksum = calcChecksum(); - } - - @Override - public Principal getPrincipal() { - return this.principal; - } - - @Override - public Object getCredentials() { - return null; - } - - public long getExpires() { - return this.date + this.timeout; - } - - public long getTimeout() { - return this.timeout; - } - - public boolean isExpired() { - return System.currentTimeMillis() >= getExpires(); - } - - public boolean isHashValid() { - final String other = calcChecksum(); - return this.checksum != null && this.checksum.equals(other); - } - - public boolean isValid() { - return !isExpired() && isHashValid(); - } - - public abstract String calcChecksum(); - - protected static String calcChecksum(final Object... fields) { - final StringBuilder sb = new StringBuilder(); - for (final Object field : fields) { - if (field != null) { - sb.append(field.toString()); - } - sb.append(":"); - } - return Utils.sha512(sb.toString(), null, 1); - } -} diff --git a/src/main/java/caosdb/server/accessControl/SessionToken.java b/src/main/java/caosdb/server/accessControl/SessionToken.java deleted file mode 100644 index 273bd50ba7c4ef89fecd0e2b9b8817acbf6d9efa..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/accessControl/SessionToken.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * 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 <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package caosdb.server.accessControl; - -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; -import org.eclipse.jetty.util.ajax.JSON; - -public class SessionToken extends SelfValidatingAuthenticationToken { - - /** - * Cryptographic pepper. Generated when class is loaded and used until the server reboots. Hence - * all SessionTokens invalidate when the server reboots. - */ - private static final transient String PEPPER = java.util.UUID.randomUUID().toString(); - - public static final String SEP = ":"; - - public SessionToken( - final Principal principal, - final long date, - final long timeout, - final String salt, - final String curry, - final String checksum) { - super(principal, date, timeout, salt, curry, checksum); - } - - public SessionToken( - final Principal principal, - final long date, - final long timeout, - final String salt, - final String curry) { - super(principal, date, timeout, salt, curry); - } - - private static final long serialVersionUID = 5887135104218573761L; - - @Override - public String calcChecksum() { - return calcChecksum( - this.date, - this.timeout, - this.principal.getRealm(), - this.principal.getUsername(), - PEPPER, - this.salt, - this.curry); - } - - @Override - public String toString() { - return JSON.toString( - new Object[] { - this.principal.getRealm(), - this.principal.getUsername(), - this.date, - this.timeout, - this.salt, - this.checksum - }); - } - - public static SessionToken parse(final String token, final String curry) { - final Object[] array = (Object[]) JSON.parse(token); - final Principal principal = new Principal((String) array[0], (String) array[1]); - final long date = (Long) array[2]; - final long timeout = (Long) array[3]; - final String salt = (String) array[4]; - final String checksum = (String) array[5]; - return new SessionToken(principal, date, timeout, salt, curry, checksum); - } - - public static SessionToken generate(final Principal principal, final String curry) { - final SessionToken ret = - new SessionToken( - principal, - System.currentTimeMillis(), - Long.parseLong( - CaosDBServer.getServerProperty(ServerProperties.KEY_SESSION_TIMEOUT_MS).trim()), - java.util.UUID.randomUUID().toString(), - curry); - if (!ret.isValid()) { - throw new RuntimeException("SessionToken not valid!"); - } - return ret; - } -} diff --git a/src/main/java/caosdb/server/database/BackendTransaction.java b/src/main/java/caosdb/server/database/BackendTransaction.java deleted file mode 100644 index 14e65e86bd9fe05b074c731e27b601fa4ed51f68..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/database/BackendTransaction.java +++ /dev/null @@ -1,293 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * 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 <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package caosdb.server.database; - -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.implementation.MySQL.MySQLDeleteEntityProperties; -import caosdb.server.database.backend.implementation.MySQL.MySQLDeletePassword; -import caosdb.server.database.backend.implementation.MySQL.MySQLDeleteRole; -import caosdb.server.database.backend.implementation.MySQL.MySQLDeleteSparseEntity; -import caosdb.server.database.backend.implementation.MySQL.MySQLDeleteUser; -import caosdb.server.database.backend.implementation.MySQL.MySQLGetAllNames; -import caosdb.server.database.backend.implementation.MySQL.MySQLGetChildren; -import caosdb.server.database.backend.implementation.MySQL.MySQLGetDependentEntities; -import caosdb.server.database.backend.implementation.MySQL.MySQLGetFileRecordByPath; -import caosdb.server.database.backend.implementation.MySQL.MySQLGetIDByName; -import caosdb.server.database.backend.implementation.MySQL.MySQLGetInfo; -import caosdb.server.database.backend.implementation.MySQL.MySQLGetUpdateableChecksums; -import caosdb.server.database.backend.implementation.MySQL.MySQLInsertEntityDatatype; -import caosdb.server.database.backend.implementation.MySQL.MySQLInsertEntityProperties; -import caosdb.server.database.backend.implementation.MySQL.MySQLInsertLinCon; -import caosdb.server.database.backend.implementation.MySQL.MySQLInsertLogRecord; -import caosdb.server.database.backend.implementation.MySQL.MySQLInsertParents; -import caosdb.server.database.backend.implementation.MySQL.MySQLInsertRole; -import caosdb.server.database.backend.implementation.MySQL.MySQLInsertSparseEntity; -import caosdb.server.database.backend.implementation.MySQL.MySQLInsertTransactionHistory; -import caosdb.server.database.backend.implementation.MySQL.MySQLIsSubType; -import caosdb.server.database.backend.implementation.MySQL.MySQLRegisterSubDomain; -import caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveAll; -import caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveAllUncheckedFiles; -import caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveDatatypes; -import caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveLogRecord; -import caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveParents; -import caosdb.server.database.backend.implementation.MySQL.MySQLRetrievePasswordValidator; -import caosdb.server.database.backend.implementation.MySQL.MySQLRetrievePermissionRules; -import caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveProperties; -import caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveQueryTemplateDefinition; -import caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveRole; -import caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveSparseEntity; -import caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveTransactionHistory; -import caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveUser; -import caosdb.server.database.backend.implementation.MySQL.MySQLRuleLoader; -import caosdb.server.database.backend.implementation.MySQL.MySQLSetFileCheckedTimestampImpl; -import caosdb.server.database.backend.implementation.MySQL.MySQLSetPassword; -import caosdb.server.database.backend.implementation.MySQL.MySQLSetPermissionRules; -import caosdb.server.database.backend.implementation.MySQL.MySQLSetQueryTemplateDefinition; -import caosdb.server.database.backend.implementation.MySQL.MySQLSyncStats; -import caosdb.server.database.backend.implementation.MySQL.MySQLUpdateSparseEntity; -import caosdb.server.database.backend.implementation.MySQL.MySQLUpdateUser; -import caosdb.server.database.backend.implementation.MySQL.MySQLUpdateUserRoles; -import caosdb.server.database.backend.implementation.UnixFileSystem.UnixFileSystemCheckHash; -import caosdb.server.database.backend.implementation.UnixFileSystem.UnixFileSystemCheckSize; -import caosdb.server.database.backend.implementation.UnixFileSystem.UnixFileSystemFileExists; -import caosdb.server.database.backend.implementation.UnixFileSystem.UnixFileSystemFileWasModifiedAfter; -import caosdb.server.database.backend.implementation.UnixFileSystem.UnixFileSystemGetFileIterator; -import caosdb.server.database.backend.interfaces.BackendTransactionImpl; -import caosdb.server.database.backend.interfaces.DeleteEntityPropertiesImpl; -import caosdb.server.database.backend.interfaces.DeletePasswordImpl; -import caosdb.server.database.backend.interfaces.DeleteRoleImpl; -import caosdb.server.database.backend.interfaces.DeleteSparseEntityImpl; -import caosdb.server.database.backend.interfaces.DeleteUserImpl; -import caosdb.server.database.backend.interfaces.FileCheckHash; -import caosdb.server.database.backend.interfaces.FileCheckSize; -import caosdb.server.database.backend.interfaces.FileExists; -import caosdb.server.database.backend.interfaces.FileWasModifiedAfter; -import caosdb.server.database.backend.interfaces.GetAllNamesImpl; -import caosdb.server.database.backend.interfaces.GetChildrenImpl; -import caosdb.server.database.backend.interfaces.GetDependentEntitiesImpl; -import caosdb.server.database.backend.interfaces.GetFileIteratorImpl; -import caosdb.server.database.backend.interfaces.GetFileRecordByPathImpl; -import caosdb.server.database.backend.interfaces.GetIDByNameImpl; -import caosdb.server.database.backend.interfaces.GetInfoImpl; -import caosdb.server.database.backend.interfaces.GetUpdateableChecksumsImpl; -import caosdb.server.database.backend.interfaces.InsertEntityDatatypeImpl; -import caosdb.server.database.backend.interfaces.InsertEntityPropertiesImpl; -import caosdb.server.database.backend.interfaces.InsertLinConImpl; -import caosdb.server.database.backend.interfaces.InsertLogRecordImpl; -import caosdb.server.database.backend.interfaces.InsertParentsImpl; -import caosdb.server.database.backend.interfaces.InsertRoleImpl; -import caosdb.server.database.backend.interfaces.InsertSparseEntityImpl; -import caosdb.server.database.backend.interfaces.InsertTransactionHistoryImpl; -import caosdb.server.database.backend.interfaces.IsSubTypeImpl; -import caosdb.server.database.backend.interfaces.RegisterSubDomainImpl; -import caosdb.server.database.backend.interfaces.RetrieveAllImpl; -import caosdb.server.database.backend.interfaces.RetrieveAllUncheckedFilesImpl; -import caosdb.server.database.backend.interfaces.RetrieveDatatypesImpl; -import caosdb.server.database.backend.interfaces.RetrieveLogRecordImpl; -import caosdb.server.database.backend.interfaces.RetrieveParentsImpl; -import caosdb.server.database.backend.interfaces.RetrievePasswordValidatorImpl; -import caosdb.server.database.backend.interfaces.RetrievePermissionRulesImpl; -import caosdb.server.database.backend.interfaces.RetrievePropertiesImpl; -import caosdb.server.database.backend.interfaces.RetrieveQueryTemplateDefinitionImpl; -import caosdb.server.database.backend.interfaces.RetrieveRoleImpl; -import caosdb.server.database.backend.interfaces.RetrieveSparseEntityImpl; -import caosdb.server.database.backend.interfaces.RetrieveTransactionHistoryImpl; -import caosdb.server.database.backend.interfaces.RetrieveUserImpl; -import caosdb.server.database.backend.interfaces.RuleLoaderImpl; -import caosdb.server.database.backend.interfaces.SetFileCheckedTimestampImpl; -import caosdb.server.database.backend.interfaces.SetPasswordImpl; -import caosdb.server.database.backend.interfaces.SetPermissionRulesImpl; -import caosdb.server.database.backend.interfaces.SetQueryTemplateDefinitionImpl; -import caosdb.server.database.backend.interfaces.SyncStatsImpl; -import caosdb.server.database.backend.interfaces.UpdateSparseEntityImpl; -import caosdb.server.database.backend.interfaces.UpdateUserImpl; -import caosdb.server.database.backend.interfaces.UpdateUserRolesImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.misc.TransactionBenchmark; -import caosdb.server.utils.UndoHandler; -import caosdb.server.utils.Undoable; -import java.util.HashMap; - -public abstract class BackendTransaction implements Undoable { - - private final UndoHandler undoHandler = new UndoHandler(); - private Access access; - private TransactionBenchmark benchmark; - private static HashMap< - Class<? extends BackendTransactionImpl>, Class<? extends BackendTransactionImpl>> - impl = new HashMap<>(); - - protected abstract void execute(); - - public final void executeTransaction() { - final long t1 = System.currentTimeMillis(); - execute(); - final long t2 = System.currentTimeMillis(); - this.addMeasurement(this, t2 - t1); - } - - /** - * Intialiaze the adapters to the database backend. - * - * <p>Currently this is hard-coded to the MySQL-Backend but the architecture of this class is - * designed to make it easy in the future to choose other implementations (i.e. other back-ends) - */ - public static void init() { - if (impl.isEmpty()) { - setImpl(GetAllNamesImpl.class, MySQLGetAllNames.class); - setImpl(DeleteEntityPropertiesImpl.class, MySQLDeleteEntityProperties.class); - setImpl(DeleteSparseEntityImpl.class, MySQLDeleteSparseEntity.class); - setImpl(GetChildrenImpl.class, MySQLGetChildren.class); - setImpl(GetDependentEntitiesImpl.class, MySQLGetDependentEntities.class); - setImpl(GetIDByNameImpl.class, MySQLGetIDByName.class); - setImpl(GetInfoImpl.class, MySQLGetInfo.class); - setImpl(InsertEntityPropertiesImpl.class, MySQLInsertEntityProperties.class); - setImpl(InsertLinConImpl.class, MySQLInsertLinCon.class); - setImpl(InsertParentsImpl.class, MySQLInsertParents.class); - setImpl(InsertSparseEntityImpl.class, MySQLInsertSparseEntity.class); - setImpl(InsertTransactionHistoryImpl.class, MySQLInsertTransactionHistory.class); - setImpl(IsSubTypeImpl.class, MySQLIsSubType.class); - setImpl(UpdateSparseEntityImpl.class, MySQLUpdateSparseEntity.class); - setImpl(RetrieveAllImpl.class, MySQLRetrieveAll.class); - setImpl(RegisterSubDomainImpl.class, MySQLRegisterSubDomain.class); - setImpl(RetrieveDatatypesImpl.class, MySQLRetrieveDatatypes.class); - setImpl(RetrieveTransactionHistoryImpl.class, MySQLRetrieveTransactionHistory.class); - setImpl(RetrieveUserImpl.class, MySQLRetrieveUser.class); - setImpl(RetrieveParentsImpl.class, MySQLRetrieveParents.class); - setImpl(GetFileRecordByPathImpl.class, MySQLGetFileRecordByPath.class); - setImpl(RetrievePropertiesImpl.class, MySQLRetrieveProperties.class); - setImpl(RetrieveSparseEntityImpl.class, MySQLRetrieveSparseEntity.class); - setImpl(RuleLoaderImpl.class, MySQLRuleLoader.class); - setImpl(SyncStatsImpl.class, MySQLSyncStats.class); - setImpl(FileExists.class, UnixFileSystemFileExists.class); - setImpl(FileWasModifiedAfter.class, UnixFileSystemFileWasModifiedAfter.class); - setImpl(FileCheckHash.class, UnixFileSystemCheckHash.class); - setImpl(GetFileIteratorImpl.class, UnixFileSystemGetFileIterator.class); - setImpl(SetFileCheckedTimestampImpl.class, MySQLSetFileCheckedTimestampImpl.class); - setImpl(RetrieveAllUncheckedFilesImpl.class, MySQLRetrieveAllUncheckedFiles.class); - setImpl(UpdateUserImpl.class, MySQLUpdateUser.class); - setImpl(DeleteUserImpl.class, MySQLDeleteUser.class); - setImpl(SetPasswordImpl.class, MySQLSetPassword.class); - setImpl(RetrievePasswordValidatorImpl.class, MySQLRetrievePasswordValidator.class); - setImpl(DeletePasswordImpl.class, MySQLDeletePassword.class); - setImpl(GetUpdateableChecksumsImpl.class, MySQLGetUpdateableChecksums.class); - setImpl(FileCheckSize.class, UnixFileSystemCheckSize.class); - setImpl(InsertRoleImpl.class, MySQLInsertRole.class); - setImpl(RetrieveRoleImpl.class, MySQLRetrieveRole.class); - setImpl(DeleteRoleImpl.class, MySQLDeleteRole.class); - setImpl(SetPermissionRulesImpl.class, MySQLSetPermissionRules.class); - setImpl(RetrievePermissionRulesImpl.class, MySQLRetrievePermissionRules.class); - setImpl(UpdateUserRolesImpl.class, MySQLUpdateUserRoles.class); - setImpl(InsertLogRecordImpl.class, MySQLInsertLogRecord.class); - setImpl(RetrieveLogRecordImpl.class, MySQLRetrieveLogRecord.class); - setImpl(SetQueryTemplateDefinitionImpl.class, MySQLSetQueryTemplateDefinition.class); - setImpl( - RetrieveQueryTemplateDefinitionImpl.class, MySQLRetrieveQueryTemplateDefinition.class); - setImpl(InsertEntityDatatypeImpl.class, MySQLInsertEntityDatatype.class); - } - } - - /** - * Execute this BackendTransaction, using the implementation given as an argument. - * - * <p>The implementation's benchmark is set to the corresponding sub-benchmark of this object's - * benchmark. - * - * @param t This BackendTransaction's execute() method will be called. - * @return The BackendTransaction which was passed as an argument. - */ - protected <K extends BackendTransaction> K execute(final K t) { - assert t != this; - this.undoHandler.append(t); - t.setAccess(this.access); - if (benchmark != null) { - t.setTransactionBenchmark(benchmark.getBenchmark(t.getClass())); - } - final long t1 = System.currentTimeMillis(); - t.execute(); - final long t2 = System.currentTimeMillis(); - this.addMeasurement(t, t2 - t1); - return t; - } - - public static <K extends BackendTransactionImpl, L extends K> void setImpl( - final Class<K> k, final Class<L> l) { - impl.put(k, l); - } - - public void setAccess(final Access access) { - this.access = access; - } - - @SuppressWarnings("unchecked") - protected <T extends BackendTransactionImpl> T getImplementation(final Class<T> clz) { - init(); - try { - Class<?> implclz = impl.get(clz); - final T ret = (T) implclz.getConstructor(Access.class).newInstance(this.access); - if (ret instanceof Undoable) { - this.undoHandler.append((Undoable) ret); - } - if (benchmark != null) { - ret.setTransactionBenchmark(benchmark.getBenchmark(ret.getClass())); - } - return ret; - } catch (final Exception e) { - throw new TransactionException(e); - } - } - - protected UndoHandler getUndoHandler() { - return this.undoHandler; - } - - @Override - public final void undo() { - this.undoHandler.undo(); - } - - @Override - public final void cleanUp() { - this.undoHandler.cleanUp(); - } - - boolean useCache() { - return this.access.useCache(); - } - - @Override - public String toString() { - return this.getClass().getSimpleName(); - } - - /** Set the benchmark object for this AbstractTransaction. */ - public void setTransactionBenchmark(TransactionBenchmark b) { - this.benchmark = b; - } - - public void addMeasurement(Object o, long time) { - if (this.benchmark != null) { - this.benchmark.addMeasurement(o, time); - } - } -} diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLHelper.java b/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLHelper.java deleted file mode 100644 index 458823167423893b6defb166f013618be3a796d7..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLHelper.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * 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 <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package caosdb.server.database.backend.implementation.MySQL; - -import caosdb.server.database.misc.DBHelper; -import caosdb.server.transaction.TransactionInterface; -import caosdb.server.transaction.WriteTransaction; -import caosdb.server.utils.Info; -import caosdb.server.utils.Initialization; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.HashMap; - -/** - * Provides cached statements for a MySQL back-end. - * - * @author tf - */ -public class MySQLHelper implements DBHelper { - - private Connection connection = null; - - public Connection getConnection() throws SQLException, ConnectionException { - if (this.connection == null) { - this.connection = DatabaseConnectionPool.getConnection(); - if (this.transaction instanceof WriteTransaction) { - this.connection.setReadOnly(false); - this.connection.setAutoCommit(false); - } else if (this.transaction instanceof Initialization || this.transaction instanceof Info) { - this.connection.setReadOnly(false); - this.connection.setAutoCommit(true); - } else { - this.connection.setReadOnly(false); - this.connection.setAutoCommit(true); - } - } - return this.connection; - } - - public PreparedStatement prepareStatement(final String statement) - throws SQLException, ConnectionException { - if (this.stmtCache.containsKey(statement)) { - final PreparedStatement ret = this.stmtCache.get(statement); - if (!ret.isClosed()) { - return ret; - } - } - - final PreparedStatement stmt = getConnection().prepareStatement(statement); - this.stmtCache.put(statement, stmt); - return stmt; - } - - private HashMap<String, PreparedStatement> stmtCache = new HashMap<String, PreparedStatement>(); - - @Override - public void setHelped(final TransactionInterface transaction) { - this.transaction = transaction; - } - - private TransactionInterface transaction = null; - - @Override - public void commit() throws SQLException { - if (this.connection != null - && !this.connection.isClosed() - && !this.connection.getAutoCommit()) { - this.connection.commit(); - } - } - - @Override - public void cleanUp() { - - // close all statements (if necessary), roll back to last save point (if - // possible) and close connection (if necessary). - try { - if (this.connection != null && !this.connection.isClosed()) { - // close all cached statements (if possible) - for (final PreparedStatement stmt : this.stmtCache.values()) { - try { - if (!stmt.isClosed()) { - stmt.close(); - } - } catch (final SQLException e) { - e.printStackTrace(); - } - } - - try { - if (!this.connection.getAutoCommit()) { - this.connection.rollback(); - } - } catch (final SQLException r) { - r.printStackTrace(); - } - this.connection.close(); - } - } catch (final SQLException e) { - e.printStackTrace(); - } - - // clear everything - this.stmtCache.clear(); - this.stmtCache = null; - this.connection = null; - } -} diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveTransactionHistory.java b/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveTransactionHistory.java deleted file mode 100644 index 43785187d6293c601f1d5b49ac12a7980df218da..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveTransactionHistory.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * 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 <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package caosdb.server.database.backend.implementation.MySQL; - -import static caosdb.server.database.DatabaseUtils.bytes2UTF8; - -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.RetrieveTransactionHistoryImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.ProtoTransactionLogMessage; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; - -public class MySQLRetrieveTransactionHistory extends MySQLTransaction - implements RetrieveTransactionHistoryImpl { - - public MySQLRetrieveTransactionHistory(final Access access) { - super(access); - } - - public static final String STMT_RETRIEVE_HISTORY = - "SELECT transaction, realm, username, seconds, nanos FROM transaction_log WHERE entity_id=? "; - - @Override - public ArrayList<ProtoTransactionLogMessage> execute(final Integer id) - throws TransactionException { - try { - final PreparedStatement stmt = prepareStatement(STMT_RETRIEVE_HISTORY); - - final ArrayList<ProtoTransactionLogMessage> ret = new ArrayList<ProtoTransactionLogMessage>(); - stmt.setInt(1, id); - final ResultSet rs = stmt.executeQuery(); - try { - while (rs.next()) { - final String transaction = bytes2UTF8(rs.getBytes("transaction")); - final String realm = bytes2UTF8(rs.getBytes("realm")); - final String username = bytes2UTF8(rs.getBytes("username")); - final Integer seconds = rs.getInt("seconds"); - final Integer nanos = rs.getInt("nanos"); - - ret.add(new ProtoTransactionLogMessage(transaction, realm, username, seconds, nanos)); - } - return ret; - } finally { - rs.close(); - } - } catch (final SQLException e) { - throw new TransactionException(e); - } catch (final ConnectionException e) { - throw new TransactionException(e); - } - } -} diff --git a/src/main/java/caosdb/server/database/backend/interfaces/InsertEntityDatatypeImpl.java b/src/main/java/caosdb/server/database/backend/interfaces/InsertEntityDatatypeImpl.java deleted file mode 100644 index 2f6f7c859281344997e1c781e9a56aafa5d03fc4..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/database/backend/interfaces/InsertEntityDatatypeImpl.java +++ /dev/null @@ -1,8 +0,0 @@ -package caosdb.server.database.backend.interfaces; - -import caosdb.server.database.proto.SparseEntity; -import caosdb.server.utils.Undoable; - -public interface InsertEntityDatatypeImpl extends BackendTransactionImpl, Undoable { - public abstract void execute(SparseEntity entity); -} diff --git a/src/main/java/caosdb/server/database/backend/interfaces/RetrieveTransactionHistoryImpl.java b/src/main/java/caosdb/server/database/backend/interfaces/RetrieveTransactionHistoryImpl.java deleted file mode 100644 index 217ec61c71f01d6c3ef7f0641b135f9a55900702..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/database/backend/interfaces/RetrieveTransactionHistoryImpl.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * 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 <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package caosdb.server.database.backend.interfaces; - -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.ProtoTransactionLogMessage; -import java.util.ArrayList; - -public interface RetrieveTransactionHistoryImpl extends BackendTransactionImpl { - - public ArrayList<ProtoTransactionLogMessage> execute(Integer id) throws TransactionException; -} diff --git a/src/main/java/caosdb/server/database/backend/transaction/RetrieveFullEntity.java b/src/main/java/caosdb/server/database/backend/transaction/RetrieveFullEntity.java deleted file mode 100644 index 7ac8c1592e0cb275e60008532cdabb33919369a9..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/database/backend/transaction/RetrieveFullEntity.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * 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 <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package caosdb.server.database.backend.transaction; - -import caosdb.server.database.BackendTransaction; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.RetrieveEntity; -import caosdb.server.entity.Role; -import caosdb.server.entity.container.Container; -import caosdb.server.utils.EntityStatus; - -public class RetrieveFullEntity extends BackendTransaction { - - private final Container<? extends EntityInterface> container; - - public RetrieveFullEntity(final EntityInterface entity) { - final Container<EntityInterface> c = new Container<>(); - c.add(entity); - this.container = c; - } - - public RetrieveFullEntity(final Container<? extends EntityInterface> container) { - this.container = container; - } - - public RetrieveFullEntity(Integer id) { - this(new RetrieveEntity(id)); - } - - @Override - public void execute() { - for (final EntityInterface e : this.container) { - if (e.hasId() && e.getId() > 0 && e.getEntityStatus() == EntityStatus.QUALIFIED) { - - execute(new RetrieveSparseEntity(e)); - if (e.getEntityStatus() == EntityStatus.VALID) { - if (e.getRole() == Role.QueryTemplate) { - execute(new RetrieveQueryTemplateDefinition(e)); - } - execute(new RetrieveParents(e)); - - execute(new RetrieveProperties(e)); - } - } - } - } - - public Container<? extends EntityInterface> getContainer() { - return container; - } -} diff --git a/src/main/java/caosdb/server/database/backend/transaction/RetrieveTransactionHistory.java b/src/main/java/caosdb/server/database/backend/transaction/RetrieveTransactionHistory.java deleted file mode 100644 index 72bc1e5b1ec3a3509cc5cbba23e38b908d4e969f..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/database/backend/transaction/RetrieveTransactionHistory.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * Copyright (C) 2019 IndiScale GmbH - * Copyright (C) 2019 Timm Fitschen (t.fitschen@indiscale.com) - * - * 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 <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package caosdb.server.database.backend.transaction; - -import caosdb.datetime.UTCDateTime; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.RetrieveTransactionHistoryImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.ProtoTransactionLogMessage; -import caosdb.server.entity.EntityInterface; -import caosdb.server.utils.TransactionLogMessage; -import java.util.ArrayList; - -public class RetrieveTransactionHistory extends BackendTransaction { - - private final EntityInterface entity; - - public RetrieveTransactionHistory(final EntityInterface entity) { - this.entity = entity; - } - - @Override - protected void execute() { - final RetrieveTransactionHistoryImpl t = - getImplementation(RetrieveTransactionHistoryImpl.class); - process(t.execute(entity.getId())); - } - - private void process(final ArrayList<ProtoTransactionLogMessage> l) throws TransactionException { - for (final ProtoTransactionLogMessage t : l) { - final UTCDateTime dateTime = UTCDateTime.UTCSeconds(t.seconds, t.nanos); - - this.entity.addTransactionLog( - new TransactionLogMessage(t.transaction, this.entity, t.username, dateTime)); - } - } -} diff --git a/src/main/java/caosdb/server/database/proto/ProtoTransactionLogMessage.java b/src/main/java/caosdb/server/database/proto/ProtoTransactionLogMessage.java deleted file mode 100644 index a34d962854852409fd9e14c2125de56ce61326f5..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/database/proto/ProtoTransactionLogMessage.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * 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 <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package caosdb.server.database.proto; - -import java.io.Serializable; - -public class ProtoTransactionLogMessage implements Serializable { - - public ProtoTransactionLogMessage( - final String transaction, - final String realm, - final String username, - final long seconds, - final int nanos) { - this.transaction = transaction; - this.realm = realm; - this.username = username; - this.seconds = seconds; - this.nanos = nanos; - } - - public ProtoTransactionLogMessage() {} - - private static final long serialVersionUID = 452072581780180334L; - public String transaction = null; - public String realm; - public String username = null; - public Long seconds = null; - public Integer nanos = null; -} diff --git a/src/main/java/caosdb/server/datatype/ReferenceValue.java b/src/main/java/caosdb/server/datatype/ReferenceValue.java deleted file mode 100644 index 25fa0b381cb436236dd6e3676970cf7e54c17776..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/datatype/ReferenceValue.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * 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 <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package caosdb.server.datatype; - -import caosdb.server.datatype.AbstractDatatype.Table; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.Message; -import caosdb.server.utils.ServerMessages; -import org.jdom2.Element; - -public class ReferenceValue implements SingleValue { - private EntityInterface entity = null; - private String name = null; - private Integer id = null; - - public static ReferenceValue parseReference(final Object reference) throws Message { - if (reference == null) { - return null; - } - if (reference instanceof EntityInterface) { - return new ReferenceValue((EntityInterface) reference); - } else if (reference instanceof ReferenceValue) { - return (ReferenceValue) reference; - } else if (reference instanceof GenericValue) { - try { - return new ReferenceValue(Integer.parseInt(((GenericValue) reference).toDatabaseString())); - } catch (final NumberFormatException e) { - return new ReferenceValue(((GenericValue) reference).toDatabaseString()); - } - } else if (reference instanceof CollectionValue) { - throw ServerMessages.DATA_TYPE_DOES_NOT_ACCEPT_COLLECTION_VALUES; - } else { - try { - return new ReferenceValue(Integer.parseInt(reference.toString())); - } catch (final NumberFormatException e) { - return new ReferenceValue(reference.toString()); - } - } - } - - @Override - public String toString() { - if (this.entity != null) { - return this.entity.getId().toString(); - } else if (this.id == null && this.name != null) { - return this.name; - } - return this.id.toString(); - } - - public ReferenceValue(final EntityInterface entity) { - this.entity = entity; - } - - public ReferenceValue(final Integer id) { - this.id = id; - } - - public ReferenceValue(final String name) { - this.name = name; - } - - public final EntityInterface getEntity() { - return this.entity; - } - - public final void setEntity(final EntityInterface entity) { - this.entity = entity; - } - - public final String getName() { - if (this.entity != null && this.entity.hasName()) { - return this.entity.getName(); - } - return this.name; - } - - public final Integer getId() { - if (this.entity != null && this.entity.hasId()) { - return this.entity.getId(); - } - return this.id; - } - - public final void setId(final Integer id) { - this.id = id; - } - - @Override - public void addToElement(final Element e) { - e.addContent(toString()); - } - - @Override - public Table getTable() { - return Table.reference_data; - } - - @Override - public String toDatabaseString() { - return toString(); - } - - @Override - public boolean equals(final Object obj) { - if (obj instanceof ReferenceValue) { - final ReferenceValue that = (ReferenceValue) obj; - if (that.getId() != null && getId() != null) { - return that.getId().equals(getId()); - } else if (that.getName() != null && getName() != null) { - return that.getName().equals(getName()); - } - } - return false; - } -} diff --git a/src/main/java/caosdb/server/entity/BaseEntity.java b/src/main/java/caosdb/server/entity/BaseEntity.java deleted file mode 100644 index 62d4873b54c262eb75920f3f5c990e9988f07e50..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/entity/BaseEntity.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * 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 <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package caosdb.server.entity; - -class BaseEntity { - - EntityID id = null; -} diff --git a/src/main/java/caosdb/server/entity/EntityID.java b/src/main/java/caosdb/server/entity/EntityID.java deleted file mode 100644 index fbfb83c8028f5f2e0d8376c6dc480c19046c0d5b..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/entity/EntityID.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * 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 <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package caosdb.server.entity; - -public class EntityID {} diff --git a/src/main/java/caosdb/server/entity/NamedEntity.java b/src/main/java/caosdb/server/entity/NamedEntity.java deleted file mode 100644 index 76ba79a317e146ca4b86793545f95d9e05e42480..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/entity/NamedEntity.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * 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 <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package caosdb.server.entity; - -class NamedEntity extends BaseEntity { - - String name = null; -} diff --git a/src/main/java/caosdb/server/entity/RetrieveEntity.java b/src/main/java/caosdb/server/entity/RetrieveEntity.java deleted file mode 100644 index 5b54c2bcd4ce401bc469728f774ad68198ba0986..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/entity/RetrieveEntity.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * 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 <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package caosdb.server.entity; - -import caosdb.server.database.proto.SparseEntity; -import caosdb.server.datatype.AbstractCollectionDatatype; - -public class RetrieveEntity extends Entity { - - public RetrieveEntity(final int id) { - super(id); - } - - public RetrieveEntity(final String name) { - super(name); - } - - public RetrieveEntity parseSparseEntity(final SparseEntity spe) { - setId(spe.id); - this.setRole(spe.role); - setEntityACL(spe.acl); - - if (!isNameOverride()) { - setName(spe.name); - } - if (!isDescOverride()) { - setDescription(spe.description); - } - if (!isDatatypeOverride()) { - final String dt = spe.datatype; - final String col = spe.collection; - - if (dt != null - && !dt.equalsIgnoreCase("null") - && (!hasDatatype() || !dt.equalsIgnoreCase(getDatatype().toString()))) { - if (col != null && !col.equalsIgnoreCase("null")) { - this.setDatatype(AbstractCollectionDatatype.collectionDatatypeFactory(col, dt)); - } else { - this.setDatatype(dt); - } - } - } - - if (spe.filePath != null) { - setFileProperties(new FileProperties(spe.fileHash, spe.filePath, spe.fileSize)); - } else { - setFileProperties(null); - } - - return this; - } -} diff --git a/src/main/java/caosdb/server/entity/ValidEntity.java b/src/main/java/caosdb/server/entity/ValidEntity.java deleted file mode 100644 index 3e99d4ead10152f3ce434a91c8c3d3643cc61273..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/entity/ValidEntity.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * 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 <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package caosdb.server.entity; - -import caosdb.server.database.proto.SparseEntity; -import caosdb.server.datatype.AbstractCollectionDatatype; - -public class ValidEntity extends Entity { - - public ValidEntity(final int id) { - super(id); - } - - public ValidEntity parseSparseEntity(final SparseEntity spe) { - setId(spe.id); - this.setRole(spe.role); - setEntityACL(spe.acl); - - if (!isNameOverride()) { - setName(spe.name); - } - if (!isDescOverride()) { - setDescription(spe.description); - } - if (!isDatatypeOverride()) { - final String dt = spe.datatype; - final String col = spe.collection; - - if (dt != null - && !dt.equalsIgnoreCase("null") - && (!hasDatatype() || !dt.equalsIgnoreCase(getDatatype().toString()))) { - if (col != null && !col.equalsIgnoreCase("null")) { - this.setDatatype(AbstractCollectionDatatype.collectionDatatypeFactory(col, dt)); - } else { - this.setDatatype(dt); - } - } - } - - if (spe.filePath != null) { - setFileProperties(new FileProperties(spe.fileHash, spe.filePath, spe.fileSize)); - } else { - setFileProperties(null); - } - - return this; - } -} diff --git a/src/main/java/caosdb/server/entity/xml/EntityToElementStrategy.java b/src/main/java/caosdb/server/entity/xml/EntityToElementStrategy.java deleted file mode 100644 index 19bfe80c6b5a35b8cc214ffb6c260294633b8495..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/entity/xml/EntityToElementStrategy.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * 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 <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package caosdb.server.entity.xml; - -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.Message; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.TransactionLogMessage; -import java.util.Comparator; -import org.apache.shiro.SecurityUtils; -import org.jdom2.Content; -import org.jdom2.Content.CType; -import org.jdom2.Element; - -public class EntityToElementStrategy implements ToElementStrategy { - - private final String tagName; - - public EntityToElementStrategy(final String tagName) { - this.tagName = tagName; - } - - public static Element sparseEntityToElement( - final String tagName, final EntityInterface entity, final SetFieldStrategy setFieldStrategy) { - final Element element = new Element(tagName); - - if (entity.getEntityACL() != null) { - element.addContent(entity.getEntityACL().getPermissionsFor(SecurityUtils.getSubject())); - } - if (setFieldStrategy.isToBeSet("id") && entity.hasId()) { - element.setAttribute("id", Integer.toString(entity.getId())); - } - if (setFieldStrategy.isToBeSet("cuid") && entity.hasCuid()) { - element.setAttribute("cuid", entity.getCuid()); - } - if (setFieldStrategy.isToBeSet("name") && entity.hasName()) { - element.setAttribute("name", entity.getName()); - } - if (setFieldStrategy.isToBeSet("description") && entity.hasDescription()) { - element.setAttribute("description", entity.getDescription()); - } - if (setFieldStrategy.isToBeSet("datatype") && entity.hasDatatype()) { - if (entity.getDatatype().getName() != null) { - element.setAttribute("datatype", entity.getDatatype().getName()); - } else { - element.setAttribute("datatype", entity.getDatatype().getId().toString()); - } - } - if (setFieldStrategy.isToBeSet("message") && entity.hasMessages()) { - for (final ToElementable m : entity.getMessages()) { - m.addToElement(element); - } - } - if (setFieldStrategy.isToBeSet("query") && entity.getQueryTemplateDefinition() != null) { - final Element q = new Element("Query"); - q.setText(entity.getQueryTemplateDefinition()); - element.addContent(q); - } - - return element; - } - - @Override - public Element toElement(final EntityInterface entity, final SetFieldStrategy setFieldStrategy) { - final Element element = sparseEntityToElement(this.tagName, entity, setFieldStrategy); - - if (setFieldStrategy.isToBeSet("importance") && entity.hasStatementStatus()) { - element.setAttribute("importance", entity.getStatementStatus().toString()); - } - if (setFieldStrategy.isToBeSet("parent") && entity.hasParents()) { - entity.getParents().addToElement(element); - } - if (entity.hasProperties()) { - entity.getProperties().addToElement(element, setFieldStrategy); - } - if (setFieldStrategy.isToBeSet("history") && entity.hasTransactionLogMessages()) { - for (final TransactionLogMessage t : entity.getTransactionLogMessages()) { - t.xmlAppendTo(element); - } - } - if (setFieldStrategy.isToBeSet("value") && entity.hasValue()) { - if (entity.hasDatatype()) { - try { - - entity.getDatatype().parseValue(entity.getValue()).addToElement(element); - } catch (final Message e) { - // - } - } else { - entity.getValue().addToElement(element); - } - // put value at first position - element.sortContent( - new Comparator<Content>() { - - @Override - public int compare(final Content o1, final Content o2) { - if (o1.getCType() == CType.CDATA || o1.getCType() == CType.Text) { - return -1; - } - if (o2.getCType() == CType.CDATA || o2.getCType() == CType.Text) { - return 1; - } - return 0; - } - }); - } - return element; - } - - @Override - public Element addToElement( - final EntityInterface entity, final Element parent, final SetFieldStrategy setFieldStrategy) { - if (entity.getEntityStatus() != EntityStatus.IGNORE) { - parent.addContent(toElement(entity, setFieldStrategy)); - } - return parent; - } -} diff --git a/src/main/java/caosdb/server/grpc/EntityTransactionImpl.java b/src/main/java/caosdb/server/grpc/EntityTransactionImpl.java deleted file mode 100644 index 70f5b0c589d44c0b28a4941d89becd3decd7c292..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/grpc/EntityTransactionImpl.java +++ /dev/null @@ -1,19 +0,0 @@ -package caosdb.server.grpc; - -import caosdb.grpc.Entity; -import caosdb.grpc.EntityTransactionServiceGrpc.EntityTransactionServiceImplBase; -import io.grpc.stub.StreamObserver; - -public class EntityTransactionImpl extends EntityTransactionServiceImplBase { - - @Override - public void retrieve(Entity request, StreamObserver<Entity> responseObserver) { - Entity response = Entity.newBuilder(request) - .setName("EntityName") - .setDescription("EntityDescription") - .build(); - - responseObserver.onNext(response); - responseObserver.onCompleted(); - } -} diff --git a/src/main/java/caosdb/server/jobs/extension/AWIBoxLoan.java b/src/main/java/caosdb/server/jobs/extension/AWIBoxLoan.java deleted file mode 100644 index 30dd77e0c0fc7f97f85db7d45c00cf762badc695..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/jobs/extension/AWIBoxLoan.java +++ /dev/null @@ -1,562 +0,0 @@ -package caosdb.server.jobs.extension; - -import static caosdb.server.permissions.Role.ANONYMOUS_ROLE; - -import caosdb.server.accessControl.UserSources; -import caosdb.server.database.exceptions.EntityDoesNotExistException; -import caosdb.server.datatype.SingleValue; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.Message; -import caosdb.server.entity.Message.MessageType; -import caosdb.server.entity.wrapper.Property; -import caosdb.server.jobs.JobAnnotation; -import caosdb.server.jobs.core.CheckPropValid; -import caosdb.server.permissions.EntityACL; -import caosdb.server.permissions.EntityACLFactory; -import caosdb.server.permissions.EntityPermission; -import caosdb.server.query.Query; -import caosdb.server.transaction.Delete; -import caosdb.server.transaction.Insert; -import caosdb.server.transaction.Update; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; -import caosdb.server.utils.Utils; -import java.util.Iterator; -import java.util.List; -import java.util.Objects; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@JobAnnotation(transaction = caosdb.server.transaction.WriteTransaction.class, loadAlways = true) -public class AWIBoxLoan extends AWIBoxLoanModel { - - public Logger logger = LoggerFactory.getLogger(getClass()); - private static final Message UNIQUE_USER = - new Message("The user must have a unique combination of first name and last name!"); - private static final Message BOX_HAS_LOAN = - new Message( - "This box cannot be be requested right now because it appears to have a Loan property attached to it. This usually means, that the box is already requested or borrowed by someone."); - - @Override - protected void run() { - try { - if (isAnonymous() - && (getTransaction() instanceof Delete - || isAcceptBorrowUpdateLoan() - || isConfirmLoanUpdateLoan() - || isRejectReturnUpdateLoan() - || isAcceptReturnUpdateLoan() - || isManualReturnUpdateBox() - || isManualReturnUpdateLoan() - || !(isRequestLoanSetUser() - || isRequestLoanInsertLoan() - || isRequestLoanUpdateBox() - || isRequestReturnSetUser() - || isRequestReturnUpdateLoan()))) { - addError(ServerMessages.AUTHORIZATION_ERROR); - getContainer() - .addMessage( - new Message(MessageType.Info, 0, "Anonymous users have restricted permissions.")); - return; - } - } catch (EntityDoesNotExistException exc) { - addError(ServerMessages.AUTHORIZATION_ERROR); - getContainer() - .addMessage( - new Message(MessageType.Info, 0, "Anonymous users have restricted permissions.")); - return; - } - - try { - if (!(getTransaction() instanceof Delete - || isRequestLoanSetUser() - || isRequestLoanInsertLoan() - || isManualReturnUpdateLoan() - || isManualReturnUpdateBox() - || isRequestLoanUpdateBox() - || isAcceptBorrowUpdateLoan() - || isConfirmLoanUpdateLoan() - || isRequestReturnSetUser() - || isRequestReturnUpdateLoan() - || isRejectReturnUpdateLoan())) { - isAcceptReturnUpdateLoan(); - } - } catch (EntityDoesNotExistException exc) { - // ignore - } - - // special ACL for boxes, loans and persons - try { - if (getTransaction() instanceof Insert) { - for (EntityInterface e : getContainer()) { - if (isBoxRecord(e)) { - e.setEntityACL(EntityACL.combine(e.getEntityACL(), getBoxACL())); - } else if (isLoanRecord(e)) { - e.setEntityACL(EntityACL.combine(e.getEntityACL(), getLoanACL())); - } else if (isPersonRecord(e)) { - e.setEntityACL(EntityACL.combine(e.getEntityACL(), getPersonACL())); - } - } - } - } catch (EntityDoesNotExistException e) { - } - } - - boolean isManualReturnUpdateLoan() { - for (EntityInterface e : getContainer()) { - if (!isLoanRecord(e) || !hasManualReturnLoanProperties(e)) { - logger.trace("isManualReturnUpdateLoan: false"); - return false; - } - } - for (EntityInterface e : getContainer()) { - removeAnonymousPermissions(e); - } - logger.trace("isManualReturnUpdateLoan: true"); - return true; - } - - boolean hasManualReturnLoanProperties(EntityInterface e) { - for (Property p : e.getProperties()) { - if (isReturnedProperty(p)) { - return true; - } - } - return false; - } - - boolean isReturnedProperty(Property p) { - return Objects.equals(p.getId(), getReturnedId()); - } - - void removeAnonymousPermissions(EntityInterface e) { - EntityACLFactory f = new EntityACLFactory(); - f.deny(ANONYMOUS_ROLE, false, EntityPermission.UPDATE_ADD_PROPERTY); - f.deny(ANONYMOUS_ROLE, false, EntityPermission.UPDATE_REMOVE_PROPERTY); - e.setEntityACL(EntityACL.combine(e.getEntityACL(), f.create())); - } - - boolean isManualReturnUpdateBox() { - for (EntityInterface e : getContainer()) { - if (!isBoxRecord(e) || !hasManualReturnBoxProperties(e)) { - logger.trace("isManualReturnUpdateBox: false"); - return false; - } - } - logger.trace("isManualReturnUpdateBox: true"); - return true; - } - - boolean hasManualReturnBoxProperties(EntityInterface e) { - return validBoxHasLoanProperty(e) && boxLoanHasReturnedProperty(e); - } - - boolean boxLoanHasReturnedProperty(EntityInterface e) { - try { - EntityInterface validBox = retrieveValidEntity(e.getId()); - - for (Property p : validBox.getProperties()) { - if (isLoanProperty(p)) { - return validLoanHasReturnedProperty(p.getId()); - } - } - } catch (EntityDoesNotExistException exc) { - return false; - } - return false; - } - - boolean validLoanHasReturnedProperty(Integer id) { - try { - EntityInterface validLoan = retrieveValidEntity(id); - for (Property p : validLoan.getProperties()) { - if (isReturnedProperty(p)) { - return true; - } - } - } catch (EntityDoesNotExistException exc) { - return false; - } - return false; - } - - boolean isLoanProperty(Property p) { - return Objects.equals(p.getId(), getLoanId()); - } - - private boolean isRejectReturnUpdateLoan() { - for (EntityInterface e : getContainer()) { - if (!isLoanRecord(e) || !hasRejectReturnProperties(e)) { - logger.trace("isRejectReturnUpdateLoan: false"); - return false; - } - } - for (EntityInterface e : getContainer()) { - removeDestinationProperty(e); - } - logger.trace("isRejectReturnUpdateLoan: true"); - return true; - } - - void removeDestinationProperty(EntityInterface e) { - Iterator<Property> iterator = e.getProperties().iterator(); - while (iterator.hasNext()) { - Property p = iterator.next(); - if (isDestinationProperty(p)) { - iterator.remove(); - } - } - } - - boolean hasRejectReturnProperties(EntityInterface e) { - boolean found = false; - for (Property p : e.getProperties()) { - if (isDestinationProperty(p)) { - found = true; - } else if (isReturnAcceptedProperty(p) || isReturnRequestProperty(p)) { - logger.trace("hasRejectReturnProperties: false"); - return false; - } - } - logger.trace("hasRejectReturnProperties found: {}", found); - return found; - } - - boolean isDestinationProperty(Property p) { - return Objects.equals(p.getId(), getDestinationId()); - } - - boolean isAcceptReturnUpdateLoan() { - for (EntityInterface e : getContainer()) { - if (!isLoanRecord(e) || !hasAcceptReturnProperties(e)) { - logger.trace("isAcceptReturnUpdateLoan: false"); - return false; - } - } - logger.trace("isAcceptReturnUpdateLoan: true"); - return true; - } - - boolean hasAcceptReturnProperties(EntityInterface e) { - boolean found = false; - for (Property p : e.getProperties()) { - if (isReturnAcceptedProperty(p)) { - found = true; - } - } - return found; - } - - boolean isConfirmLoanUpdateLoan() { - for (EntityInterface e : getContainer()) { - if (!isLoanRecord(e) || !hasConfirmLoanProperties(e)) { - logger.trace("isConfirmLoanUpdateLoan: false"); - return false; - } - } - // switch from destination to location - for (EntityInterface e : getContainer()) { - switchDestinationToLocation(e); - } - logger.trace("isConfirmLoanUpdateLoan: true"); - return true; - } - - void switchDestinationToLocation(EntityInterface e) { - Iterator<Property> iterator = e.getProperties().iterator(); - EntityInterface p = retrieveValidEntity(getLocationId()); - while (iterator.hasNext()) { - Property next = iterator.next(); - if (isDestinationProperty(next)) { - iterator.remove(); - p.setValue(next.getValue()); - e.addProperty(new Property(p)); - break; - } - } - } - - boolean hasConfirmLoanProperties(EntityInterface e) { - boolean found = false; - for (Property p : e.getProperties()) { - if (isLentProperty(p)) { - found = true; - } else if (isReturnAcceptedProperty(p) || isDestinationProperty(p)) { - logger.trace("hasConfirmLoanProperties: false"); - return false; - } - } - logger.trace("hasConfirmLoanProperties found: {}", found); - return found; - } - - boolean isAcceptBorrowUpdateLoan() { - for (EntityInterface e : getContainer()) { - if (!isLoanRecord(e) || !hasLoanAcceptProperties(e)) { - logger.trace("isAcceptBorrowUpdateLoan: false"); - return false; - } - } - logger.trace("isAcceptBorrowUpdateLoan: true"); - return true; - } - - boolean hasLoanAcceptProperties(EntityInterface e) { - boolean found = false; - for (Property p : e.getProperties()) { - if (isLoanAcceptProperty(p)) { - found = true; - } else if (isLentProperty(p) || isReturnAcceptedProperty(p)) { - logger.trace("hasLoanAcceptProperties: false"); - return false; - } - } - logger.trace("hasLoanAcceptProperties found: {}", found); - return found; - } - - boolean isReturnAcceptedProperty(Property p) { - return Objects.equals(p.getId(), getReturnAcceptedId()); - } - - boolean isLentProperty(Property p) { - return Objects.equals(p.getId(), getLentId()); - } - - boolean isLoanAcceptProperty(Property p) { - return Objects.equals(p.getId(), getLoanAcceptedId()); - } - - EntityACL getPersonACL() { - // same as loan acl - property updates are allowed for anonymous. - return getLoanACL(); - } - - EntityACL getLoanACL() { - EntityACLFactory f = new EntityACLFactory(); - f.grant(ANONYMOUS_ROLE, false, EntityPermission.UPDATE_ADD_PROPERTY); - f.grant(ANONYMOUS_ROLE, false, EntityPermission.UPDATE_REMOVE_PROPERTY); - return f.create(); - } - - EntityACL getBoxACL() { - EntityACLFactory f = new EntityACLFactory(); - f.grant(ANONYMOUS_ROLE, false, EntityPermission.UPDATE_ADD_PROPERTY); - f.grant(ANONYMOUS_ROLE, false, EntityPermission.UPDATE_REMOVE_PROPERTY); - return f.create(); - } - - boolean isAnonymous() { - boolean ret = getUser().hasRole(UserSources.ANONYMOUS_ROLE); - logger.trace("is Anonymous: {}", ret); - return ret; - } - - boolean isRequestReturnUpdateLoan() { - // is UPDATE transaction - if (getTransaction() instanceof Update) { - // Container has only loan elements with special properties - for (EntityInterface e : getContainer()) { - if (!isLoanRecord(e) || !hasOnlyAllowedLoanProperties4RequestReturn(e)) { - logger.trace("isRequestReturnUpdateLoan: false"); - return false; - } - setReturnRequestedDate(e); - } - appendJob(AWIBoxLoanRequestReturnCuratorEmail.class); - logger.trace("isRequestReturnUpdateLoan: true"); - return true; - } - logger.trace("isRequestReturnUpdateLoan: false"); - return false; - } - - boolean isRequestReturnSetUser() { - // same as request_loan.set_user - logger.trace("isRequestReturnSetUser: ->"); - return isRequestLoanSetUser(); - } - - boolean isRequestLoanUpdateBox() { - // is UPDATE transaction - if (getTransaction() instanceof Update) { - // Container has only box elements - for (EntityInterface e : getContainer()) { - if (validBoxHasLoanProperty(e)) { - e.addError(BOX_HAS_LOAN); - return false; - } - if (!isBoxRecord(e) || !hasOnlyAllowedBoxProperties4RequestLoan(e)) { - return false; - } - // TODO this breaks the box loan functionality if any other prior changes have been made to - // the box - // appendJob(e, CheckNoAdditionalPropertiesPresent.class); - } - return true; - } - return false; - } - - boolean validBoxHasLoanProperty(EntityInterface e) { - try { - EntityInterface validBox = retrieveValidEntity(e.getId()); - for (Property p : validBox.getProperties()) { - if (isLoanProperty(p)) { - return true; - } - } - } catch (EntityDoesNotExistException exc) { - return false; - } - return false; - } - - /** Has only one new property -> Loan. */ - boolean hasOnlyAllowedBoxProperties4RequestLoan(EntityInterface e) { - int count = 0; - for (Property p : e.getProperties()) { - if (p.getEntityStatus() == EntityStatus.QUALIFIED && Objects.equals(p.getId(), getLoanId())) { - count++; - } - } - - // Box has only one update, a loan property - return count == 1; - } - - boolean isRequestLoanInsertLoan() { - // is INSERT transaction - if (getTransaction() instanceof Insert) { - // Container has only loan elements - for (EntityInterface e : getContainer()) { - if (!isLoanRecord(e)) { - return false; - } - } - for (EntityInterface e : getContainer()) { - if (isAnonymous()) { - setCuratorAsOwner(e); - } - setLoanRequestDate(e); - // TODO this check breaks the box loan functionality if any other changes have been made to - // the box entity - // appendJob(e, CheckNoAdditionalPropertiesPresent.class); - // appendJob(e, CheckNoOverridesPresent.class); - } - appendJob(AWIBoxLoanRequestLoanCuratorEmail.class); - return true; - } - return false; - } - - void setCuratorAsOwner(EntityInterface e) { - e.setEntityACL(EntityACL.getOwnerACLFor(caosdb.server.permissions.Role.create("curator"))); - } - - void setReturnRequestedDate(EntityInterface e) { - // TODO setDateProperty(e, getReturnRequestedId()); - } - - private void setDateProperty(EntityInterface e, Integer propertyId) { - // TODO - EntityInterface p = retrieveValidEntity(propertyId); - p.setValue(getTransaction().getTimestamp()); - e.addProperty(new Property(p)); - } - - void setLoanRequestDate(EntityInterface e) { - // TODO setDateProperty(e, getLoanRequestedId()); - } - - boolean isRequestLoanSetUser() { - // is INSERT/UPDATE transaction - // Container has only one element, user - if ((getTransaction() instanceof Update || getTransaction() instanceof Insert) - && getContainer().size() == 1 - && isPersonRecord(getContainer().get(0)) - && checkUniqueName(getContainer().get(0)) - && checkEmail(getContainer().get(0))) { - // TODO this check breaks the box loan functionality if any other changes have been made to - // the box entity - // appendJob(getContainer().get(0), CheckNoAdditionalPropertiesPresent.class); - // appendJob(getContainer().get(0), CheckNoOverridesPresent.class); - logger.trace("isRequestReturnSetUser: true"); - return true; - } - logger.trace("isRequestReturnSetUser: false"); - return false; - } - - boolean checkEmail(EntityInterface entity) { - runJobFromSchedule(entity, CheckPropValid.class); - for (Property p : entity.getProperties()) { - if (Objects.equals(p.getId(), getEmailID()) && p.getValue() instanceof SingleValue) { - if (!Utils.isRFC822Compliant(((SingleValue) p.getValue()).toDatabaseString())) { - p.addError(ServerMessages.EMAIL_NOT_WELL_FORMED); - } else { - p.setName("email"); // TODO fix webinterface to use lower-case email - p.setNameOverride(false); - } - return true; - } - } - return false; - } - - private boolean checkUniqueName(EntityInterface entity) { - String firstName = null; - String lastName = null; - Query q = - new Query( - "FIND " - + getPersonID().toString() - + " WITH " - + getFirstNameId().toString() - + "='" - + firstName - + "' AND " - + getLastNameId().toString() - + "='" - + lastName - + "'", - getUser()) - .execute(getTransaction().getAccess()); - List<Integer> resultSet = q.getResultSet(); - if (resultSet.isEmpty() - || (resultSet.size() == 1 && Objects.equals(resultSet.get(0), entity.getId()))) { - return true; - } - entity.addError(UNIQUE_USER); - return false; - } - - /** - * Has only 5/6 new/updated properties: content, returnRequested, destination, Borrower, comment - * (optional), location - * - * @throws Message - */ - boolean hasOnlyAllowedLoanProperties4RequestReturn(EntityInterface e) { - runJobFromSchedule(e, CheckPropValid.class); - // appendJob(e, CheckNoOverridesPresent.class); - - boolean foundReturnRequested = false; - for (Property p : e.getProperties()) { - if (p.getEntityStatus() == EntityStatus.QUALIFIED) { // this means update - if (isReturnRequestProperty(p)) { - foundReturnRequested = true; - } else if (isReturnAcceptedProperty(p) || isReturnedProperty(p)) { - logger.trace("hasOnlyAllowedLoanProperties4RequestReturn: false"); - return false; // this is not a returnRequest, return has already been accepted - } - } - } - logger.trace("hasOnlyAllowedLoanProperties4RequestReturn found: {}", foundReturnRequested); - return foundReturnRequested; - } - - boolean isReturnRequestProperty(Property p) { - return Objects.equals(p.getId(), getReturnRequestedId()); - } -} diff --git a/src/main/java/caosdb/server/jobs/extension/AWIBoxLoanCuratorEmail.java b/src/main/java/caosdb/server/jobs/extension/AWIBoxLoanCuratorEmail.java deleted file mode 100644 index 2bf51e76e7357839ee0c52d28caa18017691849f..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/jobs/extension/AWIBoxLoanCuratorEmail.java +++ /dev/null @@ -1,92 +0,0 @@ -package caosdb.server.jobs.extension; - -import caosdb.datetime.DateTimeInterface; -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; -import caosdb.server.datatype.ReferenceValue; -import caosdb.server.datatype.SingleValue; -import caosdb.server.datatype.Value; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.wrapper.Property; -import caosdb.server.utils.mail.Mail; -import java.util.TimeZone; - -public abstract class AWIBoxLoanCuratorEmail extends AWIBoxLoanModel { - - public static final String KEY_EXT_AWI_CURATOR_EMAIL = "EXT_AWI_BOX_CURATOR_EMAIL"; - protected static final String FROM_EMAIL = - CaosDBServer.getServerProperty(ServerProperties.KEY_NO_REPLY_EMAIL); - protected static final String FROM_NAME = - CaosDBServer.getServerProperty(ServerProperties.KEY_NO_REPLY_NAME); - protected static final String CURATOR_EMAIL = - CaosDBServer.getServerProperty(KEY_EXT_AWI_CURATOR_EMAIL); - - protected String loanToString(EntityInterface e) { - StringBuilder s = new StringBuilder(); - for (Property p : e.getProperties()) { - s.append("\n"); - s.append(p.getName()); - s.append(": "); - if (p.getValue() instanceof ReferenceValue) { - Integer id = ((ReferenceValue) p.getValue()).getId(); - if (isBorrowerProperty(p)) { - s.append(borrowerToString(id)); - } else if (isBoxProperty(p)) { - s.append(boxToString(id)); - } else { - s.append(valueToString(p.getValue())); - } - } else { - s.append(valueToString(p.getValue())); - } - } - return s.toString(); - } - - private String valueToString(Value value) { - if (value == null) { - return ""; - } - if (value instanceof DateTimeInterface) { - return ((DateTimeInterface) value).toDateTimeString(TimeZone.getDefault()); - } - if (value instanceof SingleValue) { - return ((SingleValue) value).toDatabaseString(); - } else { - return value.toString(); - } - } - - private String boxToString(Integer id) { - StringBuilder s = new StringBuilder(); - EntityInterface box = retrieveValidEntity(id); - for (Property sp : box.getProperties()) { - if (isNumberProperty(sp) || isContentProperty(sp) || isLocationProperty(sp)) { - s.append("\n "); - s.append(sp.getName()); - s.append(": "); - s.append(valueToString(sp.getValue())); - } - } - return s.toString(); - } - - private String borrowerToString(Integer id) { - StringBuilder s = new StringBuilder(); - EntityInterface borrower = retrieveValidEntity(id); - for (Property sp : borrower.getProperties()) { - s.append("\n "); - s.append(sp.getName()); - s.append(": "); - s.append(valueToString(sp.getValue())); - } - return s.toString(); - } - - protected void sendCuratorEmail(String body, String subject) { - for (String addr : CURATOR_EMAIL.split(" ")) { - Mail m = new Mail(FROM_NAME, FROM_EMAIL, null, addr, subject, body); - m.send(); - } - } -} diff --git a/src/main/java/caosdb/server/jobs/extension/AWIBoxLoanModel.java b/src/main/java/caosdb/server/jobs/extension/AWIBoxLoanModel.java deleted file mode 100644 index 92a8a240363cf8659e0d3526dec1c5fcac8ddd11..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/jobs/extension/AWIBoxLoanModel.java +++ /dev/null @@ -1,154 +0,0 @@ -package caosdb.server.jobs.extension; - -import caosdb.server.CaosDBServer; -import caosdb.server.database.exceptions.EntityDoesNotExistException; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.Role; -import caosdb.server.entity.wrapper.Property; -import caosdb.server.jobs.ContainerJob; -import caosdb.server.utils.Utils; -import java.util.Objects; - -public abstract class AWIBoxLoanModel extends ContainerJob { - - /** Is Record and has single user parent. */ - boolean isPersonRecord(EntityInterface entity) { - try { - return entity.getParents().size() == 1 - && Objects.equals( - retrieveValidIDByName(entity.getParents().get(0).getName()), getPersonID()); - } catch (EntityDoesNotExistException exc) { - return false; - } - } - - /** Is Record an has single box parent. */ - boolean isBoxRecord(EntityInterface e) { - return e.getRole() == Role.Record - && e.getParents().size() == 1 - && Objects.equals(e.getParents().get(0).getId(), getBoxId()); - } - - /** Is Record and has single loan parent */ - boolean isLoanRecord(EntityInterface e) { - try { - return e.getRole() == Role.Record - && e.getParents().size() == 1 - && Objects.equals(retrieveValidIDByName(e.getParents().get(0).getName()), getLoanId()); - } catch (EntityDoesNotExistException exc) { - return false; - } - } - - boolean isBoxProperty(Property p) { - return Objects.equals(p.getId(), getBoxId()); - } - - boolean isBorrowerProperty(Property p) { - return Objects.equals(p.getId(), getBorrowerId()); - } - - boolean isLocationProperty(Property p) { - return Objects.equals(p.getId(), getLocationId()); - } - - boolean isContentProperty(Property p) { - return Objects.equals(p.getId(), getContentId()); - } - - boolean isNumberProperty(Property p) { - return Objects.equals(p.getId(), getNumberId()); - } - - Integer getIdOf(String string) { - String id = CaosDBServer.getServerProperty("EXT_AWI_" + string.toUpperCase() + "_ID"); - if (id != null && Utils.isNonNullInteger(id)) { - return Integer.parseInt(id); - } - String name = CaosDBServer.getServerProperty("EXT_AWI_" + string.toUpperCase() + "_NAME"); - if (name == null || name.isEmpty()) { - name = string; - } - return retrieveValidIDByName(name); - } - - Integer getBorrowerId() { - return getIdOf("Borrower"); - } - - Integer getCommentId() { - return getIdOf("comment"); - } - - Integer getLocationId() { - return getIdOf("Location"); - } - - Integer getDestinationId() { - return getIdOf("destination"); - } - - Integer getContentId() { - return getIdOf("Content"); - } - - Integer getBoxId() { - return getIdOf("Box"); - } - - Integer getLoanId() { - return getIdOf("Loan"); - } - - Integer getPersonID() { - return getIdOf("Person"); - } - - Integer getEmailID() { - return getIdOf("email"); - } - - Integer getLoanAcceptedId() { - return getIdOf("loanAccepted"); - } - - Integer getReturnAcceptedId() { - return getIdOf("returnAccepted"); - } - - Integer getLentId() { - return getIdOf("lent"); - } - - Integer getLoanRequestedId() { - return getIdOf("loanRequested"); - } - - Integer getExhaustContentsId() { - return getIdOf("exhaustContents"); - } - - Integer getExpectedReturnId() { - return getIdOf("expectedReturn"); - } - - Integer getReturnRequestedId() { - return getIdOf("returnRequested"); - } - - Integer getLastNameId() { - return getIdOf("lastName"); - } - - Integer getFirstNameId() { - return getIdOf("firstName"); - } - - Integer getNumberId() { - return getIdOf("Number"); - } - - Integer getReturnedId() { - return getIdOf("returned"); - } -} diff --git a/src/main/java/caosdb/server/jobs/extension/AWIBoxLoanRequestLoanCuratorEmail.java b/src/main/java/caosdb/server/jobs/extension/AWIBoxLoanRequestLoanCuratorEmail.java deleted file mode 100644 index ff490e99a72e93b03b04a0134c81790b1a2a1bec..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/jobs/extension/AWIBoxLoanRequestLoanCuratorEmail.java +++ /dev/null @@ -1,24 +0,0 @@ -package caosdb.server.jobs.extension; - -import caosdb.server.entity.EntityInterface; -import caosdb.server.jobs.JobAnnotation; -import caosdb.server.jobs.JobExecutionTime; - -@JobAnnotation(time = JobExecutionTime.POST_TRANSACTION) -public class AWIBoxLoanRequestLoanCuratorEmail extends AWIBoxLoanCuratorEmail { - - private static final String SUBJECT = "Box Loan Requests"; - - @Override - protected void run() { - StringBuilder body = new StringBuilder("LOAN REQUEST(S):"); - - if (!getContainer().isEmpty()) { - for (EntityInterface e : getContainer()) { - body.append("\n"); - body.append(loanToString(e)); - } - this.sendCuratorEmail(body.toString(), SUBJECT); - } - } -} diff --git a/src/main/java/caosdb/server/jobs/extension/AWIBoxLoanRequestReturnCuratorEmail.java b/src/main/java/caosdb/server/jobs/extension/AWIBoxLoanRequestReturnCuratorEmail.java deleted file mode 100644 index 373ce0b8d10ef6db560decb6afcc3e7ab5aa71b3..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/jobs/extension/AWIBoxLoanRequestReturnCuratorEmail.java +++ /dev/null @@ -1,22 +0,0 @@ -package caosdb.server.jobs.extension; - -import caosdb.server.entity.EntityInterface; -import caosdb.server.jobs.JobAnnotation; -import caosdb.server.jobs.JobExecutionTime; - -@JobAnnotation(time = JobExecutionTime.POST_TRANSACTION) -public class AWIBoxLoanRequestReturnCuratorEmail extends AWIBoxLoanCuratorEmail { - private static final String SUBJECT = "Box Return Requests"; - - @Override - protected void run() { - if (!getContainer().isEmpty()) { - StringBuilder body = new StringBuilder("RETURN REQUEST(S):"); - for (EntityInterface e : getContainer()) { - body.append("\n"); - body.append(loanToString(e)); - } - this.sendCuratorEmail(body.toString(), SUBJECT); - } - } -} diff --git a/src/main/java/caosdb/server/jobs/extension/SQLiteTransaction.java b/src/main/java/caosdb/server/jobs/extension/SQLiteTransaction.java deleted file mode 100644 index 4882f0aff290cc53f80372f1451b538c664dae56..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/jobs/extension/SQLiteTransaction.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * 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 <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package caosdb.server.jobs.extension; - -import caosdb.server.CaosDBException; -import caosdb.server.entity.FileProperties; -import caosdb.server.entity.Message; -import caosdb.server.jobs.EntityJob; -import caosdb.server.utils.FileUtils; -import java.io.IOException; -import java.security.NoSuchAlgorithmException; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.concurrent.locks.ReentrantLock; - -public class SQLiteTransaction extends EntityJob { - private static HashMap<String, ReentrantLock> lockedTables = new HashMap<String, ReentrantLock>(); - - @SuppressWarnings("unlikely-arg-type") - @Override - public final void run() { - Connection con = null; - try { - if (getEntity().hasFileProperties()) { - if (getEntity().getFileProperties().retrieveFromFileSystem() != null) { - - if (getEntity().hasMessage("execute")) { - try { - if (!lockedTables.containsKey( - getEntity().getFileProperties().getFile().getCanonicalPath())) { - synchronized (lockedTables) { - lockedTables.put( - getEntity().getFileProperties().getFile().getCanonicalPath(), - new ReentrantLock()); - } - } - - lockedTables.get(getEntity().getFileProperties().getFile().getCanonicalPath()).lock(); - try { - con = - getConnection( - getEntity() - .getFileProperties() - .retrieveFromFileSystem() - .getCanonicalPath()); - final Statement stmt = con.createStatement(); - - // - final List<Message> msgs = getEntity().getMessages("execute"); - Collections.sort(msgs); - for (final Message m : msgs) { - getEntity().removeMessage(m); - stmt.execute(m.getBody()); - final ResultSet rs = stmt.getResultSet(); - final int updateCount = stmt.getUpdateCount(); - if (rs != null) { - final ResultSetMetaData rsmd = rs.getMetaData(); - final int columns = rsmd.getColumnCount(); - final StringBuilder s = new StringBuilder(); - if (columns > 0) { - s.append("|"); - for (int i = 1; i <= columns; i++) { - s.append(rsmd.getColumnName(i)); - s.append("|"); - } - s.append("\n"); - while (rs.next()) { - s.append("|"); - for (int i = 1; i <= columns; i++) { - s.append(rs.getString(i)); - s.append("|"); - } - s.append("\n"); - } - } else { - s.append(""); - } - final Message mret = new Message("result", m.getCode(), null, s.toString()); - getEntity().addMessage(mret); - - } else if (updateCount != -1) { - final Message mret = - new Message( - "result", - m.getCode(), - null, - Integer.toString(updateCount) + " row(s) affected by the query."); - getEntity().addMessage(mret); - } - } - } finally { - lockedTables - .get(getEntity().getFileProperties().getFile().getCanonicalPath()) - .unlock(); - } - synchronized ( - lockedTables.get(getEntity().getFileProperties().getFile().getCanonicalPath())) { - if (!lockedTables - .get(getEntity().getFileProperties().getFile().getCanonicalPath()) - .hasQueuedThreads()) { - lockedTables.remove( - lockedTables.get( - getEntity().getFileProperties().getFile().getCanonicalPath())); - } - } - } finally { - if (con != null && !con.isClosed()) { - con.close(); - } - resetSizeAndChecksum(getEntity().getFileProperties()); - } - } - } - } - } catch (final NoSuchAlgorithmException e) { - throw new JobException(this, e); - } catch (final IOException e) { - throw new JobException(this, e); - } catch (final CaosDBException e) { - throw new JobException(this, e); - } catch (final ClassNotFoundException e) { - throw new JobException(this, e); - } catch (final SQLException e) { - throw new JobException(this, e); - } - } - - private static void resetSizeAndChecksum(final FileProperties f) - throws NoSuchAlgorithmException, IOException { - f.setSize(f.getFile().length()); - f.setChecksum(FileUtils.getChecksum(f.getFile())); - } - - private static Connection getConnection(final String database) - throws ClassNotFoundException, SQLException { - if (!driverLoaded) { - Class.forName("org.sqlite.JDBC"); - driverLoaded = true; - } - final Connection connection = DriverManager.getConnection("jdbc:sqlite:" + database); - return connection; - } - - private static boolean driverLoaded = false; -} diff --git a/src/main/java/caosdb/server/resource/transaction/handlers/IDHandler.java b/src/main/java/caosdb/server/resource/transaction/handlers/IDHandler.java deleted file mode 100644 index e641ed416c86075d23a37d70ad791c26a820a966..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/resource/transaction/handlers/IDHandler.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * 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 <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package caosdb.server.resource.transaction.handlers; - -import caosdb.server.entity.container.EntityByIdContainer; -import caosdb.server.resource.transaction.EntityResource; - -public class IDHandler<T extends EntityByIdContainer> extends RequestHandler<T> { - - @Override - public void handle(final EntityResource t, final T container) throws Exception { - for (final int id : t.getRequestedIDs()) { - container.add(id); - } - } -} diff --git a/src/main/java/caosdb/server/scripting/ScriptingUtils.java b/src/main/java/caosdb/server/scripting/ScriptingUtils.java deleted file mode 100644 index cee65faf9b25d3b9bfe0b28cc508edf59626682c..0000000000000000000000000000000000000000 --- a/src/main/java/caosdb/server/scripting/ScriptingUtils.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * 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 <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package caosdb.server.scripting; - -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; -import caosdb.server.entity.Message; -import caosdb.server.utils.ConfigurationException; -import caosdb.server.utils.ServerMessages; -import caosdb.server.utils.Utils; -import java.io.File; -import java.nio.file.Path; - -public class ScriptingUtils { - - private File bin; - private File working; - - public ScriptingUtils() { - this.bin = - new File( - CaosDBServer.getServerProperty(ServerProperties.KEY_SERVER_SIDE_SCRIPTING_BIN_DIR)); - this.working = - new File( - CaosDBServer.getServerProperty(ServerProperties.KEY_SERVER_SIDE_SCRIPTING_WORKING_DIR)); - if (!bin.exists()) { - bin.mkdirs(); - } - if (!bin.isDirectory()) { - throw new ConfigurationException( - "The ServerProperty `" - + ServerProperties.KEY_SERVER_SIDE_SCRIPTING_BIN_DIR - + "` must point to a directory"); - } - - if (!working.exists()) { - working.mkdirs(); - } - if (!working.isDirectory()) { - throw new ConfigurationException( - "The ServerProperty `" - + ServerProperties.KEY_SERVER_SIDE_SCRIPTING_WORKING_DIR - + "` must point to a directory"); - } - } - - public File getScriptFile(final String command) { - final Path script = bin.toPath().resolve(command); - return script.toFile(); - } - - public void checkScriptExists(final String command) throws Message { - if (!getScriptFile(command).exists()) { - throw ServerMessages.SERVER_SIDE_SCRIPT_DOES_NOT_EXIST; - } - } - - public void checkScriptExecutable(final String command) throws Message { - if (!getScriptFile(command).canExecute()) { - throw ServerMessages.SERVER_SIDE_SCRIPT_NOT_EXECUTABLE; - } - } - - public File getTmpWorkingDir() { - String uid = Utils.getUID(); - return working.toPath().resolve(uid).toFile(); - } - - public File getStdOutFile(File workingDir) { - return workingDir.toPath().resolve(".STDOUT").toFile(); - } - - public File getStdErrFile(File workingDir) { - return workingDir.toPath().resolve(".STDERR").toFile(); - } -} diff --git a/src/main/java/caosdb/datetime/Date.java b/src/main/java/org/caosdb/datetime/Date.java similarity index 96% rename from src/main/java/caosdb/datetime/Date.java rename to src/main/java/org/caosdb/datetime/Date.java index b0d025df6382ef52cf18105aa5601fb4cda3c869..2b7aa522272f48b468dd8c4945360dee14f52d6e 100644 --- a/src/main/java/caosdb/datetime/Date.java +++ b/src/main/java/org/caosdb/datetime/Date.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.datetime; +package org.caosdb.datetime; -import caosdb.server.datatype.AbstractDatatype.Table; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.TimeZone; +import org.caosdb.server.datatype.AbstractDatatype.Table; import org.jdom2.Element; public class Date extends SemiCompleteDateTime { diff --git a/src/main/java/caosdb/datetime/DateTimeFactory2.java b/src/main/java/org/caosdb/datetime/DateTimeFactory2.java similarity index 97% rename from src/main/java/caosdb/datetime/DateTimeFactory2.java rename to src/main/java/org/caosdb/datetime/DateTimeFactory2.java index 40aa7473c1f0e0424243387be0871f4a900668b8..103359c7b4ff6f995996866e2283bab47562699c 100644 --- a/src/main/java/caosdb/datetime/DateTimeFactory2.java +++ b/src/main/java/org/caosdb/datetime/DateTimeFactory2.java @@ -20,15 +20,15 @@ * * ** end header */ -package caosdb.datetime; +package org.caosdb.datetime; -import caosdb.server.query.CQLParsingErrorListener; -import caosdb.server.query.CQLParsingErrorListener.ParsingError; import java.util.Arrays; import java.util.Calendar; import java.util.TimeZone; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; +import org.caosdb.server.query.CQLParsingErrorListener; +import org.caosdb.server.query.CQLParsingErrorListener.ParsingError; public class DateTimeFactory2 implements DateTimeFactoryInterface { diff --git a/src/main/java/caosdb/datetime/DateTimeFactoryInterface.java b/src/main/java/org/caosdb/datetime/DateTimeFactoryInterface.java similarity index 98% rename from src/main/java/caosdb/datetime/DateTimeFactoryInterface.java rename to src/main/java/org/caosdb/datetime/DateTimeFactoryInterface.java index 89ce60d338668bcf95aec207cd82f16a46d6d49b..c81018f939747344b6991e291d3439f164dad283 100644 --- a/src/main/java/caosdb/datetime/DateTimeFactoryInterface.java +++ b/src/main/java/org/caosdb/datetime/DateTimeFactoryInterface.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.datetime; +package org.caosdb.datetime; import java.util.Date; diff --git a/src/main/java/caosdb/datetime/DateTimeInterface.java b/src/main/java/org/caosdb/datetime/DateTimeInterface.java similarity index 93% rename from src/main/java/caosdb/datetime/DateTimeInterface.java rename to src/main/java/org/caosdb/datetime/DateTimeInterface.java index 33d508cc9ba698410914d74d1f8227d57bb1ded8..e6f1b93382da7deaf1ec1226d193fe1db4b3735d 100644 --- a/src/main/java/caosdb/datetime/DateTimeInterface.java +++ b/src/main/java/org/caosdb/datetime/DateTimeInterface.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.datetime; +package org.caosdb.datetime; -import caosdb.server.datatype.SingleValue; import java.util.TimeZone; +import org.caosdb.server.datatype.SingleValue; public interface DateTimeInterface extends SingleValue { diff --git a/src/main/java/caosdb/datetime/DateTimeLexer.g4 b/src/main/java/org/caosdb/datetime/DateTimeLexer.g4 similarity index 100% rename from src/main/java/caosdb/datetime/DateTimeLexer.g4 rename to src/main/java/org/caosdb/datetime/DateTimeLexer.g4 diff --git a/src/main/java/caosdb/datetime/DateTimeParser.g4 b/src/main/java/org/caosdb/datetime/DateTimeParser.g4 similarity index 100% rename from src/main/java/caosdb/datetime/DateTimeParser.g4 rename to src/main/java/org/caosdb/datetime/DateTimeParser.g4 diff --git a/src/main/java/caosdb/datetime/DateTimeStringStrategy.java b/src/main/java/org/caosdb/datetime/DateTimeStringStrategy.java similarity index 97% rename from src/main/java/caosdb/datetime/DateTimeStringStrategy.java rename to src/main/java/org/caosdb/datetime/DateTimeStringStrategy.java index 299a1b78a913a6abea3c8abcdec265eb78996cc4..635b2cfa0569e62847e8f4f2af0684c5919e8f8d 100644 --- a/src/main/java/caosdb/datetime/DateTimeStringStrategy.java +++ b/src/main/java/org/caosdb/datetime/DateTimeStringStrategy.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.datetime; +package org.caosdb.datetime; import java.util.TimeZone; diff --git a/src/main/java/caosdb/datetime/FragmentDateTime.java b/src/main/java/org/caosdb/datetime/FragmentDateTime.java similarity index 98% rename from src/main/java/caosdb/datetime/FragmentDateTime.java rename to src/main/java/org/caosdb/datetime/FragmentDateTime.java index 46bec5498284f842dbea83dcf41848d088d5d9bc..52faf5f2040de56c05bb7ce4b5aee130fadf67c3 100644 --- a/src/main/java/caosdb/datetime/FragmentDateTime.java +++ b/src/main/java/org/caosdb/datetime/FragmentDateTime.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.datetime; +package org.caosdb.datetime; import java.util.TimeZone; diff --git a/src/main/java/caosdb/datetime/GregorianCalendarDateTimeStringStrategy.java b/src/main/java/org/caosdb/datetime/GregorianCalendarDateTimeStringStrategy.java similarity index 98% rename from src/main/java/caosdb/datetime/GregorianCalendarDateTimeStringStrategy.java rename to src/main/java/org/caosdb/datetime/GregorianCalendarDateTimeStringStrategy.java index 22e83dc7070e1adf726af251a106c7d8b1ba7cab..459f1d592beca6b62704e9592c6afe39c1104f57 100644 --- a/src/main/java/caosdb/datetime/GregorianCalendarDateTimeStringStrategy.java +++ b/src/main/java/org/caosdb/datetime/GregorianCalendarDateTimeStringStrategy.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.datetime; +package org.caosdb.datetime; import java.text.SimpleDateFormat; import java.util.Calendar; diff --git a/src/main/java/caosdb/datetime/Interval.java b/src/main/java/org/caosdb/datetime/Interval.java similarity index 97% rename from src/main/java/caosdb/datetime/Interval.java rename to src/main/java/org/caosdb/datetime/Interval.java index 59a3915e53abf1b88f281359bd115d776125f47f..9890fb4c0643c498dc5e7d5108b9c9c4a13cc9b8 100644 --- a/src/main/java/caosdb/datetime/Interval.java +++ b/src/main/java/org/caosdb/datetime/Interval.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.datetime; +package org.caosdb.datetime; public interface Interval extends DateTimeInterface { diff --git a/src/main/java/caosdb/datetime/LeapSecondDateTimeStringStrategy.java b/src/main/java/org/caosdb/datetime/LeapSecondDateTimeStringStrategy.java similarity index 98% rename from src/main/java/caosdb/datetime/LeapSecondDateTimeStringStrategy.java rename to src/main/java/org/caosdb/datetime/LeapSecondDateTimeStringStrategy.java index 28beb7603ac798f1399b108fe87f1b729975a537..5aff2dce7979e32f595c4ec8bae12378239cc3dc 100644 --- a/src/main/java/caosdb/datetime/LeapSecondDateTimeStringStrategy.java +++ b/src/main/java/org/caosdb/datetime/LeapSecondDateTimeStringStrategy.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.datetime; +package org.caosdb.datetime; import java.text.SimpleDateFormat; import java.util.Calendar; diff --git a/src/main/java/caosdb/datetime/SemiCompleteDateTime.java b/src/main/java/org/caosdb/datetime/SemiCompleteDateTime.java similarity index 98% rename from src/main/java/caosdb/datetime/SemiCompleteDateTime.java rename to src/main/java/org/caosdb/datetime/SemiCompleteDateTime.java index 55a7f5d567f1ec5be9902135f45393699195d549..5bd4daca00dae6c70473b76147736e65dcc2da68 100644 --- a/src/main/java/caosdb/datetime/SemiCompleteDateTime.java +++ b/src/main/java/org/caosdb/datetime/SemiCompleteDateTime.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.datetime; +package org.caosdb.datetime; -import caosdb.server.datatype.AbstractDatatype.Table; import java.util.TimeZone; +import org.caosdb.server.datatype.AbstractDatatype.Table; import org.jdom2.Element; public class SemiCompleteDateTime extends FragmentDateTime implements Interval { diff --git a/src/main/java/caosdb/datetime/UTCDateTime.java b/src/main/java/org/caosdb/datetime/UTCDateTime.java similarity index 96% rename from src/main/java/caosdb/datetime/UTCDateTime.java rename to src/main/java/org/caosdb/datetime/UTCDateTime.java index 215de67befe403aa6a202ed178244b3de898d23e..0ecb3ac60dfe796692c344e590f3935c36fceac3 100644 --- a/src/main/java/caosdb/datetime/UTCDateTime.java +++ b/src/main/java/org/caosdb/datetime/UTCDateTime.java @@ -20,13 +20,13 @@ * * ** end header */ -package caosdb.datetime; +package org.caosdb.datetime; -import caosdb.server.datatype.AbstractDatatype.Table; import java.util.ArrayList; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.TimeZone; +import org.caosdb.server.datatype.AbstractDatatype.Table; import org.jdom2.Element; public class UTCDateTime implements Interval { @@ -296,7 +296,7 @@ public class UTCDateTime implements Interval { throw new NullPointerException("toString method!!!"); } - public static UTCDateTime UTCSeconds(final Long utcseconds, final Integer nanosecond) { + public static UTCDateTime UTCSeconds(final Long utcseconds, final Integer nanoseconds) { if (LEAP_SECONDS.isEmpty()) { initLeapSeconds(); } @@ -310,10 +310,10 @@ public class UTCDateTime implements Interval { if (leapSeconds2 != leapSeconds && LEAP_SECONDS.contains(systemSeconds)) { gc.add(Calendar.SECOND, -1); return new UTCDateTime( - systemSeconds, leapSeconds, nanosecond, new LeapSecondDateTimeStringStrategy(gc, 1)); + systemSeconds, leapSeconds, nanoseconds, new LeapSecondDateTimeStringStrategy(gc, 1)); } else { return new UTCDateTime( - systemSeconds, leapSeconds, nanosecond, new GregorianCalendarDateTimeStringStrategy(gc)); + systemSeconds, leapSeconds, nanoseconds, new GregorianCalendarDateTimeStringStrategy(gc)); } } diff --git a/src/main/java/caosdb/datetime/UTCTimeZoneShift.java b/src/main/java/org/caosdb/datetime/UTCTimeZoneShift.java similarity index 97% rename from src/main/java/caosdb/datetime/UTCTimeZoneShift.java rename to src/main/java/org/caosdb/datetime/UTCTimeZoneShift.java index a5930d7d72250749d351000343e92ee4b24a02ac..e4b9c3c1e29c0092b24d2b88fac4f06991e666e5 100644 --- a/src/main/java/caosdb/datetime/UTCTimeZoneShift.java +++ b/src/main/java/org/caosdb/datetime/UTCTimeZoneShift.java @@ -20,13 +20,13 @@ * * ** end header */ -package caosdb.datetime; +package org.caosdb.datetime; import java.util.Date; import java.util.TimeZone; public class UTCTimeZoneShift extends TimeZone { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 6962096078347188058L; public static final int POSITIVE = 1; public static final int NEGATIVE = -1; diff --git a/src/main/java/caosdb/server/CaosAuthenticator.java b/src/main/java/org/caosdb/server/CaosAuthenticator.java similarity index 60% rename from src/main/java/caosdb/server/CaosAuthenticator.java rename to src/main/java/org/caosdb/server/CaosAuthenticator.java index 25f112aa52050a0b872b2ff83e95400ad4bd925e..b26e50008e47fbf471e8721423aff9b583ce571a 100644 --- a/src/main/java/caosdb/server/CaosAuthenticator.java +++ b/src/main/java/org/caosdb/server/CaosAuthenticator.java @@ -20,15 +20,16 @@ * * ** end header */ -package caosdb.server; +package org.caosdb.server; -import caosdb.server.accessControl.AuthenticationUtils; -import caosdb.server.accessControl.OneTimeAuthenticationToken; -import caosdb.server.accessControl.SessionToken; -import caosdb.server.resource.DefaultResource; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.subject.Subject; +import org.caosdb.server.accessControl.AnonymousAuthenticationToken; +import org.caosdb.server.accessControl.AuthenticationUtils; +import org.caosdb.server.resource.DefaultResource; +import org.caosdb.server.utils.ServerMessages; import org.restlet.Context; import org.restlet.Request; import org.restlet.Response; @@ -48,50 +49,26 @@ public class CaosAuthenticator extends Authenticator { protected boolean authenticate(final Request request, final Response response) { final Subject subject = SecurityUtils.getSubject(); - return attemptOneTimeTokenLogin(subject, request) || attemptSessionValidation(subject, request); + return attemptSessionValidation(subject, request); } private static boolean attemptSessionValidation(final Subject subject, final Request request) { try { - final SessionToken sessionToken = + final AuthenticationToken sessionToken = AuthenticationUtils.parseSessionTokenCookie( - request.getCookies().getFirst(AuthenticationUtils.SESSION_TOKEN_COOKIE), null); + request.getCookies().getFirst(AuthenticationUtils.SESSION_TOKEN_COOKIE)); if (sessionToken != null) { subject.login(sessionToken); } - } catch (AuthenticationException e) { - logger.info("LOGIN_FAILED", e); - } - // anonymous users - if (!subject.isAuthenticated() - && CaosDBServer.getServerProperty(ServerProperties.KEY_AUTH_OPTIONAL) - .equalsIgnoreCase("TRUE")) { - subject.login(AuthenticationUtils.ANONYMOUS_USER); - } - return subject.isAuthenticated(); - } - private static boolean attemptOneTimeTokenLogin(final Subject subject, final Request request) { - try { - OneTimeAuthenticationToken oneTimeToken = null; - - // try and parse from the query segment of the uri - oneTimeToken = - AuthenticationUtils.parseOneTimeTokenQuerySegment( - request.getResourceRef().getQueryAsForm().getFirstValue("AuthToken"), null); - - // try and parse from cookie - if (oneTimeToken == null) { - oneTimeToken = - AuthenticationUtils.parseOneTimeTokenCookie( - request.getCookies().getFirst(AuthenticationUtils.ONE_TIME_TOKEN_COOKIE), null); + // anonymous users + if (!subject.isAuthenticated() + && CaosDBServer.getServerProperty(ServerProperties.KEY_AUTH_OPTIONAL) + .equalsIgnoreCase("TRUE")) { + subject.login(AnonymousAuthenticationToken.getInstance()); } - - if (oneTimeToken != null) { - subject.login(oneTimeToken); - } - } catch (final AuthenticationException e) { + } catch (AuthenticationException e) { logger.info("LOGIN_FAILED", e); } return subject.isAuthenticated(); @@ -100,7 +77,7 @@ public class CaosAuthenticator extends Authenticator { @Override protected int unauthenticated(final Request request, final Response response) { final DefaultResource defaultResource = - new DefaultResource(AuthenticationUtils.UNAUTHENTICATED.toElement()); + new DefaultResource(ServerMessages.UNAUTHENTICATED.toElement()); defaultResource.init(getContext(), request, response); defaultResource.handle(); response.setStatus(org.restlet.data.Status.CLIENT_ERROR_UNAUTHORIZED); diff --git a/src/main/java/caosdb/server/CaosAuthorizer.java b/src/main/java/org/caosdb/server/CaosAuthorizer.java similarity index 92% rename from src/main/java/caosdb/server/CaosAuthorizer.java rename to src/main/java/org/caosdb/server/CaosAuthorizer.java index 7b0e0194b8aeb2e5f7a33e0e6be8d2ff52afaf6e..58e814a374ae2d7c5018d041b23eb4fdafa39ef0 100644 --- a/src/main/java/caosdb/server/CaosAuthorizer.java +++ b/src/main/java/org/caosdb/server/CaosAuthorizer.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server; +package org.caosdb.server; -import caosdb.server.resource.DefaultResource; -import caosdb.server.utils.ServerMessages; +import org.caosdb.server.resource.DefaultResource; +import org.caosdb.server.utils.ServerMessages; import org.restlet.Request; import org.restlet.Response; import org.restlet.security.Authorizer; diff --git a/src/main/java/caosdb/server/CaosDBException.java b/src/main/java/org/caosdb/server/CaosDBException.java similarity index 91% rename from src/main/java/caosdb/server/CaosDBException.java rename to src/main/java/org/caosdb/server/CaosDBException.java index 3e0e50769cd3f08423ea83fa851b2cdfca54e50f..617dfdff95d17ffc15d24bdec2497902eab495a7 100644 --- a/src/main/java/caosdb/server/CaosDBException.java +++ b/src/main/java/org/caosdb/server/CaosDBException.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server; +package org.caosdb.server; public class CaosDBException extends RuntimeException { - private static final long serialVersionUID = 5317733089121727021L; + private static final long serialVersionUID = -6679522664294087311L; public CaosDBException(final String string) { super(string); diff --git a/src/main/java/caosdb/server/CaosDBServer.java b/src/main/java/org/caosdb/server/CaosDBServer.java similarity index 82% rename from src/main/java/caosdb/server/CaosDBServer.java rename to src/main/java/org/caosdb/server/CaosDBServer.java index 2beabb789a3e5771502a422e1064e3cc060256b3..cfe9ff141d3f1ef06e665e36936446c8234e27c5 100644 --- a/src/main/java/caosdb/server/CaosDBServer.java +++ b/src/main/java/org/caosdb/server/CaosDBServer.java @@ -17,7 +17,7 @@ * * ** end header */ -package caosdb.server; +package org.caosdb.server; import java.io.BufferedReader; import java.io.FileNotFoundException; @@ -29,17 +29,64 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Properties; import java.util.TimeZone; +import java.util.UUID; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.LogRecord; import org.apache.shiro.SecurityUtils; import org.apache.shiro.config.Ini; import org.apache.shiro.config.Ini.Section; -import org.apache.shiro.config.IniSecurityManagerFactory; +import org.apache.shiro.env.BasicIniEnvironment; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.subject.Subject; -import org.apache.shiro.util.Factory; import org.apache.shiro.util.ThreadContext; +import org.caosdb.server.accessControl.AnonymousAuthenticationToken; +import org.caosdb.server.accessControl.AnonymousRealm; +import org.caosdb.server.accessControl.AuthenticationUtils; +import org.caosdb.server.accessControl.CaosDBAuthorizingRealm; +import org.caosdb.server.accessControl.CaosDBDefaultRealm; +import org.caosdb.server.accessControl.ConsumedInfoCleanupJob; +import org.caosdb.server.accessControl.OneTimeAuthenticationToken; +import org.caosdb.server.accessControl.SessionToken; +import org.caosdb.server.accessControl.SessionTokenRealm; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.transaction.RetrieveDatatypes; +import org.caosdb.server.database.misc.TransactionBenchmark; +import org.caosdb.server.datatype.AbstractDatatype; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Role; +import org.caosdb.server.entity.container.Container; +import org.caosdb.server.grpc.GRPCServer; +import org.caosdb.server.logging.RequestErrorLogMessage; +import org.caosdb.server.resource.AuthenticationResource; +import org.caosdb.server.resource.DefaultResource; +import org.caosdb.server.resource.EntityOwnerResource; +import org.caosdb.server.resource.EntityPermissionsResource; +import org.caosdb.server.resource.FileSystemResource; +import org.caosdb.server.resource.InfoResource; +import org.caosdb.server.resource.LogoutResource; +import org.caosdb.server.resource.PermissionRulesResource; +import org.caosdb.server.resource.RolesResource; +import org.caosdb.server.resource.ScriptingResource; +import org.caosdb.server.resource.ServerLogsResource; +import org.caosdb.server.resource.ServerPropertiesResource; +import org.caosdb.server.resource.SharedFileResource; +import org.caosdb.server.resource.ThumbnailsResource; +import org.caosdb.server.resource.UserResource; +import org.caosdb.server.resource.UserRolesResource; +import org.caosdb.server.resource.Webinterface; +import org.caosdb.server.resource.WebinterfaceBuildNumber; +import org.caosdb.server.resource.transaction.EntityNamesResource; +import org.caosdb.server.resource.transaction.EntityResource; +import org.caosdb.server.transaction.ChecksumUpdater; +import org.caosdb.server.utils.FileUtils; +import org.caosdb.server.utils.Initialization; +import org.quartz.JobDetail; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; +import org.quartz.Trigger; +import org.quartz.impl.StdSchedulerFactory; import org.restlet.Application; import org.restlet.Component; import org.restlet.Context; @@ -62,67 +109,71 @@ import org.restlet.routing.Variable; import org.restlet.util.Series; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import caosdb.server.accessControl.AnonymousRealm; -import caosdb.server.accessControl.AuthenticationUtils; -import caosdb.server.accessControl.CaosDBAuthorizingRealm; -import caosdb.server.accessControl.CaosDBDefaultRealm; -import caosdb.server.accessControl.OneTimeTokenRealm; -import caosdb.server.accessControl.Principal; -import caosdb.server.accessControl.SessionToken; -import caosdb.server.accessControl.SessionTokenRealm; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.transaction.RetrieveDatatypes; -import caosdb.server.database.misc.TransactionBenchmark; -import caosdb.server.datatype.AbstractDatatype; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.Role; -import caosdb.server.entity.container.Container; -import caosdb.server.logging.RequestErrorLogMessage; -import caosdb.server.resource.AuthenticationResource; -import caosdb.server.resource.DefaultResource; -import caosdb.server.resource.EntityOwnerResource; -import caosdb.server.resource.EntityPermissionsResource; -import caosdb.server.resource.FileSystemResource; -import caosdb.server.resource.InfoResource; -import caosdb.server.resource.LogoutResource; -import caosdb.server.resource.PermissionRulesResource; -import caosdb.server.resource.RolesResource; -import caosdb.server.resource.ScriptingResource; -import caosdb.server.resource.ServerLogsResource; -import caosdb.server.resource.ServerPropertiesResource; -import caosdb.server.resource.SharedFileResource; -import caosdb.server.resource.ThumbnailsResource; -import caosdb.server.resource.UserResource; -import caosdb.server.resource.UserRolesResource; -import caosdb.server.resource.Webinterface; -import caosdb.server.resource.WebinterfaceBuildNumber; -import caosdb.server.resource.transaction.EntityNamesResource; -import caosdb.server.resource.transaction.EntityResource; -import caosdb.server.terminal.CaosDBTerminal; -import caosdb.server.terminal.StatsPanel; -import caosdb.server.terminal.SystemErrPanel; -import caosdb.server.transaction.ChecksumUpdater; -import caosdb.server.utils.FileUtils; -import caosdb.server.utils.Initialization; -import caosdb.server.utils.NullPrintStream; -import caosdb.server.utils.Utils; public class CaosDBServer extends Application { private static Logger logger = LoggerFactory.getLogger(CaosDBServer.class); - private static boolean START_GUI = true; private static Properties SERVER_PROPERTIES = null; private static Component component = null; private static ArrayList<Runnable> postShutdownHooks = new ArrayList<Runnable>(); private static ArrayList<Runnable> preShutdownHooks = new ArrayList<Runnable>(); private static boolean START_BACKEND = true; private static boolean INSECURE = false; + public static final String REQUEST_TIME_LOGGER = "REQUEST_TIME_LOGGER"; + public static final String REQUEST_ERRORS_LOGGER = "REQUEST_ERRORS_LOGGER"; + private static Scheduler SCHEDULER; public static String getServerProperty(final String key) { return getServerProperties().getProperty(key); } + /** + * This main method starts up a web application that will listen on a port defined in the config + * file. + * + * @param args One option temporarily (for testing) available: silent: If present: disable + * System.out-stream (stream to a NullPrintStream). This makes the response of the database + * amazingly faster. + * @throws IOException + * @throws FileNotFoundException + * @throws SecurityException + * @throws Exception If problems occur. + */ + public static void main(final String[] args) + throws SecurityException, FileNotFoundException, IOException { + try { + init(args); + initScheduler(); + initServerProperties(); + initTimeZone(); + initOneTimeTokens(); + initShiro(); + initBackend(); + initWebServer(); + initShutDownHook(); + } catch (Exception e1) { + logger.error("Could not start the server.", e1); + System.exit(1); + } + } + + private static void init(final String[] args) { + for (final String s : args) { + if (s.equals("nobackend")) { + START_BACKEND = false; + } else if (s.equals("insecure")) { + INSECURE = true; + } + } + INSECURE = INSECURE && isDebugMode(); // only allow insecure in debug mode + START_BACKEND = START_BACKEND || !isDebugMode(); // always start backend if not in debug mode + } + + private static void initScheduler() throws SchedulerException { + SCHEDULER = StdSchedulerFactory.getDefaultScheduler(); + SCHEDULER.start(); + } + public static void initServerProperties() throws IOException { SERVER_PROPERTIES = ServerProperties.initServerProperties(); } @@ -206,21 +257,15 @@ public class CaosDBServer extends Application { } } - private static void init(final String[] args) { - // Important change: - // Make silent the default option - START_GUI = false; - for (final String s : args) { - if (s.equals("silent")) { - START_GUI = false; - } else if (s.equals("gui")) { - START_GUI = true; - } else if (s.equals("nobackend")) { - START_BACKEND = false; - } else if (s.equals("insecure")) { - INSECURE = true; - } - } + public static void initOneTimeTokens() throws Exception { + OneTimeAuthenticationToken.initConfig(); + ConsumedInfoCleanupJob.scheduleDaily(); + } + + public static void initShiro() { + // init Shiro (user authentication/authorization and session management) + final Ini config = getShiroConfig(); + initShiro(config); } public static Ini getShiroConfig() { @@ -228,12 +273,11 @@ public class CaosDBServer extends Application { final Section mainSec = config.addSection("main"); mainSec.put("CaosDB", CaosDBDefaultRealm.class.getCanonicalName()); mainSec.put("SessionTokenValidator", SessionTokenRealm.class.getCanonicalName()); - mainSec.put("OneTimeTokenValidator", OneTimeTokenRealm.class.getCanonicalName()); mainSec.put("CaosDBAuthorizingRealm", CaosDBAuthorizingRealm.class.getCanonicalName()); mainSec.put("AnonymousRealm", AnonymousRealm.class.getCanonicalName()); mainSec.put( "securityManager.realms", - "$CaosDB, $SessionTokenValidator, $OneTimeTokenValidator, $CaosDBAuthorizingRealm, $AnonymousRealm"); + "$CaosDB, $SessionTokenValidator, $CaosDBAuthorizingRealm, $AnonymousRealm"); // disable shiro's default session management. We have quasi-stateless // sessions @@ -243,43 +287,15 @@ public class CaosDBServer extends Application { return config; } - /** - * This main method starts up a web application that will listen on a port defined in the config - * file. - * - * @param args One option temporarily (for testing) available: silent: If present: disable - * System.out-stream (stream to a NullPrintStream). This makes the response of the database - * amazingly faster. - * @throws IOException - * @throws FileNotFoundException - * @throws SecurityException - * @throws Exception If problems occur. - */ - public static void main(final String[] args) - throws SecurityException, FileNotFoundException, IOException { - try { - init(args); - initServerProperties(); - initTimeZone(); - } catch (IOException | InterruptedException e1) { - logger.error("Could not configure the server.", e1); - System.exit(1); - } - - INSECURE = INSECURE && isDebugMode(); // only allow insecure in debug mode - START_BACKEND = START_BACKEND || !isDebugMode(); // always start backend if - // not in debug mode - - // init Shiro (user authentication/authorization and session management) - final Ini config = getShiroConfig(); - final Factory<SecurityManager> factory = new IniSecurityManagerFactory(config); - final SecurityManager securityManager = factory.getInstance(); + public static void initShiro(Ini config) { + BasicIniEnvironment env = new BasicIniEnvironment(config); + final SecurityManager securityManager = env.getSecurityManager(); SecurityUtils.setSecurityManager(securityManager); + } - final Initialization init = Initialization.setUp(); - try { - // init backend - if (START_BACKEND) { + public static void initBackend() throws Exception { + if (START_BACKEND) { + try (final Initialization init = Initialization.setUp()) { BackendTransaction.init(); // init benchmark @@ -296,67 +312,36 @@ public class CaosDBServer extends Application { // ChecksumUpdater ChecksumUpdater.start(); - } else { - logger.info("NO BACKEND"); } + } else { + logger.info("NO BACKEND"); + } + } - // GUI - if (START_GUI) { - final CaosDBTerminal caosDBTerminal = new CaosDBTerminal(); - caosDBTerminal.setName("CaosDBTerminal"); - caosDBTerminal.start(); - - addPreShutdownHook( - new Runnable() { - - @Override - public void run() { - caosDBTerminal.shutDown(); - SystemErrPanel.close(); - } - }); - // wait until the terminal is initialized. - Thread.sleep(1000); - - // add Benchmark - StatsPanel.addStat("TransactionBenchmark", TransactionBenchmark.getRootInstance()); - } else { - logger.info("NO GUI"); - System.setOut(new NullPrintStream()); - } + private static void initWebServer() throws Exception { + final int port_https = + Integer.parseInt(getServerProperty(ServerProperties.KEY_SERVER_PORT_HTTPS)); + final int port_http = + Integer.parseInt(getServerProperty(ServerProperties.KEY_SERVER_PORT_HTTP)); + int port_redirect_https; + try { + port_redirect_https = + Integer.parseInt(getServerProperty(ServerProperties.KEY_REDIRECT_HTTP_TO_HTTPS_PORT)); + } catch (NumberFormatException e) { + port_redirect_https = port_https; + } + final int initialConnections = + Integer.parseInt(getServerProperty(ServerProperties.KEY_INITIAL_CONNECTIONS)); + final int maxTotalConnections = + Integer.parseInt(getServerProperty(ServerProperties.KEY_MAX_CONNECTIONS)); - // Web server properties - final int port_https = - Integer.parseInt(getServerProperty(ServerProperties.KEY_SERVER_PORT_HTTPS)); - final int port_http = - Integer.parseInt(getServerProperty(ServerProperties.KEY_SERVER_PORT_HTTP)); - int port_redirect_https; - try { - port_redirect_https = - Integer.parseInt(getServerProperty(ServerProperties.KEY_REDIRECT_HTTP_TO_HTTPS_PORT)); - } catch (NumberFormatException e) { - port_redirect_https = port_https; - } - final int initialConnections = - Integer.parseInt(getServerProperty(ServerProperties.KEY_INITIAL_CONNECTIONS)); - final int maxTotalConnections = - Integer.parseInt(getServerProperty(ServerProperties.KEY_MAX_CONNECTIONS)); - - init.release(); - - GRPCServer.startServer(8080); - if (INSECURE) { - runHTTPServer(port_http, initialConnections, maxTotalConnections); - } else { - runHTTPSServer( - port_https, port_http, port_redirect_https, initialConnections, maxTotalConnections); - } - initShutDownHook(); - } catch (final Exception e) { - logger.error("Server start failed.", e); - init.release(); - System.exit(1); + if (INSECURE) { + runHTTPServer(port_http, initialConnections, maxTotalConnections); + } else { + runHTTPSServer( + port_https, port_http, port_redirect_https, initialConnections, maxTotalConnections); } + GRPCServer.startServer(8080); } private static void initDatatypes(final Access access) throws Exception { @@ -449,7 +434,7 @@ public class CaosDBServer extends Application { null, port_https, (Restlet) null, - "caosdb.server.CaosDBServerConnectorHelper"); + "org.caosdb.server.CaosDBServerConnectorHelper"); component.getServers().add(httpsServer); // redirector http to https @@ -487,13 +472,14 @@ public class CaosDBServer extends Application { // Create an application (this class). final Application application = new CaosDBServer(); - application.getStatusService().setContactEmail("timm.fitschen@ds.mpg.de"); application .getStatusService() - .setHomeRef(new Reference(getServerProperty(ServerProperties.KEY_CONTEXT_ROOT) + "/")); + .setContactEmail( + getServerProperty(ServerProperties.KEY_ADMIN_NAME) + + " <" + + getServerProperty(ServerProperties.KEY_ADMIN_EMAIL) + + ">"); - // Attach the application to the component with a defined contextRoot. - application.getStatusService().setContactEmail("timm.fitschen@ds.mpg.de"); application .getStatusService() .setHomeRef(new Reference(getServerProperty(ServerProperties.KEY_CONTEXT_ROOT) + "/")); @@ -509,9 +495,6 @@ public class CaosDBServer extends Application { } } - public static final String REQUEST_TIME_LOGGER = "REQUEST_TIME_LOGGER"; - public static final String REQUEST_ERRORS_LOGGER = "REQUEST_ERRORS_LOGGER"; - /** * Specify the dispatching restlet that maps URIs to their associated resources for processing. * @@ -561,10 +544,10 @@ public class CaosDBServer extends Application { private void setSessionCookies(final Response response) { final Subject subject = SecurityUtils.getSubject(); + // if authenticated as a normal user: generate and set session cookie. if (subject.isAuthenticated() - && subject.getPrincipal() != AuthenticationUtils.ANONYMOUS_USER.getPrincipal()) { - final SessionToken sessionToken = - SessionToken.generate((Principal) subject.getPrincipal(), null); + && subject.getPrincipal() != AnonymousAuthenticationToken.PRINCIPAL) { + final SessionToken sessionToken = SessionToken.generate(subject); // set session token cookie (httpOnly, secure cookie which // is used to recognize a user session) @@ -824,6 +807,10 @@ public class CaosDBServer extends Application { public static Properties getServerProperties() { return SERVER_PROPERTIES; } + + public static void scheduleJob(JobDetail job, Trigger trigger) throws SchedulerException { + SCHEDULER.scheduleJob(job, trigger); + } } class CaosDBComponent extends Component { @@ -853,7 +840,7 @@ class CaosDBComponent extends Component { public void handle(final Request request, final Response response) { long t1 = System.currentTimeMillis(); // The server request ID is just a long random number - request.getAttributes().put("SRID", Utils.getUID()); + request.getAttributes().put("SRID", UUID.randomUUID().toString()); response.setServerInfo(CaosDBServer.getServerInfo()); super.handle(request, response); log(request, response, t1); diff --git a/src/main/java/caosdb/server/CaosDBServerConnectorHelper.java b/src/main/java/org/caosdb/server/CaosDBServerConnectorHelper.java similarity index 98% rename from src/main/java/caosdb/server/CaosDBServerConnectorHelper.java rename to src/main/java/org/caosdb/server/CaosDBServerConnectorHelper.java index 718d9a5ed5d4007c5c5b6b5b24b940e6973c8f34..8a9749bc2225d71b87ea338a88db3f9aa9596bba 100644 --- a/src/main/java/caosdb/server/CaosDBServerConnectorHelper.java +++ b/src/main/java/org/caosdb/server/CaosDBServerConnectorHelper.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server; +package org.caosdb.server; import java.util.LinkedList; import org.restlet.Server; diff --git a/src/main/java/caosdb/server/FileSystem.java b/src/main/java/org/caosdb/server/FileSystem.java similarity index 95% rename from src/main/java/caosdb/server/FileSystem.java rename to src/main/java/org/caosdb/server/FileSystem.java index 79e764b96d3b477a57b90b83b1a3f437a1d21266..6bff612ca69acc24b699f8807b6969e343c60fb3 100644 --- a/src/main/java/caosdb/server/FileSystem.java +++ b/src/main/java/org/caosdb/server/FileSystem.java @@ -22,18 +22,8 @@ * ** end header */ -package caosdb.server; - -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.transaction.GetFileRecordByPath; -import caosdb.server.database.exceptions.EntityDoesNotExistException; -import caosdb.server.database.misc.TransactionBenchmark; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.FileProperties; -import caosdb.server.entity.Message; -import caosdb.server.utils.FileUtils; -import caosdb.server.utils.ServerMessages; -import caosdb.server.utils.Utils; +package org.caosdb.server; + import com.google.common.io.Files; import java.io.File; import java.io.FileOutputStream; @@ -45,6 +35,16 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.regex.Pattern; import org.apache.commons.fileupload.FileItemStream; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.transaction.GetFileRecordByPath; +import org.caosdb.server.database.exceptions.EntityDoesNotExistException; +import org.caosdb.server.database.misc.TransactionBenchmark; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.FileProperties; +import org.caosdb.server.entity.Message; +import org.caosdb.server.utils.FileUtils; +import org.caosdb.server.utils.ServerMessages; +import org.caosdb.server.utils.Utils; public class FileSystem { private static String filesystem = null; diff --git a/src/main/java/caosdb/server/HttpToHttpsRedirector.java b/src/main/java/org/caosdb/server/HttpToHttpsRedirector.java similarity index 98% rename from src/main/java/caosdb/server/HttpToHttpsRedirector.java rename to src/main/java/org/caosdb/server/HttpToHttpsRedirector.java index 6e250028bbec9450bb2984d9cf1922d0d4e45cb5..5f15406faa837d311a8e5bf62b5e8dd28209d094 100644 --- a/src/main/java/caosdb/server/HttpToHttpsRedirector.java +++ b/src/main/java/org/caosdb/server/HttpToHttpsRedirector.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server; +package org.caosdb.server; import org.restlet.Request; import org.restlet.Response; diff --git a/src/main/java/caosdb/server/ServerProperties.java b/src/main/java/org/caosdb/server/ServerProperties.java similarity index 94% rename from src/main/java/caosdb/server/ServerProperties.java rename to src/main/java/org/caosdb/server/ServerProperties.java index c1dd59f3902601ea90c021a4a7b723723d1b0670..3172a3e88e7790580af1b7865c024fa2b40c017b 100644 --- a/src/main/java/caosdb/server/ServerProperties.java +++ b/src/main/java/org/caosdb/server/ServerProperties.java @@ -22,7 +22,7 @@ * * ** end header */ -package caosdb.server; +package org.caosdb.server; import java.io.BufferedInputStream; import java.io.File; @@ -38,7 +38,7 @@ import org.slf4j.LoggerFactory; public class ServerProperties extends Properties { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = -6178774548807398071L; private static Logger logger = LoggerFactory.getLogger(ServerProperties.class.getName()); public static final String KEY_FILE_SYSTEM_ROOT = "FILE_SYSTEM_ROOT"; @@ -88,7 +88,9 @@ public class ServerProperties extends Properties { public static final String KEY_BUGTRACKER_URI = "BUGTRACKER_URI"; public static final String KEY_SESSION_TIMEOUT_MS = "SESSION_TIMEOUT_MS"; - public static final String KEY_ACTIVATION_TIMEOUT_MS = "ACTIVATION_TIMEOUT_MS"; + public static final String KEY_ONE_TIME_TOKEN_EXPIRES_MS = "ONE_TIME_TOKEN_EXPIRES_MS"; + public static final String KEY_ONE_TIME_TOKEN_REPLAYS_TIMEOUT_MS = + "ONE_TIME_TOKEN_REPLAYS_TIMEOUT_MS"; public static final String KEY_CACHE_CONF_LOC = "CACHE_CONF_LOC"; public static final String KEY_CACHE_DISABLE = "CACHE_DISABLE"; @@ -115,6 +117,7 @@ public class ServerProperties extends Properties { public static final String KEY_SERVER_OWNER = "SERVER_OWNER"; public static final String KEY_SERVER_SIDE_SCRIPTING_BIN_DIR = "SERVER_SIDE_SCRIPTING_BIN_DIR"; + public static final String KEY_SERVER_SIDE_SCRIPTING_BIN_DIRS = "SERVER_SIDE_SCRIPTING_BIN_DIRS"; public static final String KEY_SERVER_SIDE_SCRIPTING_HOME_DIR = "SERVER_SIDE_SCRIPTING_HOME_DIR"; public static final String KEY_SERVER_SIDE_SCRIPTING_WORKING_DIR = "SERVER_SIDE_SCRIPTING_WORKING_DIR"; @@ -129,6 +132,7 @@ public class ServerProperties extends Properties { public static final String KEY_TIMEZONE = "TIMEZONE"; public static final String KEY_WEBUI_HTTP_HEADER_CACHE_MAX_AGE = "WEBUI_HTTP_HEADER_CACHE_MAX_AGE"; + public static final String KEY_AUTHTOKEN_CONFIG = "AUTHTOKEN_CONFIG"; /** * Read the config files and initialize the server properties. diff --git a/src/main/java/caosdb/server/ServerPropertiesSerializer.java b/src/main/java/org/caosdb/server/ServerPropertiesSerializer.java similarity index 92% rename from src/main/java/caosdb/server/ServerPropertiesSerializer.java rename to src/main/java/org/caosdb/server/ServerPropertiesSerializer.java index 10189f99e2ff30a2d9306ad9dc007810607747dd..f68538a3aa8bb15ec6f53944dfb072e20dfbc557 100644 --- a/src/main/java/caosdb/server/ServerPropertiesSerializer.java +++ b/src/main/java/org/caosdb/server/ServerPropertiesSerializer.java @@ -1,10 +1,10 @@ -package caosdb.server; +package org.caosdb.server; -import caosdb.server.utils.Serializer; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Properties; +import org.caosdb.server.utils.Serializer; import org.jdom2.Element; public class ServerPropertiesSerializer implements Serializer<Properties, Element> { diff --git a/src/main/java/caosdb/server/accessControl/ACMPermissions.java b/src/main/java/org/caosdb/server/accessControl/ACMPermissions.java similarity index 98% rename from src/main/java/caosdb/server/accessControl/ACMPermissions.java rename to src/main/java/org/caosdb/server/accessControl/ACMPermissions.java index 29988106b842fbd2b825899093e102a7448e8951..84844e892297e68d2ad22cbf5dad935612d1c4f4 100644 --- a/src/main/java/caosdb/server/accessControl/ACMPermissions.java +++ b/src/main/java/org/caosdb/server/accessControl/ACMPermissions.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.accessControl; +package org.caosdb.server.accessControl; public class ACMPermissions { diff --git a/src/main/java/caosdb/server/accessControl/AnonymousAuthenticationToken.java b/src/main/java/org/caosdb/server/accessControl/AnonymousAuthenticationToken.java similarity index 86% rename from src/main/java/caosdb/server/accessControl/AnonymousAuthenticationToken.java rename to src/main/java/org/caosdb/server/accessControl/AnonymousAuthenticationToken.java index cd3f86f61eb66759b3eb7d0c91c29dc23637000b..97b6f9ee669b673f969e6856a5e23172327fb33e 100644 --- a/src/main/java/caosdb/server/accessControl/AnonymousAuthenticationToken.java +++ b/src/main/java/org/caosdb/server/accessControl/AnonymousAuthenticationToken.java @@ -20,15 +20,15 @@ * * ** end header */ -package caosdb.server.accessControl; +package org.caosdb.server.accessControl; import org.apache.shiro.authc.AuthenticationToken; public class AnonymousAuthenticationToken implements AuthenticationToken { - private static final long serialVersionUID = 1424325396819592888L; + private static final long serialVersionUID = 3573372964529451961L; private static final AnonymousAuthenticationToken INSTANCE = new AnonymousAuthenticationToken(); - public static final Object PRINCIPAL = new Object(); + public static final Principal PRINCIPAL = new Principal("anonymous", "anonymous"); private AnonymousAuthenticationToken() {} @@ -37,7 +37,7 @@ public class AnonymousAuthenticationToken implements AuthenticationToken { } @Override - public Object getPrincipal() { + public Principal getPrincipal() { return PRINCIPAL; } diff --git a/src/main/java/caosdb/server/accessControl/AnonymousRealm.java b/src/main/java/org/caosdb/server/accessControl/AnonymousRealm.java similarity index 97% rename from src/main/java/caosdb/server/accessControl/AnonymousRealm.java rename to src/main/java/org/caosdb/server/accessControl/AnonymousRealm.java index 831d45a727c95277c9d64624e136b2a2e120b3b4..006400bf649619390d5eaa642642a73b6a94f337 100644 --- a/src/main/java/caosdb/server/accessControl/AnonymousRealm.java +++ b/src/main/java/org/caosdb/server/accessControl/AnonymousRealm.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.accessControl; +package org.caosdb.server.accessControl; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; diff --git a/src/main/java/caosdb/server/accessControl/AuthenticationUtils.java b/src/main/java/org/caosdb/server/accessControl/AuthenticationUtils.java similarity index 70% rename from src/main/java/caosdb/server/accessControl/AuthenticationUtils.java rename to src/main/java/org/caosdb/server/accessControl/AuthenticationUtils.java index 6e0fd5370ffcc2435067d68b3f2f810819ae9fbb..e6907f40b57b5ef44dc9c4772327ddf8920df173 100644 --- a/src/main/java/caosdb/server/accessControl/AuthenticationUtils.java +++ b/src/main/java/org/caosdb/server/accessControl/AuthenticationUtils.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2020 Indiscale GmbH <info@indiscale.com> + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -20,25 +22,21 @@ * * ** end header */ -package caosdb.server.accessControl; +package org.caosdb.server.accessControl; -import static caosdb.server.utils.Utils.URLDecodeWithUTF8; +import static org.caosdb.server.utils.Utils.URLDecodeWithUTF8; -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; -import caosdb.server.entity.Message; -import caosdb.server.entity.Message.MessageType; -import caosdb.server.permissions.ResponsibleAgent; -import caosdb.server.permissions.Role; -import caosdb.server.utils.Utils; import java.sql.Timestamp; import java.util.Collection; import java.util.LinkedList; -import org.apache.shiro.authc.AuthenticationToken; +import org.apache.shiro.subject.Subject; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.ServerProperties; +import org.caosdb.server.permissions.ResponsibleAgent; +import org.caosdb.server.permissions.Role; +import org.caosdb.server.utils.Utils; import org.restlet.data.Cookie; import org.restlet.data.CookieSetting; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Useful static methods, mainly for parsing and serializing SessionTokens by the means of web @@ -48,16 +46,16 @@ import org.slf4j.LoggerFactory; */ public class AuthenticationUtils { - private static final Logger logger = LoggerFactory.getLogger(AuthenticationUtils.class); - - public static final String ONE_TIME_TOKEN_COOKIE = "OneTimeToken"; - public static final Message UNAUTHENTICATED = - new Message(MessageType.Error, 401, "Sign up, please!"); public static final String SESSION_TOKEN_COOKIE = "SessionToken"; public static final String SESSION_TIMEOUT_COOKIE = "SessionTimeOut"; - public static final AuthenticationToken ANONYMOUS_USER = - AnonymousAuthenticationToken.getInstance(); + public static boolean isAnonymous(Subject user) { + return AnonymousAuthenticationToken.PRINCIPAL.equals(user.getPrincipal()); + } + + public static boolean isAnonymous(Principal principal) { + return AnonymousAuthenticationToken.PRINCIPAL.equals(principal); + } /** * Create a cookie for a {@link SelfValidatingAuthenticationToken}. Returns null if the parameter @@ -87,11 +85,8 @@ public class AuthenticationUtils { return null; } - public static CookieSetting createOneTimeTokenCookie(final OneTimeAuthenticationToken token) { - return createTokenCookie(AuthenticationUtils.ONE_TIME_TOKEN_COOKIE, token); - } - - public static CookieSetting createSessionTokenCookie(final SessionToken token) { + public static CookieSetting createSessionTokenCookie( + final SelfValidatingAuthenticationToken token) { return createTokenCookie(AuthenticationUtils.SESSION_TOKEN_COOKIE, token); } @@ -103,48 +98,16 @@ public class AuthenticationUtils { * @return A new SessionToken * @see {@link AuthenticationUtils#createSessionTokenCookie(SessionToken)}, {@link SessionToken} */ - public static SessionToken parseSessionTokenCookie(final Cookie cookie, final String curry) { + public static SelfValidatingAuthenticationToken parseSessionTokenCookie(final Cookie cookie) { if (cookie != null) { final String tokenString = URLDecodeWithUTF8(cookie.getValue()); if (tokenString != null && !tokenString.equals("")) { - try { - return SessionToken.parse(tokenString, curry); - } catch (final Exception e) { - logger.warn("AUTHTOKEN_PARSING_FAILED", e); - } + return SelfValidatingAuthenticationToken.parse(tokenString); } } return null; } - private static OneTimeAuthenticationToken parseOneTimeToken( - final String tokenString, final String curry) { - if (tokenString != null && !tokenString.equals("")) { - try { - return OneTimeAuthenticationToken.parse(tokenString, curry); - } catch (final Exception e) { - logger.warn("AUTHTOKEN_PARSING_FAILED", e); - } - } - return null; - } - - public static OneTimeAuthenticationToken parseOneTimeTokenQuerySegment( - final String tokenString, final String curry) { - if (tokenString != null) { - return parseOneTimeToken(URLDecodeWithUTF8(tokenString), curry); - } - return null; - } - - public static OneTimeAuthenticationToken parseOneTimeTokenCookie( - final Cookie cookie, final String curry) { - if (cookie != null) { - return parseOneTimeToken(URLDecodeWithUTF8(cookie.getValue()), curry); - } - return null; - } - /** * Create a session timeout cookie. The value is a plain UTC timestamp which tells the user how * long his session will stay active. This cookie will be ignored by the server and carries only @@ -163,9 +126,7 @@ public class AuthenticationUtils { if (token != null && token.isValid()) { t = new Timestamp(token.getExpires()).toString().replaceFirst(" ", "T"); - exp_in_sec = (int) Math.ceil(token.getTimeout() / 1000.0); // new - // expiration - // time. + exp_in_sec = (int) Math.ceil(token.getTimeout() / 1000.0); // new expiration time return new CookieSetting( 0, AuthenticationUtils.SESSION_TIMEOUT_COOKIE, @@ -180,6 +141,7 @@ public class AuthenticationUtils { return null; } + // TODO move public static boolean isResponsibleAgentExistent(final ResponsibleAgent agent) { // 1) check OWNER, OTHER if (Role.OTHER_ROLE.equals(agent) || Role.OWNER_ROLE.equals(agent)) { @@ -227,4 +189,14 @@ public class AuthenticationUtils { false, false); } + + public static Collection<String> getRoles(Subject user) { + return new CaosDBAuthorizingRealm().doGetAuthorizationInfo(user.getPrincipals()).getRoles(); + } + + public static boolean isFromOneTimeTokenRealm(Subject subject) { + return ((Principal) subject.getPrincipal()) + .getRealm() + .equals(OneTimeAuthenticationToken.REALM_NAME); + } } diff --git a/src/main/java/org/caosdb/server/accessControl/CaosDBAuthorizingRealm.java b/src/main/java/org/caosdb/server/accessControl/CaosDBAuthorizingRealm.java new file mode 100644 index 0000000000000000000000000000000000000000..e10a0b29b38b2e246bde8c89c43a8b82a9307b7e --- /dev/null +++ b/src/main/java/org/caosdb/server/accessControl/CaosDBAuthorizingRealm.java @@ -0,0 +1,94 @@ +/* + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2018 Research Group Biomedical Physics, + * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * + * 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 <https://www.gnu.org/licenses/>. + * + * ** end header + */ +package org.caosdb.server.accessControl; + +import java.util.Collection; +import java.util.Set; +import org.apache.shiro.authc.AuthenticationInfo; +import org.apache.shiro.authc.AuthenticationToken; +import org.apache.shiro.authz.AuthorizationInfo; +import org.apache.shiro.authz.SimpleAuthorizationInfo; +import org.apache.shiro.realm.AuthorizingRealm; +import org.apache.shiro.subject.PrincipalCollection; + +public class CaosDBAuthorizingRealm extends AuthorizingRealm { + + private static final CaosDBRolePermissionResolver role_permission_resolver = + new CaosDBRolePermissionResolver(); + + public Collection<String> getSessionRoles(SelfValidatingAuthenticationToken token) { + return token.getRoles(); + } + + public Collection<String> getSessionPermissions(SelfValidatingAuthenticationToken token) { + return token.getPermissions(); + } + + @Override + protected AuthorizationInfo doGetAuthorizationInfo(final PrincipalCollection principals) { + final SimpleAuthorizationInfo authzInfo = new SimpleAuthorizationInfo(); + Object principal = principals.getPrimaryPrincipal(); + + // Add explicitly given roles and permissions. + if (principal instanceof SelfValidatingAuthenticationToken) { + Collection<String> sessionPermissions = + getSessionPermissions((SelfValidatingAuthenticationToken) principal); + + Collection<String> sessionRoles = + getSessionRoles((SelfValidatingAuthenticationToken) principal); + + authzInfo.addRoles(sessionRoles); + authzInfo.addStringPermissions(sessionPermissions); + } + + // Find all roles which are associated with this principal in this realm. + final Set<String> principalRoles = + UserSources.resolve((Principal) principals.getPrimaryPrincipal()); + if (principalRoles != null) { + authzInfo.addRoles(principalRoles); + } + + if (authzInfo.getRoles() != null && !authzInfo.getRoles().isEmpty()) { + authzInfo.addObjectPermission( + role_permission_resolver.resolvePermissionsInRole(authzInfo.getRoles())); + } + + return authzInfo; + } + + public CaosDBAuthorizingRealm() { + setCachingEnabled(false); + setAuthorizationCachingEnabled(false); + } + + @Override + public boolean supports(final AuthenticationToken token) { + // this is not an authenticating realm - just for authorizing. + return false; + } + + @Override + protected AuthenticationInfo doGetAuthenticationInfo(final AuthenticationToken token) { + return null; + } +} diff --git a/src/main/java/caosdb/server/accessControl/CaosDBDefaultRealm.java b/src/main/java/org/caosdb/server/accessControl/CaosDBDefaultRealm.java similarity index 98% rename from src/main/java/caosdb/server/accessControl/CaosDBDefaultRealm.java rename to src/main/java/org/caosdb/server/accessControl/CaosDBDefaultRealm.java index 209487b751c0b73b5fd9085827295d5eb2ce831d..47fe71fd9dc3407c736998e79524f034933936a9 100644 --- a/src/main/java/caosdb/server/accessControl/CaosDBDefaultRealm.java +++ b/src/main/java/org/caosdb/server/accessControl/CaosDBDefaultRealm.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.accessControl; +package org.caosdb.server.accessControl; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; diff --git a/src/main/java/caosdb/server/accessControl/CaosDBRolePermissionResolver.java b/src/main/java/org/caosdb/server/accessControl/CaosDBRolePermissionResolver.java similarity index 81% rename from src/main/java/caosdb/server/accessControl/CaosDBRolePermissionResolver.java rename to src/main/java/org/caosdb/server/accessControl/CaosDBRolePermissionResolver.java index 3350a68700f108e8ed5cf7309e9f305ac0bb669b..17637b010a1ddcd7ed88e3ba448e3fa68b894b43 100644 --- a/src/main/java/caosdb/server/accessControl/CaosDBRolePermissionResolver.java +++ b/src/main/java/org/caosdb/server/accessControl/CaosDBRolePermissionResolver.java @@ -20,19 +20,20 @@ * * ** end header */ -package caosdb.server.accessControl; +package org.caosdb.server.accessControl; -import caosdb.server.entity.Message; -import caosdb.server.permissions.CaosPermission; -import caosdb.server.permissions.PermissionRule; -import caosdb.server.transaction.RetrievePermissionRulesTransaction; -import caosdb.server.utils.ServerMessages; import java.util.HashSet; import java.util.Set; import org.apache.shiro.authc.AuthenticationException; +import org.caosdb.server.entity.Message; +import org.caosdb.server.permissions.CaosPermission; +import org.caosdb.server.permissions.PermissionRule; +import org.caosdb.server.transaction.RetrievePermissionRulesTransaction; +import org.caosdb.server.utils.ServerMessages; public class CaosDBRolePermissionResolver { + /** Return CaosPermission with the rules which are associated with the roles. */ public CaosPermission resolvePermissionsInRole(final Set<String> roles) { final HashSet<PermissionRule> rules = new HashSet<PermissionRule>(); for (final String role : roles) { diff --git a/src/main/java/org/caosdb/server/accessControl/Config.java b/src/main/java/org/caosdb/server/accessControl/Config.java new file mode 100644 index 0000000000000000000000000000000000000000..4c50b445127c089dd1be7151dc6d35825877a2ae --- /dev/null +++ b/src/main/java/org/caosdb/server/accessControl/Config.java @@ -0,0 +1,86 @@ +package org.caosdb.server.accessControl; + +public class Config { + private String[] permissions = {}; + private String[] roles = {}; + private String purpose = null; + private OneTimeTokenToFile output = null; + private int maxReplays = 1; + private long expiresAfter = OneTimeAuthenticationToken.DEFAULT_TIMEOUT_MS; + private long replayTimeout = OneTimeAuthenticationToken.DEFAULT_REPLAYS_TIMEOUT_MS; + private String name = AnonymousAuthenticationToken.PRINCIPAL.getUsername(); + + public Config() {} + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public long getExpiresAfter() { + return expiresAfter; + } + + public void setExpiresAfter(long timeout) { + this.expiresAfter = timeout; + } + + public void setReplayTimeoutSeconds(long seconds) { + this.setReplayTimeout(seconds * 1000); + } + + public void setExpiresAfterSeconds(long seconds) { + this.setExpiresAfter(seconds * 1000); + } + + public void setMaxReplays(int maxReplays) { + this.maxReplays = maxReplays; + } + + public int getMaxReplays() { + return maxReplays; + } + + public String[] getPermissions() { + return permissions; + } + + public String getPurpose() { + return purpose; + } + + public void setPermissions(String[] permissions) { + this.permissions = permissions; + } + + public String[] getRoles() { + return roles; + } + + public void setRoles(String[] roles) { + this.roles = roles; + } + + public void setPurpose(String purpose) { + this.purpose = purpose; + } + + public OneTimeTokenToFile getOutput() { + return output; + } + + public void setOutput(OneTimeTokenToFile output) { + this.output = output; + } + + public long getReplayTimeout() { + return replayTimeout; + } + + public void setReplayTimeout(long replaysTimeout) { + this.replayTimeout = replaysTimeout; + } +} diff --git a/src/main/java/org/caosdb/server/accessControl/ConsumedInfoCleanupJob.java b/src/main/java/org/caosdb/server/accessControl/ConsumedInfoCleanupJob.java new file mode 100644 index 0000000000000000000000000000000000000000..b5945c5cd2dbec86a7de6ffa265c65706342f86e --- /dev/null +++ b/src/main/java/org/caosdb/server/accessControl/ConsumedInfoCleanupJob.java @@ -0,0 +1,29 @@ +package org.caosdb.server.accessControl; + +import org.caosdb.server.CaosDBServer; +import org.quartz.CronScheduleBuilder; +import org.quartz.Job; +import org.quartz.JobBuilder; +import org.quartz.JobDetail; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.quartz.SchedulerException; +import org.quartz.Trigger; +import org.quartz.TriggerBuilder; + +public class ConsumedInfoCleanupJob implements Job { + + public static void scheduleDaily() throws SchedulerException { + JobDetail job = JobBuilder.newJob(ConsumedInfoCleanupJob.class).build(); + Trigger trigger = + TriggerBuilder.newTrigger() + .withSchedule(CronScheduleBuilder.dailyAtHourAndMinute(0, 0)) + .build(); + CaosDBServer.scheduleJob(job, trigger); + } + + @Override + public void execute(JobExecutionContext context) throws JobExecutionException { + OneTimeTokenConsumedInfo.cleanupConsumedInfo(); + } +} diff --git a/src/main/java/caosdb/server/accessControl/CredentialsValidator.java b/src/main/java/org/caosdb/server/accessControl/CredentialsValidator.java similarity index 96% rename from src/main/java/caosdb/server/accessControl/CredentialsValidator.java rename to src/main/java/org/caosdb/server/accessControl/CredentialsValidator.java index 1c9474eb8d40ae7c28188be3c9b62bc73288978d..dfcbe8dfe5a2c840b2674c0fa419df185fe638ad 100644 --- a/src/main/java/caosdb/server/accessControl/CredentialsValidator.java +++ b/src/main/java/org/caosdb/server/accessControl/CredentialsValidator.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.accessControl; +package org.caosdb.server.accessControl; public interface CredentialsValidator<T> { diff --git a/src/main/java/caosdb/server/accessControl/HashPasswordValidator.java b/src/main/java/org/caosdb/server/accessControl/HashPasswordValidator.java similarity index 95% rename from src/main/java/caosdb/server/accessControl/HashPasswordValidator.java rename to src/main/java/org/caosdb/server/accessControl/HashPasswordValidator.java index 2d883d906b633e5e1d4d313e2334844e1e7670fa..dcf1e3feabbb1e6855844169f03961d5ad71532a 100644 --- a/src/main/java/caosdb/server/accessControl/HashPasswordValidator.java +++ b/src/main/java/org/caosdb/server/accessControl/HashPasswordValidator.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.accessControl; +package org.caosdb.server.accessControl; -import caosdb.server.utils.Utils; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import org.caosdb.server.utils.Utils; public class HashPasswordValidator implements CredentialsValidator<String> { diff --git a/src/main/java/caosdb/server/accessControl/InternalUserSource.java b/src/main/java/org/caosdb/server/accessControl/InternalUserSource.java similarity index 91% rename from src/main/java/caosdb/server/accessControl/InternalUserSource.java rename to src/main/java/org/caosdb/server/accessControl/InternalUserSource.java index 16e795aa9b7228c4f14f11bbb0d2178a4f7517a0..23f772dfbd24aef21a6335ce4bc6df392e082078 100644 --- a/src/main/java/caosdb/server/accessControl/InternalUserSource.java +++ b/src/main/java/org/caosdb/server/accessControl/InternalUserSource.java @@ -20,16 +20,16 @@ * * ** end header */ -package caosdb.server.accessControl; +package org.caosdb.server.accessControl; -import caosdb.server.entity.Message; -import caosdb.server.transaction.RetrievePasswordValidatorTransaction; -import caosdb.server.transaction.RetrieveUserTransaction; -import caosdb.server.utils.ServerMessages; import java.util.Map; import java.util.Set; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authz.AuthorizationException; +import org.caosdb.server.entity.Message; +import org.caosdb.server.transaction.RetrievePasswordValidatorTransaction; +import org.caosdb.server.transaction.RetrieveUserTransaction; +import org.caosdb.server.utils.ServerMessages; public class InternalUserSource implements UserSource { diff --git a/src/main/java/caosdb/server/accessControl/Mode.java b/src/main/java/org/caosdb/server/accessControl/Mode.java similarity index 95% rename from src/main/java/caosdb/server/accessControl/Mode.java rename to src/main/java/org/caosdb/server/accessControl/Mode.java index de7af914ae2b120a279da3fe936b1e67845fd0cb..8f91a9ba6eb6fc8c35a0cb519e0e7820e3628f57 100644 --- a/src/main/java/caosdb/server/accessControl/Mode.java +++ b/src/main/java/org/caosdb/server/accessControl/Mode.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.accessControl; +package org.caosdb.server.accessControl; public enum Mode { ONETIME, diff --git a/src/main/java/org/caosdb/server/accessControl/OneTimeAuthenticationToken.java b/src/main/java/org/caosdb/server/accessControl/OneTimeAuthenticationToken.java new file mode 100644 index 0000000000000000000000000000000000000000..f87dd0da71b5478c636476dac3041ced82035e27 --- /dev/null +++ b/src/main/java/org/caosdb/server/accessControl/OneTimeAuthenticationToken.java @@ -0,0 +1,265 @@ +/* + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2018 Research Group Biomedical Physics, + * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2020 Indiscale GmbH <info@indiscale.com> + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * + * 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 <https://www.gnu.org/licenses/>. + * + * ** end header + */ +package org.caosdb.server.accessControl; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectReader; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import org.apache.shiro.subject.Subject; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.ServerProperties; +import org.eclipse.jetty.util.ajax.JSON; +import org.quartz.SchedulerException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class OneTimeAuthenticationToken extends SelfValidatingAuthenticationToken { + + public static final long DEFAULT_MAX_REPLAYS = 1L; + public static final int DEFAULT_REPLAYS_TIMEOUT_MS = + Integer.parseInt( + CaosDBServer.getServerProperty(ServerProperties.KEY_ONE_TIME_TOKEN_REPLAYS_TIMEOUT_MS)); + public static final int DEFAULT_TIMEOUT_MS = + Integer.parseInt( + CaosDBServer.getServerProperty(ServerProperties.KEY_ONE_TIME_TOKEN_EXPIRES_MS)); + public static final String REALM_NAME = "OneTimeAuthenticationToken"; // TODO move to UserSources + public static final Logger LOGGER = LoggerFactory.getLogger(OneTimeAuthenticationToken.class); + + private long maxReplays; + private long replaysTimeout; + + public OneTimeAuthenticationToken( + final Principal principal, + final long date, + final long timeout, + final String salt, + final String checksum, + final String[] permissions, + final String[] roles, + final long maxReplays, + final long replaysTimeout) { + super(principal, date, timeout, salt, checksum, permissions, roles); + this.replaysTimeout = replaysTimeout; + this.maxReplays = maxReplays; + consume(); + } + + public long getReplaysTimeout() { + return replaysTimeout; + } + + public void consume() { + OneTimeTokenConsumedInfo.consume(this); + } + + public OneTimeAuthenticationToken( + final Principal principal, + final long timeout, + final String[] permissions, + final String[] roles, + final Long maxReplays, + final Long replaysTimeout) { + super( + principal, + timeout, + permissions, + roles, + defaultIfNull(maxReplays, DEFAULT_MAX_REPLAYS), + defaultIfNull(replaysTimeout, DEFAULT_REPLAYS_TIMEOUT_MS)); + } + + private static final long serialVersionUID = 6811668234440927543L; + + /** + * Return consumed. + * + * @param array + * @param curry + * @return + */ + public static OneTimeAuthenticationToken parse(final Object[] array) { + final Principal principal = new Principal((String) array[1], (String) array[2]); + final String[] roles = toStringArray((Object[]) array[3]); + final String[] permissions = toStringArray((Object[]) array[4]); + final long date = (Long) array[5]; + final long timeout = (Long) array[6]; + final String salt = (String) array[7]; + final String checksum = (String) array[8]; + final long maxReplays = (Long) array[9]; + final long replaysTimeout = (Long) array[10]; + return new OneTimeAuthenticationToken( + principal, date, timeout, salt, checksum, permissions, roles, maxReplays, replaysTimeout); + } + + private static OneTimeAuthenticationToken generate( + final Principal principal, + final String[] permissions, + final String[] roles, + final long timeout, + final long maxReplays, + final long replaysTimeout) { + + return new OneTimeAuthenticationToken( + principal, timeout, permissions, roles, maxReplays, replaysTimeout); + } + + public static List<Config> loadConfig(InputStream input) throws Exception { + List<Config> results = new LinkedList<>(); + ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + ObjectReader reader = mapper.readerFor(Config.class); + Iterator<Config> configs = reader.readValues(input); + configs.forEachRemaining(results::add); + return results; + } + + public static Map<String, Config> getPurposeMap(List<Config> configs) throws Exception { + Map<String, Config> result = new HashMap<>(); + for (Config config : configs) { + if (config.getPurpose() != null && !config.getPurpose().isEmpty()) { + if (result.containsKey(config.getPurpose())) { + throw new Exception( + "OneTimeAuthToken configuration contains duplicate values for the 'purpose' property."); + } + result.put(config.getPurpose(), config); + } + } + return result; + } + + public static OneTimeAuthenticationToken generate(Config c) { + return generate(c, new Principal(REALM_NAME, c.getName())); + } + + public static OneTimeAuthenticationToken generateForPurpose(String purpose, Subject user) { + Config c = purposes.get(purpose); + if (c != null) { + Principal principal = (Principal) user.getPrincipal(); + + return generate(c, principal); + } + return null; + } + + public static OneTimeAuthenticationToken generate(Config c, Principal principal) { + return generate( + principal, + c.getPermissions(), + c.getRoles(), + c.getExpiresAfter(), + c.getMaxReplays(), + c.getReplayTimeout()); + } + + static Map<String, Config> purposes = new HashMap<>(); + + public static Map<String, Config> getPurposeMap() { + return purposes; + } + + public static void initConfig(InputStream yamlConfig) throws Exception { + List<Config> configs = loadConfig(yamlConfig); + initOutput(configs); + purposes.putAll(getPurposeMap(configs)); + } + + private static void initOutput(List<Config> configs) throws IOException, SchedulerException { + for (Config config : configs) { + if (config.getOutput() != null) { + config.getOutput().init(config); + } + } + } + + public static void initConfig() throws Exception { + resetConfig(); + try (FileInputStream f = + new FileInputStream( + CaosDBServer.getServerProperty(ServerProperties.KEY_AUTHTOKEN_CONFIG))) { + initConfig(f); + } catch (IOException e) { + LOGGER.error("Could not load the auth token configuration", e); + } + } + + @Override + protected void setFields(Object[] fields) { + if (fields.length == 2) { + this.maxReplays = (long) fields[0]; + this.replaysTimeout = (long) fields[1]; + } else { + throw new InstantiationError("Too few fields."); + } + } + + @Override + public String calcChecksum(String pepper) { + return calcChecksum( + "O", + this.getRealm(), + this.getUsername(), + this.date, + this.timeout, + this.salt, + calcChecksum((Object[]) this.permissions), + calcChecksum((Object[]) this.roles), + this.maxReplays, + this.replaysTimeout, + pepper); + } + + @Override + public String toString() { + return JSON.toString( + new Object[] { + "O", + this.getRealm(), + this.getUsername(), + this.roles, + this.permissions, + this.date, + this.timeout, + this.salt, + this.checksum, + this.maxReplays, + this.replaysTimeout + }); + } + + public long getMaxReplays() { + return maxReplays; + } + + public static void resetConfig() { + purposes.clear(); + } +} diff --git a/src/main/java/org/caosdb/server/accessControl/OneTimeTokenConsumedInfo.java b/src/main/java/org/caosdb/server/accessControl/OneTimeTokenConsumedInfo.java new file mode 100644 index 0000000000000000000000000000000000000000..20c648b2d6b4aa2a492de6bc4bb6d1f5465eea27 --- /dev/null +++ b/src/main/java/org/caosdb/server/accessControl/OneTimeTokenConsumedInfo.java @@ -0,0 +1,89 @@ +package org.caosdb.server.accessControl; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import org.apache.shiro.authc.AuthenticationException; + +/** + * Utility class to manage OTTs: mark as consumed, removed expired OTTs, manage maximum number of + * replays and replay timeout of tokens. + */ +class OneTimeTokenConsumedInfo { + + private static Map<String, OneTimeTokenConsumedInfo> consumedOneTimeTokens = new HashMap<>(); + + public static void cleanupConsumedInfo() { + synchronized (consumedOneTimeTokens) { + for (Iterator<Map.Entry<String, OneTimeTokenConsumedInfo>> it = + consumedOneTimeTokens.entrySet().iterator(); + it.hasNext(); ) { + Map.Entry<String, OneTimeTokenConsumedInfo> next = it.next(); + if (next.getValue().isExpired()) { + it.remove(); + } + } + } + } + + /** If the token is valid, consume it once and store this information. */ + public static void consume(OneTimeAuthenticationToken oneTimeAuthenticationToken) { + if (oneTimeAuthenticationToken.isValid()) { + String key = OneTimeTokenConsumedInfo.getKey(oneTimeAuthenticationToken); + OneTimeTokenConsumedInfo consumedInfo = null; + synchronized (consumedOneTimeTokens) { + consumedInfo = consumedOneTimeTokens.get(key); + if (consumedInfo == null) { + consumedInfo = new OneTimeTokenConsumedInfo(oneTimeAuthenticationToken); + consumedOneTimeTokens.put(key, consumedInfo); + } + } + consumedInfo.consume(); + } + } + + private OneTimeAuthenticationToken oneTimeAuthenticationToken; + private List<Long> replays = new LinkedList<>(); + + public OneTimeTokenConsumedInfo(OneTimeAuthenticationToken oneTimeAuthenticationToken) { + this.oneTimeAuthenticationToken = oneTimeAuthenticationToken; + } + + public static String getKey(OneTimeAuthenticationToken token) { + return token.checksum; + } + + private int getNoOfReplays() { + return replays.size(); + } + + private long getMaxReplays() { + return oneTimeAuthenticationToken.getMaxReplays(); + } + + private long getReplayTimeout() { + if (replays.size() == 0) { + return Long.MAX_VALUE; + } + long firstReplayTime = replays.get(0); + return firstReplayTime + oneTimeAuthenticationToken.getReplaysTimeout(); + } + + /** If there are still replays and time left, increase the replay counter by one. */ + public void consume() { + synchronized (replays) { + if (getNoOfReplays() >= getMaxReplays()) { + throw new AuthenticationException("One-time token was consumed too often."); + } else if (getReplayTimeout() < System.currentTimeMillis()) { + throw new AuthenticationException("One-time token replays timeout expired."); + } + replays.add(System.currentTimeMillis()); + } + } + + public boolean isExpired() { + return oneTimeAuthenticationToken.isExpired(); + } +} diff --git a/src/main/java/org/caosdb/server/accessControl/OneTimeTokenToFile.java b/src/main/java/org/caosdb/server/accessControl/OneTimeTokenToFile.java new file mode 100644 index 0000000000000000000000000000000000000000..46017701069f9f184bf50b8bab285014cd8a47ad --- /dev/null +++ b/src/main/java/org/caosdb/server/accessControl/OneTimeTokenToFile.java @@ -0,0 +1,83 @@ +package org.caosdb.server.accessControl; + +import com.google.common.io.Files; +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import org.caosdb.server.CaosDBServer; +import org.quartz.CronScheduleBuilder; +import org.quartz.Job; +import org.quartz.JobBuilder; +import org.quartz.JobDataMap; +import org.quartz.JobDetail; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.quartz.SchedulerException; +import org.quartz.Trigger; +import org.quartz.TriggerBuilder; + +public class OneTimeTokenToFile implements Job { + private String file = null; + private String schedule = null; + + public OneTimeTokenToFile() {} + + public static void output(OneTimeAuthenticationToken t, String file) throws IOException { + output(t, new File(file)); + } + + public static void output(OneTimeAuthenticationToken t, File file) throws IOException { + Files.createParentDirs(file); + try (PrintWriter writer = new PrintWriter(file, "utf-8")) { + writer.print(t.toString()); + } + } + + public String getFile() { + return file; + } + + public void setFile(String file) { + this.file = file; + } + + public String getSchedule() { + return schedule; + } + + public void setSchedule(String schedule) { + this.schedule = schedule; + } + + /** If no schedule was set, immediately write the config to file, else schedule the job. */ + public void init(Config config) throws IOException, SchedulerException { + + if (this.schedule != null) { + OneTimeAuthenticationToken.generate(config); // test config, throw away token + JobDataMap map = new JobDataMap(); + map.put("config", config); + map.put("file", file); + JobDetail outputJob = JobBuilder.newJob(OneTimeTokenToFile.class).setJobData(map).build(); + Trigger trigger = + TriggerBuilder.newTrigger() + .withIdentity(config.toString()) + .withSchedule(CronScheduleBuilder.cronSchedule(this.schedule)) + .build(); + CaosDBServer.scheduleJob(outputJob, trigger); + } else { + output(OneTimeAuthenticationToken.generate(config), file); + } + } + + @Override + public void execute(JobExecutionContext context) throws JobExecutionException { + Config config = (Config) context.getMergedJobDataMap().get("config"); + String file = context.getMergedJobDataMap().getString("file"); + try { + output(OneTimeAuthenticationToken.generate(config), file); + } catch (IOException e) { + // TODO log + e.printStackTrace(); + } + } +} diff --git a/src/main/java/caosdb/server/accessControl/Pam.java b/src/main/java/org/caosdb/server/accessControl/Pam.java similarity index 99% rename from src/main/java/caosdb/server/accessControl/Pam.java rename to src/main/java/org/caosdb/server/accessControl/Pam.java index 0cae6fd74ae3924e868757e1f058a430a23b1ff3..992665c1db3ef42d3770c71e89fa5444f43f9d95 100644 --- a/src/main/java/caosdb/server/accessControl/Pam.java +++ b/src/main/java/org/caosdb/server/accessControl/Pam.java @@ -23,9 +23,8 @@ * * ** end header */ -package caosdb.server.accessControl; +package org.caosdb.server.accessControl; -import caosdb.server.caching.Cache; import java.io.File; import java.io.IOException; import java.util.HashSet; @@ -36,6 +35,7 @@ import org.apache.commons.jcs.access.behavior.ICacheAccess; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.shiro.authz.AuthorizationException; +import org.caosdb.server.caching.Cache; import org.jvnet.libpam.PAMException; import org.jvnet.libpam.UnixUser; diff --git a/src/main/java/caosdb/server/accessControl/PamScriptCaller.java b/src/main/java/org/caosdb/server/accessControl/PamScriptCaller.java similarity index 96% rename from src/main/java/caosdb/server/accessControl/PamScriptCaller.java rename to src/main/java/org/caosdb/server/accessControl/PamScriptCaller.java index 4cf1836df953b78f0fccb4801a85205b11869b18..dc9137e0192cb73d35ae6579b760a8d4f56685b7 100644 --- a/src/main/java/caosdb/server/accessControl/PamScriptCaller.java +++ b/src/main/java/org/caosdb/server/accessControl/PamScriptCaller.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.accessControl; +package org.caosdb.server.accessControl; public interface PamScriptCaller { public boolean isValid(String username, String password); diff --git a/src/main/java/caosdb/server/accessControl/Principal.java b/src/main/java/org/caosdb/server/accessControl/Principal.java similarity index 91% rename from src/main/java/caosdb/server/accessControl/Principal.java rename to src/main/java/org/caosdb/server/accessControl/Principal.java index 3183d864bd5baecc4429cf22fc0ab3ca75d8ca15..fc96fb99670b51d0a128710722e2c10effed152a 100644 --- a/src/main/java/caosdb/server/accessControl/Principal.java +++ b/src/main/java/org/caosdb/server/accessControl/Principal.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.accessControl; +package org.caosdb.server.accessControl; -import caosdb.server.permissions.ResponsibleAgent; import java.util.HashMap; +import org.caosdb.server.permissions.ResponsibleAgent; import org.jdom2.Element; public class Principal implements ResponsibleAgent { @@ -47,6 +47,11 @@ public class Principal implements ResponsibleAgent { this(split[0], split[1]); } + public Principal(Principal principal) { + this.username = principal.username; + this.realm = principal.realm; + } + public String getRealm() { return this.realm; } diff --git a/src/main/java/caosdb/server/accessControl/RealmUsernamePasswordToken.java b/src/main/java/org/caosdb/server/accessControl/RealmUsernamePasswordToken.java similarity index 93% rename from src/main/java/caosdb/server/accessControl/RealmUsernamePasswordToken.java rename to src/main/java/org/caosdb/server/accessControl/RealmUsernamePasswordToken.java index e07db9a603991a09ffb74d155697bc9b1583489d..1d9343104a5ffea8f3d0db4eb0498ae210381f0a 100644 --- a/src/main/java/caosdb/server/accessControl/RealmUsernamePasswordToken.java +++ b/src/main/java/org/caosdb/server/accessControl/RealmUsernamePasswordToken.java @@ -20,13 +20,13 @@ * * ** end header */ -package caosdb.server.accessControl; +package org.caosdb.server.accessControl; import org.apache.shiro.authc.AuthenticationToken; public class RealmUsernamePasswordToken implements AuthenticationToken { - private static final long serialVersionUID = -6314149707379428753L; + private static final long serialVersionUID = 1970181902441118122L; String realm; String username; String password; diff --git a/src/main/java/caosdb/server/accessControl/Role.java b/src/main/java/org/caosdb/server/accessControl/Role.java similarity index 91% rename from src/main/java/caosdb/server/accessControl/Role.java rename to src/main/java/org/caosdb/server/accessControl/Role.java index e19e245905bc0f90b4e4b004fce75e2e1203eb4f..1a34b49974804ae202ceaf4044ff1f620eaa5d12 100644 --- a/src/main/java/caosdb/server/accessControl/Role.java +++ b/src/main/java/org/caosdb/server/accessControl/Role.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.accessControl; +package org.caosdb.server.accessControl; import java.io.Serializable; import org.jdom2.Element; public class Role implements Serializable { - private static final long serialVersionUID = -9212426446735375109L; + private static final long serialVersionUID = 8968219504349206982L; public String name = null; public String description = null; diff --git a/src/main/java/org/caosdb/server/accessControl/SelfValidatingAuthenticationToken.java b/src/main/java/org/caosdb/server/accessControl/SelfValidatingAuthenticationToken.java new file mode 100644 index 0000000000000000000000000000000000000000..1832563fb981b52da8c90168e7dae97d6dfbc487 --- /dev/null +++ b/src/main/java/org/caosdb/server/accessControl/SelfValidatingAuthenticationToken.java @@ -0,0 +1,233 @@ +/* + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2018 Research Group Biomedical Physics, + * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2020 Indiscale GmbH <info@indiscale.com> + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * + * 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 <https://www.gnu.org/licenses/>. + * + * ** end header + */ +package org.caosdb.server.accessControl; + +import java.util.Arrays; +import java.util.Collection; +import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.authc.AuthenticationToken; +import org.caosdb.server.utils.Utils; +import org.eclipse.jetty.util.ajax.JSON; + +/** + * These AuthenticationTokens are characterized by the following properties: + * + * <ul> + * <li>date: The creation time. + * <li>timeout: How long this token is valid after creation. + * <li>checksum: The checksum is calculated from all relevant parts of the authentication token + * (including the salt, timeout, permissions, roles, and date) and most importantly, the + * pepper which serves as a randomized password of the server. The salt makes it hard to guess + * the pepper by creating a rainbow table with plausible values for the other properties. + * <li>salt: Salt for the password checksum, may be used by inheriting classes. + * <li>pepper: A static property, generated when class is loaded and used until the server + * reboots. It servers as randomized password of the server. "In cryptography, a pepper is a + * secret added to an input such as a password prior to being hashed with a cryptographic hash + * function." (from: Pepper (cryptography), + * https://en.wikipedia.org/w/index.php?title=Pepper_(cryptography)&oldid=960047694 (last + * visited July 7, 2020)) In our case, the pepper is added to the token before hashing, but + * not exposed to the public, while the salt is. That also means that the resulting hash + * cannot be generated by any client nor be validated by any client, and that all tokens of + * this kind invalidate when the server reboots. + */ +public abstract class SelfValidatingAuthenticationToken extends Principal + implements AuthenticationToken { + + protected static final transient String PEPPER = Utils.getSecureFilename(32); + private static final long serialVersionUID = -7469302791917310460L; + // date is the token creation time, in ms since 1970 + protected final long date; + // token validity duration + protected final long timeout; + protected final String checksum; + protected final String salt; + protected final String[] permissions; + protected final String[] roles; + + public Collection<String> getPermissions() { + return Arrays.asList(this.permissions); + } + + public Collection<String> getRoles() { + return Arrays.asList(this.roles); + } + + public static final String getFreshSalt() { + // salt should be at least 8 octets long. https://www.ietf.org/rfc/rfc2898.txt + // let's double that + return Utils.getSecureFilename(16); + } + + protected static <T> T defaultIfNull(T val, T def) { + if (val != null) { + return val; + } + return def; + } + + public SelfValidatingAuthenticationToken( + final Principal principal, + final long date, + final long timeout, + final String salt, + final String checksum, + final String[] permissions, + final String[] roles) { + this(principal, date, timeout, salt, permissions, roles, checksum, false); + } + + private SelfValidatingAuthenticationToken( + final Principal principal, + final long date, + final long timeout, + final String salt, + final String[] permissions, + final String[] roles, + String checksum, + boolean newChecksum, + Object... fields) { + super(principal); + this.date = date; + this.timeout = timeout; + this.salt = salt; + this.permissions = defaultIfNull(permissions, new String[] {}); + this.roles = defaultIfNull(roles, new String[] {}); + if (fields.length > 0) setFields(fields); + // only calculate a checksum iff none is given and newChecksum is explicitly 'true'. + this.checksum = checksum == null && newChecksum ? calcChecksum() : checksum; + } + + /** Customizable customization method, will be called with the remaining constructor arguments. */ + protected abstract void setFields(Object[] fields); + + public SelfValidatingAuthenticationToken( + final Principal principal, + final long timeout, + final String[] permissions, + final String[] roles, + Object... fields) { + this( + principal, + System.currentTimeMillis(), + timeout, + getFreshSalt(), + permissions, + roles, + null, + true, + fields); + } + + public final String calcChecksum() { + return calcChecksum(PEPPER); + } + + @Override + public abstract String toString(); + + /** + * Implementation specific version of a peppered checksum. + * + * <p>For secure operation, implementing classes must make sure that the pepper is actually used + * in calculating the checksum and that the checksum can not be used to infer information about + * the pepper. This can be achieved for example by using the {@link calcChecksum(final Object... + * fields)} method. + */ + public abstract String calcChecksum(String pepper); + + /** No credentials (returns null), since this token is self-validating. */ + @Override + public Object getCredentials() { + return null; + } + + public long getExpires() { + return this.date + this.timeout; + } + + public long getTimeout() { + return this.timeout; + } + + public boolean isExpired() { + return System.currentTimeMillis() >= getExpires(); + } + + /** + * Test if the hash stored in `checksum` is equal to the one calculated using the secret pepper. + */ + public boolean isHashValid() { + final String other = calcChecksum(); + return this.checksum != null && this.checksum.equals(other); + } + + public boolean isValid() { + return !isExpired() && isHashValid(); + } + + /** Return the hash (SHA512) of the stringified arguments. */ + protected static String calcChecksum(final Object... fields) { + final StringBuilder sb = new StringBuilder(); + for (final Object field : fields) { + if (field != null) { + sb.append(field.toString()); + } + sb.append(":"); + } + return Utils.sha512(sb.toString(), null, 1); + } + + protected static String[] toStringArray(final Object[] array) { + final String[] ret = new String[array.length]; + for (int i = 0; i < ret.length; i++) { + ret[i] = (String) array[i]; + } + return ret; + } + + /** + * Parse a JSON string and return the generated token. Depending on the first element of the JSON, + * this is either (if it is "O") a OneTimeAuthenticationToken or (if it is "S") a SessionToken. + * + * @throws AuthenticationToken if the string could not be parsed into a token. + */ + public static SelfValidatingAuthenticationToken parse(String token) { + Object[] array = (Object[]) JSON.parse(token); + switch (array[0].toString()) { + case "O": + return OneTimeAuthenticationToken.parse(array); + case "S": + return SessionToken.parse(array); + default: + throw new AuthenticationException("Could not parse the authtoken string (unknown type)."); + } + } + + /** No "other" identity, so this returns itself. */ + @Override + public SelfValidatingAuthenticationToken getPrincipal() { + return this; + } +} diff --git a/src/main/java/org/caosdb/server/accessControl/SessionToken.java b/src/main/java/org/caosdb/server/accessControl/SessionToken.java new file mode 100644 index 0000000000000000000000000000000000000000..760f119541918a153cf8d4ca452fa0f9b7adced0 --- /dev/null +++ b/src/main/java/org/caosdb/server/accessControl/SessionToken.java @@ -0,0 +1,135 @@ +/* + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2018 Research Group Biomedical Physics, + * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2020 Indiscale GmbH <info@indiscale.com> + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * Copyright (C) 2020 Daniel Hornung <d.hornung@indiscale.com> + * + * 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 <https://www.gnu.org/licenses/>. + * + * ** end header + */ +package org.caosdb.server.accessControl; + +import org.apache.shiro.subject.Subject; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.ServerProperties; +import org.eclipse.jetty.util.ajax.JSON; + +/** + * Session tokens are formatted as JSON arrays with the following elements: + * + * <ul> + * <li>Anything but "O" (upper-case "o"), preferred is "S". + * <li>Realm + * <li>name within the Realm + * <li>list of roles + * <li>list of permissions + * <li>time of token generation (long, ms since 1970) + * <li>validity duration (long, ms) + * <li>salt + * <li>checksum + */ +public class SessionToken extends SelfValidatingAuthenticationToken { + + public SessionToken( + final Principal principal, + final long date, + final long timeout, + final String salt, + final String checksum, + final String[] permissions, + final String[] roles) { + super(principal, date, timeout, salt, checksum, permissions, roles); + } + + public SessionToken( + final Principal principal, + final long timeout, + final String[] permissions, + final String[] roles) { + super(principal, timeout, permissions, roles); + } + + private static final long serialVersionUID = 3739602277654194951L; + + public static SessionToken parse(final Object[] array) { + // array[0] is not used here, it was already consumed to determine the type of token. + final Principal principal = new Principal((String) array[1], (String) array[2]); + final String[] roles = toStringArray((Object[]) array[3]); + final String[] permissions = toStringArray((Object[]) array[4]); + final long date = (Long) array[5]; + final long timeout = (Long) array[6]; + final String salt = (String) array[7]; + final String checksum = (String) array[8]; + return new SessionToken(principal, date, timeout, salt, checksum, permissions, roles); + } + + private static SessionToken generate( + final Principal principal, final String[] permissions, final String[] roles) { + int timeout = + Integer.parseInt(CaosDBServer.getServerProperty(ServerProperties.KEY_SESSION_TIMEOUT_MS)); + + return new SessionToken(principal, timeout, permissions, roles); + } + + public static SessionToken generate(Subject subject) { + String[] permissions = new String[] {}; + String[] roles = new String[] {}; + if (subject.getPrincipal() instanceof SelfValidatingAuthenticationToken) { + SelfValidatingAuthenticationToken p = + (SelfValidatingAuthenticationToken) subject.getPrincipal(); + permissions = p.getPermissions().toArray(permissions); + roles = p.getRoles().toArray(roles); + } + return generate((Principal) subject.getPrincipal(), permissions, roles); + } + + /** Nothing to set in this implemention. */ + @Override + protected void setFields(Object[] fields) {} + + @Override + public String calcChecksum(String pepper) { + return calcChecksum( + "S", + this.getRealm(), + this.getUsername(), + this.date, + this.timeout, + this.salt, + calcChecksum((Object[]) this.permissions), + calcChecksum((Object[]) this.roles), + pepper); + } + + @Override + public String toString() { + return JSON.toString( + new Object[] { + "S", + this.getRealm(), + this.getUsername(), + this.roles, + this.permissions, + this.date, + this.timeout, + this.salt, + this.checksum + }); + } +} diff --git a/src/main/java/caosdb/server/accessControl/SessionTokenRealm.java b/src/main/java/org/caosdb/server/accessControl/SessionTokenRealm.java similarity index 89% rename from src/main/java/caosdb/server/accessControl/SessionTokenRealm.java rename to src/main/java/org/caosdb/server/accessControl/SessionTokenRealm.java index 6ee72d0295153051e5ad31a6fd0fa092ab53d6e3..d78ffb405a8470a005da54736e25fbd69340b7e5 100644 --- a/src/main/java/caosdb/server/accessControl/SessionTokenRealm.java +++ b/src/main/java/org/caosdb/server/accessControl/SessionTokenRealm.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.accessControl; +package org.caosdb.server.accessControl; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; @@ -37,13 +37,13 @@ public class SessionTokenRealm extends AuthenticatingRealm { (SelfValidatingAuthenticationToken) token; if (sessionToken.isValid()) { - return new SimpleAuthenticationInfo(sessionToken.getPrincipal(), null, getName()); + return new SimpleAuthenticationInfo(sessionToken, null, getName()); } return null; } public SessionTokenRealm() { - setAuthenticationTokenClass(SessionToken.class); + setAuthenticationTokenClass(SelfValidatingAuthenticationToken.class); setCredentialsMatcher(new AllowAllCredentialsMatcher()); setCachingEnabled(false); setAuthenticationCachingEnabled(false); diff --git a/src/main/java/caosdb/server/accessControl/UserSource.java b/src/main/java/org/caosdb/server/accessControl/UserSource.java similarity index 98% rename from src/main/java/caosdb/server/accessControl/UserSource.java rename to src/main/java/org/caosdb/server/accessControl/UserSource.java index 0ece8d5014227916feb1c50b986aaf4d9a9bf91b..ff9882bfbf581e3633d99c3a20c5113e1d329e55 100644 --- a/src/main/java/caosdb/server/accessControl/UserSource.java +++ b/src/main/java/org/caosdb/server/accessControl/UserSource.java @@ -22,7 +22,7 @@ * * ** end header */ -package caosdb.server.accessControl; +package org.caosdb.server.accessControl; import java.util.Map; import java.util.Set; diff --git a/src/main/java/caosdb/server/accessControl/UserSources.java b/src/main/java/org/caosdb/server/accessControl/UserSources.java similarity index 65% rename from src/main/java/caosdb/server/accessControl/UserSources.java rename to src/main/java/org/caosdb/server/accessControl/UserSources.java index d0f707ebaaec8aa97e9b87d760fc0631cbd2f72a..8f69c8c5c86faea903a29049c3a604121b8951ad 100644 --- a/src/main/java/caosdb/server/accessControl/UserSources.java +++ b/src/main/java/org/caosdb/server/accessControl/UserSources.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2020 Indiscale GmbH <info@indiscale.com> + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -20,16 +22,9 @@ * * ** end header */ -package caosdb.server.accessControl; - -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; -import caosdb.server.entity.Message; -import caosdb.server.transaction.RetrieveRoleTransaction; -import caosdb.server.transaction.RetrieveUserTransaction; -import caosdb.server.utils.ServerMessages; +package org.caosdb.server.accessControl; + import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.util.HashMap; @@ -37,19 +32,49 @@ import java.util.HashSet; import java.util.Set; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.config.Ini; -import org.apache.shiro.subject.PrincipalCollection; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.ServerProperties; +import org.caosdb.server.entity.Message; +import org.caosdb.server.permissions.Role; +import org.caosdb.server.transaction.RetrieveRoleTransaction; +import org.caosdb.server.transaction.RetrieveUserTransaction; +import org.caosdb.server.utils.ServerMessages; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * This singleton class is the primary resource for authenticating users and resolving principals to + * roles. + * + * <p>Key concepts: + * + * <ul> + * <li>User name: A string which identifies a user uniquely across one realm. Why is this so? + * Because it is possible, that two different people from collaborating work groups with + * similar names have the same user name in their group e.g. "mueller@uni1.de" and + * "mueller@uni2.de" or two people from different user groups use the name "admin". In the + * "mueller" example the domain name of the email is the realm of authentication. + * <li>Realm: A string which uniquely identifies "where a user comes from". It guarantees the + * authentication of a user with a particular user name. Currently the possible realms are + * quite limited. Only "CaosDB" (which is controlled by the internal user source) and "PAM" + * which delegates authentication to the host system via PAM (Pluggable Authentication Module) + * are known and extension is not too easy. + * <li>User Source: An instance which provides the access to a realm where users can be + * authenticated. + * <li>Principal: The combination of realm and user name - hence a system-wide unique identifier + * for users and the primary key to identifying who did what and who is allowed to to do what. + * </ul> + * + * @author Timm Fitschen (t.fitschen@indiscale.com) + */ public class UserSources extends HashMap<String, UserSource> { - public static final String ANONYMOUS_ROLE = "anonymous"; private static final Logger logger = LoggerFactory.getLogger(UserSources.class); public static final String KEY_DEFAULT_REALM = "defaultRealm"; - public static final String KEY_REALMS = "defaultRealm"; + public static final String KEY_REALMS = "realms"; public static final String KEY_REALM_CLASS = "class"; - private static final long serialVersionUID = 6782744064206400521L; + private static final long serialVersionUID = 256585362760388255L; private static final UserSource internalRealm = new InternalUserSource(); private static UserSources instance = new UserSources(); @@ -61,6 +86,11 @@ public class UserSources extends HashMap<String, UserSource> { private UserSources() { initMap(); this.put(getInternalRealm()); + if (this.map.getSection(Ini.DEFAULT_SECTION_NAME) == null + || !this.map.getSection(Ini.DEFAULT_SECTION_NAME).containsKey(KEY_REALMS)) { + // no realms defined + return; + } final String[] realms = this.map .getSectionProperty(Ini.DEFAULT_SECTION_NAME, KEY_REALMS) @@ -88,6 +118,8 @@ public class UserSources extends HashMap<String, UserSource> { } } + private Ini map = null; + public UserSource put(final UserSource src) { if (src.getName() == null) { throw new IllegalArgumentException("A user source's name must not be null."); @@ -103,21 +135,14 @@ public class UserSources extends HashMap<String, UserSource> { return instance.put(src); } - private Ini map = null; - public void initMap() { - this.map = null; - try { - final FileInputStream f = - new FileInputStream( - CaosDBServer.getServerProperty(ServerProperties.KEY_USER_SOURCES_INI_FILE)); - this.map = new Ini(); + this.map = new Ini(); + try (final FileInputStream f = + new FileInputStream( + CaosDBServer.getServerProperty(ServerProperties.KEY_USER_SOURCES_INI_FILE))) { this.map.load(f); - f.close(); - } catch (final FileNotFoundException e) { - e.printStackTrace(); } catch (final IOException e) { - e.printStackTrace(); + logger.debug("could not load usersources.ini", e); } } @@ -126,16 +151,19 @@ public class UserSources extends HashMap<String, UserSource> { * * @param realm * @param username - * @return + * @return A set of user roles. */ - public static Set<String> resolve(String realm, final String username) { - + public static Set<String> resolveRoles(String realm, final String username) { if (realm == null) { realm = guessRealm(username); } + UserSource userSource = instance.get(realm); + if (userSource == null) { + return null; + } // find all roles that are associated with this principal in this realm - final Set<String> ret = instance.get(realm).resolveRolesForUsername(username); + final Set<String> ret = userSource.resolveRolesForUsername(username); return ret; } @@ -165,19 +193,19 @@ public class UserSources extends HashMap<String, UserSource> { } public static String getDefaultRealm() { - return instance.map.getSectionProperty(Ini.DEFAULT_SECTION_NAME, KEY_DEFAULT_REALM); + return instance.map.getSectionProperty(Ini.DEFAULT_SECTION_NAME, KEY_DEFAULT_REALM, "CaosDB"); } - public static Set<String> resolve(final PrincipalCollection principals) { - if (principals.getPrimaryPrincipal() == AuthenticationUtils.ANONYMOUS_USER.getPrincipal()) { + // @todo Refactor name: resolveRoles(...)? + public static Set<String> resolve(final Principal principal) { + if (AnonymousAuthenticationToken.PRINCIPAL == principal) { // anymous has one role Set<String> roles = new HashSet<>(); - roles.add(ANONYMOUS_ROLE); + roles.add(Role.ANONYMOUS_ROLE.toString()); return roles; } - Principal primaryPrincipal = (Principal) principals.getPrimaryPrincipal(); - return resolve(primaryPrincipal.getRealm(), primaryPrincipal.getUsername()); + return resolveRoles(principal.getRealm(), principal.getUsername()); } public static boolean isRoleExisting(final String role) { diff --git a/src/main/java/caosdb/server/accessControl/UserStatus.java b/src/main/java/org/caosdb/server/accessControl/UserStatus.java similarity index 95% rename from src/main/java/caosdb/server/accessControl/UserStatus.java rename to src/main/java/org/caosdb/server/accessControl/UserStatus.java index 5acf24f0daf8891f21bdee83062d8c6ee6f77ab4..6091d3e146eb5eb835044f97d1dcbafd8d042135 100644 --- a/src/main/java/caosdb/server/accessControl/UserStatus.java +++ b/src/main/java/org/caosdb/server/accessControl/UserStatus.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.accessControl; +package org.caosdb.server.accessControl; public enum UserStatus { ACTIVE, diff --git a/src/main/java/caosdb/server/caching/Cache.java b/src/main/java/org/caosdb/server/caching/Cache.java similarity index 98% rename from src/main/java/caosdb/server/caching/Cache.java rename to src/main/java/org/caosdb/server/caching/Cache.java index 338b1d853fd0610be780362a0242193fa46eb320..fe5e12c5ec1e7a6acd83dbfb8f64ead676600840 100644 --- a/src/main/java/caosdb/server/caching/Cache.java +++ b/src/main/java/org/caosdb/server/caching/Cache.java @@ -22,7 +22,7 @@ * * ** end header */ -package caosdb.server.caching; +package org.caosdb.server.caching; import java.io.Serializable; import org.apache.commons.jcs.access.behavior.ICacheAccess; diff --git a/src/main/java/caosdb/server/caching/CacheHelper.java b/src/main/java/org/caosdb/server/caching/CacheHelper.java similarity index 96% rename from src/main/java/caosdb/server/caching/CacheHelper.java rename to src/main/java/org/caosdb/server/caching/CacheHelper.java index 32c854400310959a7834fe32a6f90de9e1b584d1..0dfd32da5bc125b242622384fcae54eee722e4ef 100644 --- a/src/main/java/caosdb/server/caching/CacheHelper.java +++ b/src/main/java/org/caosdb/server/caching/CacheHelper.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.caching; +package org.caosdb.server.caching; import java.io.Serializable; import org.apache.commons.jcs.access.behavior.ICacheAccess; diff --git a/src/main/java/caosdb/server/caching/JCSCacheHelper.java b/src/main/java/org/caosdb/server/caching/JCSCacheHelper.java similarity index 92% rename from src/main/java/caosdb/server/caching/JCSCacheHelper.java rename to src/main/java/org/caosdb/server/caching/JCSCacheHelper.java index 1ce455a949bcfb76a36815b3b14bcea89e676a4a..1613b8be8194425ab14e5e68b9215a0ba92be8d3 100644 --- a/src/main/java/caosdb/server/caching/JCSCacheHelper.java +++ b/src/main/java/org/caosdb/server/caching/JCSCacheHelper.java @@ -5,7 +5,7 @@ * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen * Copyright (C) 2019 IndiScale GmbH - * Copyright (C) 2019 Timm Fitschen (t.fitschen@indiscale.com) + * Copyright (C) 2019,2020 Timm Fitschen (t.fitschen@indiscale.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -22,10 +22,8 @@ * * ** end header */ -package caosdb.server.caching; +package org.caosdb.server.caching; -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; @@ -36,6 +34,8 @@ import org.apache.commons.jcs.JCS; import org.apache.commons.jcs.access.behavior.ICacheAccess; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.ServerProperties; /** * A CacheHelper implementation which is configured statically via the {@link @@ -88,6 +88,9 @@ public class JCSCacheHelper implements CacheHelper { } logger.info("Configuring JCS Caching with {}", config); } + + // If the JCS config is updated/reset, it has to be shut down before. + JCS.shutdown(); JCS.setConfigProperties(config); } diff --git a/src/main/java/org/caosdb/server/database/BackendTransaction.java b/src/main/java/org/caosdb/server/database/BackendTransaction.java new file mode 100644 index 0000000000000000000000000000000000000000..5bf978343d72272309d4f4ab0f039770419c87b8 --- /dev/null +++ b/src/main/java/org/caosdb/server/database/BackendTransaction.java @@ -0,0 +1,298 @@ +/* + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2018 Research Group Biomedical Physics, + * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2020 IndiScale GmbH + * Copyright (C) 2020 Timm Fitschen (t.fitschen@indiscale.com) + * + * 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 <https://www.gnu.org/licenses/>. + * + * ** end header + */ +package org.caosdb.server.database; + +import java.util.HashMap; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLDeleteEntityProperties; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLDeletePassword; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLDeleteRole; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLDeleteSparseEntity; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLDeleteUser; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLGetAllNames; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLGetChildren; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLGetDependentEntities; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLGetFileRecordByPath; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLGetIDByName; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLGetInfo; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLGetUpdateableChecksums; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLInsertEntityDatatype; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLInsertEntityProperties; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLInsertLinCon; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLInsertLogRecord; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLInsertParents; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLInsertRole; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLInsertSparseEntity; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLInsertTransactionHistory; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLIsSubType; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLRegisterSubDomain; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveAll; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveAllUncheckedFiles; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveDatatypes; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveLogRecord; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveParents; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrievePasswordValidator; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrievePermissionRules; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveProperties; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveQueryTemplateDefinition; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveRole; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveSparseEntity; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveUser; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLRetrieveVersionHistory; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLRuleLoader; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLSetFileCheckedTimestampImpl; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLSetFileChecksum; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLSetPassword; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLSetPermissionRules; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLSetQueryTemplateDefinition; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLSyncStats; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLUpdateSparseEntity; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLUpdateUser; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLUpdateUserRoles; +import org.caosdb.server.database.backend.implementation.UnixFileSystem.UnixFileSystemCheckHash; +import org.caosdb.server.database.backend.implementation.UnixFileSystem.UnixFileSystemCheckSize; +import org.caosdb.server.database.backend.implementation.UnixFileSystem.UnixFileSystemFileExists; +import org.caosdb.server.database.backend.implementation.UnixFileSystem.UnixFileSystemFileWasModifiedAfter; +import org.caosdb.server.database.backend.implementation.UnixFileSystem.UnixFileSystemGetFileIterator; +import org.caosdb.server.database.backend.interfaces.BackendTransactionImpl; +import org.caosdb.server.database.backend.interfaces.DeleteEntityPropertiesImpl; +import org.caosdb.server.database.backend.interfaces.DeletePasswordImpl; +import org.caosdb.server.database.backend.interfaces.DeleteRoleImpl; +import org.caosdb.server.database.backend.interfaces.DeleteSparseEntityImpl; +import org.caosdb.server.database.backend.interfaces.DeleteUserImpl; +import org.caosdb.server.database.backend.interfaces.FileCheckHash; +import org.caosdb.server.database.backend.interfaces.FileCheckSize; +import org.caosdb.server.database.backend.interfaces.FileExists; +import org.caosdb.server.database.backend.interfaces.FileWasModifiedAfter; +import org.caosdb.server.database.backend.interfaces.GetAllNamesImpl; +import org.caosdb.server.database.backend.interfaces.GetChildrenImpl; +import org.caosdb.server.database.backend.interfaces.GetDependentEntitiesImpl; +import org.caosdb.server.database.backend.interfaces.GetFileIteratorImpl; +import org.caosdb.server.database.backend.interfaces.GetFileRecordByPathImpl; +import org.caosdb.server.database.backend.interfaces.GetIDByNameImpl; +import org.caosdb.server.database.backend.interfaces.GetInfoImpl; +import org.caosdb.server.database.backend.interfaces.GetUpdateableChecksumsImpl; +import org.caosdb.server.database.backend.interfaces.InsertEntityDatatypeImpl; +import org.caosdb.server.database.backend.interfaces.InsertEntityPropertiesImpl; +import org.caosdb.server.database.backend.interfaces.InsertLinConImpl; +import org.caosdb.server.database.backend.interfaces.InsertLogRecordImpl; +import org.caosdb.server.database.backend.interfaces.InsertParentsImpl; +import org.caosdb.server.database.backend.interfaces.InsertRoleImpl; +import org.caosdb.server.database.backend.interfaces.InsertSparseEntityImpl; +import org.caosdb.server.database.backend.interfaces.InsertTransactionHistoryImpl; +import org.caosdb.server.database.backend.interfaces.IsSubTypeImpl; +import org.caosdb.server.database.backend.interfaces.RegisterSubDomainImpl; +import org.caosdb.server.database.backend.interfaces.RetrieveAllImpl; +import org.caosdb.server.database.backend.interfaces.RetrieveAllUncheckedFilesImpl; +import org.caosdb.server.database.backend.interfaces.RetrieveDatatypesImpl; +import org.caosdb.server.database.backend.interfaces.RetrieveLogRecordImpl; +import org.caosdb.server.database.backend.interfaces.RetrieveParentsImpl; +import org.caosdb.server.database.backend.interfaces.RetrievePasswordValidatorImpl; +import org.caosdb.server.database.backend.interfaces.RetrievePermissionRulesImpl; +import org.caosdb.server.database.backend.interfaces.RetrievePropertiesImpl; +import org.caosdb.server.database.backend.interfaces.RetrieveQueryTemplateDefinitionImpl; +import org.caosdb.server.database.backend.interfaces.RetrieveRoleImpl; +import org.caosdb.server.database.backend.interfaces.RetrieveSparseEntityImpl; +import org.caosdb.server.database.backend.interfaces.RetrieveUserImpl; +import org.caosdb.server.database.backend.interfaces.RetrieveVersionHistoryImpl; +import org.caosdb.server.database.backend.interfaces.RuleLoaderImpl; +import org.caosdb.server.database.backend.interfaces.SetFileCheckedTimestampImpl; +import org.caosdb.server.database.backend.interfaces.SetFileChecksumImpl; +import org.caosdb.server.database.backend.interfaces.SetPasswordImpl; +import org.caosdb.server.database.backend.interfaces.SetPermissionRulesImpl; +import org.caosdb.server.database.backend.interfaces.SetQueryTemplateDefinitionImpl; +import org.caosdb.server.database.backend.interfaces.SyncStatsImpl; +import org.caosdb.server.database.backend.interfaces.UpdateSparseEntityImpl; +import org.caosdb.server.database.backend.interfaces.UpdateUserImpl; +import org.caosdb.server.database.backend.interfaces.UpdateUserRolesImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.misc.TransactionBenchmark; +import org.caosdb.server.utils.UndoHandler; +import org.caosdb.server.utils.Undoable; + +public abstract class BackendTransaction implements Undoable { + + private final UndoHandler undoHandler = new UndoHandler(); + private Access access; + private TransactionBenchmark benchmark; + private static HashMap< + Class<? extends BackendTransactionImpl>, Class<? extends BackendTransactionImpl>> + impl = new HashMap<>(); + + protected abstract void execute(); + + public final void executeTransaction() { + final long t1 = System.currentTimeMillis(); + execute(); + final long t2 = System.currentTimeMillis(); + this.addMeasurement(this, t2 - t1); + } + + /** + * Intialiaze the adapters to the database backend. + * + * <p>Currently this is hard-coded to the MySQL-Backend but the architecture of this class is + * designed to make it easy in the future to choose other implementations (i.e. other back-ends) + */ + public static void init() { + if (impl.isEmpty()) { + setImpl(GetAllNamesImpl.class, MySQLGetAllNames.class); + setImpl(DeleteEntityPropertiesImpl.class, MySQLDeleteEntityProperties.class); + setImpl(DeleteSparseEntityImpl.class, MySQLDeleteSparseEntity.class); + setImpl(GetChildrenImpl.class, MySQLGetChildren.class); + setImpl(GetDependentEntitiesImpl.class, MySQLGetDependentEntities.class); + setImpl(GetIDByNameImpl.class, MySQLGetIDByName.class); + setImpl(GetInfoImpl.class, MySQLGetInfo.class); + setImpl(InsertEntityPropertiesImpl.class, MySQLInsertEntityProperties.class); + setImpl(InsertLinConImpl.class, MySQLInsertLinCon.class); + setImpl(InsertParentsImpl.class, MySQLInsertParents.class); + setImpl(InsertSparseEntityImpl.class, MySQLInsertSparseEntity.class); + setImpl(InsertTransactionHistoryImpl.class, MySQLInsertTransactionHistory.class); + setImpl(IsSubTypeImpl.class, MySQLIsSubType.class); + setImpl(UpdateSparseEntityImpl.class, MySQLUpdateSparseEntity.class); + setImpl(RetrieveAllImpl.class, MySQLRetrieveAll.class); + setImpl(RegisterSubDomainImpl.class, MySQLRegisterSubDomain.class); + setImpl(RetrieveDatatypesImpl.class, MySQLRetrieveDatatypes.class); + setImpl(RetrieveUserImpl.class, MySQLRetrieveUser.class); + setImpl(RetrieveParentsImpl.class, MySQLRetrieveParents.class); + setImpl(GetFileRecordByPathImpl.class, MySQLGetFileRecordByPath.class); + setImpl(RetrievePropertiesImpl.class, MySQLRetrieveProperties.class); + setImpl(RetrieveSparseEntityImpl.class, MySQLRetrieveSparseEntity.class); + setImpl(RuleLoaderImpl.class, MySQLRuleLoader.class); + setImpl(SyncStatsImpl.class, MySQLSyncStats.class); + setImpl(FileExists.class, UnixFileSystemFileExists.class); + setImpl(FileWasModifiedAfter.class, UnixFileSystemFileWasModifiedAfter.class); + setImpl(FileCheckHash.class, UnixFileSystemCheckHash.class); + setImpl(GetFileIteratorImpl.class, UnixFileSystemGetFileIterator.class); + setImpl(SetFileCheckedTimestampImpl.class, MySQLSetFileCheckedTimestampImpl.class); + setImpl(RetrieveAllUncheckedFilesImpl.class, MySQLRetrieveAllUncheckedFiles.class); + setImpl(UpdateUserImpl.class, MySQLUpdateUser.class); + setImpl(DeleteUserImpl.class, MySQLDeleteUser.class); + setImpl(SetPasswordImpl.class, MySQLSetPassword.class); + setImpl(RetrievePasswordValidatorImpl.class, MySQLRetrievePasswordValidator.class); + setImpl(DeletePasswordImpl.class, MySQLDeletePassword.class); + setImpl(GetUpdateableChecksumsImpl.class, MySQLGetUpdateableChecksums.class); + setImpl(FileCheckSize.class, UnixFileSystemCheckSize.class); + setImpl(InsertRoleImpl.class, MySQLInsertRole.class); + setImpl(RetrieveRoleImpl.class, MySQLRetrieveRole.class); + setImpl(DeleteRoleImpl.class, MySQLDeleteRole.class); + setImpl(SetPermissionRulesImpl.class, MySQLSetPermissionRules.class); + setImpl(RetrievePermissionRulesImpl.class, MySQLRetrievePermissionRules.class); + setImpl(UpdateUserRolesImpl.class, MySQLUpdateUserRoles.class); + setImpl(InsertLogRecordImpl.class, MySQLInsertLogRecord.class); + setImpl(RetrieveLogRecordImpl.class, MySQLRetrieveLogRecord.class); + setImpl(SetQueryTemplateDefinitionImpl.class, MySQLSetQueryTemplateDefinition.class); + setImpl( + RetrieveQueryTemplateDefinitionImpl.class, MySQLRetrieveQueryTemplateDefinition.class); + setImpl(InsertEntityDatatypeImpl.class, MySQLInsertEntityDatatype.class); + setImpl(RetrieveVersionHistoryImpl.class, MySQLRetrieveVersionHistory.class); + setImpl(SetFileChecksumImpl.class, MySQLSetFileChecksum.class); + } + } + + /** + * Execute this BackendTransaction, using the implementation given as an argument. + * + * <p>The implementation's benchmark is set to the corresponding sub-benchmark of this object's + * benchmark. + * + * @param t This BackendTransaction's execute() method will be called. + * @return The BackendTransaction which was passed as an argument. + */ + protected <K extends BackendTransaction> K execute(final K t) { + assert t != this; + this.undoHandler.append(t); + t.setAccess(this.access); + if (benchmark != null) { + t.setTransactionBenchmark(benchmark.getBenchmark(t.getClass())); + } + final long t1 = System.currentTimeMillis(); + t.execute(); + final long t2 = System.currentTimeMillis(); + this.addMeasurement(t, t2 - t1); + return t; + } + + public static <K extends BackendTransactionImpl, L extends K> void setImpl( + final Class<K> k, final Class<L> l) { + impl.put(k, l); + } + + public void setAccess(final Access access) { + this.access = access; + } + + @SuppressWarnings("unchecked") + protected <T extends BackendTransactionImpl> T getImplementation(final Class<T> clz) { + init(); + try { + Class<?> implclz = impl.get(clz); + final T ret = (T) implclz.getConstructor(Access.class).newInstance(this.access); + if (ret instanceof Undoable) { + this.undoHandler.append((Undoable) ret); + } + if (benchmark != null) { + ret.setTransactionBenchmark(benchmark.getBenchmark(ret.getClass())); + } + return ret; + } catch (final Exception e) { + throw new TransactionException(e); + } + } + + protected UndoHandler getUndoHandler() { + return this.undoHandler; + } + + @Override + public final void undo() { + this.undoHandler.undo(); + } + + @Override + public final void cleanUp() { + this.undoHandler.cleanUp(); + } + + boolean useCache() { + return this.access.useCache(); + } + + @Override + public String toString() { + return this.getClass().getSimpleName(); + } + + /** Set the benchmark object for this AbstractTransaction. */ + public void setTransactionBenchmark(TransactionBenchmark b) { + this.benchmark = b; + } + + public void addMeasurement(Object o, long time) { + if (this.benchmark != null) { + this.benchmark.addMeasurement(o, time); + } + } +} diff --git a/src/main/java/caosdb/server/database/CacheableBackendTransaction.java b/src/main/java/org/caosdb/server/database/CacheableBackendTransaction.java similarity index 88% rename from src/main/java/caosdb/server/database/CacheableBackendTransaction.java rename to src/main/java/org/caosdb/server/database/CacheableBackendTransaction.java index fc4c9659d9a8ea80393bebad945bd6badf9580c4..621fa31cd1603633fdb259591d29abf00c6312a4 100644 --- a/src/main/java/caosdb/server/database/CacheableBackendTransaction.java +++ b/src/main/java/org/caosdb/server/database/CacheableBackendTransaction.java @@ -4,8 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * Copyright (C) 2019 IndiScale GmbH - * Copyright (C) 2019 Timm Fitschen (t.fitschen@indiscale.com) + * Copyright (C) 2019,2020 IndiScale GmbH + * Copyright (C) 2019,2020 Timm Fitschen <t.fitschen@indiscale.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -22,11 +22,11 @@ * * ** end header */ -package caosdb.server.database; +package org.caosdb.server.database; -import caosdb.server.database.exceptions.TransactionException; import java.io.Serializable; import org.apache.commons.jcs.access.behavior.ICacheAccess; +import org.caosdb.server.database.exceptions.TransactionException; public abstract class CacheableBackendTransaction<K, V extends Serializable> extends BackendTransaction { @@ -51,7 +51,7 @@ public abstract class CacheableBackendTransaction<K, V extends Serializable> private final V execute(final K key) throws TransactionException { // get from cache if possible... if (cacheIsEnabled() && key != null) { - final V cached = getCache().get(getKey()); + final V cached = getCache().get(key); if (cached != null) { this.cached = true; return cached; @@ -64,7 +64,7 @@ public abstract class CacheableBackendTransaction<K, V extends Serializable> if (notCached != null) { if (cacheIsEnabled() && key != null) { // now cache if possible - getCache().put(getKey(), notCached); + getCache().put(key, notCached); } } return notCached; diff --git a/src/main/java/caosdb/server/database/ChainTransaction.java b/src/main/java/org/caosdb/server/database/ChainTransaction.java similarity index 91% rename from src/main/java/caosdb/server/database/ChainTransaction.java rename to src/main/java/org/caosdb/server/database/ChainTransaction.java index ccbd0e2b6751dbfd83a685ab687d3b0d044a9606..6adee64ade2b4633f33f4b0a5397628d63e05e7c 100644 --- a/src/main/java/caosdb/server/database/ChainTransaction.java +++ b/src/main/java/org/caosdb/server/database/ChainTransaction.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database; +package org.caosdb.server.database; -import caosdb.server.database.backend.interfaces.BackendTransactionImpl; import java.util.LinkedList; +import org.caosdb.server.database.backend.interfaces.BackendTransactionImpl; public class ChainTransaction<T extends BackendTransactionImpl> { private final LinkedList<T> chain = new LinkedList<T>(); diff --git a/src/main/java/caosdb/server/database/Database.java b/src/main/java/org/caosdb/server/database/Database.java similarity index 97% rename from src/main/java/caosdb/server/database/Database.java rename to src/main/java/org/caosdb/server/database/Database.java index d67acdff9d8fbacdbdefdfdeb5013c3838156461..797aadcced181febbc0539975ba1f46d8ee2d9de 100644 --- a/src/main/java/caosdb/server/database/Database.java +++ b/src/main/java/org/caosdb/server/database/Database.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.database; +package org.caosdb.server.database; public class Database { diff --git a/src/main/java/caosdb/server/database/DatabaseMonitor.java b/src/main/java/org/caosdb/server/database/DatabaseMonitor.java similarity index 90% rename from src/main/java/caosdb/server/database/DatabaseMonitor.java rename to src/main/java/org/caosdb/server/database/DatabaseMonitor.java index 6efd782f0f02eef34fbed97c433a70464c9e4322..ed98d1d6d88e3e797ce022c0880640d9a9128a0d 100644 --- a/src/main/java/caosdb/server/database/DatabaseMonitor.java +++ b/src/main/java/org/caosdb/server/database/DatabaseMonitor.java @@ -20,26 +20,26 @@ * * ** end header */ -package caosdb.server.database; - -import caosdb.server.database.access.Access; -import caosdb.server.database.access.AccessControlAccess; -import caosdb.server.database.access.InfoAccess; -import caosdb.server.database.access.InitAccess; -import caosdb.server.database.access.TransactionAccess; -import caosdb.server.entity.container.TransactionContainer; -import caosdb.server.transaction.AccessControlTransaction; -import caosdb.server.transaction.TransactionInterface; -import caosdb.server.transaction.WriteTransaction; -import caosdb.server.utils.Info; -import caosdb.server.utils.Initialization; -import caosdb.server.utils.Observable; -import caosdb.server.utils.Observer; -import caosdb.server.utils.Releasable; +package org.caosdb.server.database; + import java.util.Iterator; import java.util.LinkedList; import java.util.concurrent.Semaphore; import java.util.concurrent.locks.ReentrantLock; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.access.AccessControlAccess; +import org.caosdb.server.database.access.InfoAccess; +import org.caosdb.server.database.access.InitAccess; +import org.caosdb.server.database.access.TransactionAccess; +import org.caosdb.server.entity.container.TransactionContainer; +import org.caosdb.server.transaction.AccessControlTransaction; +import org.caosdb.server.transaction.TransactionInterface; +import org.caosdb.server.transaction.WriteTransaction; +import org.caosdb.server.utils.Info; +import org.caosdb.server.utils.Initialization; +import org.caosdb.server.utils.Observable; +import org.caosdb.server.utils.Observer; +import org.caosdb.server.utils.Releasable; /** * Acquire and release weak access. DatabaseMonitor uses this class for managing access to entities @@ -53,7 +53,7 @@ import java.util.concurrent.locks.ReentrantLock; */ class WeakAccessSemaphore extends Semaphore implements Observable, Releasable { - private static final long serialVersionUID = 4999687434687029136L; + private static final long serialVersionUID = -262226321839837533L; private int acquired = 0; // how many thread have weak access Semaphore block = new Semaphore(1, true); @@ -154,7 +154,7 @@ class WeakAccessSemaphore extends Semaphore implements Observable, Releasable { */ class StrongAccessLock extends ReentrantLock implements Observable, Releasable { - private static final long serialVersionUID = 1918369324107546576L; + private static final long serialVersionUID = -262226321839837533L; private WeakAccessSemaphore wa = null; private Thread allocator = null; private Thread acquirer = null; diff --git a/src/main/java/caosdb/server/database/DatabaseUtils.java b/src/main/java/org/caosdb/server/database/DatabaseUtils.java similarity index 86% rename from src/main/java/caosdb/server/database/DatabaseUtils.java rename to src/main/java/org/caosdb/server/database/DatabaseUtils.java index 84c38fa448b7d8a1035aa28ded7bbfcecc5a88b3..4f6a58a4fc50fa91170fad6139384bccb413fa81 100644 --- a/src/main/java/caosdb/server/database/DatabaseUtils.java +++ b/src/main/java/org/caosdb/server/database/DatabaseUtils.java @@ -20,30 +20,30 @@ * * ** end header */ -package caosdb.server.database; +package org.caosdb.server.database; -import caosdb.server.database.proto.FlatProperty; -import caosdb.server.database.proto.ProtoProperty; -import caosdb.server.database.proto.SparseEntity; -import caosdb.server.database.proto.VerySparseEntity; -import caosdb.server.datatype.AbstractCollectionDatatype; -import caosdb.server.datatype.CollectionValue; -import caosdb.server.datatype.IndexedSingleValue; -import caosdb.server.datatype.ReferenceValue; -import caosdb.server.datatype.SingleValue; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.Message; -import caosdb.server.entity.Role; -import caosdb.server.entity.StatementStatus; -import caosdb.server.entity.wrapper.Domain; -import caosdb.server.entity.wrapper.Parent; -import caosdb.server.entity.wrapper.Property; import com.google.common.base.Objects; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import org.caosdb.server.database.proto.FlatProperty; +import org.caosdb.server.database.proto.ProtoProperty; +import org.caosdb.server.database.proto.SparseEntity; +import org.caosdb.server.database.proto.VerySparseEntity; +import org.caosdb.server.datatype.AbstractCollectionDatatype; +import org.caosdb.server.datatype.CollectionValue; +import org.caosdb.server.datatype.IndexedSingleValue; +import org.caosdb.server.datatype.ReferenceValue; +import org.caosdb.server.datatype.SingleValue; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Message; +import org.caosdb.server.entity.Role; +import org.caosdb.server.entity.StatementStatus; +import org.caosdb.server.entity.wrapper.Domain; +import org.caosdb.server.entity.wrapper.Parent; +import org.caosdb.server.entity.wrapper.Property; public class DatabaseUtils { @@ -173,12 +173,7 @@ public class DatabaseUtils { while (rs.next()) { final FlatProperty fp = new FlatProperty(); fp.id = rs.getInt("PropertyID"); - - final String v = bytes2UTF8(rs.getBytes("PropertyValue")); - if (v != null) { - fp.value = v; - } - + fp.value = bytes2UTF8(rs.getBytes("PropertyValue")); fp.status = bytes2UTF8(rs.getBytes("PropertyStatus")); fp.idx = rs.getInt("PropertyIndex"); ret.add(fp); @@ -217,12 +212,11 @@ public class DatabaseUtils { ret.datatype = bytes2UTF8(rs.getBytes("Datatype")); ret.collection = bytes2UTF8(rs.getBytes("Collection")); - final String path = bytes2UTF8(rs.getBytes("FilePath")); - if (!rs.wasNull()) { - ret.filePath = path; - ret.fileSize = rs.getLong("FileSize"); - ret.fileHash = bytes2UTF8(rs.getBytes("FileHash")); - } + ret.filePath = bytes2UTF8(rs.getBytes("FilePath")); + ret.fileSize = rs.getLong("FileSize"); + ret.fileHash = bytes2UTF8(rs.getBytes("FileHash")); + + ret.versionId = bytes2UTF8(rs.getBytes("Version")); return ret; } @@ -261,7 +255,8 @@ public class DatabaseUtils { } } - private static void replace(final Property p, final HashMap<Integer, Property> domainMap) { + private static void replace( + final Property p, final HashMap<Integer, Property> domainMap, boolean isHead) { // ... find the corresponding domain and replace it ReferenceValue ref; try { @@ -270,6 +265,17 @@ public class DatabaseUtils { throw new RuntimeException("This should never happen."); } final EntityInterface replacement = domainMap.get((ref.getId())); + if (replacement == null) { + if (isHead) { + throw new NullPointerException("Replacement was null"); + } + // entity has been deleted (we are processing properties of an old entity version) + p.setValue(null); + p.addWarning( + new Message( + "The referenced entity has been deleted in the mean time and is not longer available.")); + return; + } if (replacement.isDescOverride()) { p.setDescOverride(true); p.setDescription(replacement.getDescription()); @@ -317,15 +323,18 @@ public class DatabaseUtils { } // loop over all properties + boolean isHead = + e.getVersion().getSuccessors() == null || e.getVersion().getSuccessors().isEmpty(); for (final Property p : protoProperties) { + // if this is a replacement if (p.getStatementStatus() == StatementStatus.REPLACEMENT) { - replace(p, domainMap); + replace(p, domainMap, isHead); } for (final Property subP : p.getProperties()) { if (subP.getStatementStatus() == StatementStatus.REPLACEMENT) { - replace(subP, domainMap); + replace(subP, domainMap, isHead); } } diff --git a/src/main/java/caosdb/server/database/access/AbstractAccess.java b/src/main/java/org/caosdb/server/database/access/AbstractAccess.java similarity index 92% rename from src/main/java/caosdb/server/database/access/AbstractAccess.java rename to src/main/java/org/caosdb/server/database/access/AbstractAccess.java index 8013c609577236761123c0902c35606be0017567..9d00a876e8db21446b88b6ab00dfeb12ee043c0d 100644 --- a/src/main/java/caosdb/server/database/access/AbstractAccess.java +++ b/src/main/java/org/caosdb/server/database/access/AbstractAccess.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.database.access; +package org.caosdb.server.database.access; -import caosdb.server.database.misc.DBHelper; -import caosdb.server.database.misc.RollBackHandler; -import caosdb.server.transaction.TransactionInterface; import java.util.HashMap; +import org.caosdb.server.database.misc.DBHelper; +import org.caosdb.server.database.misc.RollBackHandler; +import org.caosdb.server.transaction.TransactionInterface; public abstract class AbstractAccess<T extends TransactionInterface> implements Access { diff --git a/src/main/java/caosdb/server/database/access/Access.java b/src/main/java/org/caosdb/server/database/access/Access.java similarity index 92% rename from src/main/java/caosdb/server/database/access/Access.java rename to src/main/java/org/caosdb/server/database/access/Access.java index 0114f6723ab283f7f14094954e26001535203975..228e8e004aea7454a287bccd898794c2bb4f1b9c 100644 --- a/src/main/java/caosdb/server/database/access/Access.java +++ b/src/main/java/org/caosdb/server/database/access/Access.java @@ -20,9 +20,9 @@ * * ** end header */ -package caosdb.server.database.access; +package org.caosdb.server.database.access; -import caosdb.server.database.misc.DBHelper; +import org.caosdb.server.database.misc.DBHelper; public interface Access { diff --git a/src/main/java/caosdb/server/database/access/AccessControlAccess.java b/src/main/java/org/caosdb/server/database/access/AccessControlAccess.java similarity index 91% rename from src/main/java/caosdb/server/database/access/AccessControlAccess.java rename to src/main/java/org/caosdb/server/database/access/AccessControlAccess.java index 14e32a3d62d92077844779d07f5b282a74b5b0aa..450f0c61310e5706c450ad793c7485073393d4c9 100644 --- a/src/main/java/caosdb/server/database/access/AccessControlAccess.java +++ b/src/main/java/org/caosdb/server/database/access/AccessControlAccess.java @@ -20,9 +20,9 @@ * * ** end header */ -package caosdb.server.database.access; +package org.caosdb.server.database.access; -import caosdb.server.transaction.AccessControlTransaction; +import org.caosdb.server.transaction.AccessControlTransaction; public class AccessControlAccess extends AbstractAccess<AccessControlTransaction> { diff --git a/src/main/java/caosdb/server/database/access/InfoAccess.java b/src/main/java/org/caosdb/server/database/access/InfoAccess.java similarity index 93% rename from src/main/java/caosdb/server/database/access/InfoAccess.java rename to src/main/java/org/caosdb/server/database/access/InfoAccess.java index e26d7de1b868ca80d2cd1fd77f6ec06f2ba58bd9..3d66e67a2d243d753c98e6934688eb34e1e94c0e 100644 --- a/src/main/java/caosdb/server/database/access/InfoAccess.java +++ b/src/main/java/org/caosdb/server/database/access/InfoAccess.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database.access; +package org.caosdb.server.database.access; -import caosdb.server.utils.Info; import java.sql.SQLException; +import org.caosdb.server.utils.Info; public class InfoAccess extends AbstractAccess<Info> { diff --git a/src/main/java/caosdb/server/database/access/InitAccess.java b/src/main/java/org/caosdb/server/database/access/InitAccess.java similarity index 92% rename from src/main/java/caosdb/server/database/access/InitAccess.java rename to src/main/java/org/caosdb/server/database/access/InitAccess.java index b5b24d835f34ceaeb7b042b3e813859b71807133..1a6108cc62d4dd421d40128a5346ee2d216f6b9c 100644 --- a/src/main/java/caosdb/server/database/access/InitAccess.java +++ b/src/main/java/org/caosdb/server/database/access/InitAccess.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database.access; +package org.caosdb.server.database.access; -import caosdb.server.utils.Initialization; import java.sql.SQLException; +import org.caosdb.server.utils.Initialization; public class InitAccess extends AbstractAccess<Initialization> { diff --git a/src/main/java/caosdb/server/database/access/TransactionAccess.java b/src/main/java/org/caosdb/server/database/access/TransactionAccess.java similarity index 89% rename from src/main/java/caosdb/server/database/access/TransactionAccess.java rename to src/main/java/org/caosdb/server/database/access/TransactionAccess.java index 84f422afa9e13f532a33439a7eddd9dc02644b24..406d0fb6577f89c6d1c49627802e39a4514f6cfd 100644 --- a/src/main/java/caosdb/server/database/access/TransactionAccess.java +++ b/src/main/java/org/caosdb/server/database/access/TransactionAccess.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database.access; +package org.caosdb.server.database.access; -import caosdb.server.transaction.TransactionInterface; -import caosdb.server.utils.Releasable; +import org.caosdb.server.transaction.TransactionInterface; +import org.caosdb.server.utils.Releasable; public class TransactionAccess extends AbstractAccess<TransactionInterface> { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/ConnectionException.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/ConnectionException.java similarity index 88% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/ConnectionException.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/ConnectionException.java index 6e688f9ad5993f352f9de6047ef2a20ec3d8c3c7..83c334ac21fb929606144f84960966acde59df42 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/ConnectionException.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/ConnectionException.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; public class ConnectionException extends Exception { - private static final long serialVersionUID = 3581951559636079126L; + private static final long serialVersionUID = 6119424337789255870L; public ConnectionException(final Throwable t) { super(t); diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/DatabaseConnectionPool.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/DatabaseConnectionPool.java similarity index 94% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/DatabaseConnectionPool.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/DatabaseConnectionPool.java index 9700daf3a99b30e42baf8580f863998d7efe67a1..f77f810a93428a66247b6559e2bef2ac344cd5d9 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/DatabaseConnectionPool.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/DatabaseConnectionPool.java @@ -20,11 +20,8 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.CaosDBException; -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; import com.google.common.base.Objects; import java.sql.CallableStatement; import java.sql.Connection; @@ -32,6 +29,9 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; +import org.caosdb.server.CaosDBException; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.ServerProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import snaq.db.ConnectionPool; @@ -85,8 +85,7 @@ class DatabaseConnectionPool { + CaosDBServer.getServerProperty(ServerProperties.KEY_MYSQL_PORT) + "/" + CaosDBServer.getServerProperty(ServerProperties.KEY_MYSQL_DATABASE_NAME) - + "?noAccessToProcedureBodies=true&cacheCallableStmts=true&autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&connectionCollation=utf8_unicode_ci&characterSetResults=utf8&serverTimezone=CET"; - // + "?profileSQL=true&characterSetResults=utf8"; + + "?noAccessToProcedureBodies=true&autoReconnect=true&serverTimezone=UTC&characterEncoding=UTF-8"; final String user = CaosDBServer.getServerProperty(ServerProperties.KEY_MYSQL_USER_NAME); final String pwd = CaosDBServer.getServerProperty(ServerProperties.KEY_MYSQL_USER_PASSWORD); final ConnectionPool pool = new ConnectionPool("MySQL Pool", 2, 5, 0, 0, url, user, pwd); diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLDeleteEntityProperties.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLDeleteEntityProperties.java similarity index 83% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLDeleteEntityProperties.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLDeleteEntityProperties.java index 989291a6342dcd5d7319cb3963127587d9cac5f8..28285ae9a2890e6fc6d69b63e620810867035f50 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLDeleteEntityProperties.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLDeleteEntityProperties.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.DeleteEntityPropertiesImpl; -import caosdb.server.database.exceptions.IntegrityException; -import caosdb.server.database.exceptions.TransactionException; import java.sql.PreparedStatement; import java.sql.SQLIntegrityConstraintViolationException; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.DeleteEntityPropertiesImpl; +import org.caosdb.server.database.exceptions.IntegrityException; +import org.caosdb.server.database.exceptions.TransactionException; public class MySQLDeleteEntityProperties extends MySQLTransaction implements DeleteEntityPropertiesImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLDeletePassword.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLDeletePassword.java similarity index 84% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLDeletePassword.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLDeletePassword.java index da3c083a8b21e56338436b4156ae8f33eb3bda01..2569226e271b55a1785da7b548eeae93fbd4c262 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLDeletePassword.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLDeletePassword.java @@ -20,15 +20,15 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.DeletePasswordImpl; -import caosdb.server.database.exceptions.IntegrityException; -import caosdb.server.database.exceptions.TransactionException; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.SQLIntegrityConstraintViolationException; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.DeletePasswordImpl; +import org.caosdb.server.database.exceptions.IntegrityException; +import org.caosdb.server.database.exceptions.TransactionException; public class MySQLDeletePassword extends MySQLTransaction implements DeletePasswordImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLDeleteRole.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLDeleteRole.java similarity index 86% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLDeleteRole.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLDeleteRole.java index 6e5c278cf0581936285f1346508682b7304b17cb..8fd8d35fda6b99f7d79b245a10ace4ed9521e0ce 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLDeleteRole.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLDeleteRole.java @@ -20,13 +20,13 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.DeleteRoleImpl; -import caosdb.server.database.exceptions.TransactionException; import java.sql.PreparedStatement; import java.sql.SQLException; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.DeleteRoleImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class MySQLDeleteRole extends MySQLTransaction implements DeleteRoleImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLDeleteSparseEntity.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLDeleteSparseEntity.java similarity index 83% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLDeleteSparseEntity.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLDeleteSparseEntity.java index 8293754dcacef49b5ef28bdaba38632ed0771700..9f504f3f2690a6415179761b5a647b2a13bb95d0 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLDeleteSparseEntity.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLDeleteSparseEntity.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.DeleteSparseEntityImpl; -import caosdb.server.database.exceptions.IntegrityException; -import caosdb.server.database.exceptions.TransactionException; import java.sql.PreparedStatement; import java.sql.SQLIntegrityConstraintViolationException; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.DeleteSparseEntityImpl; +import org.caosdb.server.database.exceptions.IntegrityException; +import org.caosdb.server.database.exceptions.TransactionException; public class MySQLDeleteSparseEntity extends MySQLTransaction implements DeleteSparseEntityImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLDeleteUser.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLDeleteUser.java similarity index 88% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLDeleteUser.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLDeleteUser.java index c037b390fcbd116e6cde1dce7bff654e84c9c7e5..88b20e4a0186844cecce2cc2f5fd14423f5bf4c1 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLDeleteUser.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLDeleteUser.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.DeleteUserImpl; -import caosdb.server.database.exceptions.TransactionException; import java.sql.PreparedStatement; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.DeleteUserImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class MySQLDeleteUser extends MySQLTransaction implements DeleteUserImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLGetAllNames.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetAllNames.java similarity index 80% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLGetAllNames.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetAllNames.java index 060cf9b8a77ad15e430b34f06e2b17737dd27cc2..09cae6886c2daa94d93ab76539a3e1343f5aecbe 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLGetAllNames.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetAllNames.java @@ -1,15 +1,15 @@ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.DatabaseUtils; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.GetAllNamesImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.SparseEntity; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; +import org.caosdb.server.database.DatabaseUtils; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.GetAllNamesImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.SparseEntity; /** Retrieve name, role and acl of all entities from the MySQL backend. */ public class MySQLGetAllNames extends MySQLTransaction implements GetAllNamesImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLGetChildren.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetChildren.java similarity index 88% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLGetChildren.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetChildren.java index b230efae23cdc7769678a09f008c11cc5dd4851b..d63de2d530d0f32bf3d068e7d1351cfb9609ce79 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLGetChildren.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetChildren.java @@ -20,15 +20,15 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.GetChildrenImpl; -import caosdb.server.database.exceptions.TransactionException; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.List; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.GetChildrenImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class MySQLGetChildren extends MySQLTransaction implements GetChildrenImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLGetDependentEntities.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetDependentEntities.java similarity index 87% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLGetDependentEntities.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetDependentEntities.java index 2ef8208363d7ad2681f8b0690c09f863723f8f2f..7875ced0d89fd11ed14cf668bb9110f643c053c9 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLGetDependentEntities.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetDependentEntities.java @@ -20,15 +20,15 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.GetDependentEntitiesImpl; -import caosdb.server.database.exceptions.TransactionException; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.List; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.GetDependentEntitiesImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class MySQLGetDependentEntities extends MySQLTransaction implements GetDependentEntitiesImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLGetFileRecordByPath.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetFileRecordByPath.java similarity index 87% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLGetFileRecordByPath.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetFileRecordByPath.java index b929c923ba44c50d02fd4afd78645c20748c225c..9b147d289b337f63dd359ce604719d9e00a149be 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLGetFileRecordByPath.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetFileRecordByPath.java @@ -20,15 +20,15 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.GetFileRecordByPathImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.SparseEntity; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.GetFileRecordByPathImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.SparseEntity; public class MySQLGetFileRecordByPath extends MySQLTransaction implements GetFileRecordByPathImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLGetIDByName.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetIDByName.java similarity index 91% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLGetIDByName.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetIDByName.java index e9797640d98b6e9f2afb2b95ff3ea5103b623070..5a546ae1ae16c606a9b367cce94e1ceddf073239 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLGetIDByName.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetIDByName.java @@ -20,15 +20,15 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.GetIDByNameImpl; -import caosdb.server.database.exceptions.TransactionException; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.List; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.GetIDByNameImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class MySQLGetIDByName extends MySQLTransaction implements GetIDByNameImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLGetInfo.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetInfo.java similarity index 87% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLGetInfo.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetInfo.java index 5032f1855aab3d68d7b6670fb794d6e9dccc9336..2e7a110c6f42ffe2b489525509d742810119e187 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLGetInfo.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetInfo.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.GetInfoImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.ProtoInfo; import java.sql.PreparedStatement; import java.sql.ResultSet; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.GetInfoImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.ProtoInfo; public class MySQLGetInfo extends MySQLTransaction implements GetInfoImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLGetUpdateableChecksums.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetUpdateableChecksums.java similarity index 87% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLGetUpdateableChecksums.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetUpdateableChecksums.java index 534c6ad25df267395770db07ababa6dd9004ef04..cf4e0aa7816b7f119f610ad7a602abfbe01432e4 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLGetUpdateableChecksums.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLGetUpdateableChecksums.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.GetUpdateableChecksumsImpl; -import caosdb.server.database.exceptions.TransactionException; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.GetUpdateableChecksumsImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class MySQLGetUpdateableChecksums extends MySQLTransaction implements GetUpdateableChecksumsImpl { diff --git a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLHelper.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..2ad36235bd16e1cecde9908d334f643ebc127e54 --- /dev/null +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLHelper.java @@ -0,0 +1,192 @@ +/* + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2018 Research Group Biomedical Physics, + * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2020 Indiscale GmbH <info@indiscale.com> + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * + * 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 <https://www.gnu.org/licenses/>. + * + * ** end header + */ +package org.caosdb.server.database.backend.implementation.MySQL; + +import java.io.UnsupportedEncodingException; +import java.sql.CallableStatement; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.HashMap; +import org.caosdb.server.accessControl.Principal; +import org.caosdb.server.database.misc.DBHelper; +import org.caosdb.server.transaction.ChecksumUpdater; +import org.caosdb.server.transaction.TransactionInterface; +import org.caosdb.server.transaction.WriteTransaction; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provides cached statements for a MySQL back-end. + * + * @author tf + */ +public class MySQLHelper implements DBHelper { + + private Connection connection = null; + + private Logger logger = LoggerFactory.getLogger(getClass()); + + /** + * Initialize a transaction by calling the corresponding SQL procedure. + * + * <p>In the database, this adds a row to the transaction table with SRID, user and timestamp. + */ + public void initTransaction(Connection connection, WriteTransaction<?> transaction) + throws SQLException { + try (CallableStatement call = connection.prepareCall("CALL set_transaction(?,?,?,?,?)")) { + + String username = ((Principal) transaction.getTransactor().getPrincipal()).getUsername(); + String realm = ((Principal) transaction.getTransactor().getPrincipal()).getRealm(); + long seconds = transaction.getTimestamp().getUTCSeconds(); + int nanos = transaction.getTimestamp().getNanoseconds(); + byte[] srid = transaction.getSRID().getBytes("UTF-8"); + + call.setBytes(1, srid); + call.setString(2, username); + call.setString(3, realm); + call.setLong(4, seconds); + call.setInt(5, nanos); + call.execute(); + + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + System.exit(1); + } + } + + public Connection initConnection(TransactionInterface transaction) + throws ConnectionException, SQLException { + Connection connection; + connection = DatabaseConnectionPool.getConnection(); + + if (transaction instanceof ChecksumUpdater) { + connection.setReadOnly(false); + connection.setAutoCommit(false); + } else if (transaction instanceof WriteTransaction) { + connection.setReadOnly(false); + connection.setAutoCommit(false); + initTransaction(connection, (WriteTransaction<?>) transaction); + } else { + connection.setReadOnly(false); + connection.setAutoCommit(true); + } + + return connection; + } + + public Connection getConnection() throws SQLException, ConnectionException { + if (this.connection == null) { + this.connection = initConnection(this.transaction); + } + return this.connection; + } + + /** + * Prepare a statement from a string. Reuse prepared statements from the cache if available. + * + * @param statement + * @return + * @throws SQLException + * @throws ConnectionException + */ + public PreparedStatement prepareStatement(final String statement) + throws SQLException, ConnectionException { + if (this.stmtCache.containsKey(statement)) { + final PreparedStatement ret = this.stmtCache.get(statement); + if (!ret.isClosed()) { + return ret; + } + } + + final PreparedStatement stmt = getConnection().prepareStatement(statement); + this.stmtCache.put(statement, stmt); + return stmt; + } + + private HashMap<String, PreparedStatement> stmtCache = new HashMap<String, PreparedStatement>(); + + @Override + public void setHelped(final TransactionInterface transaction) { + this.transaction = transaction; + } + + private TransactionInterface transaction = null; + + /** Make all changes permanent. */ + @Override + public void commit() throws SQLException { + if (this.connection != null + && !this.connection.isClosed() + && !this.connection.getAutoCommit()) { + this.connection.commit(); + } + } + + /** + * Reset SRID variable, close all statements, roll back to last save point and close connection. + */ + @Override + public void cleanUp() { + + try { + if (this.connection != null && !this.connection.isClosed()) { + try (Statement s = connection.createStatement()) { + s.execute("SET @SRID = NULL"); + } catch (SQLException e) { + logger.error("Exception while resetting the @SRID variable.", e); + } + + // close all cached statements (if possible) + for (final PreparedStatement stmt : this.stmtCache.values()) { + try { + if (!stmt.isClosed()) { + stmt.close(); + } + } catch (final SQLException e) { + logger.warn("Exception while closing a prepared statement.", e); + } + } + + try { + if (!this.connection.getAutoCommit()) { + this.connection.rollback(); + } + } catch (final SQLException r) { + logger.warn("Exception during roll-back attempt.", r); + } + this.connection.close(); + } + } catch (final SQLException e) { + logger.warn("Exception during clean-up.", e); + } + + // clear everything + this.stmtCache.clear(); + this.stmtCache = null; + this.connection = null; + } +} diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertEntityDatatype.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertEntityDatatype.java similarity index 84% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertEntityDatatype.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertEntityDatatype.java index 47671864570c1a041b8b164a0f045fbf70b47987..c4cb7cf98e5da51f98d71b4c5f6fc91e6961892e 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertEntityDatatype.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertEntityDatatype.java @@ -1,12 +1,12 @@ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.InsertEntityDatatypeImpl; -import caosdb.server.database.exceptions.IntegrityException; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.SparseEntity; import java.sql.PreparedStatement; import java.sql.SQLIntegrityConstraintViolationException; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.InsertEntityDatatypeImpl; +import org.caosdb.server.database.exceptions.IntegrityException; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.SparseEntity; public class MySQLInsertEntityDatatype extends MySQLTransaction implements InsertEntityDatatypeImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertEntityProperties.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertEntityProperties.java similarity index 84% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertEntityProperties.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertEntityProperties.java index cbc01eb3572b2b8dad47e54eea3e430ac853ecd1..d4243d7712cc3982221e1e815cdbdaaa4561a205 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertEntityProperties.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertEntityProperties.java @@ -20,19 +20,19 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; import static java.sql.Types.BIGINT; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.InsertEntityPropertiesImpl; -import caosdb.server.database.exceptions.IntegrityException; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.FlatProperty; -import caosdb.server.datatype.AbstractDatatype.Table; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.SQLIntegrityConstraintViolationException; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.InsertEntityPropertiesImpl; +import org.caosdb.server.database.exceptions.IntegrityException; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.FlatProperty; +import org.caosdb.server.datatype.AbstractDatatype.Table; public class MySQLInsertEntityProperties extends MySQLTransaction implements InsertEntityPropertiesImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertLinCon.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertLinCon.java similarity index 85% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertLinCon.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertLinCon.java index e286212c1d2e365ecab24452be53a602e6f2c21e..b8ea787292e375fcda8b99caa4464bfdf32c3fd7 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertLinCon.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertLinCon.java @@ -20,13 +20,13 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.InsertLinConImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.LinCon; import java.sql.PreparedStatement; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.InsertLinConImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.LinCon; public class MySQLInsertLinCon extends MySQLTransaction implements InsertLinConImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertLogRecord.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertLogRecord.java similarity index 88% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertLogRecord.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertLogRecord.java index 054d13e575e9d4d45329f8626756934ac2cf50cf..6807808d18fb6ba9ce0a4ed9287ea21612cc2d2c 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertLogRecord.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertLogRecord.java @@ -20,15 +20,15 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.InsertLogRecordImpl; -import caosdb.server.database.exceptions.TransactionException; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.List; import java.util.logging.LogRecord; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.InsertLogRecordImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class MySQLInsertLogRecord extends MySQLTransaction implements InsertLogRecordImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertParents.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertParents.java similarity index 85% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertParents.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertParents.java index 87493cebfc2c6b7043427be2b490d5203f383ec9..a37bf066aa1573e67390f88bfe18bbed0d6dbb3b 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertParents.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertParents.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.InsertParentsImpl; -import caosdb.server.database.exceptions.TransactionException; import java.sql.PreparedStatement; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.InsertParentsImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class MySQLInsertParents extends MySQLTransaction implements InsertParentsImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertRole.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertRole.java similarity index 85% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertRole.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertRole.java index 796270973abeea2d247c6d12e12b7bfdcc41a622..66f5a888dd8aa7f429dbd1698ff8245e3efb021a 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertRole.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertRole.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.accessControl.Role; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.InsertRoleImpl; -import caosdb.server.database.exceptions.TransactionException; import java.sql.PreparedStatement; import java.sql.SQLException; +import org.caosdb.server.accessControl.Role; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.InsertRoleImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class MySQLInsertRole extends MySQLTransaction implements InsertRoleImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertSparseEntity.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertSparseEntity.java similarity index 85% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertSparseEntity.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertSparseEntity.java index 4ad9f5b6a3cc3e51c05bc83bbc9332807b79484d..1b945acf566db938f12847f758636dbfddeac3d1 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertSparseEntity.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertSparseEntity.java @@ -20,17 +20,18 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.InsertSparseEntityImpl; -import caosdb.server.database.exceptions.IntegrityException; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.SparseEntity; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLIntegrityConstraintViolationException; import java.sql.Types; +import org.caosdb.server.database.DatabaseUtils; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.InsertSparseEntityImpl; +import org.caosdb.server.database.exceptions.IntegrityException; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.SparseEntity; public class MySQLInsertSparseEntity extends MySQLTransaction implements InsertSparseEntityImpl { @@ -56,6 +57,7 @@ public class MySQLInsertSparseEntity extends MySQLTransaction implements InsertS try (final ResultSet rs = insertEntityStmt.executeQuery()) { if (rs.next()) { entity.id = rs.getInt("EntityID"); + entity.versionId = DatabaseUtils.bytes2UTF8(rs.getBytes("Version")); } else { throw new TransactionException("Didn't get new EntityID back."); } diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertTransactionHistory.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertTransactionHistory.java similarity index 88% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertTransactionHistory.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertTransactionHistory.java index f3563ce0881707677d9095b5787f99af9f7813d9..27b0f8a156ae6b5c936772bf03d0d8ed8da4e42e 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLInsertTransactionHistory.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLInsertTransactionHistory.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.InsertTransactionHistoryImpl; -import caosdb.server.database.exceptions.TransactionException; import java.sql.PreparedStatement; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.InsertTransactionHistoryImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class MySQLInsertTransactionHistory extends MySQLTransaction implements InsertTransactionHistoryImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLIsSubType.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLIsSubType.java similarity index 88% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLIsSubType.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLIsSubType.java index 5a9b1a3e8b06d003229b3265c2777d046abcb6ef..bb847de7bf86e6e8a49414a52933a7bb87cf8d60 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLIsSubType.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLIsSubType.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.IsSubTypeImpl; -import caosdb.server.database.exceptions.TransactionException; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.IsSubTypeImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class MySQLIsSubType extends MySQLTransaction implements IsSubTypeImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRegisterSubDomain.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRegisterSubDomain.java similarity index 88% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRegisterSubDomain.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRegisterSubDomain.java index 055177a879d5ebad2e63cc3b77d56864c7bda437..ca4997281c76ec18e54dd1c165ca082eee5e0893 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRegisterSubDomain.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRegisterSubDomain.java @@ -20,16 +20,16 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.RegisterSubDomainImpl; -import caosdb.server.database.exceptions.TransactionException; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayDeque; import java.util.Deque; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.RegisterSubDomainImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class MySQLRegisterSubDomain extends MySQLTransaction implements RegisterSubDomainImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveAll.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveAll.java similarity index 89% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveAll.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveAll.java index 7ae921315f55e94994a2868d5b0a9b8d8406542b..ec0c0c1b0a067d529ecb72309d7fe83a8b37f819 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveAll.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveAll.java @@ -20,17 +20,17 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.RetrieveAllImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.entity.Role; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.RetrieveAllImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.entity.Role; public class MySQLRetrieveAll extends MySQLTransaction implements RetrieveAllImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveAllUncheckedFiles.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveAllUncheckedFiles.java similarity index 91% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveAllUncheckedFiles.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveAllUncheckedFiles.java index 0e557da58074729b9c3635453dd4b84b657599bb..09a4e7c2edabea49617224fdb9159116f2cd742b 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveAllUncheckedFiles.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveAllUncheckedFiles.java @@ -20,16 +20,16 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.RetrieveAllUncheckedFilesImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.SparseEntity; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Iterator; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.RetrieveAllUncheckedFilesImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.SparseEntity; public class MySQLRetrieveAllUncheckedFiles extends MySQLTransaction implements RetrieveAllUncheckedFilesImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveDatatypes.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveDatatypes.java similarity index 87% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveDatatypes.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveDatatypes.java index a8e12672cf21592c23d8cea0aa22629b4b68855c..e085f0510a5c0a95f1e0a3bc2f702b4e345d706e 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveDatatypes.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveDatatypes.java @@ -20,17 +20,17 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.DatabaseUtils; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.RetrieveDatatypesImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.VerySparseEntity; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import org.caosdb.server.database.DatabaseUtils; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.RetrieveDatatypesImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.VerySparseEntity; public class MySQLRetrieveDatatypes extends MySQLTransaction implements RetrieveDatatypesImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveLogRecord.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveLogRecord.java similarity index 93% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveLogRecord.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveLogRecord.java index b675b967dda169ad57c8e721dbb82d10eb0563d4..bba36d2eb9de29fee40f023b9b97602d5b94b8a3 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveLogRecord.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveLogRecord.java @@ -20,11 +20,8 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.RetrieveLogRecordImpl; -import caosdb.server.database.exceptions.TransactionException; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.ObjectInputStream; @@ -35,6 +32,9 @@ import java.util.LinkedList; import java.util.List; import java.util.logging.Level; import java.util.logging.LogRecord; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.RetrieveLogRecordImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class MySQLRetrieveLogRecord extends MySQLTransaction implements RetrieveLogRecordImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveParents.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveParents.java similarity index 72% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveParents.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveParents.java index c1c430cfee6e7a6b88391aa02df072e918f8d692..7b8c0d48db3c84183c16b449822065e0c8d798b9 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveParents.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveParents.java @@ -20,17 +20,18 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.DatabaseUtils; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.RetrieveParentsImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.VerySparseEntity; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.Types; import java.util.ArrayList; +import org.caosdb.server.database.DatabaseUtils; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.RetrieveParentsImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.VerySparseEntity; public class MySQLRetrieveParents extends MySQLTransaction implements RetrieveParentsImpl { @@ -38,16 +39,22 @@ public class MySQLRetrieveParents extends MySQLTransaction implements RetrievePa super(access); } - private static final String stmtStr = "call retrieveEntityParents(?)"; + private static final String stmtStr = "call retrieveEntityParents(?, ?)"; @Override - public ArrayList<VerySparseEntity> execute(final Integer id) throws TransactionException { + public ArrayList<VerySparseEntity> execute(final Integer id, final String version) + throws TransactionException { try { ResultSet rs = null; try { final PreparedStatement prepareStatement = prepareStatement(stmtStr); prepareStatement.setInt(1, id); + if (version == null) { + prepareStatement.setNull(2, Types.VARBINARY); + } else { + prepareStatement.setString(2, version); + } rs = prepareStatement.executeQuery(); return DatabaseUtils.parseParentResultSet(rs); } finally { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrievePasswordValidator.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrievePasswordValidator.java similarity index 82% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrievePasswordValidator.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrievePasswordValidator.java index 9b951cba69f9b637e333bfb93f3459fc9a0366a4..1ff7dd7afd0b468a90d9e3b82faca1adc5cae84f 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrievePasswordValidator.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrievePasswordValidator.java @@ -20,19 +20,19 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import static caosdb.server.database.DatabaseUtils.bytes2UTF8; +import static org.caosdb.server.database.DatabaseUtils.bytes2UTF8; -import caosdb.server.accessControl.CredentialsValidator; -import caosdb.server.accessControl.HashPasswordValidator; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.RetrievePasswordValidatorImpl; -import caosdb.server.database.exceptions.TransactionException; import java.security.NoSuchAlgorithmException; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import org.caosdb.server.accessControl.CredentialsValidator; +import org.caosdb.server.accessControl.HashPasswordValidator; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.RetrievePasswordValidatorImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class MySQLRetrievePasswordValidator extends MySQLTransaction implements RetrievePasswordValidatorImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrievePermissionRules.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrievePermissionRules.java similarity index 88% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrievePermissionRules.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrievePermissionRules.java index 7428157e45156e18e0ce1819f731dd4729faee99..40767db34c2ba318637c87ebc7b21ba278c2c574 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrievePermissionRules.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrievePermissionRules.java @@ -20,17 +20,17 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.RetrievePermissionRulesImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.permissions.PermissionRule; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashSet; import java.util.Map; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.RetrievePermissionRulesImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.permissions.PermissionRule; import org.eclipse.jetty.util.ajax.JSON; public class MySQLRetrievePermissionRules extends MySQLTransaction diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveProperties.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveProperties.java similarity index 72% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveProperties.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveProperties.java index 8b9a547bac69cf221dbf7c204a93e95326bb484c..39de8692a48fb57b9ad22d0054bcd5bc3541e632 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveProperties.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveProperties.java @@ -20,19 +20,20 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; - -import caosdb.server.database.DatabaseUtils; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.RetrievePropertiesImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.FlatProperty; -import caosdb.server.database.proto.ProtoProperty; +package org.caosdb.server.database.backend.implementation.MySQL; + import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.Types; import java.util.ArrayList; import java.util.List; +import org.caosdb.server.database.DatabaseUtils; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.RetrievePropertiesImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.FlatProperty; +import org.caosdb.server.database.proto.ProtoProperty; public class MySQLRetrieveProperties extends MySQLTransaction implements RetrievePropertiesImpl { @@ -40,15 +41,17 @@ public class MySQLRetrieveProperties extends MySQLTransaction implements Retriev super(access); } - private static final String stmtStr = "call retrieveEntityProperties(?,?)"; - private static final String stmtStr2 = "call retrieveOverrides(?,?)"; + private static final String stmtStr = "call retrieveEntityProperties(?,?,?)"; + private static final String stmtStr2 = "call retrieveOverrides(?,?,?)"; @Override - public ArrayList<ProtoProperty> execute(final Integer entity) throws TransactionException { + public ArrayList<ProtoProperty> execute(final Integer entity, final String version) + throws TransactionException { try { final PreparedStatement prepareStatement = prepareStatement(stmtStr); - final List<FlatProperty> props = retrieveFlatPropertiesStage1(0, entity, prepareStatement); + final List<FlatProperty> props = + retrieveFlatPropertiesStage1(0, entity, version, prepareStatement); final ArrayList<ProtoProperty> protos = new ArrayList<ProtoProperty>(); for (final FlatProperty p : props) { @@ -56,7 +59,7 @@ public class MySQLRetrieveProperties extends MySQLTransaction implements Retriev proto.property = p; final List<FlatProperty> subProps = - retrieveFlatPropertiesStage1(entity, p.id, prepareStatement); + retrieveFlatPropertiesStage1(entity, p.id, version, prepareStatement); proto.subProperties = subProps; @@ -71,7 +74,10 @@ public class MySQLRetrieveProperties extends MySQLTransaction implements Retriev } private List<FlatProperty> retrieveFlatPropertiesStage1( - final Integer domain, final Integer entity, final PreparedStatement stmt) + final Integer domain, + final Integer entity, + final String version, + final PreparedStatement stmt) throws SQLException, ConnectionException { ResultSet rs = null; try { @@ -82,6 +88,12 @@ public class MySQLRetrieveProperties extends MySQLTransaction implements Retriev } stmt.setInt(2, entity); + if (version == null) { + stmt.setNull(3, Types.VARBINARY); + } else { + stmt.setString(3, version); + } + long t1 = System.currentTimeMillis(); rs = stmt.executeQuery(); long t2 = System.currentTimeMillis(); @@ -91,7 +103,7 @@ public class MySQLRetrieveProperties extends MySQLTransaction implements Retriev final PreparedStatement stmt2 = prepareStatement(stmtStr2); - retrieveOverrides(domain, entity, stmt2, props); + retrieveOverrides(domain, entity, version, stmt2, props); return props; } finally { @@ -104,6 +116,7 @@ public class MySQLRetrieveProperties extends MySQLTransaction implements Retriev private void retrieveOverrides( final Integer domain, final Integer entity, + final String version, final PreparedStatement stmt2, final List<FlatProperty> props) throws SQLException { @@ -112,6 +125,11 @@ public class MySQLRetrieveProperties extends MySQLTransaction implements Retriev try { stmt2.setInt(1, domain); stmt2.setInt(2, entity); + if (version == null) { + stmt2.setNull(3, Types.VARBINARY); + } else { + stmt2.setString(3, version); + } long t1 = System.currentTimeMillis(); rs = stmt2.executeQuery(); long t2 = System.currentTimeMillis(); diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveQueryTemplateDefinition.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveQueryTemplateDefinition.java similarity index 76% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveQueryTemplateDefinition.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveQueryTemplateDefinition.java index 92f2cd5fe4c26d796112baec5d908b9431187ae7..fd0efb8e8756cfb7bec596382356e1ea951ad484 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveQueryTemplateDefinition.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveQueryTemplateDefinition.java @@ -20,14 +20,15 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.RetrieveQueryTemplateDefinitionImpl; -import caosdb.server.database.exceptions.TransactionException; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.Types; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.RetrieveQueryTemplateDefinitionImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class MySQLRetrieveQueryTemplateDefinition extends MySQLTransaction implements RetrieveQueryTemplateDefinitionImpl { @@ -37,14 +38,19 @@ public class MySQLRetrieveQueryTemplateDefinition extends MySQLTransaction } public static final String STMT_RETRIEVE_QUERY_TEMPLATE_DEF = - "SELECT definition FROM query_template_def WHERE id=?"; + "call retrieveQueryTemplateDef(?,?)"; @Override - public String retrieve(final Integer id) { + public String retrieve(final Integer id, final String version) { try { final PreparedStatement stmt = prepareStatement(STMT_RETRIEVE_QUERY_TEMPLATE_DEF); stmt.setInt(1, id); + if (version == null) { + stmt.setNull(2, Types.VARBINARY); + } else { + stmt.setString(2, version); + } final ResultSet rs = stmt.executeQuery(); if (rs.next()) { return rs.getString("definition"); diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveRole.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveRole.java similarity index 86% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveRole.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveRole.java index 04cad3e9ad677e4e1d473ead7af06858b0e2a429..f0219040c47bc09fe2052d8e95a3ea83637e6aae 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveRole.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveRole.java @@ -20,15 +20,15 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.accessControl.Role; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.RetrieveRoleImpl; -import caosdb.server.database.exceptions.TransactionException; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import org.caosdb.server.accessControl.Role; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.RetrieveRoleImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class MySQLRetrieveRole extends MySQLTransaction implements RetrieveRoleImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveSparseEntity.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveSparseEntity.java similarity index 72% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveSparseEntity.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveSparseEntity.java index 2aff2aaedda70672eb676597a2e3ba7a1db14352..3775c1dd4f0b87eb36f43084776d58c0f14f5f80 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveSparseEntity.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveSparseEntity.java @@ -20,16 +20,17 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.DatabaseUtils; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.RetrieveSparseEntityImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.SparseEntity; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.Types; +import org.caosdb.server.database.DatabaseUtils; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.RetrieveSparseEntityImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.SparseEntity; /** * Retrieve a single SparseEntity by id. @@ -43,14 +44,19 @@ public class MySQLRetrieveSparseEntity extends MySQLTransaction super(access); } - private static final String stmtStr = "call retrieveEntity(?)"; + private static final String stmtStr = "call retrieveEntity(?,?)"; @Override - public SparseEntity execute(final int id) throws TransactionException { + public SparseEntity execute(final int id, final String version) throws TransactionException { try { final PreparedStatement preparedStatement = prepareStatement(stmtStr); preparedStatement.setInt(1, id); + if (version == null) { + preparedStatement.setNull(2, Types.VARBINARY); + } else { + preparedStatement.setString(2, version); + } try (final ResultSet rs = preparedStatement.executeQuery()) { if (rs.next()) { return DatabaseUtils.parseEntityResultSet(rs); diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveUser.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveUser.java similarity index 86% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveUser.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveUser.java index 97ef5084da95ccd56d760ae4e04aacab60c97665..bde1878db5d49b2da201b7d589c1ee8b8d73f656 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveUser.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveUser.java @@ -20,20 +20,20 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import static caosdb.server.database.DatabaseUtils.bytes2UTF8; +import static org.caosdb.server.database.DatabaseUtils.bytes2UTF8; -import caosdb.server.accessControl.Principal; -import caosdb.server.accessControl.UserStatus; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.RetrieveUserImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.ProtoUser; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashSet; +import org.caosdb.server.accessControl.Principal; +import org.caosdb.server.accessControl.UserStatus; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.RetrieveUserImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.ProtoUser; public class MySQLRetrieveUser extends MySQLTransaction implements RetrieveUserImpl { diff --git a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveVersionHistory.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveVersionHistory.java new file mode 100644 index 0000000000000000000000000000000000000000..7ecfbfb7ac70a4a5ec248eb0e2be2c590f0676aa --- /dev/null +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRetrieveVersionHistory.java @@ -0,0 +1,89 @@ +/* + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * + * 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 <https://www.gnu.org/licenses/>. + * + * ** end header + */ +package org.caosdb.server.database.backend.implementation.MySQL; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.LinkedList; +import org.caosdb.server.database.DatabaseUtils; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.RetrieveVersionHistoryImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.VersionHistoryItem; + +/** + * Transaction to retrieve all versions of an entity. + * + * <p>Creates a mapping ID :: (VersionHistoryItem) + */ +public class MySQLRetrieveVersionHistory extends MySQLTransaction + implements RetrieveVersionHistoryImpl { + + public static final String VERSION_HISTORY_STMT = "CALL get_version_history(?)"; + + public MySQLRetrieveVersionHistory(Access access) { + super(access); + } + + @Override + public HashMap<String, VersionHistoryItem> execute(Integer entityId) { + + HashMap<String, VersionHistoryItem> result = new HashMap<>(); + try { + PreparedStatement s = prepareStatement(VERSION_HISTORY_STMT); + s.setInt(1, entityId); + ResultSet rs = s.executeQuery(); + + while (rs.next()) { + String childId = DatabaseUtils.bytes2UTF8(rs.getBytes("child")); + String parentId = DatabaseUtils.bytes2UTF8(rs.getBytes("parent")); + Long childSeconds = rs.getLong("child_seconds"); + Integer childNanos = rs.getInt("child_nanos"); + String childUsername = DatabaseUtils.bytes2UTF8(rs.getBytes("child_username")); + String childRealm = DatabaseUtils.bytes2UTF8(rs.getBytes("child_realm")); + VersionHistoryItem v = result.get(childId); + if (v == null) { + v = new VersionHistoryItem(); + v.id = childId; + v.seconds = childSeconds; + v.nanos = childNanos; + v.username = childUsername; + v.realm = childRealm; + result.put(childId, v); + } + + if (parentId != null) { + if (v.parents == null) { + v.parents = new LinkedList<>(); + } + v.parents.add(parentId); + } + } + } catch (SQLException | ConnectionException e) { + throw new TransactionException(e); + } + return result; + } +} diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRuleLoader.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRuleLoader.java similarity index 85% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRuleLoader.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRuleLoader.java index a240a7dec99e881c73912e638bc13314c10b68af..525c3973e5267d336727e723a383aff575dd8493 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLRuleLoader.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLRuleLoader.java @@ -20,19 +20,19 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import static caosdb.server.database.DatabaseUtils.bytes2UTF8; +import static org.caosdb.server.database.DatabaseUtils.bytes2UTF8; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.RuleLoaderImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.Rule; -import caosdb.server.jobs.core.Mode; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.RuleLoaderImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.Rule; +import org.caosdb.server.jobs.core.Mode; public class MySQLRuleLoader extends MySQLTransaction implements RuleLoaderImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLSetFileCheckedTimestampImpl.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLSetFileCheckedTimestampImpl.java similarity index 86% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLSetFileCheckedTimestampImpl.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLSetFileCheckedTimestampImpl.java index 14214077dfb3fb6ae3e5d589e15e17929810cd3e..fa4c60ad1a688fa13ee8e1f82ee6a8a1649d6d4f 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLSetFileCheckedTimestampImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLSetFileCheckedTimestampImpl.java @@ -20,13 +20,13 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.SetFileCheckedTimestampImpl; -import caosdb.server.database.exceptions.TransactionException; import java.sql.PreparedStatement; import java.sql.SQLException; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.SetFileCheckedTimestampImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class MySQLSetFileCheckedTimestampImpl extends MySQLTransaction implements SetFileCheckedTimestampImpl { diff --git a/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLSetFileChecksum.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLSetFileChecksum.java new file mode 100644 index 0000000000000000000000000000000000000000..960457cb09d1e68ca64260bb30416c2716edd6fa --- /dev/null +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLSetFileChecksum.java @@ -0,0 +1,29 @@ +package org.caosdb.server.database.backend.implementation.MySQL; + +import java.sql.PreparedStatement; +import java.sql.SQLException; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.SetFileChecksumImpl; +import org.caosdb.server.database.exceptions.TransactionException; + +public class MySQLSetFileChecksum extends MySQLTransaction implements SetFileChecksumImpl { + + public MySQLSetFileChecksum(Access access) { + super(access); + } + + public static final String STMT_SET_CHECKSUM = + "UPDATE files SET hash = unhex(?) WHERE file_id = ?"; + + @Override + public void execute(Integer id, String checksum) { + try { + PreparedStatement stmt = prepareStatement(STMT_SET_CHECKSUM); + stmt.setInt(2, id); + stmt.setString(1, checksum); + stmt.execute(); + } catch (SQLException | ConnectionException e) { + throw new TransactionException(e); + } + } +} diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLSetPassword.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLSetPassword.java similarity index 89% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLSetPassword.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLSetPassword.java index cacbdb4dc7d88338691f3f70890a1caeb677d246..9972c3af019f092087158a9f85659af9cdd2b6dc 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLSetPassword.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLSetPassword.java @@ -20,18 +20,18 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.SetPasswordImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.utils.Utils; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.sql.PreparedStatement; import java.sql.SQLException; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.SetPasswordImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.utils.Utils; public class MySQLSetPassword extends MySQLTransaction implements SetPasswordImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLSetPermissionRules.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLSetPermissionRules.java similarity index 89% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLSetPermissionRules.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLSetPermissionRules.java index c4691e8a01540b7f0557a1c219970d411aa87cae..1569cd494c44eed6ebc083b8e5046ea6649f7ad1 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLSetPermissionRules.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLSetPermissionRules.java @@ -20,17 +20,17 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.SetPermissionRulesImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.permissions.PermissionRule; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.HashSet; import java.util.Map; import java.util.Set; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.SetPermissionRulesImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.permissions.PermissionRule; import org.eclipse.jetty.util.ajax.JSON; public class MySQLSetPermissionRules extends MySQLTransaction implements SetPermissionRulesImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLSetQueryTemplateDefinition.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLSetQueryTemplateDefinition.java similarity index 87% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLSetQueryTemplateDefinition.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLSetQueryTemplateDefinition.java index 29f87a3f399209f440b88bb04d545816fc0958b2..e938010ca56f85d7ad574e51d1b8ef7d88b6c5ad 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLSetQueryTemplateDefinition.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLSetQueryTemplateDefinition.java @@ -20,13 +20,13 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.SetQueryTemplateDefinitionImpl; -import caosdb.server.database.exceptions.TransactionException; import java.sql.PreparedStatement; import java.sql.SQLException; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.SetQueryTemplateDefinitionImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class MySQLSetQueryTemplateDefinition extends MySQLTransaction implements SetQueryTemplateDefinitionImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLSyncStats.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLSyncStats.java similarity index 94% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLSyncStats.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLSyncStats.java index 4cae9e41560cfddf05c1d7e015e38b7af419a55f..c874f21b14e15889cb0345303318ecf3504b7c05 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLSyncStats.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLSyncStats.java @@ -20,12 +20,8 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.SyncStatsImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.utils.ServerStat; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -36,6 +32,10 @@ import java.io.ObjectOutputStream; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.SyncStatsImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.utils.ServerStat; public class MySQLSyncStats extends MySQLTransaction implements SyncStatsImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLTransaction.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLTransaction.java similarity index 87% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLTransaction.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLTransaction.java index f116a136c1b3e1942ddc2400139db3c82210fac8..5b46579efeac34078fa176f03eb94206dc72f0e0 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLTransaction.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLTransaction.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.BackendTransactionImpl; -import caosdb.server.database.misc.DBHelper; -import caosdb.server.database.misc.TransactionBenchmark; import java.sql.PreparedStatement; import java.sql.SQLException; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.BackendTransactionImpl; +import org.caosdb.server.database.misc.DBHelper; +import org.caosdb.server.database.misc.TransactionBenchmark; public class MySQLTransaction implements BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLUpdateSparseEntity.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLUpdateSparseEntity.java similarity index 65% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLUpdateSparseEntity.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLUpdateSparseEntity.java index 4cc59f9d0f0a813bb92294f6fabb1cd51f43c151..1c8039253b4c5e74a8054dfa937fec23c55440e8 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLUpdateSparseEntity.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLUpdateSparseEntity.java @@ -20,17 +20,19 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.UpdateSparseEntityImpl; -import caosdb.server.database.exceptions.IntegrityException; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.SparseEntity; import java.sql.PreparedStatement; +import java.sql.ResultSet; import java.sql.SQLException; import java.sql.SQLIntegrityConstraintViolationException; import java.sql.Types; +import org.caosdb.server.database.DatabaseUtils; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.UpdateSparseEntityImpl; +import org.caosdb.server.database.exceptions.IntegrityException; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.SparseEntity; public class MySQLUpdateSparseEntity extends MySQLTransaction implements UpdateSparseEntityImpl { @@ -39,15 +41,31 @@ public class MySQLUpdateSparseEntity extends MySQLTransaction implements UpdateS } public static final String STMT_UPDATE_ENTITY = "call updateEntity(?,?,?,?,?,?,?)"; - public static final String STMT_UPDATE_FILE_PROPS = - "INSERT INTO files (hash, size, path, file_id) VALUES (unhex(?),?,?,?) ON DUPLICATE KEY UPDATE hash=unhex(?), size=?, path=?;"; + public static final String STMT_UPDATE_FILE_PROPS = "call setFileProperties(?,?,?,?)"; @Override public void execute(final SparseEntity spe) throws TransactionException { try { - final PreparedStatement updateEntityStmt = prepareStatement(STMT_UPDATE_ENTITY); + // file properties; + final PreparedStatement updateFilePropsStmt = prepareStatement(STMT_UPDATE_FILE_PROPS); + updateFilePropsStmt.setInt(1, spe.id); + if (spe.filePath != null) { + updateFilePropsStmt.setString(2, spe.filePath); + updateFilePropsStmt.setLong(3, spe.fileSize); + if (spe.fileHash != null) { + updateFilePropsStmt.setString(4, spe.fileHash); + } else { + updateFilePropsStmt.setNull(4, Types.VARCHAR); + } + } else { + updateFilePropsStmt.setNull(2, Types.VARCHAR); + updateFilePropsStmt.setNull(3, Types.BIGINT); + updateFilePropsStmt.setNull(4, Types.VARCHAR); + } + updateFilePropsStmt.execute(); // very sparse entity + final PreparedStatement updateEntityStmt = prepareStatement(STMT_UPDATE_ENTITY); updateEntityStmt.setInt(1, spe.id); updateEntityStmt.setString(2, spe.name); updateEntityStmt.setString(3, spe.description); @@ -59,28 +77,12 @@ public class MySQLUpdateSparseEntity extends MySQLTransaction implements UpdateS } updateEntityStmt.setString(6, spe.collection); updateEntityStmt.setString(7, spe.acl); - updateEntityStmt.execute(); + ResultSet rs = updateEntityStmt.executeQuery(); - // file properties; - if (spe.filePath != null) { - final PreparedStatement updateFilePropsStmt = prepareStatement(STMT_UPDATE_FILE_PROPS); - if (spe.fileHash != null) { - updateFilePropsStmt.setString(1, spe.fileHash); - updateFilePropsStmt.setString(5, spe.fileHash); - } else { - updateFilePropsStmt.setNull(1, Types.VARCHAR); - updateFilePropsStmt.setNull(5, Types.VARCHAR); - } - updateFilePropsStmt.setLong(2, spe.fileSize); - updateFilePropsStmt.setLong(6, spe.fileSize); - - updateFilePropsStmt.setString(3, spe.filePath); - updateFilePropsStmt.setString(7, spe.filePath); - - updateFilePropsStmt.setInt(4, spe.id); - - updateFilePropsStmt.execute(); + if (rs.next()) { + spe.versionId = DatabaseUtils.bytes2UTF8(rs.getBytes("Version")); } + } catch (final SQLIntegrityConstraintViolationException e) { throw new IntegrityException(e); } catch (final SQLException e) { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLUpdateUser.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLUpdateUser.java similarity index 88% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLUpdateUser.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLUpdateUser.java index 4d35ac31d0ab9ff5fc42ce6ac7da988e283f9899..bd368698956163a8473ead7507aac0ba2b83d552 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLUpdateUser.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLUpdateUser.java @@ -20,15 +20,15 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.UpdateUserImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.ProtoUser; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Types; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.UpdateUserImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.ProtoUser; public class MySQLUpdateUser extends MySQLTransaction implements UpdateUserImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLUpdateUserRoles.java b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLUpdateUserRoles.java similarity index 89% rename from src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLUpdateUserRoles.java rename to src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLUpdateUserRoles.java index 96b759a3a4e986da177a21e218bbad853b5e0ca5..62cb68bf58fc8269cc365fa167929ff79726499b 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/MySQL/MySQLUpdateUserRoles.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/MySQL/MySQLUpdateUserRoles.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.MySQL; +package org.caosdb.server.database.backend.implementation.MySQL; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.UpdateUserRolesImpl; -import caosdb.server.database.exceptions.TransactionException; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.HashSet; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.UpdateUserRolesImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class MySQLUpdateUserRoles extends MySQLTransaction implements UpdateUserRolesImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemCheckHash.java b/src/main/java/org/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemCheckHash.java similarity index 83% rename from src/main/java/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemCheckHash.java rename to src/main/java/org/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemCheckHash.java index 84a195b324ff456dde97271c22e3b14c17bf6131..e6b95a9925bbd560b9ccf80cdb6883efc2098f49 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemCheckHash.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemCheckHash.java @@ -20,16 +20,16 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.UnixFileSystem; +package org.caosdb.server.database.backend.implementation.UnixFileSystem; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.FileCheckHash; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.entity.Message; -import caosdb.server.utils.Hasher; import java.io.File; import java.io.IOException; import java.security.NoSuchAlgorithmException; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.FileCheckHash; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.entity.Message; +import org.caosdb.server.utils.Hasher; public class UnixFileSystemCheckHash extends UnixFileSystemTransaction implements FileCheckHash { diff --git a/src/main/java/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemCheckSize.java b/src/main/java/org/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemCheckSize.java similarity index 82% rename from src/main/java/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemCheckSize.java rename to src/main/java/org/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemCheckSize.java index 019b3925efd9ce22da8c945a3adcd4b586aa0d1a..c695ff58ec9ca0b41f7aaa1ce5513a5ec657d9a6 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemCheckSize.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemCheckSize.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.UnixFileSystem; +package org.caosdb.server.database.backend.implementation.UnixFileSystem; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.FileCheckSize; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.entity.Message; import java.io.File; import java.io.IOException; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.FileCheckSize; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.entity.Message; public class UnixFileSystemCheckSize extends UnixFileSystemTransaction implements FileCheckSize { diff --git a/src/main/java/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemFileExists.java b/src/main/java/org/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemFileExists.java similarity index 82% rename from src/main/java/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemFileExists.java rename to src/main/java/org/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemFileExists.java index cc163c7faede75fb216be2c99f532568a36b1f22..908d917c1b858eb7d6da77bfe90fae7e4f6c6289 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemFileExists.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemFileExists.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.UnixFileSystem; +package org.caosdb.server.database.backend.implementation.UnixFileSystem; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.FileExists; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.entity.Message; import java.io.File; import java.io.IOException; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.FileExists; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.entity.Message; public class UnixFileSystemFileExists extends UnixFileSystemTransaction implements FileExists { diff --git a/src/main/java/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemFileWasModifiedAfter.java b/src/main/java/org/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemFileWasModifiedAfter.java similarity index 82% rename from src/main/java/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemFileWasModifiedAfter.java rename to src/main/java/org/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemFileWasModifiedAfter.java index 6b98d37d2911e9853caa5c29e05e4392e433d17d..70c97fecd67af94aa153fa6e0c6b0c8154cc936d 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemFileWasModifiedAfter.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemFileWasModifiedAfter.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.UnixFileSystem; +package org.caosdb.server.database.backend.implementation.UnixFileSystem; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.FileWasModifiedAfter; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.entity.Message; import java.io.File; import java.io.IOException; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.FileWasModifiedAfter; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.entity.Message; public class UnixFileSystemFileWasModifiedAfter extends UnixFileSystemTransaction implements FileWasModifiedAfter { diff --git a/src/main/java/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemGetFileIterator.java b/src/main/java/org/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemGetFileIterator.java similarity index 89% rename from src/main/java/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemGetFileIterator.java rename to src/main/java/org/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemGetFileIterator.java index 5bd6cd56fa40dc8696a8471e33381f1ab2584639..89c275dd6d1fdd324f86f6cce6de179f795c7915 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemGetFileIterator.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemGetFileIterator.java @@ -20,16 +20,16 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.UnixFileSystem; +package org.caosdb.server.database.backend.implementation.UnixFileSystem; -import caosdb.server.FileSystem; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.GetFileIteratorImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.entity.Message; import java.io.File; import java.util.Arrays; import java.util.Iterator; +import org.caosdb.server.FileSystem; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.GetFileIteratorImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.entity.Message; public class UnixFileSystemGetFileIterator extends UnixFileSystemTransaction implements GetFileIteratorImpl { diff --git a/src/main/java/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemHelper.java b/src/main/java/org/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemHelper.java similarity index 87% rename from src/main/java/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemHelper.java rename to src/main/java/org/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemHelper.java index 5b197f3d4e6268e604aa27447f43a98857a5fec7..260a401fa6609dbfae363023a3ceb8b717bb87c7 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemHelper.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemHelper.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.UnixFileSystem; +package org.caosdb.server.database.backend.implementation.UnixFileSystem; -import caosdb.server.database.misc.DBHelper; -import caosdb.server.transaction.TransactionInterface; +import org.caosdb.server.database.misc.DBHelper; +import org.caosdb.server.transaction.TransactionInterface; public class UnixFileSystemHelper implements DBHelper { diff --git a/src/main/java/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemTransaction.java b/src/main/java/org/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemTransaction.java similarity index 84% rename from src/main/java/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemTransaction.java rename to src/main/java/org/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemTransaction.java index 63e87d6a4f968d3d4833111f9ca9875daf18d9cc..ccf137448ee445f86594017ffc28a09d24158bcb 100644 --- a/src/main/java/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemTransaction.java +++ b/src/main/java/org/caosdb/server/database/backend/implementation/UnixFileSystem/UnixFileSystemTransaction.java @@ -20,16 +20,16 @@ * * ** end header */ -package caosdb.server.database.backend.implementation.UnixFileSystem; +package org.caosdb.server.database.backend.implementation.UnixFileSystem; -import caosdb.server.FileSystem; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.BackendTransactionImpl; -import caosdb.server.database.misc.DBHelper; -import caosdb.server.database.misc.TransactionBenchmark; -import caosdb.server.entity.Message; import java.io.File; import java.io.IOException; +import org.caosdb.server.FileSystem; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.BackendTransactionImpl; +import org.caosdb.server.database.misc.DBHelper; +import org.caosdb.server.database.misc.TransactionBenchmark; +import org.caosdb.server.entity.Message; public abstract class UnixFileSystemTransaction implements BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/BackendTransactionImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/BackendTransactionImpl.java similarity index 90% rename from src/main/java/caosdb/server/database/backend/interfaces/BackendTransactionImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/BackendTransactionImpl.java index d4751f94cda0b0bdea703d5f207527ea756681f3..8a2dbb0cc67776e68cf6dd9a437754f233ae6190 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/BackendTransactionImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/BackendTransactionImpl.java @@ -20,9 +20,9 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.misc.TransactionBenchmark; +import org.caosdb.server.database.misc.TransactionBenchmark; public interface BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/DeleteEntityPropertiesImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/DeleteEntityPropertiesImpl.java similarity index 86% rename from src/main/java/caosdb/server/database/backend/interfaces/DeleteEntityPropertiesImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/DeleteEntityPropertiesImpl.java index d53bb92eaa64dfba603430351489d702d5d10d93..93b7023bf10fd1b035b8d8483bc328cfef5aa5c4 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/DeleteEntityPropertiesImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/DeleteEntityPropertiesImpl.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.utils.Undoable; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.utils.Undoable; public interface DeleteEntityPropertiesImpl extends BackendTransactionImpl, Undoable { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/DeletePasswordImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/DeletePasswordImpl.java similarity index 89% rename from src/main/java/caosdb/server/database/backend/interfaces/DeletePasswordImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/DeletePasswordImpl.java index 9def6b6326203df923a384ac3b58d89df9eda0d5..32c485a97776b0b24efaf32b8719f85b2a770cab 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/DeletePasswordImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/DeletePasswordImpl.java @@ -20,9 +20,9 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.exceptions.TransactionException; public interface DeletePasswordImpl extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/DeleteRoleImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/DeleteRoleImpl.java similarity index 89% rename from src/main/java/caosdb/server/database/backend/interfaces/DeleteRoleImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/DeleteRoleImpl.java index 230b3c04f4b11eefde2a4335c66a5ebcc1242219..0bd6c5c71921961032fa33741c35210ffb455915 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/DeleteRoleImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/DeleteRoleImpl.java @@ -20,9 +20,9 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.exceptions.TransactionException; public interface DeleteRoleImpl extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/DeleteSparseEntityImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/DeleteSparseEntityImpl.java similarity index 86% rename from src/main/java/caosdb/server/database/backend/interfaces/DeleteSparseEntityImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/DeleteSparseEntityImpl.java index 4c05ac0daabc7a23c2bfa85c9ca115ec85b5b1f9..30ee60609065c0ac02b5b40a143c0643d37b5667 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/DeleteSparseEntityImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/DeleteSparseEntityImpl.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.utils.Undoable; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.utils.Undoable; public interface DeleteSparseEntityImpl extends BackendTransactionImpl, Undoable { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/DeleteUserImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/DeleteUserImpl.java similarity index 89% rename from src/main/java/caosdb/server/database/backend/interfaces/DeleteUserImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/DeleteUserImpl.java index 4f717f738845886d0779d47e19003e64ef323461..3ee0a1e4f7cea5ee00810149b2da589217e8dfe7 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/DeleteUserImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/DeleteUserImpl.java @@ -20,9 +20,9 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.exceptions.TransactionException; public interface DeleteUserImpl extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/FileCheckHash.java b/src/main/java/org/caosdb/server/database/backend/interfaces/FileCheckHash.java similarity index 86% rename from src/main/java/caosdb/server/database/backend/interfaces/FileCheckHash.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/FileCheckHash.java index 11bc5cba2dc606ae02b1627b027a6c266fe43f67..edd0718c41d17f045009c1c84f1fe31260ac225f 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/FileCheckHash.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/FileCheckHash.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.utils.Hasher; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.utils.Hasher; public interface FileCheckHash extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/FileCheckSize.java b/src/main/java/org/caosdb/server/database/backend/interfaces/FileCheckSize.java similarity index 89% rename from src/main/java/caosdb/server/database/backend/interfaces/FileCheckSize.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/FileCheckSize.java index 36baac7422a73068ec9e37cb7636489ce6c4312d..bce3249865e8c9373ee26e59496a568a494b2021 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/FileCheckSize.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/FileCheckSize.java @@ -20,9 +20,9 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.exceptions.TransactionException; public interface FileCheckSize extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/FileExists.java b/src/main/java/org/caosdb/server/database/backend/interfaces/FileExists.java similarity index 89% rename from src/main/java/caosdb/server/database/backend/interfaces/FileExists.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/FileExists.java index 546b6a9decef489b128813dd944f3c7aa66dc281..9a5ab664547113477a1f3ae0175d7a6f37311d10 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/FileExists.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/FileExists.java @@ -20,9 +20,9 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.exceptions.TransactionException; public interface FileExists extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/FileWasModifiedAfter.java b/src/main/java/org/caosdb/server/database/backend/interfaces/FileWasModifiedAfter.java similarity index 89% rename from src/main/java/caosdb/server/database/backend/interfaces/FileWasModifiedAfter.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/FileWasModifiedAfter.java index 318a15a48c29f8e479ddb192ec24a7750ca1dbcd..08fccc584e1ae653b478abf22a34d4b57b6c4c89 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/FileWasModifiedAfter.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/FileWasModifiedAfter.java @@ -20,9 +20,9 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.exceptions.TransactionException; public interface FileWasModifiedAfter extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/GetAllNamesImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/GetAllNamesImpl.java similarity index 73% rename from src/main/java/caosdb/server/database/backend/interfaces/GetAllNamesImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/GetAllNamesImpl.java index 3a89e579d2713457c72ec2df73e1c1c936d50db2..9ca7a04052eef00c3202fa5b3375b3abe6d7fb54 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/GetAllNamesImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/GetAllNamesImpl.java @@ -1,7 +1,7 @@ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.proto.SparseEntity; import java.util.List; +import org.caosdb.server.database.proto.SparseEntity; /** * Interface for the retrieval of all known names from the backend. diff --git a/src/main/java/caosdb/server/database/backend/interfaces/GetChildrenImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/GetChildrenImpl.java similarity index 89% rename from src/main/java/caosdb/server/database/backend/interfaces/GetChildrenImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/GetChildrenImpl.java index 7f7f7450934787e7abae2ed3b1dbc27b3501e6fd..a58579feb9de5982a09629dfe018e564c4e62b55 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/GetChildrenImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/GetChildrenImpl.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; import java.util.List; +import org.caosdb.server.database.exceptions.TransactionException; public interface GetChildrenImpl extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/GetDependentEntitiesImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/GetDependentEntitiesImpl.java similarity index 89% rename from src/main/java/caosdb/server/database/backend/interfaces/GetDependentEntitiesImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/GetDependentEntitiesImpl.java index 1ed4cf5ffe6ebb5966bd942e6cbd37bacd369f40..ca63fac685ce97f75954b996ba9ee74013ae5b46 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/GetDependentEntitiesImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/GetDependentEntitiesImpl.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; import java.util.List; +import org.caosdb.server.database.exceptions.TransactionException; public interface GetDependentEntitiesImpl extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/GetFileIteratorImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/GetFileIteratorImpl.java similarity index 89% rename from src/main/java/caosdb/server/database/backend/interfaces/GetFileIteratorImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/GetFileIteratorImpl.java index 5288689936c67648de98de130c8249f92ec1b8f2..0b7e45707d66c945380a6398dea8f5f1a36cc604 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/GetFileIteratorImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/GetFileIteratorImpl.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; import java.util.Iterator; +import org.caosdb.server.database.exceptions.TransactionException; public interface GetFileIteratorImpl extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/GetFileRecordByPathImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/GetFileRecordByPathImpl.java similarity index 85% rename from src/main/java/caosdb/server/database/backend/interfaces/GetFileRecordByPathImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/GetFileRecordByPathImpl.java index d0dd185aff415ad8ed156b27e8d22e792b896916..e7f6966709cf34518e37ec42143f1dc8794ed5ff 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/GetFileRecordByPathImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/GetFileRecordByPathImpl.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.SparseEntity; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.SparseEntity; public interface GetFileRecordByPathImpl extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/GetIDByNameImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/GetIDByNameImpl.java similarity index 90% rename from src/main/java/caosdb/server/database/backend/interfaces/GetIDByNameImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/GetIDByNameImpl.java index 23a06a1dd4a4388cf43a83ecf237c23f0f9ed482..d788a3570ebd045549420456814786b5e0b15b42 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/GetIDByNameImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/GetIDByNameImpl.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; import java.util.List; +import org.caosdb.server.database.exceptions.TransactionException; public interface GetIDByNameImpl extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/GetInfoImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/GetInfoImpl.java similarity index 85% rename from src/main/java/caosdb/server/database/backend/interfaces/GetInfoImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/GetInfoImpl.java index 5281242461f39f9449a136ae44f5235b8dc167fa..d2bb1326e591d912a0562664ec2d26c0008827f9 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/GetInfoImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/GetInfoImpl.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.ProtoInfo; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.ProtoInfo; public interface GetInfoImpl extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/GetUpdateableChecksumsImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/GetUpdateableChecksumsImpl.java similarity index 89% rename from src/main/java/caosdb/server/database/backend/interfaces/GetUpdateableChecksumsImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/GetUpdateableChecksumsImpl.java index d7d3b142474f1e1398f9bc109fefad7b62e1c0c2..53aac4905a331a9f1e5fc71708cef9fdfa20efa5 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/GetUpdateableChecksumsImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/GetUpdateableChecksumsImpl.java @@ -20,9 +20,9 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.exceptions.TransactionException; public interface GetUpdateableChecksumsImpl extends BackendTransactionImpl { diff --git a/src/main/java/org/caosdb/server/database/backend/interfaces/InsertEntityDatatypeImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/InsertEntityDatatypeImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..6da8d5cf9a7534e58cfbe634ad4594da2b2b466c --- /dev/null +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/InsertEntityDatatypeImpl.java @@ -0,0 +1,8 @@ +package org.caosdb.server.database.backend.interfaces; + +import org.caosdb.server.database.proto.SparseEntity; +import org.caosdb.server.utils.Undoable; + +public interface InsertEntityDatatypeImpl extends BackendTransactionImpl, Undoable { + public abstract void execute(SparseEntity entity); +} diff --git a/src/main/java/caosdb/server/database/backend/interfaces/InsertEntityPropertiesImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/InsertEntityPropertiesImpl.java similarity index 80% rename from src/main/java/caosdb/server/database/backend/interfaces/InsertEntityPropertiesImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/InsertEntityPropertiesImpl.java index 14c76afaa6cf6372b8b35977b70ce1a18c276464..e45fe9ead23f963c3010577de61be02e7c00042f 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/InsertEntityPropertiesImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/InsertEntityPropertiesImpl.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.FlatProperty; -import caosdb.server.datatype.AbstractDatatype.Table; -import caosdb.server.utils.Undoable; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.FlatProperty; +import org.caosdb.server.datatype.AbstractDatatype.Table; +import org.caosdb.server.utils.Undoable; public interface InsertEntityPropertiesImpl extends BackendTransactionImpl, Undoable { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/InsertLinConImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/InsertLinConImpl.java similarity index 83% rename from src/main/java/caosdb/server/database/backend/interfaces/InsertLinConImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/InsertLinConImpl.java index 679f682441c0f5647d009874ef596a3df719acba..98ba022ecf7fb061a6d95190bc3b6f1007cf51ac 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/InsertLinConImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/InsertLinConImpl.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.LinCon; -import caosdb.server.utils.Undoable; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.LinCon; +import org.caosdb.server.utils.Undoable; public interface InsertLinConImpl extends BackendTransactionImpl, Undoable { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/InsertLogRecordImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/InsertLogRecordImpl.java similarity index 90% rename from src/main/java/caosdb/server/database/backend/interfaces/InsertLogRecordImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/InsertLogRecordImpl.java index 511e0ed4b1ffdb645b45a4db96283e0059b6726f..78bab8e251ff6e151963f1be8caf5e73211cc8e3 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/InsertLogRecordImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/InsertLogRecordImpl.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; import java.util.List; import java.util.logging.LogRecord; +import org.caosdb.server.database.exceptions.TransactionException; public interface InsertLogRecordImpl extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/InsertParentsImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/InsertParentsImpl.java similarity index 86% rename from src/main/java/caosdb/server/database/backend/interfaces/InsertParentsImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/InsertParentsImpl.java index f83aa32e633c113379926ddc5e3c9b6c9e4b7ae5..aa65abe60be758197c761be3d728437c53fefcf3 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/InsertParentsImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/InsertParentsImpl.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.utils.Undoable; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.utils.Undoable; public interface InsertParentsImpl extends BackendTransactionImpl, Undoable { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/InsertRoleImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/InsertRoleImpl.java similarity index 86% rename from src/main/java/caosdb/server/database/backend/interfaces/InsertRoleImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/InsertRoleImpl.java index 3ee2746cc93f8a47dbca675839360ea5297309e1..ff305cab73f58928774cfdbdba95dbc61dad3077 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/InsertRoleImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/InsertRoleImpl.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.accessControl.Role; -import caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.accessControl.Role; +import org.caosdb.server.database.exceptions.TransactionException; public interface InsertRoleImpl extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/InsertSparseEntityImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/InsertSparseEntityImpl.java similarity index 87% rename from src/main/java/caosdb/server/database/backend/interfaces/InsertSparseEntityImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/InsertSparseEntityImpl.java index 8ad9a9f7ac0608c4e1e51ba4783a985d0e20d985..33f46e97872bcd6a519d6980234b201639aa5e1e 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/InsertSparseEntityImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/InsertSparseEntityImpl.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.proto.SparseEntity; -import caosdb.server.utils.Undoable; +import org.caosdb.server.database.proto.SparseEntity; +import org.caosdb.server.utils.Undoable; public interface InsertSparseEntityImpl extends BackendTransactionImpl, Undoable { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/InsertTransactionHistoryImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/InsertTransactionHistoryImpl.java similarity index 87% rename from src/main/java/caosdb/server/database/backend/interfaces/InsertTransactionHistoryImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/InsertTransactionHistoryImpl.java index 0ccb5d1548670eca923bd0f845f68b00e7ce6df9..a0b7db433ef24c515946e3b4fb1556f2aa2a7c16 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/InsertTransactionHistoryImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/InsertTransactionHistoryImpl.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.utils.Undoable; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.utils.Undoable; public interface InsertTransactionHistoryImpl extends BackendTransactionImpl, Undoable { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/IsSubTypeImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/IsSubTypeImpl.java similarity index 89% rename from src/main/java/caosdb/server/database/backend/interfaces/IsSubTypeImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/IsSubTypeImpl.java index 7a4f9717d01817aa6e0ae3bde5a9b7df56a923d0..2e61c5fb1331ebd102e1e2034bc0ef6a47dcf5dc 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/IsSubTypeImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/IsSubTypeImpl.java @@ -20,9 +20,9 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.exceptions.TransactionException; public interface IsSubTypeImpl extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/RegisterSubDomainImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/RegisterSubDomainImpl.java similarity index 89% rename from src/main/java/caosdb/server/database/backend/interfaces/RegisterSubDomainImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/RegisterSubDomainImpl.java index d5e0c7d1437376d5096d0b248613fcee304457e0..e9df6f8897b4753a273be9877c8a5fa49b106932 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/RegisterSubDomainImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/RegisterSubDomainImpl.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; import java.util.Deque; +import org.caosdb.server.database.exceptions.TransactionException; public interface RegisterSubDomainImpl extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/RetrieveAllImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveAllImpl.java similarity index 89% rename from src/main/java/caosdb/server/database/backend/interfaces/RetrieveAllImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveAllImpl.java index 54f8755e6a96ccac44bb471fecfa41fe0b1a6e9f..0aaa9707136ab1fc3cb498c80e2a1ad33771b746 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/RetrieveAllImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveAllImpl.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; import java.util.List; +import org.caosdb.server.database.exceptions.TransactionException; public interface RetrieveAllImpl extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/RetrieveAllUncheckedFilesImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveAllUncheckedFilesImpl.java similarity index 86% rename from src/main/java/caosdb/server/database/backend/interfaces/RetrieveAllUncheckedFilesImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveAllUncheckedFilesImpl.java index 5d49a0e4a552e6faad4eeb6c9c9f8eb147b8fa65..031bfbf9a4566a6f5c1f7c017f86dcba81ed07ff 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/RetrieveAllUncheckedFilesImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveAllUncheckedFilesImpl.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.SparseEntity; import java.util.Iterator; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.SparseEntity; public interface RetrieveAllUncheckedFilesImpl extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/RetrieveDatatypesImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveDatatypesImpl.java similarity index 85% rename from src/main/java/caosdb/server/database/backend/interfaces/RetrieveDatatypesImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveDatatypesImpl.java index aa20a3ce8ad3aa599bf719c433128faf285f12ff..91c68dc56a31fe520d6b29c4b6780afe433f9039 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/RetrieveDatatypesImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveDatatypesImpl.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.VerySparseEntity; import java.util.ArrayList; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.VerySparseEntity; public interface RetrieveDatatypesImpl extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/RetrieveLogRecordImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveLogRecordImpl.java similarity index 90% rename from src/main/java/caosdb/server/database/backend/interfaces/RetrieveLogRecordImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveLogRecordImpl.java index 8fa00a0dc722213d264576b06679ac855484545f..b6646d269123d70a3b6d06a381c7a83792e1b659 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/RetrieveLogRecordImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveLogRecordImpl.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; import java.util.List; import java.util.logging.Level; import java.util.logging.LogRecord; +import org.caosdb.server.database.exceptions.TransactionException; public interface RetrieveLogRecordImpl extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/RetrieveParentsImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveParentsImpl.java similarity index 77% rename from src/main/java/caosdb/server/database/backend/interfaces/RetrieveParentsImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveParentsImpl.java index 551ee962d8768aa90b9f5aaed313c050f0873079..1948be05dbb69cb0259184bf03413edd6c61dbb1 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/RetrieveParentsImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveParentsImpl.java @@ -20,13 +20,14 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.VerySparseEntity; import java.util.ArrayList; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.VerySparseEntity; public interface RetrieveParentsImpl extends BackendTransactionImpl { - public ArrayList<VerySparseEntity> execute(Integer id) throws TransactionException; + public ArrayList<VerySparseEntity> execute(Integer id, String version) + throws TransactionException; } diff --git a/src/main/java/caosdb/server/database/backend/interfaces/RetrievePasswordValidatorImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrievePasswordValidatorImpl.java similarity index 85% rename from src/main/java/caosdb/server/database/backend/interfaces/RetrievePasswordValidatorImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/RetrievePasswordValidatorImpl.java index 9eaee5f0fdc80356047aadc9d5ae6787228de6c7..3b3c285181416b484e3d0636828f6ef422f921c3 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/RetrievePasswordValidatorImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrievePasswordValidatorImpl.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.accessControl.CredentialsValidator; -import caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.accessControl.CredentialsValidator; +import org.caosdb.server.database.exceptions.TransactionException; public interface RetrievePasswordValidatorImpl extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/RetrievePermissionRulesImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrievePermissionRulesImpl.java similarity index 86% rename from src/main/java/caosdb/server/database/backend/interfaces/RetrievePermissionRulesImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/RetrievePermissionRulesImpl.java index 01d2c20d4fdfece4e1f57281dcaf20ee635642ce..cdbb5eb994cba45762c64244b9a4c1a4b2f40c33 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/RetrievePermissionRulesImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrievePermissionRulesImpl.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.permissions.PermissionRule; import java.util.HashSet; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.permissions.PermissionRule; public interface RetrievePermissionRulesImpl extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/RetrievePropertiesImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrievePropertiesImpl.java similarity index 78% rename from src/main/java/caosdb/server/database/backend/interfaces/RetrievePropertiesImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/RetrievePropertiesImpl.java index 3c8449f7fc62581457091ea5ab0ccc5921b89a92..54dba75e7b84dcae38d33a8bbd0245288dba65ee 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/RetrievePropertiesImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrievePropertiesImpl.java @@ -20,13 +20,13 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.ProtoProperty; import java.util.ArrayList; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.ProtoProperty; public interface RetrievePropertiesImpl extends BackendTransactionImpl { - public ArrayList<ProtoProperty> execute(Integer id) throws TransactionException; + public ArrayList<ProtoProperty> execute(Integer id, String version) throws TransactionException; } diff --git a/src/main/java/caosdb/server/database/backend/interfaces/RetrieveQueryTemplateDefinitionImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveQueryTemplateDefinitionImpl.java similarity index 90% rename from src/main/java/caosdb/server/database/backend/interfaces/RetrieveQueryTemplateDefinitionImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveQueryTemplateDefinitionImpl.java index fee860ca2c0ee4341ae91a4a1736d518cd71a5e8..df144c796b9349699432945c861ac42c44045db0 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/RetrieveQueryTemplateDefinitionImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveQueryTemplateDefinitionImpl.java @@ -20,9 +20,9 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; public interface RetrieveQueryTemplateDefinitionImpl extends BackendTransactionImpl { - public String retrieve(final Integer id); + public String retrieve(Integer id, String version); } diff --git a/src/main/java/caosdb/server/database/backend/interfaces/RetrieveRoleImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveRoleImpl.java similarity index 86% rename from src/main/java/caosdb/server/database/backend/interfaces/RetrieveRoleImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveRoleImpl.java index 518cac1abb030d4cb0cafbb21f53a88e6e2b94c2..92fde36b07d205b59cbf5000da403d936f03fe35 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/RetrieveRoleImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveRoleImpl.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.accessControl.Role; -import caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.accessControl.Role; +import org.caosdb.server.database.exceptions.TransactionException; public interface RetrieveRoleImpl extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/RetrieveSparseEntityImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveSparseEntityImpl.java similarity index 79% rename from src/main/java/caosdb/server/database/backend/interfaces/RetrieveSparseEntityImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveSparseEntityImpl.java index 82a534c03182d577e7b27eca9b2ff9def1c60677..8bb790c98e2c45d788f7f1bd8ede6c7c4a2faa03 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/RetrieveSparseEntityImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveSparseEntityImpl.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.SparseEntity; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.SparseEntity; public interface RetrieveSparseEntityImpl extends BackendTransactionImpl { - public SparseEntity execute(int id) throws TransactionException; + public SparseEntity execute(int id, String version) throws TransactionException; } diff --git a/src/main/java/caosdb/server/database/backend/interfaces/RetrieveUserImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveUserImpl.java similarity index 82% rename from src/main/java/caosdb/server/database/backend/interfaces/RetrieveUserImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveUserImpl.java index ffb1f16a7227c845c8b4c51f5dd0e97ac5f33f4e..2ff8286331add6143d76d18562935d795ba85cff 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/RetrieveUserImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveUserImpl.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.accessControl.Principal; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.ProtoUser; +import org.caosdb.server.accessControl.Principal; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.ProtoUser; public interface RetrieveUserImpl extends BackendTransactionImpl { diff --git a/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveVersionHistoryImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveVersionHistoryImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..50b6e13ca8eeb4b6b404ba3e9deb776111e5011e --- /dev/null +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/RetrieveVersionHistoryImpl.java @@ -0,0 +1,9 @@ +package org.caosdb.server.database.backend.interfaces; + +import java.util.HashMap; +import org.caosdb.server.database.proto.VersionHistoryItem; + +public interface RetrieveVersionHistoryImpl extends BackendTransactionImpl { + + public HashMap<String, VersionHistoryItem> execute(Integer entityId); +} diff --git a/src/main/java/caosdb/server/database/backend/interfaces/RuleLoaderImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/RuleLoaderImpl.java similarity index 86% rename from src/main/java/caosdb/server/database/backend/interfaces/RuleLoaderImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/RuleLoaderImpl.java index c1e84dd3f97ab9fc1f2b9e477a2df120119c9356..151e3d9d21d02d953cffeec8a55b4e01377fc023 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/RuleLoaderImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/RuleLoaderImpl.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.Rule; import java.util.ArrayList; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.Rule; public interface RuleLoaderImpl extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/SetFileCheckedTimestampImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/SetFileCheckedTimestampImpl.java similarity index 89% rename from src/main/java/caosdb/server/database/backend/interfaces/SetFileCheckedTimestampImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/SetFileCheckedTimestampImpl.java index eab362764d5fd6fe4392c375a2bb324d26ba895d..a398353978b430bbc655ad78b1cadbfcc91f1d9e 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/SetFileCheckedTimestampImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/SetFileCheckedTimestampImpl.java @@ -20,9 +20,9 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.exceptions.TransactionException; public interface SetFileCheckedTimestampImpl extends BackendTransactionImpl { diff --git a/src/main/java/org/caosdb/server/database/backend/interfaces/SetFileChecksumImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/SetFileChecksumImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..ca33df8987aa4f82051feaaff936ea29455198a4 --- /dev/null +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/SetFileChecksumImpl.java @@ -0,0 +1,6 @@ +package org.caosdb.server.database.backend.interfaces; + +public interface SetFileChecksumImpl extends BackendTransactionImpl { + + void execute(Integer id, String checksum); +} diff --git a/src/main/java/caosdb/server/database/backend/interfaces/SetPasswordImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/SetPasswordImpl.java similarity index 89% rename from src/main/java/caosdb/server/database/backend/interfaces/SetPasswordImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/SetPasswordImpl.java index 6e4c951feb55d27b61f60a699f315d18e2662a3e..e60f578879ae1dde60c257e7b7dadd523319daa1 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/SetPasswordImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/SetPasswordImpl.java @@ -20,9 +20,9 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.exceptions.TransactionException; public interface SetPasswordImpl extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/SetPermissionRulesImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/SetPermissionRulesImpl.java similarity index 86% rename from src/main/java/caosdb/server/database/backend/interfaces/SetPermissionRulesImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/SetPermissionRulesImpl.java index 29a28415012b7fee4eb2a1219729e293db6f78cf..89ab9bd13acfc67e8d500b3645ffc1770b183c55 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/SetPermissionRulesImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/SetPermissionRulesImpl.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.permissions.PermissionRule; import java.util.Set; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.permissions.PermissionRule; public interface SetPermissionRulesImpl extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/SetQueryTemplateDefinitionImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/SetQueryTemplateDefinitionImpl.java similarity index 94% rename from src/main/java/caosdb/server/database/backend/interfaces/SetQueryTemplateDefinitionImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/SetQueryTemplateDefinitionImpl.java index 4d6695fe5d8fe574c44ad39a1342cf43a2628d33..aee26c5e53117028a9de91911cf9710a4164b6a7 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/SetQueryTemplateDefinitionImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/SetQueryTemplateDefinitionImpl.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; public interface SetQueryTemplateDefinitionImpl extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/SyncStatsImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/SyncStatsImpl.java similarity index 87% rename from src/main/java/caosdb/server/database/backend/interfaces/SyncStatsImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/SyncStatsImpl.java index 6a4d1d39cf607f79295bc3e761fe40912e5f5c31..d5a15f0e88cdc4be6e3b726a559f766e053bda2e 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/SyncStatsImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/SyncStatsImpl.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.utils.ServerStat; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.utils.ServerStat; public interface SyncStatsImpl extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/UpdateSparseEntityImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/UpdateSparseEntityImpl.java similarity index 83% rename from src/main/java/caosdb/server/database/backend/interfaces/UpdateSparseEntityImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/UpdateSparseEntityImpl.java index f35832097bfb2b1738c343fceb51c8b259e10f4a..e7cb2612d1f90c826004fc168b355c1537574e00 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/UpdateSparseEntityImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/UpdateSparseEntityImpl.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.SparseEntity; -import caosdb.server.utils.Undoable; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.SparseEntity; +import org.caosdb.server.utils.Undoable; public interface UpdateSparseEntityImpl extends BackendTransactionImpl, Undoable { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/UpdateUserImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/UpdateUserImpl.java similarity index 85% rename from src/main/java/caosdb/server/database/backend/interfaces/UpdateUserImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/UpdateUserImpl.java index 5479c13fd1fdf4cb59996816a778494328f03cfa..eb26002c1163295d9dd00c32bd8d092ad26b2b55 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/UpdateUserImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/UpdateUserImpl.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.ProtoUser; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.ProtoUser; public interface UpdateUserImpl extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/interfaces/UpdateUserRolesImpl.java b/src/main/java/org/caosdb/server/database/backend/interfaces/UpdateUserRolesImpl.java similarity index 90% rename from src/main/java/caosdb/server/database/backend/interfaces/UpdateUserRolesImpl.java rename to src/main/java/org/caosdb/server/database/backend/interfaces/UpdateUserRolesImpl.java index 5d1763b6c74ba8b5ca55b317bf708c1bfd2bbda9..f2abfbe3cb7846f16e21d8f9a719ad708884841c 100644 --- a/src/main/java/caosdb/server/database/backend/interfaces/UpdateUserRolesImpl.java +++ b/src/main/java/org/caosdb/server/database/backend/interfaces/UpdateUserRolesImpl.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database.backend.interfaces; +package org.caosdb.server.database.backend.interfaces; -import caosdb.server.database.exceptions.TransactionException; import java.util.HashSet; +import org.caosdb.server.database.exceptions.TransactionException; public interface UpdateUserRolesImpl extends BackendTransactionImpl { diff --git a/src/main/java/caosdb/server/database/backend/transaction/DeleteEntity.java b/src/main/java/org/caosdb/server/database/backend/transaction/DeleteEntity.java similarity index 83% rename from src/main/java/caosdb/server/database/backend/transaction/DeleteEntity.java rename to src/main/java/org/caosdb/server/database/backend/transaction/DeleteEntity.java index e94d90e6e8430d7aace3fa84ea22f6f458cbc41a..7f3d3435e1d4913d99ea0c9b7b064da85e12ac02 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/DeleteEntity.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/DeleteEntity.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.container.TransactionContainer; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.container.TransactionContainer; public class DeleteEntity extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/DeleteEntityProperties.java b/src/main/java/org/caosdb/server/database/backend/transaction/DeleteEntityProperties.java similarity index 74% rename from src/main/java/caosdb/server/database/backend/transaction/DeleteEntityProperties.java rename to src/main/java/org/caosdb/server/database/backend/transaction/DeleteEntityProperties.java index 15ace2b9820398cb270a6a1e098e6f642b66ab9d..7b02fbf003e49c18bc14a602f7e2f781b495c682 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/DeleteEntityProperties.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/DeleteEntityProperties.java @@ -20,15 +20,15 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import static caosdb.server.transaction.Transaction.ERROR_INTEGRITY_VIOLATION; +import static org.caosdb.server.transaction.Transaction.ERROR_INTEGRITY_VIOLATION; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.DeleteEntityPropertiesImpl; -import caosdb.server.database.exceptions.IntegrityException; -import caosdb.server.entity.EntityInterface; -import caosdb.server.utils.EntityStatus; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.DeleteEntityPropertiesImpl; +import org.caosdb.server.database.exceptions.IntegrityException; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.utils.EntityStatus; public class DeleteEntityProperties extends BackendTransaction { @@ -40,8 +40,8 @@ public class DeleteEntityProperties extends BackendTransaction { @Override public void execute() { - RetrieveProperties.removeCached(this.entity.getId()); - RetrieveParents.removeCached(this.entity.getId()); + RetrieveProperties.removeCached(this.entity.getIdVersion()); + RetrieveParents.removeCached(this.entity.getIdVersion()); final DeleteEntityPropertiesImpl ret = getImplementation(DeleteEntityPropertiesImpl.class); diff --git a/src/main/java/caosdb/server/database/backend/transaction/DeleteFile.java b/src/main/java/org/caosdb/server/database/backend/transaction/DeleteFile.java similarity index 83% rename from src/main/java/caosdb/server/database/backend/transaction/DeleteFile.java rename to src/main/java/org/caosdb/server/database/backend/transaction/DeleteFile.java index 82c022bef0f321f5a1be81e5f58207c9d06cd427..254e4e70d27518d676ada2d73d28a750148c8871 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/DeleteFile.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/DeleteFile.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.CaosDBException; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.Message; import java.io.IOException; +import org.caosdb.server.CaosDBException; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Message; public class DeleteFile extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/DeletePassword.java b/src/main/java/org/caosdb/server/database/backend/transaction/DeletePassword.java similarity index 83% rename from src/main/java/caosdb/server/database/backend/transaction/DeletePassword.java rename to src/main/java/org/caosdb/server/database/backend/transaction/DeletePassword.java index a467ae18367c91f02dd2cccefb4a336fe61c1210..402726a945d606091cd83505c69631f28d3ec455 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/DeletePassword.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/DeletePassword.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.DeletePasswordImpl; -import caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.DeletePasswordImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class DeletePassword extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/DeleteRole.java b/src/main/java/org/caosdb/server/database/backend/transaction/DeleteRole.java similarity index 83% rename from src/main/java/caosdb/server/database/backend/transaction/DeleteRole.java rename to src/main/java/org/caosdb/server/database/backend/transaction/DeleteRole.java index 1c80d1b99ccc234b51db93a59b73da508fc35982..eab8f6f3d5a8bf8153d1855de653f840a41bb302 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/DeleteRole.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/DeleteRole.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.DeleteRoleImpl; -import caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.DeleteRoleImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class DeleteRole extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/DeleteSparseEntity.java b/src/main/java/org/caosdb/server/database/backend/transaction/DeleteSparseEntity.java similarity index 77% rename from src/main/java/caosdb/server/database/backend/transaction/DeleteSparseEntity.java rename to src/main/java/org/caosdb/server/database/backend/transaction/DeleteSparseEntity.java index 39deb1416c743f838bfc1b96c29fd845dbcef742..55989d219ad738d5a866e0ef6f322368c8fc559b 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/DeleteSparseEntity.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/DeleteSparseEntity.java @@ -22,15 +22,15 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import static caosdb.server.transaction.Transaction.ERROR_INTEGRITY_VIOLATION; +import static org.caosdb.server.transaction.Transaction.ERROR_INTEGRITY_VIOLATION; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.DeleteSparseEntityImpl; -import caosdb.server.database.exceptions.IntegrityException; -import caosdb.server.entity.EntityInterface; -import caosdb.server.utils.EntityStatus; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.DeleteSparseEntityImpl; +import org.caosdb.server.database.exceptions.IntegrityException; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.utils.EntityStatus; public class DeleteSparseEntity extends BackendTransaction { @@ -42,7 +42,7 @@ public class DeleteSparseEntity extends BackendTransaction { @Override protected void execute() { - RetrieveSparseEntity.removeCached(this.entity.getId()); + RetrieveSparseEntity.removeCached(this.entity); if (entity.hasFileProperties()) { GetFileRecordByPath.removeCached(this.entity.getFileProperties().getPath()); } diff --git a/src/main/java/caosdb/server/database/backend/transaction/DeleteUser.java b/src/main/java/org/caosdb/server/database/backend/transaction/DeleteUser.java similarity index 82% rename from src/main/java/caosdb/server/database/backend/transaction/DeleteUser.java rename to src/main/java/org/caosdb/server/database/backend/transaction/DeleteUser.java index 90f2d02e8cbfc2d37aba745cf5601f075ad75e06..13ea87446a8d8e786629ec6d7d9ffd032c0f58d0 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/DeleteUser.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/DeleteUser.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.accessControl.Principal; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.DeleteUserImpl; -import caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.accessControl.Principal; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.DeleteUserImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class DeleteUser extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/FileConsistencyCheck.java b/src/main/java/org/caosdb/server/database/backend/transaction/FileConsistencyCheck.java similarity index 84% rename from src/main/java/caosdb/server/database/backend/transaction/FileConsistencyCheck.java rename to src/main/java/org/caosdb/server/database/backend/transaction/FileConsistencyCheck.java index 5238ec7494abc15baa42e9b8f9d4f659ccd9af99..5cece246538219266537613aec31da24962e1910 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/FileConsistencyCheck.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/FileConsistencyCheck.java @@ -20,15 +20,15 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.FileCheckHash; -import caosdb.server.database.backend.interfaces.FileCheckSize; -import caosdb.server.database.backend.interfaces.FileExists; -import caosdb.server.database.backend.interfaces.FileWasModifiedAfter; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.utils.Hasher; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.FileCheckHash; +import org.caosdb.server.database.backend.interfaces.FileCheckSize; +import org.caosdb.server.database.backend.interfaces.FileExists; +import org.caosdb.server.database.backend.interfaces.FileWasModifiedAfter; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.utils.Hasher; public class FileConsistencyCheck extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/GetAllNames.java b/src/main/java/org/caosdb/server/database/backend/transaction/GetAllNames.java similarity index 61% rename from src/main/java/caosdb/server/database/backend/transaction/GetAllNames.java rename to src/main/java/org/caosdb/server/database/backend/transaction/GetAllNames.java index f30ec5b2b33de6ba7341b26f4e94244f6501255c..f45f5104283d7d27771a3e2a9b0a38772d4cccf0 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/GetAllNames.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/GetAllNames.java @@ -1,12 +1,12 @@ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.GetAllNamesImpl; -import caosdb.server.database.proto.SparseEntity; -import caosdb.server.entity.Entity; -import caosdb.server.entity.EntityInterface; import java.util.ArrayList; import java.util.List; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.GetAllNamesImpl; +import org.caosdb.server.database.proto.SparseEntity; +import org.caosdb.server.entity.Entity; +import org.caosdb.server.entity.EntityInterface; public class GetAllNames extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/GetChildren.java b/src/main/java/org/caosdb/server/database/backend/transaction/GetChildren.java similarity index 84% rename from src/main/java/caosdb/server/database/backend/transaction/GetChildren.java rename to src/main/java/org/caosdb/server/database/backend/transaction/GetChildren.java index d476345c2e05cf75d5bcfdf333edf760ff991e3a..32bf8883b9f2662207352c8b80356b95f97d7d76 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/GetChildren.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/GetChildren.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.GetChildrenImpl; -import caosdb.server.database.exceptions.TransactionException; import java.util.List; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.GetChildrenImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class GetChildren extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/GetDependentEntities.java b/src/main/java/org/caosdb/server/database/backend/transaction/GetDependentEntities.java similarity index 84% rename from src/main/java/caosdb/server/database/backend/transaction/GetDependentEntities.java rename to src/main/java/org/caosdb/server/database/backend/transaction/GetDependentEntities.java index e4e6e96f999d5ceb3402d1235de04ae6f32e358b..067a422fd509b0987e0e5c8b69da1ee081c258a0 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/GetDependentEntities.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/GetDependentEntities.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.GetDependentEntitiesImpl; -import caosdb.server.database.exceptions.TransactionException; import java.util.List; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.GetDependentEntitiesImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class GetDependentEntities extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/GetFileIterator.java b/src/main/java/org/caosdb/server/database/backend/transaction/GetFileIterator.java similarity index 84% rename from src/main/java/caosdb/server/database/backend/transaction/GetFileIterator.java rename to src/main/java/org/caosdb/server/database/backend/transaction/GetFileIterator.java index 7e28ff243575f75ea577ec80029507cfa1d49d17..c5db6bef59ddf18c95218f442556b6ee6b27ad8a 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/GetFileIterator.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/GetFileIterator.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.GetFileIteratorImpl; -import caosdb.server.database.exceptions.TransactionException; import java.util.Iterator; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.GetFileIteratorImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class GetFileIterator extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/GetFileRecordByPath.java b/src/main/java/org/caosdb/server/database/backend/transaction/GetFileRecordByPath.java similarity index 84% rename from src/main/java/caosdb/server/database/backend/transaction/GetFileRecordByPath.java rename to src/main/java/org/caosdb/server/database/backend/transaction/GetFileRecordByPath.java index 6366bd2884aca38a0d54eca4a926fcc7e8b9cda4..1a7fa8635366cce858c35f54378090ebad72fb8f 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/GetFileRecordByPath.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/GetFileRecordByPath.java @@ -22,15 +22,15 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.caching.Cache; -import caosdb.server.database.CacheableBackendTransaction; -import caosdb.server.database.backend.interfaces.GetFileRecordByPathImpl; -import caosdb.server.database.exceptions.EntityDoesNotExistException; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.SparseEntity; import org.apache.commons.jcs.access.behavior.ICacheAccess; +import org.caosdb.server.caching.Cache; +import org.caosdb.server.database.CacheableBackendTransaction; +import org.caosdb.server.database.backend.interfaces.GetFileRecordByPathImpl; +import org.caosdb.server.database.exceptions.EntityDoesNotExistException; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.SparseEntity; public class GetFileRecordByPath extends CacheableBackendTransaction<String, SparseEntity> { diff --git a/src/main/java/caosdb/server/database/backend/transaction/GetIDByName.java b/src/main/java/org/caosdb/server/database/backend/transaction/GetIDByName.java similarity index 84% rename from src/main/java/caosdb/server/database/backend/transaction/GetIDByName.java rename to src/main/java/org/caosdb/server/database/backend/transaction/GetIDByName.java index 895cd707b57d70693ec6a80396b26bce391027af..b43db0010eeeb3179bb91333d854872f5e8ab18a 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/GetIDByName.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/GetIDByName.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.GetIDByNameImpl; -import caosdb.server.database.exceptions.EntityDoesNotExistException; -import caosdb.server.database.exceptions.EntityWasNotUniqueException; -import caosdb.server.database.exceptions.TransactionException; import java.util.List; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.GetIDByNameImpl; +import org.caosdb.server.database.exceptions.EntityDoesNotExistException; +import org.caosdb.server.database.exceptions.EntityWasNotUniqueException; +import org.caosdb.server.database.exceptions.TransactionException; public class GetIDByName extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/GetInfo.java b/src/main/java/org/caosdb/server/database/backend/transaction/GetInfo.java similarity index 80% rename from src/main/java/caosdb/server/database/backend/transaction/GetInfo.java rename to src/main/java/org/caosdb/server/database/backend/transaction/GetInfo.java index dd7cfc5a6dd40e2075ecfe0987536b089aea7ef5..a1662ec03f8f5dc2fe424ba10f26e9ba4803b72c 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/GetInfo.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/GetInfo.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.GetInfoImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.ProtoInfo; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.GetInfoImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.ProtoInfo; public class GetInfo extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/GetUpdateableChecksums.java b/src/main/java/org/caosdb/server/database/backend/transaction/GetUpdateableChecksums.java similarity index 82% rename from src/main/java/caosdb/server/database/backend/transaction/GetUpdateableChecksums.java rename to src/main/java/org/caosdb/server/database/backend/transaction/GetUpdateableChecksums.java index b70c1918942a4ff376e57c5649ce5436cf7c9140..eade9ea62168710e8928e52d1dc9176e366e0300 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/GetUpdateableChecksums.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/GetUpdateableChecksums.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.GetUpdateableChecksumsImpl; -import caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.GetUpdateableChecksumsImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class GetUpdateableChecksums extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/InsertEntity.java b/src/main/java/org/caosdb/server/database/backend/transaction/InsertEntity.java similarity index 89% rename from src/main/java/caosdb/server/database/backend/transaction/InsertEntity.java rename to src/main/java/org/caosdb/server/database/backend/transaction/InsertEntity.java index e258504908b44c8054a56315fa26e8dacae8b023..42439aa54e06e2556cb7b814f1c9056afb35f9d7 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/InsertEntity.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/InsertEntity.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.container.TransactionContainer; -import caosdb.server.utils.EntityStatus; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.container.TransactionContainer; +import org.caosdb.server.utils.EntityStatus; public class InsertEntity extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/InsertEntityDatatype.java b/src/main/java/org/caosdb/server/database/backend/transaction/InsertEntityDatatype.java similarity index 56% rename from src/main/java/caosdb/server/database/backend/transaction/InsertEntityDatatype.java rename to src/main/java/org/caosdb/server/database/backend/transaction/InsertEntityDatatype.java index 58aa4d88498e7493466cde844d241336b29e3896..182874d1f1e30ed8f5249e609dbbc42a724d94af 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/InsertEntityDatatype.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/InsertEntityDatatype.java @@ -1,12 +1,12 @@ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import static caosdb.server.transaction.Transaction.ERROR_INTEGRITY_VIOLATION; +import static org.caosdb.server.transaction.Transaction.ERROR_INTEGRITY_VIOLATION; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.InsertEntityDatatypeImpl; -import caosdb.server.database.exceptions.IntegrityException; -import caosdb.server.database.proto.SparseEntity; -import caosdb.server.entity.EntityInterface; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.InsertEntityDatatypeImpl; +import org.caosdb.server.database.exceptions.IntegrityException; +import org.caosdb.server.database.proto.SparseEntity; +import org.caosdb.server.entity.EntityInterface; public class InsertEntityDatatype extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/InsertEntityProperties.java b/src/main/java/org/caosdb/server/database/backend/transaction/InsertEntityProperties.java similarity index 87% rename from src/main/java/caosdb/server/database/backend/transaction/InsertEntityProperties.java rename to src/main/java/org/caosdb/server/database/backend/transaction/InsertEntityProperties.java index a777d4206c4dc0822a4f27912a3ec708c03edd56..bd5bf63a5eb7b194e119c56293e756ff0c4b6a20 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/InsertEntityProperties.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/InsertEntityProperties.java @@ -20,26 +20,26 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; - -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.DatabaseUtils; -import caosdb.server.database.backend.interfaces.InsertEntityPropertiesImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.FlatProperty; -import caosdb.server.datatype.AbstractCollectionDatatype; -import caosdb.server.datatype.AbstractDatatype.Table; -import caosdb.server.datatype.CollectionValue; -import caosdb.server.datatype.IndexedSingleValue; -import caosdb.server.datatype.SingleValue; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.Role; -import caosdb.server.entity.StatementStatus; -import caosdb.server.entity.wrapper.Property; +package org.caosdb.server.database.backend.transaction; + import java.util.ArrayList; import java.util.Deque; import java.util.Iterator; import java.util.List; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.DatabaseUtils; +import org.caosdb.server.database.backend.interfaces.InsertEntityPropertiesImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.FlatProperty; +import org.caosdb.server.datatype.AbstractCollectionDatatype; +import org.caosdb.server.datatype.AbstractDatatype.Table; +import org.caosdb.server.datatype.CollectionValue; +import org.caosdb.server.datatype.IndexedSingleValue; +import org.caosdb.server.datatype.SingleValue; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Role; +import org.caosdb.server.entity.StatementStatus; +import org.caosdb.server.entity.wrapper.Property; public class InsertEntityProperties extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/InsertEntityValue.java b/src/main/java/org/caosdb/server/database/backend/transaction/InsertEntityValue.java similarity index 79% rename from src/main/java/caosdb/server/database/backend/transaction/InsertEntityValue.java rename to src/main/java/org/caosdb/server/database/backend/transaction/InsertEntityValue.java index 56ace8d9d2ff6cac5c611ca43424a3bdd8ecbb54..8ec6b0d1fab731d3d51b3a6793c69293575e6462 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/InsertEntityValue.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/InsertEntityValue.java @@ -20,15 +20,15 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.InsertEntityPropertiesImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.FlatProperty; -import caosdb.server.datatype.SingleValue; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.StatementStatus; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.InsertEntityPropertiesImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.FlatProperty; +import org.caosdb.server.datatype.SingleValue; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.StatementStatus; public class InsertEntityValue extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/InsertFile.java b/src/main/java/org/caosdb/server/database/backend/transaction/InsertFile.java similarity index 83% rename from src/main/java/caosdb/server/database/backend/transaction/InsertFile.java rename to src/main/java/org/caosdb/server/database/backend/transaction/InsertFile.java index fe9b930e7a51391e3379f76b6393081edbcc0583..f92dc62bb131fcfe6af2cf51c1c6abeaee7c4dda 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/InsertFile.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/InsertFile.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.Message; -import caosdb.server.utils.EntityStatus; import java.io.IOException; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Message; +import org.caosdb.server.utils.EntityStatus; public class InsertFile extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/InsertLinCon.java b/src/main/java/org/caosdb/server/database/backend/transaction/InsertLinCon.java similarity index 83% rename from src/main/java/caosdb/server/database/backend/transaction/InsertLinCon.java rename to src/main/java/org/caosdb/server/database/backend/transaction/InsertLinCon.java index 279f9f1f93329e03098401a6fc25fd6e2c2fd386..68555010031cc8f8bfe48afcf2c4d5e310bed3d8 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/InsertLinCon.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/InsertLinCon.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.InsertLinConImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.LinCon; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.InsertLinConImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.LinCon; public class InsertLinCon extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/InsertLogRecord.java b/src/main/java/org/caosdb/server/database/backend/transaction/InsertLogRecord.java similarity index 84% rename from src/main/java/caosdb/server/database/backend/transaction/InsertLogRecord.java rename to src/main/java/org/caosdb/server/database/backend/transaction/InsertLogRecord.java index 43a21d481d954d34dba66a2f9b824acfaac2aabd..3ce27add49761737c0a8365410c979665a3f16a9 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/InsertLogRecord.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/InsertLogRecord.java @@ -20,13 +20,13 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.InsertLogRecordImpl; -import caosdb.server.database.exceptions.TransactionException; import java.util.List; import java.util.logging.LogRecord; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.InsertLogRecordImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class InsertLogRecord extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/InsertParents.java b/src/main/java/org/caosdb/server/database/backend/transaction/InsertParents.java similarity index 81% rename from src/main/java/caosdb/server/database/backend/transaction/InsertParents.java rename to src/main/java/org/caosdb/server/database/backend/transaction/InsertParents.java index 439b9f58a6b463a6a7bfe731b54b6690ea17ce96..d71fec922477d664c8c8eff98800164b3a691513 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/InsertParents.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/InsertParents.java @@ -20,13 +20,13 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.InsertParentsImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.entity.EntityInterface; -import caosdb.server.utils.EntityStatus; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.InsertParentsImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.utils.EntityStatus; public class InsertParents extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/InsertRole.java b/src/main/java/org/caosdb/server/database/backend/transaction/InsertRole.java similarity index 80% rename from src/main/java/caosdb/server/database/backend/transaction/InsertRole.java rename to src/main/java/org/caosdb/server/database/backend/transaction/InsertRole.java index e44820d24c19b9215a1730e9b4f848f7578598b1..4ffa7d68f6ff8b2e328a22978803941b310c58a7 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/InsertRole.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/InsertRole.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.accessControl.Role; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.InsertRoleImpl; -import caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.accessControl.Role; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.InsertRoleImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class InsertRole extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/InsertSparseEntity.java b/src/main/java/org/caosdb/server/database/backend/transaction/InsertSparseEntity.java similarity index 72% rename from src/main/java/caosdb/server/database/backend/transaction/InsertSparseEntity.java rename to src/main/java/org/caosdb/server/database/backend/transaction/InsertSparseEntity.java index f8711197064a88dd92c408f329d1a36df55c5ed2..22720f836e5cbd4912f3aedccd25398e80a19324 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/InsertSparseEntity.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/InsertSparseEntity.java @@ -20,17 +20,18 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import static caosdb.server.transaction.Transaction.ERROR_INTEGRITY_VIOLATION; +import static org.caosdb.server.transaction.Transaction.ERROR_INTEGRITY_VIOLATION; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.InsertSparseEntityImpl; -import caosdb.server.database.exceptions.IntegrityException; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.SparseEntity; -import caosdb.server.entity.EntityInterface; -import caosdb.server.utils.Undoable; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.InsertSparseEntityImpl; +import org.caosdb.server.database.exceptions.IntegrityException; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.SparseEntity; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Version; +import org.caosdb.server.utils.Undoable; public class InsertSparseEntity extends BackendTransaction { @@ -68,5 +69,7 @@ public class InsertSparseEntity extends BackendTransaction { public void cleanUp() {} }); this.entity.setId(e.id); + this.entity.setVersion(new Version(e.versionId)); + this.entity.getVersion().setHead(true); } } diff --git a/src/main/java/caosdb/server/database/backend/transaction/InsertTransactionHistory.java b/src/main/java/org/caosdb/server/database/backend/transaction/InsertTransactionHistory.java similarity index 81% rename from src/main/java/caosdb/server/database/backend/transaction/InsertTransactionHistory.java rename to src/main/java/org/caosdb/server/database/backend/transaction/InsertTransactionHistory.java index 242eec2969b622a1f66cda5defd1d2b9d5dc5ead..db7393b04f0afe3c15622dfb750cf31d42050521 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/InsertTransactionHistory.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/InsertTransactionHistory.java @@ -20,15 +20,15 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.datetime.UTCDateTime; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.InsertTransactionHistoryImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.container.TransactionContainer; -import caosdb.server.utils.EntityStatus; +import org.caosdb.datetime.UTCDateTime; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.InsertTransactionHistoryImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.container.TransactionContainer; +import org.caosdb.server.utils.EntityStatus; public class InsertTransactionHistory extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/IsSubType.java b/src/main/java/org/caosdb/server/database/backend/transaction/IsSubType.java similarity index 85% rename from src/main/java/caosdb/server/database/backend/transaction/IsSubType.java rename to src/main/java/org/caosdb/server/database/backend/transaction/IsSubType.java index ed91f761cabde5029b376e6a3132fc9dd93537eb..d75fb2c2453613c50915678d81f53f696589afd4 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/IsSubType.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/IsSubType.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.IsSubTypeImpl; -import caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.IsSubTypeImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class IsSubType extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/RegisterSubDomain.java b/src/main/java/org/caosdb/server/database/backend/transaction/RegisterSubDomain.java similarity index 84% rename from src/main/java/caosdb/server/database/backend/transaction/RegisterSubDomain.java rename to src/main/java/org/caosdb/server/database/backend/transaction/RegisterSubDomain.java index 08b999d0e0c1e36d108c89a0cf9eed513d3290e4..ecae501d40d4e6ed9ae54e44e12d37a7628699fd 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/RegisterSubDomain.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/RegisterSubDomain.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.RegisterSubDomainImpl; -import caosdb.server.database.exceptions.TransactionException; import java.util.Deque; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.RegisterSubDomainImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class RegisterSubDomain extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/RetrieveAll.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveAll.java similarity index 80% rename from src/main/java/caosdb/server/database/backend/transaction/RetrieveAll.java rename to src/main/java/org/caosdb/server/database/backend/transaction/RetrieveAll.java index 5820547c853247245b398778fab97bd854a5a126..7b6173ede59720234c58c6ca882e69e4dda9e6b2 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/RetrieveAll.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveAll.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.RetrieveAllImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.entity.RetrieveEntity; -import caosdb.server.entity.container.TransactionContainer; import java.util.List; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.RetrieveAllImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.entity.RetrieveEntity; +import org.caosdb.server.entity.container.TransactionContainer; public class RetrieveAll extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/RetrieveAllUncheckedFiles.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveAllUncheckedFiles.java similarity index 82% rename from src/main/java/caosdb/server/database/backend/transaction/RetrieveAllUncheckedFiles.java rename to src/main/java/org/caosdb/server/database/backend/transaction/RetrieveAllUncheckedFiles.java index b99694243d9b6571c1c96ac4ce3114543380c434..655e47b8312c3a9772ae3e9055bc73494236a0ec 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/RetrieveAllUncheckedFiles.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveAllUncheckedFiles.java @@ -20,13 +20,13 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.RetrieveAllUncheckedFilesImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.SparseEntity; import java.util.Iterator; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.RetrieveAllUncheckedFilesImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.SparseEntity; public class RetrieveAllUncheckedFiles extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/RetrieveDatatypes.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveDatatypes.java similarity index 76% rename from src/main/java/caosdb/server/database/backend/transaction/RetrieveDatatypes.java rename to src/main/java/org/caosdb/server/database/backend/transaction/RetrieveDatatypes.java index 44f8427aeb2911c0483be3824a1e3fe831350cb5..56efbdd3864c5997758417ad02a97b663dfce6e5 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/RetrieveDatatypes.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveDatatypes.java @@ -20,17 +20,17 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.RetrieveDatatypesImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.VerySparseEntity; -import caosdb.server.entity.Entity; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.RetrieveEntity; -import caosdb.server.entity.container.Container; import java.util.ArrayList; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.RetrieveDatatypesImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.VerySparseEntity; +import org.caosdb.server.entity.Entity; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.RetrieveEntity; +import org.caosdb.server.entity.container.Container; public class RetrieveDatatypes extends BackendTransaction { diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntity.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntity.java new file mode 100644 index 0000000000000000000000000000000000000000..38cd7073613e6477d013f8923aaecfc188a3c234 --- /dev/null +++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntity.java @@ -0,0 +1,178 @@ +/* + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2018 Research Group Biomedical Physics, + * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> + * + * 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 <https://www.gnu.org/licenses/>. + * + * ** end header + */ +package org.caosdb.server.database.backend.transaction; + +import java.util.LinkedList; +import java.util.List; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.datatype.ReferenceDatatype; +import org.caosdb.server.datatype.ReferenceValue; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Message; +import org.caosdb.server.entity.RetrieveEntity; +import org.caosdb.server.entity.Role; +import org.caosdb.server.entity.container.Container; +import org.caosdb.server.entity.wrapper.Property; +import org.caosdb.server.query.Query; +import org.caosdb.server.query.Query.Selection; +import org.caosdb.server.utils.EntityStatus; + +/** + * Retrieve the full entity from the backend - with all parents, properties, file properties and so + * on. + * + * <p>TODO: This class should rather be called FullEntityRetrieval or FullEntityRetrieveTransaction. + * + * <p>When the entity which is to be retrieved has a defined list of {@link Query.Selection} which + * select properties from referenced entities, the referenced entities are retrieved as well. + * Otherwise, only the referenced id is retrieved and the entity stays rather flat. + * + * @author Timm Fitschen <t.fitschen@indiscale.com> + */ +public class RetrieveFullEntity extends BackendTransaction { + + private final Container<? extends EntityInterface> container; + + public RetrieveFullEntity(final EntityInterface entity) { + final Container<EntityInterface> c = new Container<>(); + c.add(entity); + this.container = c; + } + + public RetrieveFullEntity(final Container<? extends EntityInterface> container) { + this.container = container; + } + + public RetrieveFullEntity(Integer id) { + this(new RetrieveEntity(id)); + } + + @Override + public void execute() { + retrieveFullEntitiesInContainer(this.container); + } + + /** + * Retrieve the entities in the container. + * + * @param container + */ + public void retrieveFullEntitiesInContainer(Container<? extends EntityInterface> container) { + for (final EntityInterface e : container) { + if (e.hasId() && e.getId() > 0 && e.getEntityStatus() == EntityStatus.QUALIFIED) { + retrieveFullEntity(e, e.getSelections()); + } + } + } + + /** + * Retrieve a single full entity. + * + * <p>If the selections are not empty, retrieve the referenced entities matching the 'selections' + * as well. + * + * <p>This method is called recursively during the retrieval of the referenced entities. + * + * @param e The entity. + * @param selections + */ + public void retrieveFullEntity(EntityInterface e, List<Selection> selections) { + execute(new RetrieveSparseEntity(e)); + + if (e.getEntityStatus() == EntityStatus.VALID) { + execute(new RetrieveVersionInfo(e)); + if (e.getRole() == Role.QueryTemplate) { + execute(new RetrieveQueryTemplateDefinition(e)); + } + execute(new RetrieveParents(e)); + execute(new RetrieveProperties(e)); + + // recursion! retrieveSubEntities calls retrieveFull sometimes, but with reduced selectors. + if (selections != null && !selections.isEmpty()) { + retrieveSubEntities(e, selections); + } + } + } + + /** + * Retrieve the Entities which match the selections and are referenced by the Entity 'e'. + * + * @param e + * @param selections + */ + public void retrieveSubEntities(EntityInterface e, List<Selection> selections) { + for (final Selection s : selections) { + if (s.getSubselection() != null) { + + String propertyName = s.getSelector(); + + // Find matching (i.e. referencing) Properties + for (Property p : e.getProperties()) { + // get reference properties by name. + if (propertyName.equalsIgnoreCase(p.getName()) + && p.getDatatype() instanceof ReferenceDatatype) { + if (p.getValue() != null) { + try { + p.parseValue(); + } catch (Message m) { + p.addError(m); + } + + ReferenceValue value = (ReferenceValue) p.getValue(); + RetrieveEntity ref = new RetrieveEntity(value.getId()); + // recursion! (Only for the matching selections) + retrieveFullEntity(ref, getSubSelects(selections, propertyName)); + value.setEntity(ref, true); + } + } + } + } + } + } + + /** + * Return all non-null subselects of those selections which match the given select String. + * + * <p>Effectively, this reduces the depth of the selections by one (and drops non-matching + * selections). + * + * @param selections + * @param select + * @return A new list of Selections. + */ + public List<Selection> getSubSelects(List<Selection> selections, String select) { + List<Selection> result = new LinkedList<>(); + for (Selection s : selections) { + if (s.getSelector().equalsIgnoreCase(select) && s.getSubselection() != null) { + result.add(s.getSubselection()); + } + } + return result; + } + + public Container<? extends EntityInterface> getContainer() { + return container; + } +} diff --git a/src/main/java/caosdb/server/database/backend/transaction/RetrieveLogRecord.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveLogRecord.java similarity index 86% rename from src/main/java/caosdb/server/database/backend/transaction/RetrieveLogRecord.java rename to src/main/java/org/caosdb/server/database/backend/transaction/RetrieveLogRecord.java index 42211d4312af6370c0f0335dd823f6129719dafd..eae8a96589aab3558a1978890c85bdd18bc161dc 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/RetrieveLogRecord.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveLogRecord.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.RetrieveLogRecordImpl; -import caosdb.server.database.exceptions.TransactionException; import java.util.List; import java.util.logging.Level; import java.util.logging.LogRecord; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.RetrieveLogRecordImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class RetrieveLogRecord extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/RetrieveParents.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveParents.java similarity index 55% rename from src/main/java/caosdb/server/database/backend/transaction/RetrieveParents.java rename to src/main/java/org/caosdb/server/database/backend/transaction/RetrieveParents.java index 5c1b0178f51496f83a4fac6a4ce3b2447abdccd5..b551430a26ed6a254789258aca688521f5a57ae4 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/RetrieveParents.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveParents.java @@ -22,22 +22,34 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.caching.Cache; -import caosdb.server.database.CacheableBackendTransaction; -import caosdb.server.database.DatabaseUtils; -import caosdb.server.database.backend.interfaces.RetrieveParentsImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.VerySparseEntity; -import caosdb.server.entity.EntityInterface; import java.util.ArrayList; import org.apache.commons.jcs.access.behavior.ICacheAccess; +import org.caosdb.server.caching.Cache; +import org.caosdb.server.database.CacheableBackendTransaction; +import org.caosdb.server.database.DatabaseUtils; +import org.caosdb.server.database.backend.interfaces.RetrieveParentsImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.VerySparseEntity; +import org.caosdb.server.entity.EntityInterface; +// TODO Problem with the caching. +// When an old entity version has a parent which is deleted, the name is +// still in the cached VerySparseEntity. This can be resolved by using a +// similar strategy as in RetrieveProperties.java where the name etc. are +// retrieved in a second step. Thus the deletion doesn't slip through +// unnoticed. +// +// Changes are necessary in the backend-api, i.e. mysqlbackend and the +// interfaces as well. +// +// See also a failing test in caosdb-pyinttest: +// tests/test_version.py::test_bug_cached_parent_name_in_old_version public class RetrieveParents - extends CacheableBackendTransaction<Integer, ArrayList<VerySparseEntity>> { + extends CacheableBackendTransaction<String, ArrayList<VerySparseEntity>> { - private static final ICacheAccess<Integer, ArrayList<VerySparseEntity>> cache = + private static final ICacheAccess<String, ArrayList<VerySparseEntity>> cache = Cache.getCache("BACKEND_EntityParents"); /** @@ -45,9 +57,9 @@ public class RetrieveParents * * @param id */ - public static void removeCached(final Integer id) { - if (id != null && cache != null) { - cache.remove(id); + public static void removeCached(final String idVersion) { + if (idVersion != null && cache != null) { + cache.remove(idVersion); } } @@ -61,18 +73,18 @@ public class RetrieveParents @Override public ArrayList<VerySparseEntity> executeNoCache() throws TransactionException { final RetrieveParentsImpl t = getImplementation(RetrieveParentsImpl.class); - final Integer key = getKey(); - return t.execute(key); + return t.execute(this.entity.getId(), this.entity.getVersion().getId()); } @Override protected void process(final ArrayList<VerySparseEntity> t) throws TransactionException { this.entity.getParents().clear(); + DatabaseUtils.parseParentsFromVerySparseEntity(this.entity, t); } @Override - protected Integer getKey() { - return this.entity.getId(); + protected String getKey() { + return this.entity.getIdVersion(); } } diff --git a/src/main/java/caosdb/server/database/backend/transaction/RetrievePasswordValidator.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrievePasswordValidator.java similarity index 81% rename from src/main/java/caosdb/server/database/backend/transaction/RetrievePasswordValidator.java rename to src/main/java/org/caosdb/server/database/backend/transaction/RetrievePasswordValidator.java index 36ce2c946388fdbee1caabe331355e8032684e8f..d8ea908dbfb0a7f4ae83830b050f976ac383aa6f 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/RetrievePasswordValidator.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrievePasswordValidator.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.accessControl.CredentialsValidator; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.RetrievePasswordValidatorImpl; -import caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.accessControl.CredentialsValidator; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.RetrievePasswordValidatorImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class RetrievePasswordValidator extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/RetrievePermissionRules.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrievePermissionRules.java similarity index 85% rename from src/main/java/caosdb/server/database/backend/transaction/RetrievePermissionRules.java rename to src/main/java/org/caosdb/server/database/backend/transaction/RetrievePermissionRules.java index 7e9925777c21a6d041759cfdade7682b85458566..0ec6756194342341b64f9dc131b7b912f112a1dc 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/RetrievePermissionRules.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrievePermissionRules.java @@ -22,15 +22,15 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.caching.Cache; -import caosdb.server.database.CacheableBackendTransaction; -import caosdb.server.database.backend.interfaces.RetrievePermissionRulesImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.permissions.PermissionRule; import java.util.HashSet; import org.apache.commons.jcs.access.behavior.ICacheAccess; +import org.caosdb.server.caching.Cache; +import org.caosdb.server.database.CacheableBackendTransaction; +import org.caosdb.server.database.backend.interfaces.RetrievePermissionRulesImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.permissions.PermissionRule; public class RetrievePermissionRules extends CacheableBackendTransaction<String, HashSet<PermissionRule>> { diff --git a/src/main/java/caosdb/server/database/backend/transaction/RetrieveProperties.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveProperties.java similarity index 73% rename from src/main/java/caosdb/server/database/backend/transaction/RetrieveProperties.java rename to src/main/java/org/caosdb/server/database/backend/transaction/RetrieveProperties.java index 487feb56cf848e948fcacb8f33f49e4a0bc2267d..726382f28c59a45a647098c3d227288fa1fabff6 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/RetrieveProperties.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveProperties.java @@ -22,26 +22,26 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.caching.Cache; -import caosdb.server.database.CacheableBackendTransaction; -import caosdb.server.database.DatabaseUtils; -import caosdb.server.database.backend.interfaces.RetrievePropertiesImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.ProtoProperty; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.Role; -import caosdb.server.entity.wrapper.Property; import java.util.ArrayList; import org.apache.commons.jcs.access.behavior.ICacheAccess; +import org.caosdb.server.caching.Cache; +import org.caosdb.server.database.CacheableBackendTransaction; +import org.caosdb.server.database.DatabaseUtils; +import org.caosdb.server.database.backend.interfaces.RetrievePropertiesImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.ProtoProperty; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Role; +import org.caosdb.server.entity.wrapper.Property; public class RetrieveProperties - extends CacheableBackendTransaction<Integer, ArrayList<ProtoProperty>> { + extends CacheableBackendTransaction<String, ArrayList<ProtoProperty>> { private final EntityInterface entity; public static final String CACHE_REGION = "BACKEND_EntityProperties"; - private static final ICacheAccess<Integer, ArrayList<ProtoProperty>> cache = + private static final ICacheAccess<String, ArrayList<ProtoProperty>> cache = Cache.getCache(CACHE_REGION); /** @@ -49,9 +49,9 @@ public class RetrieveProperties * * @param id */ - protected static void removeCached(final Integer id) { - if (id != null && cache != null) { - cache.remove(id); + protected static void removeCached(final String idVersion) { + if (idVersion != null && cache != null) { + cache.remove(idVersion); } } @@ -63,7 +63,7 @@ public class RetrieveProperties @Override public ArrayList<ProtoProperty> executeNoCache() throws TransactionException { final RetrievePropertiesImpl t = getImplementation(RetrievePropertiesImpl.class); - return t.execute(getKey()); + return t.execute(this.entity.getId(), this.entity.getVersion().getId()); } @Override @@ -98,7 +98,7 @@ public class RetrieveProperties } @Override - protected Integer getKey() { - return this.entity.getId(); + protected String getKey() { + return this.entity.getIdVersion(); } } diff --git a/src/main/java/caosdb/server/database/backend/transaction/RetrieveQueryTemplateDefinition.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveQueryTemplateDefinition.java similarity index 75% rename from src/main/java/caosdb/server/database/backend/transaction/RetrieveQueryTemplateDefinition.java rename to src/main/java/org/caosdb/server/database/backend/transaction/RetrieveQueryTemplateDefinition.java index 208c7439aa6cf9ff8f32abc8f5cd59ea9a3cba95..90a8ac27d264731b5d714fdc0ada116795fd0ee2 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/RetrieveQueryTemplateDefinition.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveQueryTemplateDefinition.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.RetrieveQueryTemplateDefinitionImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.entity.EntityInterface; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.RetrieveQueryTemplateDefinitionImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.entity.EntityInterface; public class RetrieveQueryTemplateDefinition extends BackendTransaction { @@ -39,6 +39,7 @@ public class RetrieveQueryTemplateDefinition extends BackendTransaction { protected void execute() throws TransactionException { final RetrieveQueryTemplateDefinitionImpl t = getImplementation(RetrieveQueryTemplateDefinitionImpl.class); - this.entity.setQueryTemplateDefinition(t.retrieve(this.entity.getId())); + this.entity.setQueryTemplateDefinition( + t.retrieve(this.entity.getId(), this.entity.getVersion().getId())); } } diff --git a/src/main/java/caosdb/server/database/backend/transaction/RetrieveRole.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveRole.java similarity index 84% rename from src/main/java/caosdb/server/database/backend/transaction/RetrieveRole.java rename to src/main/java/org/caosdb/server/database/backend/transaction/RetrieveRole.java index 5bb6150a8640f45997a4a3432ad4ac27196cd15c..1e855663590d85610860fcee246a4f1ed78a31b2 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/RetrieveRole.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveRole.java @@ -22,14 +22,14 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.accessControl.Role; -import caosdb.server.caching.Cache; -import caosdb.server.database.CacheableBackendTransaction; -import caosdb.server.database.backend.interfaces.RetrieveRoleImpl; -import caosdb.server.database.exceptions.TransactionException; import org.apache.commons.jcs.access.behavior.ICacheAccess; +import org.caosdb.server.accessControl.Role; +import org.caosdb.server.caching.Cache; +import org.caosdb.server.database.CacheableBackendTransaction; +import org.caosdb.server.database.backend.interfaces.RetrieveRoleImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class RetrieveRole extends CacheableBackendTransaction<String, Role> { diff --git a/src/main/java/caosdb/server/database/backend/transaction/RetrieveSparseEntity.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveSparseEntity.java similarity index 53% rename from src/main/java/caosdb/server/database/backend/transaction/RetrieveSparseEntity.java rename to src/main/java/org/caosdb/server/database/backend/transaction/RetrieveSparseEntity.java index a91b5021f1fa722a8e8831234fc8ebc2032ba115..db35c45d52f40e5e6083770878dda4baed61a5a6 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/RetrieveSparseEntity.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveSparseEntity.java @@ -3,9 +3,9 @@ * This file is a part of the CaosDB Project. * * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * Copyright (C) 2019 IndiScale GmbH - * Copyright (C) 2019 Timm Fitschen (t.fitschen@indiscale.com) + * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2019,2020 IndiScale GmbH + * Copyright (C) 2019,2020 Timm Fitschen <t.fitschen@indiscale.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -22,33 +22,34 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.caching.Cache; -import caosdb.server.database.CacheableBackendTransaction; -import caosdb.server.database.DatabaseUtils; -import caosdb.server.database.backend.interfaces.RetrieveSparseEntityImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.SparseEntity; -import caosdb.server.entity.Entity; -import caosdb.server.entity.EntityInterface; -import caosdb.server.utils.EntityStatus; import org.apache.commons.jcs.access.behavior.ICacheAccess; +import org.caosdb.server.caching.Cache; +import org.caosdb.server.database.CacheableBackendTransaction; +import org.caosdb.server.database.DatabaseUtils; +import org.caosdb.server.database.backend.interfaces.RetrieveSparseEntityImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.SparseEntity; +import org.caosdb.server.entity.Entity; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.utils.EntityStatus; -public class RetrieveSparseEntity extends CacheableBackendTransaction<Integer, SparseEntity> { +public class RetrieveSparseEntity extends CacheableBackendTransaction<String, SparseEntity> { private final EntityInterface entity; - private static final ICacheAccess<Integer, SparseEntity> cache = + private static final ICacheAccess<String, SparseEntity> cache = Cache.getCache("BACKEND_SparseEntities"); /** - * To be called by {@link UpdateSparseEntity} and {@link DeleteEntity} on execution. + * To be called by {@link UpdateSparseEntity} and {@link DeleteSparseEntity} on execution. * - * @param id + * @param entity */ - public static void removeCached(final Integer id) { - if (id != null && cache != null) { - cache.remove(id); + public static void removeCached(final EntityInterface entity) { + if (entity != null && cache != null) { + cache.remove(entity.getId().toString()); + cache.remove(entity.getIdVersion()); } } @@ -57,14 +58,15 @@ public class RetrieveSparseEntity extends CacheableBackendTransaction<Integer, S this.entity = entity; } - public RetrieveSparseEntity(final int id) { + public RetrieveSparseEntity(final int id, final String version) { this(new Entity(id)); + this.entity.getVersion().setId(version); } @Override public SparseEntity executeNoCache() throws TransactionException { final RetrieveSparseEntityImpl t = getImplementation(RetrieveSparseEntityImpl.class); - final SparseEntity ret = t.execute(getKey()); + final SparseEntity ret = t.execute(getEntity().getId(), getEntity().getVersion().getId()); if (ret == null) { this.entity.setEntityStatus(EntityStatus.NONEXISTENT); } @@ -78,8 +80,14 @@ public class RetrieveSparseEntity extends CacheableBackendTransaction<Integer, S } @Override - protected Integer getKey() { - return this.entity.getId(); + protected String getKey() { + if ("HEAD".equalsIgnoreCase(entity.getVersion().getId())) { + return this.entity.getId().toString(); + } else if (entity.hasVersion() + && entity.getVersion().getId().toUpperCase().startsWith("HEAD")) { + return null; + } + return this.entity.getIdVersion(); } public EntityInterface getEntity() { diff --git a/src/main/java/caosdb/server/database/backend/transaction/RetrieveUser.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveUser.java similarity index 84% rename from src/main/java/caosdb/server/database/backend/transaction/RetrieveUser.java rename to src/main/java/org/caosdb/server/database/backend/transaction/RetrieveUser.java index 9f27152030f5c953ee7bd4ecfff8c83d3cbc8a73..3ffdee13fe2eac0b2078e44ecfdb1f1101fe137a 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/RetrieveUser.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveUser.java @@ -22,15 +22,15 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.accessControl.Principal; -import caosdb.server.caching.Cache; -import caosdb.server.database.CacheableBackendTransaction; -import caosdb.server.database.backend.interfaces.RetrieveUserImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.ProtoUser; import org.apache.commons.jcs.access.behavior.ICacheAccess; +import org.caosdb.server.accessControl.Principal; +import org.caosdb.server.caching.Cache; +import org.caosdb.server.database.CacheableBackendTransaction; +import org.caosdb.server.database.backend.interfaces.RetrieveUserImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.ProtoUser; public class RetrieveUser extends CacheableBackendTransaction<Principal, ProtoUser> { diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveVersionHistory.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveVersionHistory.java new file mode 100644 index 0000000000000000000000000000000000000000..a5079c4e033882c4b1068615551b5132e4ee0cba --- /dev/null +++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveVersionHistory.java @@ -0,0 +1,64 @@ +/* + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * + * 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 <https://www.gnu.org/licenses/>. + * + * ** end header + */ +package org.caosdb.server.database.backend.transaction; + +import java.util.HashMap; +import org.caosdb.datetime.UTCDateTime; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.VersionHistoryItem; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Version; + +public class RetrieveVersionHistory extends VersionTransaction { + + public RetrieveVersionHistory(EntityInterface e) { + super(e); + } + + @Override + protected void process(HashMap<String, VersionHistoryItem> map) throws TransactionException { + super.process(map); + if (!map.isEmpty()) getEntity().setVersion(getHistory()); + } + + @Override + protected Version getVersion(String id) { + Version v = new Version(id); + VersionHistoryItem i = getHistoryItems().get(v.getId()); + if (i != null) { + v.setDate(UTCDateTime.UTCSeconds(i.seconds, i.nanos)); + v.setUsername(i.username); + v.setRealm(i.realm); + } + return v; + } + + private Version getHistory() { + Version v = getVersion(getEntity().getVersion().getId()); + v.setSuccessors(getSuccessors(v.getId(), true)); + v.setPredecessors(getPredecessors(v.getId(), true)); + v.setHead(v.getSuccessors().isEmpty()); + v.setCompleteHistory(true); + return v; + } +} diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveVersionInfo.java b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveVersionInfo.java new file mode 100644 index 0000000000000000000000000000000000000000..8d0e54c95d17d0eb83af541b9fee2fb605b17ec9 --- /dev/null +++ b/src/main/java/org/caosdb/server/database/backend/transaction/RetrieveVersionInfo.java @@ -0,0 +1,55 @@ +/* + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * + * 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 <https://www.gnu.org/licenses/>. + * + * ** end header + */ +package org.caosdb.server.database.backend.transaction; + +import java.util.HashMap; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.VersionHistoryItem; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Version; + +public class RetrieveVersionInfo extends VersionTransaction { + + public RetrieveVersionInfo(EntityInterface e) { + super(e); + } + + @Override + protected void process(HashMap<String, VersionHistoryItem> map) throws TransactionException { + super.process(map); // Make the map available to the object. + if (!map.isEmpty()) getEntity().setVersion(getVersion()); + } + + @Override + protected Version getVersion(String id) { + return new Version(id); + } + + public Version getVersion() { + Version v = getVersion(getEntity().getVersion().getId()); + v.setPredecessors(getPredecessors(v.getId(), false)); + v.setSuccessors(getSuccessors(v.getId(), false)); + v.setHead(v.getSuccessors().isEmpty()); + return v; + } +} diff --git a/src/main/java/caosdb/server/database/backend/transaction/RuleLoader.java b/src/main/java/org/caosdb/server/database/backend/transaction/RuleLoader.java similarity index 82% rename from src/main/java/caosdb/server/database/backend/transaction/RuleLoader.java rename to src/main/java/org/caosdb/server/database/backend/transaction/RuleLoader.java index 303029b42179a697c939767e2caf4d490a803a69..2bc6a92a2449a8ba2d42119c0ba743129bcee2ac 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/RuleLoader.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/RuleLoader.java @@ -22,19 +22,19 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.caching.Cache; -import caosdb.server.database.CacheableBackendTransaction; -import caosdb.server.database.backend.interfaces.RuleLoaderImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.Rule; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.container.TransactionContainer; -import caosdb.server.jobs.Job; -import caosdb.server.transaction.Transaction; import java.util.ArrayList; import org.apache.commons.jcs.access.behavior.ICacheAccess; +import org.caosdb.server.caching.Cache; +import org.caosdb.server.database.CacheableBackendTransaction; +import org.caosdb.server.database.backend.interfaces.RuleLoaderImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.Rule; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.container.TransactionContainer; +import org.caosdb.server.jobs.Job; +import org.caosdb.server.transaction.Transaction; public class RuleLoader extends CacheableBackendTransaction<String, ArrayList<Rule>> { diff --git a/src/main/java/caosdb/server/database/backend/transaction/SetFileCheckedTimestamp.java b/src/main/java/org/caosdb/server/database/backend/transaction/SetFileCheckedTimestamp.java similarity index 83% rename from src/main/java/caosdb/server/database/backend/transaction/SetFileCheckedTimestamp.java rename to src/main/java/org/caosdb/server/database/backend/transaction/SetFileCheckedTimestamp.java index 1dd20a83a2fc27547a67eb6fce0d532ac24f442c..f7bf76c3d1cdcde7e712dd6d1ebe022c7300bea8 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/SetFileCheckedTimestamp.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/SetFileCheckedTimestamp.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.SetFileCheckedTimestampImpl; -import caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.SetFileCheckedTimestampImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class SetFileCheckedTimestamp extends BackendTransaction { diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/SetFileChecksum.java b/src/main/java/org/caosdb/server/database/backend/transaction/SetFileChecksum.java new file mode 100644 index 0000000000000000000000000000000000000000..afca8be4afa72ac755be595ae4345bfe134ca0ca --- /dev/null +++ b/src/main/java/org/caosdb/server/database/backend/transaction/SetFileChecksum.java @@ -0,0 +1,26 @@ +package org.caosdb.server.database.backend.transaction; + +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.SetFileChecksumImpl; +import org.caosdb.server.entity.EntityInterface; + +public class SetFileChecksum extends BackendTransaction { + + private EntityInterface entity; + + public SetFileChecksum(EntityInterface entity) { + this.entity = entity; + } + + @Override + protected void execute() { + RetrieveSparseEntity.removeCached(this.entity); + if (entity.hasFileProperties()) { + GetFileRecordByPath.removeCached(this.entity.getFileProperties().getPath()); + + final SetFileChecksumImpl t = getImplementation(SetFileChecksumImpl.class); + + t.execute(this.entity.getId(), this.entity.getFileProperties().getChecksum()); + } + } +} diff --git a/src/main/java/caosdb/server/database/backend/transaction/SetPassword.java b/src/main/java/org/caosdb/server/database/backend/transaction/SetPassword.java similarity index 84% rename from src/main/java/caosdb/server/database/backend/transaction/SetPassword.java rename to src/main/java/org/caosdb/server/database/backend/transaction/SetPassword.java index 1f6c1e5501cd6d810b85b243fd6c3274c0598feb..a22815ab9ddb09080c34a519454db53c18aeda92 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/SetPassword.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/SetPassword.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.SetPasswordImpl; -import caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.SetPasswordImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class SetPassword extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/SetPermissionRules.java b/src/main/java/org/caosdb/server/database/backend/transaction/SetPermissionRules.java similarity index 82% rename from src/main/java/caosdb/server/database/backend/transaction/SetPermissionRules.java rename to src/main/java/org/caosdb/server/database/backend/transaction/SetPermissionRules.java index a632f299e223d2b46105b81f9b6b784b0cd58204..30986303b11eba2fb63b00d17029b81855277791 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/SetPermissionRules.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/SetPermissionRules.java @@ -20,13 +20,13 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.SetPermissionRulesImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.permissions.PermissionRule; import java.util.Set; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.SetPermissionRulesImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.permissions.PermissionRule; public class SetPermissionRules extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/SetQueryTemplateDefinition.java b/src/main/java/org/caosdb/server/database/backend/transaction/SetQueryTemplateDefinition.java similarity index 81% rename from src/main/java/caosdb/server/database/backend/transaction/SetQueryTemplateDefinition.java rename to src/main/java/org/caosdb/server/database/backend/transaction/SetQueryTemplateDefinition.java index 10618ff04e8f00c18c60c796e873f7b3ae370d45..b697b04fa2be50c52c7cc565e31a58c3b2a4a3c2 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/SetQueryTemplateDefinition.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/SetQueryTemplateDefinition.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.SetQueryTemplateDefinitionImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.entity.EntityInterface; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.SetQueryTemplateDefinitionImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.entity.EntityInterface; public class SetQueryTemplateDefinition extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/SyncStats.java b/src/main/java/org/caosdb/server/database/backend/transaction/SyncStats.java similarity index 83% rename from src/main/java/caosdb/server/database/backend/transaction/SyncStats.java rename to src/main/java/org/caosdb/server/database/backend/transaction/SyncStats.java index 8d82c1884d23f7a6bb1af5dafc7d5bb5d8945c56..d2650affcc956b82b8aed76b716221a6d43d5dc8 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/SyncStats.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/SyncStats.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.SyncStatsImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.utils.ServerStat; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.SyncStatsImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.utils.ServerStat; public class SyncStats extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/UpdateEntity.java b/src/main/java/org/caosdb/server/database/backend/transaction/UpdateEntity.java similarity index 78% rename from src/main/java/caosdb/server/database/backend/transaction/UpdateEntity.java rename to src/main/java/org/caosdb/server/database/backend/transaction/UpdateEntity.java index 6378e8bbbbd8aee87382d226df0691d004e641aa..2bf965575884f29640a80ec3d3ab284b7779c8f2 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/UpdateEntity.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/UpdateEntity.java @@ -20,13 +20,13 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.container.TransactionContainer; -import caosdb.server.utils.EntityStatus; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.container.TransactionContainer; +import org.caosdb.server.utils.EntityStatus; public class UpdateEntity extends BackendTransaction { @@ -53,6 +53,9 @@ public class UpdateEntity extends BackendTransaction { execute(new InsertEntityValue(e)); execute(new InsertEntityProperties(e)); + + VersionTransaction.removeCached(e.getId()); + execute(new RetrieveVersionInfo(e)); } } } diff --git a/src/main/java/caosdb/server/database/backend/transaction/UpdateSparseEntity.java b/src/main/java/org/caosdb/server/database/backend/transaction/UpdateSparseEntity.java similarity index 75% rename from src/main/java/caosdb/server/database/backend/transaction/UpdateSparseEntity.java rename to src/main/java/org/caosdb/server/database/backend/transaction/UpdateSparseEntity.java index c6a1c7683409e0c875484e14553e4aeac2757a71..8548fb0477de9d8b52b18b8132af15295dbc9353 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/UpdateSparseEntity.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/UpdateSparseEntity.java @@ -22,13 +22,14 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.UpdateSparseEntityImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.SparseEntity; -import caosdb.server.entity.EntityInterface; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.UpdateSparseEntityImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.SparseEntity; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Version; public class UpdateSparseEntity extends BackendTransaction { @@ -40,7 +41,7 @@ public class UpdateSparseEntity extends BackendTransaction { @Override public void execute() throws TransactionException { - RetrieveSparseEntity.removeCached(this.entity.getId()); + RetrieveSparseEntity.removeCached(this.entity); if (entity.hasFileProperties()) { GetFileRecordByPath.removeCached(this.entity.getFileProperties().getPath()); } @@ -50,5 +51,7 @@ public class UpdateSparseEntity extends BackendTransaction { final SparseEntity spe = this.entity.getSparseEntity(); t.execute(spe); + + this.entity.setVersion(new Version(spe.versionId)); } } diff --git a/src/main/java/caosdb/server/database/backend/transaction/UpdateUser.java b/src/main/java/org/caosdb/server/database/backend/transaction/UpdateUser.java similarity index 78% rename from src/main/java/caosdb/server/database/backend/transaction/UpdateUser.java rename to src/main/java/org/caosdb/server/database/backend/transaction/UpdateUser.java index 4f2c2776e936f7f5dd56edcaf2b55c97e8f430bb..07740f88f3fe7f301ffd24ec85a330c8b0afdce7 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/UpdateUser.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/UpdateUser.java @@ -20,13 +20,13 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.accessControl.Principal; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.UpdateUserImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.ProtoUser; +import org.caosdb.server.accessControl.Principal; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.UpdateUserImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.ProtoUser; public class UpdateUser extends BackendTransaction { diff --git a/src/main/java/caosdb/server/database/backend/transaction/UpdateUserRoles.java b/src/main/java/org/caosdb/server/database/backend/transaction/UpdateUserRoles.java similarity index 83% rename from src/main/java/caosdb/server/database/backend/transaction/UpdateUserRoles.java rename to src/main/java/org/caosdb/server/database/backend/transaction/UpdateUserRoles.java index 359bbb3a3efa35e37d38b733c204ff8ca2840028..66b3cb8e6f03c3abde0ccaa051a1228057d973f7 100644 --- a/src/main/java/caosdb/server/database/backend/transaction/UpdateUserRoles.java +++ b/src/main/java/org/caosdb/server/database/backend/transaction/UpdateUserRoles.java @@ -20,13 +20,13 @@ * * ** end header */ -package caosdb.server.database.backend.transaction; +package org.caosdb.server.database.backend.transaction; -import caosdb.server.accessControl.Principal; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.interfaces.UpdateUserRolesImpl; -import caosdb.server.database.exceptions.TransactionException; import java.util.HashSet; +import org.caosdb.server.accessControl.Principal; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.UpdateUserRolesImpl; +import org.caosdb.server.database.exceptions.TransactionException; public class UpdateUserRoles extends BackendTransaction { diff --git a/src/main/java/org/caosdb/server/database/backend/transaction/VersionTransaction.java b/src/main/java/org/caosdb/server/database/backend/transaction/VersionTransaction.java new file mode 100644 index 0000000000000000000000000000000000000000..ee617a1c1110e9a01e9a6d6ee4c799e44cd66ab3 --- /dev/null +++ b/src/main/java/org/caosdb/server/database/backend/transaction/VersionTransaction.java @@ -0,0 +1,159 @@ +/* + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * + * 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 <https://www.gnu.org/licenses/>. + * + * ** end header + */ +package org.caosdb.server.database.backend.transaction; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import org.apache.commons.jcs.access.behavior.ICacheAccess; +import org.caosdb.server.caching.Cache; +import org.caosdb.server.database.CacheableBackendTransaction; +import org.caosdb.server.database.backend.interfaces.RetrieveVersionHistoryImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.VersionHistoryItem; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Version; + +/** + * Abstract base class which retrieves and caches the full, but flat version history. The + * implementations then use the flat version history to construct either single version information + * items (see {@link RetrieveVersionInfo}) or the complete history as a tree (see {@link + * RetrieveVersionHistory}) + * + * @author Timm Fitschen (t.fitschen@indiscale.com) + */ +public abstract class VersionTransaction + extends CacheableBackendTransaction<Integer, HashMap<String, VersionHistoryItem>> { + + private static final ICacheAccess<Integer, HashMap<String, VersionHistoryItem>> cache = + Cache.getCache("BACKEND_RetrieveVersionHistory"); + private EntityInterface entity; + + /** A map of all history items which belong to this entity. The keys are the version ids. */ + private HashMap<String, VersionHistoryItem> historyItems; + + /** + * Invalidate a cache item. This should be called upon update of entities. + * + * @param entityId + */ + public static void removeCached(Integer entityId) { + cache.remove(entityId); + } + + public VersionTransaction(EntityInterface e) { + super(cache); + this.entity = e; + } + + @Override + public HashMap<String, VersionHistoryItem> executeNoCache() throws TransactionException { + RetrieveVersionHistoryImpl impl = getImplementation(RetrieveVersionHistoryImpl.class); + return impl.execute(getKey()); + } + + /** After this method call, the version map is available to the object. */ + @Override + protected void process(HashMap<String, VersionHistoryItem> historyItems) + throws TransactionException { + this.historyItems = historyItems; + } + + @Override + protected Integer getKey() { + return entity.getId(); + } + + public HashMap<String, VersionHistoryItem> getHistoryItems() { + return this.historyItems; + } + + public EntityInterface getEntity() { + return this.entity; + } + + /** + * Return a list of direct predecessors. The predecessors are constructed by {@link + * #getVersion(String)}. + * + * <p>If transitive is true, this function is called recursively on the predecessors as well, + * resulting in a list of trees of predecessors, with the direct predecessors at the root(s). + * + * @param versionId + * @param transitive + * @return A list of predecessors. + */ + protected List<Version> getPredecessors(String versionId, boolean transitive) { + LinkedList<Version> result = new LinkedList<>(); + if (getHistoryItems().containsKey(versionId) + && getHistoryItems().get(versionId).parents != null) + for (String p : getHistoryItems().get(versionId).parents) { + Version predecessor = getVersion(p); + if (transitive) { + predecessor.setPredecessors(getPredecessors(p, transitive)); + } + result.add(predecessor); + } + return result; + } + + /** + * To be implemented by the base class. The idea is, that the base class decides which information + * is being included into the Version instance. + * + * @param versionId - the id of the version + * @return + */ + protected abstract Version getVersion(String versionId); + + /** + * Return a list of direct successors. The successors are constructed by {@link + * #getVersion(String)}. + * + * <p>If transitive is true, this function is called recursively on the successors as well, + * resulting in a list of trees of successors, with the direct successors at the root(s). + * + * @param versionId + * @param transitive + * @return A list of successors. + */ + protected List<Version> getSuccessors(String versionId, boolean transitive) { + LinkedList<Version> result = new LinkedList<>(); + + outer: + for (VersionHistoryItem i : getHistoryItems().values()) { + if (i.parents != null) + for (String p : i.parents) { + if (versionId.equals(p)) { + Version successor = getVersion(i.id); + result.add(successor); + if (transitive) { + successor.setSuccessors(getSuccessors(i.id, transitive)); + } + continue outer; + } + } + } + return result; + } +} diff --git a/src/main/java/caosdb/server/database/exceptions/EntityDoesNotExistException.java b/src/main/java/org/caosdb/server/database/exceptions/EntityDoesNotExistException.java similarity index 89% rename from src/main/java/caosdb/server/database/exceptions/EntityDoesNotExistException.java rename to src/main/java/org/caosdb/server/database/exceptions/EntityDoesNotExistException.java index 29bd175f826fbad3a386b63201561cd50d60921b..f282a355d64b583482512e550c7b4de6e6ed84ec 100644 --- a/src/main/java/caosdb/server/database/exceptions/EntityDoesNotExistException.java +++ b/src/main/java/org/caosdb/server/database/exceptions/EntityDoesNotExistException.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.database.exceptions; +package org.caosdb.server.database.exceptions; public class EntityDoesNotExistException extends TransactionException { @@ -28,5 +28,5 @@ public class EntityDoesNotExistException extends TransactionException { super((String) null); } - private static final long serialVersionUID = -3514226960430855290L; + private static final long serialVersionUID = -6674784560815319076L; } diff --git a/src/main/java/caosdb/server/database/exceptions/EntityWasNotUniqueException.java b/src/main/java/org/caosdb/server/database/exceptions/EntityWasNotUniqueException.java similarity index 89% rename from src/main/java/caosdb/server/database/exceptions/EntityWasNotUniqueException.java rename to src/main/java/org/caosdb/server/database/exceptions/EntityWasNotUniqueException.java index 8a5ab28687b79bfc1a23c8d754b5ca6254155b62..b792cd45905133ff6a21c744b83781248a818b7f 100644 --- a/src/main/java/caosdb/server/database/exceptions/EntityWasNotUniqueException.java +++ b/src/main/java/org/caosdb/server/database/exceptions/EntityWasNotUniqueException.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database.exceptions; +package org.caosdb.server.database.exceptions; public class EntityWasNotUniqueException extends TransactionException { - private static final long serialVersionUID = -6520827199072001991L; + private static final long serialVersionUID = 5181653214330392866L; public EntityWasNotUniqueException() { super((String) null); diff --git a/src/main/java/caosdb/server/database/exceptions/IntegrityException.java b/src/main/java/org/caosdb/server/database/exceptions/IntegrityException.java similarity index 90% rename from src/main/java/caosdb/server/database/exceptions/IntegrityException.java rename to src/main/java/org/caosdb/server/database/exceptions/IntegrityException.java index e3632fe390ac660d3a7c4354cace0fd2afb61dbd..440c1e574289285313416ba39f4fbe403d9febfe 100644 --- a/src/main/java/caosdb/server/database/exceptions/IntegrityException.java +++ b/src/main/java/org/caosdb/server/database/exceptions/IntegrityException.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.database.exceptions; +package org.caosdb.server.database.exceptions; public class IntegrityException extends TransactionException { @@ -32,5 +32,5 @@ public class IntegrityException extends TransactionException { super(t); } - private static final long serialVersionUID = 2897982417503972644L; + private static final long serialVersionUID = 8589937458368069183L; } diff --git a/src/main/java/caosdb/server/database/exceptions/RolledBackException.java b/src/main/java/org/caosdb/server/database/exceptions/RolledBackException.java similarity index 89% rename from src/main/java/caosdb/server/database/exceptions/RolledBackException.java rename to src/main/java/org/caosdb/server/database/exceptions/RolledBackException.java index 0b371d77bb5dc6cb5df057f6ff46f42c0bd879ef..c99fcbbdd9b1043bf3477b552365943e0aae1a5c 100644 --- a/src/main/java/caosdb/server/database/exceptions/RolledBackException.java +++ b/src/main/java/org/caosdb/server/database/exceptions/RolledBackException.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.database.exceptions; +package org.caosdb.server.database.exceptions; public class RolledBackException extends TransactionException { @@ -28,5 +28,5 @@ public class RolledBackException extends TransactionException { super(t); } - private static final long serialVersionUID = -5448737641962261951L; + private static final long serialVersionUID = 8452626730418231001L; } diff --git a/src/main/java/caosdb/server/database/exceptions/TransactionException.java b/src/main/java/org/caosdb/server/database/exceptions/TransactionException.java similarity index 90% rename from src/main/java/caosdb/server/database/exceptions/TransactionException.java rename to src/main/java/org/caosdb/server/database/exceptions/TransactionException.java index 13d306a80fda36ea9310039d2c4fb755c1b7819a..ac76fe76afe9a29532071978efe47d132cb4aa9d 100644 --- a/src/main/java/caosdb/server/database/exceptions/TransactionException.java +++ b/src/main/java/org/caosdb/server/database/exceptions/TransactionException.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.database.exceptions; +package org.caosdb.server.database.exceptions; public class TransactionException extends RuntimeException { - private static final long serialVersionUID = -8623817359165387081L; + private static final long serialVersionUID = -187878233305807610L; public TransactionException(final String string) { super(string); diff --git a/src/main/java/caosdb/server/database/misc/DBHelper.java b/src/main/java/org/caosdb/server/database/misc/DBHelper.java similarity index 91% rename from src/main/java/caosdb/server/database/misc/DBHelper.java rename to src/main/java/org/caosdb/server/database/misc/DBHelper.java index a9b3ea8930cbb874d09ec41e00dbbd2d5fc1d8a0..27bd1d089543d905416a471b6103f9b3be6e3c5b 100644 --- a/src/main/java/caosdb/server/database/misc/DBHelper.java +++ b/src/main/java/org/caosdb/server/database/misc/DBHelper.java @@ -20,9 +20,9 @@ * * ** end header */ -package caosdb.server.database.misc; +package org.caosdb.server.database.misc; -import caosdb.server.transaction.TransactionInterface; +import org.caosdb.server.transaction.TransactionInterface; public interface DBHelper { diff --git a/src/main/java/caosdb/server/database/misc/RollBackHandler.java b/src/main/java/org/caosdb/server/database/misc/RollBackHandler.java similarity index 88% rename from src/main/java/caosdb/server/database/misc/RollBackHandler.java rename to src/main/java/org/caosdb/server/database/misc/RollBackHandler.java index 38bf00af75d290d9d276beb64a74f03950758734..1591d858aaf9a35ca4851e4627ef6f0b6fc5bb41 100644 --- a/src/main/java/caosdb/server/database/misc/RollBackHandler.java +++ b/src/main/java/org/caosdb/server/database/misc/RollBackHandler.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.database.misc; +package org.caosdb.server.database.misc; -import caosdb.server.transaction.TransactionInterface; -import caosdb.server.utils.UndoHandler; +import org.caosdb.server.transaction.TransactionInterface; +import org.caosdb.server.utils.UndoHandler; public class RollBackHandler extends UndoHandler implements DBHelper { diff --git a/src/main/java/caosdb/server/database/misc/TransactionBenchmark.java b/src/main/java/org/caosdb/server/database/misc/TransactionBenchmark.java similarity index 94% rename from src/main/java/caosdb/server/database/misc/TransactionBenchmark.java rename to src/main/java/org/caosdb/server/database/misc/TransactionBenchmark.java index 2d263df490a5d54abd35bef1005b2980c66f1bae..397a1f52201727d17b057dc92567893798b63cf5 100644 --- a/src/main/java/caosdb/server/database/misc/TransactionBenchmark.java +++ b/src/main/java/org/caosdb/server/database/misc/TransactionBenchmark.java @@ -20,13 +20,8 @@ * * ** end header */ -package caosdb.server.database.misc; +package org.caosdb.server.database.misc; -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; -import caosdb.server.utils.CronJob; -import caosdb.server.utils.Info; -import caosdb.server.utils.ServerStat; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; @@ -38,10 +33,15 @@ import java.util.Map; import java.util.Map.Entry; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.ServerProperties; +import org.caosdb.server.utils.CronJob; +import org.caosdb.server.utils.Info; +import org.caosdb.server.utils.ServerStat; import org.jdom2.Element; class Counter implements Serializable { - private static final long serialVersionUID = 8679355597595634790L; + private static final long serialVersionUID = -95212746021180579L; private int c; public Counter(int initial) { @@ -58,7 +58,7 @@ class Counter implements Serializable { } class Timer implements Serializable { - private static final long serialVersionUID = 7895352555775799409L; + private static final long serialVersionUID = -95212746021180579L; private long c; public Timer(long initial) { @@ -80,7 +80,7 @@ class Timer implements Serializable { * Measurement object knows nothing about other Measurement objects. */ class Measurement implements Serializable { - private static final long serialVersionUID = -2429348657382168470L; + private static final long serialVersionUID = -95212746021180579L; private final Timer timer; private final Counter counter; private final String name; @@ -130,7 +130,7 @@ class Measurement implements Serializable { class RootBenchmark extends TransactionBenchmark implements ServerStat { - private static final long serialVersionUID = 8070554107783826603L; + private static final long serialVersionUID = -95212746021180579L; private transient boolean synced = false; /** * Fetch old data (from before last shutdown) and fill it into this instance. @@ -208,7 +208,7 @@ class RootBenchmark extends TransactionBenchmark implements ServerStat { class SubBenchmark extends TransactionBenchmark { - private static final long serialVersionUID = 323147917189195974L; + private static final long serialVersionUID = -95212746021180579L; private final String name; public SubBenchmark(String name) { @@ -270,7 +270,7 @@ class JdomConverter { */ public abstract class TransactionBenchmark implements Serializable { - private static final long serialVersionUID = -8916163825450491068L; + private static final long serialVersionUID = -95212746021180579L; private static final TransactionBenchmark rootService = new RootBenchmark().init(); public final transient Logger logger = LogManager.getLogger(getClass()); protected static final transient boolean isActive = @@ -459,8 +459,8 @@ public abstract class TransactionBenchmark implements Serializable { /** * Return a nice String for the StackTraceElement. * - * <p>The String is composed like this: CLASS::METHOD [LINE_NUMBER], with "caosdb.server." removed - * from the class name. + * <p>The String is composed like this: CLASS::METHOD [LINE_NUMBER], with "org.caosdb.server." + * removed from the class name. */ private static String prettifyStackTraceElement(final StackTraceElement ste) { return ste.getClassName().replaceFirst("caosdb\\.server\\.", "") diff --git a/src/main/java/caosdb/server/database/proto/FlatProperty.java b/src/main/java/org/caosdb/server/database/proto/FlatProperty.java similarity index 91% rename from src/main/java/caosdb/server/database/proto/FlatProperty.java rename to src/main/java/org/caosdb/server/database/proto/FlatProperty.java index a413b461305093671c57acf72a104e631ae81643..b92d3def38d26f0f5f6cd6a0455d472b8f4f3ccb 100644 --- a/src/main/java/caosdb/server/database/proto/FlatProperty.java +++ b/src/main/java/org/caosdb/server/database/proto/FlatProperty.java @@ -20,13 +20,13 @@ * * ** end header */ -package caosdb.server.database.proto; +package org.caosdb.server.database.proto; import java.io.Serializable; public class FlatProperty implements Serializable { - private static final long serialVersionUID = -9154427080823222776L; + private static final long serialVersionUID = 6039288034435124195L; public Integer id = null; public String value = null; public String status = null; diff --git a/src/main/java/caosdb/server/database/proto/LinCon.java b/src/main/java/org/caosdb/server/database/proto/LinCon.java similarity index 97% rename from src/main/java/caosdb/server/database/proto/LinCon.java rename to src/main/java/org/caosdb/server/database/proto/LinCon.java index ba75d3c5a584f9eec6e7525835155bf2ced72ed8..719e760215cd8ec5b45bc30c5b154dca64e3b740 100644 --- a/src/main/java/caosdb/server/database/proto/LinCon.java +++ b/src/main/java/org/caosdb/server/database/proto/LinCon.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.database.proto; +package org.caosdb.server.database.proto; public class LinCon { public final long signature_from; diff --git a/src/main/java/caosdb/server/database/proto/ProtoGroup.java b/src/main/java/org/caosdb/server/database/proto/ProtoGroup.java similarity index 91% rename from src/main/java/caosdb/server/database/proto/ProtoGroup.java rename to src/main/java/org/caosdb/server/database/proto/ProtoGroup.java index 990be2ff4e884ef8981fb10388a094a1a7949b1c..31d589862cfd353a176880ea33e76327ec32ba6e 100644 --- a/src/main/java/caosdb/server/database/proto/ProtoGroup.java +++ b/src/main/java/org/caosdb/server/database/proto/ProtoGroup.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.database.proto; +package org.caosdb.server.database.proto; import java.io.Serializable; import java.util.HashSet; public class ProtoGroup implements Serializable { - private static final long serialVersionUID = 1659901727564921926L; + private static final long serialVersionUID = 7647402460488051845L; public String name = null; public String description = null; public HashSet<String> users = null; diff --git a/src/main/java/caosdb/server/database/proto/ProtoInfo.java b/src/main/java/org/caosdb/server/database/proto/ProtoInfo.java similarity index 96% rename from src/main/java/caosdb/server/database/proto/ProtoInfo.java rename to src/main/java/org/caosdb/server/database/proto/ProtoInfo.java index 36470495680beaa336c86e94598d096b196dc5e3..e8486e2f0ec7e1d92818bea2793f37dc34405da3 100644 --- a/src/main/java/caosdb/server/database/proto/ProtoInfo.java +++ b/src/main/java/org/caosdb/server/database/proto/ProtoInfo.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.database.proto; +package org.caosdb.server.database.proto; public class ProtoInfo { public Integer recordsCount = null; diff --git a/src/main/java/caosdb/server/database/proto/ProtoProperty.java b/src/main/java/org/caosdb/server/database/proto/ProtoProperty.java similarity index 90% rename from src/main/java/caosdb/server/database/proto/ProtoProperty.java rename to src/main/java/org/caosdb/server/database/proto/ProtoProperty.java index 6e13836322e52715d2afdb1d6ecbac946e290212..44acaa024513d3f4b8d89c3f59bda9baf9de3044 100644 --- a/src/main/java/caosdb/server/database/proto/ProtoProperty.java +++ b/src/main/java/org/caosdb/server/database/proto/ProtoProperty.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.database.proto; +package org.caosdb.server.database.proto; import java.io.Serializable; import java.util.List; public class ProtoProperty implements Serializable { - private static final long serialVersionUID = 6797170359746385913L; + private static final long serialVersionUID = 7731301985162924975L; public List<FlatProperty> subProperties = null; public FlatProperty property = null; } diff --git a/src/main/java/caosdb/server/database/proto/ProtoUser.java b/src/main/java/org/caosdb/server/database/proto/ProtoUser.java similarity index 88% rename from src/main/java/caosdb/server/database/proto/ProtoUser.java rename to src/main/java/org/caosdb/server/database/proto/ProtoUser.java index 40f8f490dc9e4453525be9e75697df5acc514e97..cafa32d2580c8a09a97e1cd3ee48c2ec59a454cf 100644 --- a/src/main/java/caosdb/server/database/proto/ProtoUser.java +++ b/src/main/java/org/caosdb/server/database/proto/ProtoUser.java @@ -20,17 +20,17 @@ * * ** end header */ -package caosdb.server.database.proto; +package org.caosdb.server.database.proto; -import caosdb.server.accessControl.UserStatus; import java.io.Serializable; import java.util.Set; +import org.caosdb.server.accessControl.UserStatus; public class ProtoUser implements Serializable { public ProtoUser() {} - private static final long serialVersionUID = 248172393585577797L; + private static final long serialVersionUID = -2704114543883567439L; public UserStatus status = null; public String name = null; diff --git a/src/main/java/caosdb/server/database/proto/Rule.java b/src/main/java/org/caosdb/server/database/proto/Rule.java similarity index 87% rename from src/main/java/caosdb/server/database/proto/Rule.java rename to src/main/java/org/caosdb/server/database/proto/Rule.java index 1bda3f437b54546ff3a5010b44f737a49dac900d..3d25f7662052b5b59f45255218c1191cf011761e 100644 --- a/src/main/java/caosdb/server/database/proto/Rule.java +++ b/src/main/java/org/caosdb/server/database/proto/Rule.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.database.proto; +package org.caosdb.server.database.proto; -import caosdb.server.jobs.core.Mode; import java.io.Serializable; +import org.caosdb.server.jobs.core.Mode; public class Rule implements Serializable { - private static final long serialVersionUID = 7648532019937680150L; + private static final long serialVersionUID = 1122097540596265945L; public int domain = 0; public int entity = 0; diff --git a/src/main/java/caosdb/server/database/proto/SparseEntity.java b/src/main/java/org/caosdb/server/database/proto/SparseEntity.java similarity index 90% rename from src/main/java/caosdb/server/database/proto/SparseEntity.java rename to src/main/java/org/caosdb/server/database/proto/SparseEntity.java index 4f5dcc69ce5ed7c6afa636b97237b53abb56ab51..d2292c58825ac6807e24f3ad3d086b29dd8a6e7e 100644 --- a/src/main/java/caosdb/server/database/proto/SparseEntity.java +++ b/src/main/java/org/caosdb/server/database/proto/SparseEntity.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.database.proto; +package org.caosdb.server.database.proto; /** * Rather abstract representation of a sparse Entity used by the data base abstraction layer. @@ -30,7 +30,7 @@ package caosdb.server.database.proto; */ public class SparseEntity extends VerySparseEntity { - private static final long serialVersionUID = 2603892933659461049L; + private static final long serialVersionUID = -560259468853956476L; public String collection = null; public String datatype = null; @@ -38,6 +38,7 @@ public class SparseEntity extends VerySparseEntity { public String filePath = null; public Long fileSize = null; public Long fileChecked = null; + public String versionId = null; @Override public String toString() { @@ -51,6 +52,7 @@ public class SparseEntity extends VerySparseEntity { .append(this.fileHash) .append(this.filePath) .append(this.fileSize) + .append(this.versionId) .toString(); } } diff --git a/src/main/java/org/caosdb/server/database/proto/VersionHistoryItem.java b/src/main/java/org/caosdb/server/database/proto/VersionHistoryItem.java new file mode 100644 index 0000000000000000000000000000000000000000..4c0a60ce57cce03cfaa7a2c4d41af7039c463838 --- /dev/null +++ b/src/main/java/org/caosdb/server/database/proto/VersionHistoryItem.java @@ -0,0 +1,27 @@ +package org.caosdb.server.database.proto; + +import java.io.Serializable; +import java.util.List; + +/** + * This class is a flat, data-only representation of a single item of version information. This + * class is an intermediate representation which abstracts away the data base results and comes in a + * form which is easily cacheable. + * + * @author Timm Fitschen (t.fitschen@indiscale.com) + */ +public class VersionHistoryItem implements Serializable { + + private static final long serialVersionUID = 428030617967255942L; + public String id = null; + public List<String> parents = null; + public Long seconds = null; + public Integer nanos = null; + public String username = null; + public String realm = null; + + @Override + public String toString() { + return id; + } +} diff --git a/src/main/java/caosdb/server/database/proto/VerySparseEntity.java b/src/main/java/org/caosdb/server/database/proto/VerySparseEntity.java similarity index 92% rename from src/main/java/caosdb/server/database/proto/VerySparseEntity.java rename to src/main/java/org/caosdb/server/database/proto/VerySparseEntity.java index ae341830f7b2ba20a04d902fd8c7068ce3527260..8f32bf52038a00275568688b016b830b19fba5f0 100644 --- a/src/main/java/caosdb/server/database/proto/VerySparseEntity.java +++ b/src/main/java/org/caosdb/server/database/proto/VerySparseEntity.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.database.proto; +package org.caosdb.server.database.proto; import java.io.Serializable; @@ -33,7 +33,7 @@ import java.io.Serializable; */ public class VerySparseEntity implements Serializable { - private static final long serialVersionUID = -5950583518110327486L; + private static final long serialVersionUID = 7370925076064714740L; public Integer id = null; public String name = null; diff --git a/src/main/java/caosdb/server/datatype/AbstractCollectionDatatype.java b/src/main/java/org/caosdb/server/datatype/AbstractCollectionDatatype.java similarity index 98% rename from src/main/java/caosdb/server/datatype/AbstractCollectionDatatype.java rename to src/main/java/org/caosdb/server/datatype/AbstractCollectionDatatype.java index 5f07bbe9a2880f5b7fd62fdb66c708e0a2739ab3..cbd822ee10a24127483fae9adff440404a243771 100644 --- a/src/main/java/caosdb/server/datatype/AbstractCollectionDatatype.java +++ b/src/main/java/org/caosdb/server/datatype/AbstractCollectionDatatype.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.datatype; +package org.caosdb.server.datatype; import java.util.HashMap; import java.util.regex.Matcher; diff --git a/src/main/java/caosdb/server/datatype/AbstractDatatype.java b/src/main/java/org/caosdb/server/datatype/AbstractDatatype.java similarity index 92% rename from src/main/java/caosdb/server/datatype/AbstractDatatype.java rename to src/main/java/org/caosdb/server/datatype/AbstractDatatype.java index 0cde534aa74a05e33591d5e8d719316e7f1704f6..8dd9c22df4441db8b0fe882f613eb742106c983b 100644 --- a/src/main/java/caosdb/server/datatype/AbstractDatatype.java +++ b/src/main/java/org/caosdb/server/datatype/AbstractDatatype.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.datatype; +package org.caosdb.server.datatype; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.Message; -import caosdb.server.entity.container.Container; import java.util.HashMap; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Message; +import org.caosdb.server.entity.container.Container; import org.reflections.Reflections; public abstract class AbstractDatatype { @@ -86,7 +86,7 @@ public abstract class AbstractDatatype { } private static void loadClasses() throws Exception { - final Reflections datatypePackage = new Reflections("caosdb.server.datatype"); + final Reflections datatypePackage = new Reflections("org.caosdb.server.datatype"); for (final Class<? extends AbstractDatatype> c : datatypePackage.getSubTypesOf(AbstractDatatype.class)) { if (c.isAnnotationPresent(DatatypeDefinition.class)) { diff --git a/src/main/java/caosdb/server/datatype/AbstractEnumValue.java b/src/main/java/org/caosdb/server/datatype/AbstractEnumValue.java similarity index 94% rename from src/main/java/caosdb/server/datatype/AbstractEnumValue.java rename to src/main/java/org/caosdb/server/datatype/AbstractEnumValue.java index 33303f22eccbca7fcffafdb9737d4e0880dd98ca..06216c822c705fa6fbaef949386966af15ff6b13 100644 --- a/src/main/java/caosdb/server/datatype/AbstractEnumValue.java +++ b/src/main/java/org/caosdb/server/datatype/AbstractEnumValue.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.datatype; +package org.caosdb.server.datatype; -import caosdb.server.datatype.AbstractDatatype.Table; import com.google.common.base.Objects; +import org.caosdb.server.datatype.AbstractDatatype.Table; import org.jdom2.Element; public abstract class AbstractEnumValue implements SingleValue { diff --git a/src/main/java/caosdb/server/datatype/BooleanDatatype.java b/src/main/java/org/caosdb/server/datatype/BooleanDatatype.java similarity index 92% rename from src/main/java/caosdb/server/datatype/BooleanDatatype.java rename to src/main/java/org/caosdb/server/datatype/BooleanDatatype.java index c5ddafb32fac059f49416b0926b9f532e38a3cd3..92c3440aeab6ef1cc86426c4e5d2356aef6720aa 100644 --- a/src/main/java/caosdb/server/datatype/BooleanDatatype.java +++ b/src/main/java/org/caosdb/server/datatype/BooleanDatatype.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.datatype; +package org.caosdb.server.datatype; -import caosdb.server.entity.Message; -import caosdb.server.utils.ServerMessages; +import org.caosdb.server.entity.Message; +import org.caosdb.server.utils.ServerMessages; @DatatypeDefinition(name = "Boolean") public class BooleanDatatype extends AbstractDatatype { diff --git a/src/main/java/caosdb/server/datatype/BooleanValue.java b/src/main/java/org/caosdb/server/datatype/BooleanValue.java similarity index 97% rename from src/main/java/caosdb/server/datatype/BooleanValue.java rename to src/main/java/org/caosdb/server/datatype/BooleanValue.java index f06cd4e5516fceeee459909bfde9ce60747834ea..0abfa0c917f21d246854cabcfe437fe48cb3d59e 100644 --- a/src/main/java/caosdb/server/datatype/BooleanValue.java +++ b/src/main/java/org/caosdb/server/datatype/BooleanValue.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.datatype; +package org.caosdb.server.datatype; public class BooleanValue extends AbstractEnumValue { diff --git a/src/main/java/caosdb/server/datatype/CaosEnum.java b/src/main/java/org/caosdb/server/datatype/CaosEnum.java similarity index 98% rename from src/main/java/caosdb/server/datatype/CaosEnum.java rename to src/main/java/org/caosdb/server/datatype/CaosEnum.java index 17615b2381c495a3b23b28ad9a2307f1e07bccb7..1040ab9a8114544dfd8a0d5a0a75660be4de5f07 100644 --- a/src/main/java/caosdb/server/datatype/CaosEnum.java +++ b/src/main/java/org/caosdb/server/datatype/CaosEnum.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.datatype; +package org.caosdb.server.datatype; import com.google.common.base.Objects; import java.util.TreeSet; diff --git a/src/main/java/caosdb/server/datatype/CollectionDatatypeFactory.java b/src/main/java/org/caosdb/server/datatype/CollectionDatatypeFactory.java similarity index 96% rename from src/main/java/caosdb/server/datatype/CollectionDatatypeFactory.java rename to src/main/java/org/caosdb/server/datatype/CollectionDatatypeFactory.java index 2ecd11549672cf23108d650aaadd61331903c322..1f80d937a8730891ace6a561d32f0a5bd3ce9a56 100644 --- a/src/main/java/caosdb/server/datatype/CollectionDatatypeFactory.java +++ b/src/main/java/org/caosdb/server/datatype/CollectionDatatypeFactory.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.datatype; +package org.caosdb.server.datatype; public interface CollectionDatatypeFactory { diff --git a/src/main/java/caosdb/server/datatype/CollectionValue.java b/src/main/java/org/caosdb/server/datatype/CollectionValue.java similarity index 98% rename from src/main/java/caosdb/server/datatype/CollectionValue.java rename to src/main/java/org/caosdb/server/datatype/CollectionValue.java index 3e70de7322af17cf27232446c1e4c984e73ae73a..55cbf0489c3f965e19784c80439d291930d89841 100644 --- a/src/main/java/caosdb/server/datatype/CollectionValue.java +++ b/src/main/java/org/caosdb/server/datatype/CollectionValue.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.datatype; +package org.caosdb.server.datatype; import java.util.ArrayList; import java.util.Collections; diff --git a/src/main/java/caosdb/server/datatype/DatatypeDefinition.java b/src/main/java/org/caosdb/server/datatype/DatatypeDefinition.java similarity index 96% rename from src/main/java/caosdb/server/datatype/DatatypeDefinition.java rename to src/main/java/org/caosdb/server/datatype/DatatypeDefinition.java index 3728a57b9c56f474548c882a7a558ad2cbcb6a73..b28ce312d6c5e4252efcdfdd0476d8307b09f021 100644 --- a/src/main/java/caosdb/server/datatype/DatatypeDefinition.java +++ b/src/main/java/org/caosdb/server/datatype/DatatypeDefinition.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.datatype; +package org.caosdb.server.datatype; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/src/main/java/caosdb/server/datatype/DateTimeDatatype.java b/src/main/java/org/caosdb/server/datatype/DateTimeDatatype.java similarity index 84% rename from src/main/java/caosdb/server/datatype/DateTimeDatatype.java rename to src/main/java/org/caosdb/server/datatype/DateTimeDatatype.java index 833a1502d8aecff798cb1c8aa9d0364e7d613ac4..574e40cb96097544a19cf46c4ad700e9ce442208 100644 --- a/src/main/java/caosdb/server/datatype/DateTimeDatatype.java +++ b/src/main/java/org/caosdb/server/datatype/DateTimeDatatype.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.datatype; +package org.caosdb.server.datatype; -import caosdb.datetime.Date; -import caosdb.datetime.DateTimeFactory2; -import caosdb.datetime.DateTimeInterface; -import caosdb.datetime.UTCDateTime; -import caosdb.server.entity.Message; -import caosdb.server.utils.ServerMessages; +import org.caosdb.datetime.Date; +import org.caosdb.datetime.DateTimeFactory2; +import org.caosdb.datetime.DateTimeInterface; +import org.caosdb.datetime.UTCDateTime; +import org.caosdb.server.entity.Message; +import org.caosdb.server.utils.ServerMessages; @DatatypeDefinition(name = "DateTime") public class DateTimeDatatype extends AbstractDatatype { diff --git a/src/main/java/caosdb/server/datatype/DoubleDatatype.java b/src/main/java/org/caosdb/server/datatype/DoubleDatatype.java similarity index 92% rename from src/main/java/caosdb/server/datatype/DoubleDatatype.java rename to src/main/java/org/caosdb/server/datatype/DoubleDatatype.java index c7daacdc00bf4895433a3d4c0fc67c025dc6220f..f2f8d2823e4483c59945c168f5e83d029bc6da6a 100644 --- a/src/main/java/caosdb/server/datatype/DoubleDatatype.java +++ b/src/main/java/org/caosdb/server/datatype/DoubleDatatype.java @@ -21,10 +21,10 @@ * ** end header */ // Copyright (c) 2019 Daniel Hornung -package caosdb.server.datatype; +package org.caosdb.server.datatype; -import caosdb.server.entity.Message; -import caosdb.server.utils.ServerMessages; +import org.caosdb.server.entity.Message; +import org.caosdb.server.utils.ServerMessages; @DatatypeDefinition(name = "Double") public class DoubleDatatype extends AbstractDatatype { diff --git a/src/main/java/caosdb/server/datatype/FileDatatype.java b/src/main/java/org/caosdb/server/datatype/FileDatatype.java similarity index 96% rename from src/main/java/caosdb/server/datatype/FileDatatype.java rename to src/main/java/org/caosdb/server/datatype/FileDatatype.java index 62c838ca71ada9277944b09862342c46b94bead2..febc317dbd430181784b2312ff6d6162193f4100 100644 --- a/src/main/java/caosdb/server/datatype/FileDatatype.java +++ b/src/main/java/org/caosdb/server/datatype/FileDatatype.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.datatype; +package org.caosdb.server.datatype; @DatatypeDefinition(name = "File") public class FileDatatype extends ReferenceDatatype {} diff --git a/src/main/java/caosdb/server/datatype/GenericValue.java b/src/main/java/org/caosdb/server/datatype/GenericValue.java similarity index 96% rename from src/main/java/caosdb/server/datatype/GenericValue.java rename to src/main/java/org/caosdb/server/datatype/GenericValue.java index cffd62bbcbbb2dfffab2a7c55b2b7861b2bd9aae..e21841ee782a2ff86d2d993bbb0b9901a7835667 100644 --- a/src/main/java/caosdb/server/datatype/GenericValue.java +++ b/src/main/java/org/caosdb/server/datatype/GenericValue.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.datatype; +package org.caosdb.server.datatype; -import caosdb.server.datatype.AbstractDatatype.Table; import com.google.common.base.Objects; +import org.caosdb.server.datatype.AbstractDatatype.Table; import org.jdom2.Element; public class GenericValue implements SingleValue { diff --git a/src/main/java/caosdb/server/datatype/IndexedSingleValue.java b/src/main/java/org/caosdb/server/datatype/IndexedSingleValue.java similarity index 95% rename from src/main/java/caosdb/server/datatype/IndexedSingleValue.java rename to src/main/java/org/caosdb/server/datatype/IndexedSingleValue.java index f33db43ef0ca8aa50bc9fcca54a232965e98f29a..a9ed584b3ee858e6de2bbb84ad4a43da820cedb0 100644 --- a/src/main/java/caosdb/server/datatype/IndexedSingleValue.java +++ b/src/main/java/org/caosdb/server/datatype/IndexedSingleValue.java @@ -20,9 +20,9 @@ * * ** end header */ -package caosdb.server.datatype; +package org.caosdb.server.datatype; -import caosdb.server.datatype.AbstractDatatype.Table; +import org.caosdb.server.datatype.AbstractDatatype.Table; import org.jdom2.Element; public class IndexedSingleValue implements SingleValue, Comparable<IndexedSingleValue> { diff --git a/src/main/java/caosdb/server/datatype/IntegerDatatype.java b/src/main/java/org/caosdb/server/datatype/IntegerDatatype.java similarity index 91% rename from src/main/java/caosdb/server/datatype/IntegerDatatype.java rename to src/main/java/org/caosdb/server/datatype/IntegerDatatype.java index 4ab8d94dc97d0060335b99f2c91dd05f05e1dc55..b5ac2d971c7edd1eaf3947eacf1d1f94f967d808 100644 --- a/src/main/java/caosdb/server/datatype/IntegerDatatype.java +++ b/src/main/java/org/caosdb/server/datatype/IntegerDatatype.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.datatype; +package org.caosdb.server.datatype; -import caosdb.server.entity.Message; -import caosdb.server.utils.ServerMessages; +import org.caosdb.server.entity.Message; +import org.caosdb.server.utils.ServerMessages; @DatatypeDefinition(name = "Integer") public class IntegerDatatype extends AbstractDatatype { diff --git a/src/main/java/caosdb/server/datatype/ListDatatype.java b/src/main/java/org/caosdb/server/datatype/ListDatatype.java similarity index 96% rename from src/main/java/caosdb/server/datatype/ListDatatype.java rename to src/main/java/org/caosdb/server/datatype/ListDatatype.java index 877901458dcf94fee17a9f5ac8c69f1026609322..bdf148e66638757ba5ccc315a7eac557774d8f63 100644 --- a/src/main/java/caosdb/server/datatype/ListDatatype.java +++ b/src/main/java/org/caosdb/server/datatype/ListDatatype.java @@ -20,9 +20,9 @@ * * ** end header */ -package caosdb.server.datatype; +package org.caosdb.server.datatype; -import caosdb.server.entity.Message; +import org.caosdb.server.entity.Message; public class ListDatatype extends AbstractCollectionDatatype { diff --git a/src/main/java/caosdb/server/datatype/ListDatatypeFactory.java b/src/main/java/org/caosdb/server/datatype/ListDatatypeFactory.java similarity index 96% rename from src/main/java/caosdb/server/datatype/ListDatatypeFactory.java rename to src/main/java/org/caosdb/server/datatype/ListDatatypeFactory.java index 9faf9cafba914a67bd474af9f5f7cf66a2456767..d1999f13c794a496657139dfeef78b0584784082 100644 --- a/src/main/java/caosdb/server/datatype/ListDatatypeFactory.java +++ b/src/main/java/org/caosdb/server/datatype/ListDatatypeFactory.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.datatype; +package org.caosdb.server.datatype; public class ListDatatypeFactory implements CollectionDatatypeFactory { diff --git a/src/main/java/caosdb/server/datatype/ReferenceDatatype.java b/src/main/java/org/caosdb/server/datatype/ReferenceDatatype.java similarity index 94% rename from src/main/java/caosdb/server/datatype/ReferenceDatatype.java rename to src/main/java/org/caosdb/server/datatype/ReferenceDatatype.java index 1675f028987516ae8e6cadc8aaaa2e6807f35221..42f60cebc116d23137d359c11015a2978233234e 100644 --- a/src/main/java/caosdb/server/datatype/ReferenceDatatype.java +++ b/src/main/java/org/caosdb/server/datatype/ReferenceDatatype.java @@ -20,9 +20,9 @@ * * ** end header */ -package caosdb.server.datatype; +package org.caosdb.server.datatype; -import caosdb.server.entity.Message; +import org.caosdb.server.entity.Message; @DatatypeDefinition(name = "Reference") public class ReferenceDatatype extends AbstractDatatype { diff --git a/src/main/java/caosdb/server/datatype/ReferenceDatatype2.java b/src/main/java/org/caosdb/server/datatype/ReferenceDatatype2.java similarity index 91% rename from src/main/java/caosdb/server/datatype/ReferenceDatatype2.java rename to src/main/java/org/caosdb/server/datatype/ReferenceDatatype2.java index ce92aa022cfe85573049eaaeed4e26653b400679..6d96d6deaae43d4d854875424129b7558d0fddf0 100644 --- a/src/main/java/caosdb/server/datatype/ReferenceDatatype2.java +++ b/src/main/java/org/caosdb/server/datatype/ReferenceDatatype2.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.datatype; +package org.caosdb.server.datatype; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.Message; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Message; public class ReferenceDatatype2 extends ReferenceDatatype { @@ -47,7 +47,7 @@ public class ReferenceDatatype2 extends ReferenceDatatype { } public void setEntity(final EntityInterface datatypeEntity) { - this.refid.setEntity(datatypeEntity); + this.refid.setEntity(datatypeEntity, false); } @Override diff --git a/src/main/java/org/caosdb/server/datatype/ReferenceValue.java b/src/main/java/org/caosdb/server/datatype/ReferenceValue.java new file mode 100644 index 0000000000000000000000000000000000000000..89601b50a46cbf838a995a222b0d4c43150f8a19 --- /dev/null +++ b/src/main/java/org/caosdb/server/datatype/ReferenceValue.java @@ -0,0 +1,213 @@ +/* + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2018 Research Group Biomedical Physics, + * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * + * 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 <https://www.gnu.org/licenses/>. + * + * ** end header + */ +package org.caosdb.server.datatype; + +import java.util.Objects; +import org.caosdb.server.datatype.AbstractDatatype.Table; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Message; +import org.caosdb.server.utils.ServerMessages; +import org.jdom2.Element; + +/** + * A ReferenceValue represents the value of a reference property to another entity. + * + * <p>Differently from other properties, they may be versioned, i.e. they may reference to a + * specific version of an entity. + * + * <p>TODO: Ways to specify a reference value, what are the consequences of versioned references? + */ +public class ReferenceValue implements SingleValue { + private EntityInterface entity = null; + private String name = null; + private Integer id = null; + private String version = null; + private boolean versioned = false; + + public static ReferenceValue parseReference(final Object reference) throws Message { + if (reference == null) { + return null; + } + if (reference instanceof EntityInterface) { + return new ReferenceValue( + (EntityInterface) reference, ((EntityInterface) reference).hasVersion()); + } else if (reference instanceof ReferenceValue) { + return (ReferenceValue) reference; + } else if (reference instanceof GenericValue) { + String str = ((GenericValue) reference).toDatabaseString(); + return parseFromString(str); + } else if (reference instanceof CollectionValue) { + throw ServerMessages.DATA_TYPE_DOES_NOT_ACCEPT_COLLECTION_VALUES; + } else { + try { + return new ReferenceValue(Integer.parseInt(reference.toString())); + } catch (final NumberFormatException e) { + return new ReferenceValue(reference.toString()); + } + } + } + + /** + * Split a reference string into an entity part and a version part, if there is a version part. + * + * <p>If parsing the entity ID part to an integer fails, a NumberFormatException may be thrown. + */ + public static ReferenceValue parseIdVersion(String str) { + String[] split = str.split("@", 2); + if (split.length == 2) { + return new ReferenceValue(Integer.parseInt(split[0]), split[1]); + } else { + return new ReferenceValue(Integer.parseInt(str)); + } + } + + /** + * Create a ReferenceValue from a string. + * + * <p>If the string looks like a valid "entityID@version" string, the result will have the + * corresponding entity and version parts. + */ + public static ReferenceValue parseFromString(String str) { + try { + return parseIdVersion(str); + } catch (final NumberFormatException e) { + return new ReferenceValue(str); + } + } + + /** + * Produce a nice but short string: + * + * <p>Case 1 "versioned" (reference to an entity without specifying that entity's version): + * Produces a string like "1234" or "Experiment". Note that referencing via name is never + * versioned. + * + * <p>Case 2 "unversioned" (reference to an entity with a specified version): Produces a string + * like "1234@ab987f". + */ + @Override + public String toString() { + if (this.entity != null && versioned) { // Was specified as "versioned", with resolved entity + return this.entity.getIdVersion(); + } else if (this.entity != null) { // resolved, but unversioned + return this.entity.getId().toString(); + } else if (this.id == null + && this.name != null) { // Only name is available, no id (and thus no resolved entity) + return this.name; + } + // Specification via id is the only remaining possibility + return getIdVersion(); // if version is null, returns ID only + } + + public String getIdVersion() { + if (this.version != null) { + return new StringBuilder().append(this.id).append("@").append(this.version).toString(); + } + return this.id.toString(); + } + + public ReferenceValue(final EntityInterface entity, boolean versioned) { + this.versioned = versioned; + this.entity = entity; + } + + public ReferenceValue(final Integer id) { + this(id, null); + } + + public ReferenceValue(final Integer id, final String version) { + this.id = id; + this.version = version; + this.versioned = version != null; + } + + /** If the reference is given by name, versioning is not possible (at the moment). */ + public ReferenceValue(final String name) { + this.name = name; + } + + public final EntityInterface getEntity() { + return this.entity; + } + + public final void setEntity(final EntityInterface entity, boolean versioned) { + this.versioned = versioned; + this.entity = entity; + } + + public final String getName() { + if (this.entity != null && this.entity.hasName()) { + return this.entity.getName(); + } + return this.name; + } + + public final Integer getId() { + if (this.entity != null && this.entity.hasId()) { + return this.entity.getId(); + } + return this.id; + } + + public final String getVersion() { + if (this.entity != null && versioned && this.entity.hasVersion()) { + return this.entity.getVersion().getId(); + } + return this.version; + } + + public final void setId(final Integer id) { + this.id = id; + } + + @Override + public void addToElement(final Element e) { + e.addContent(toString()); + } + + @Override + public Table getTable() { + return Table.reference_data; + } + + @Override + public String toDatabaseString() { + return toString(); + } + + @Override + public boolean equals(final Object obj) { + if (obj instanceof ReferenceValue) { + final ReferenceValue that = (ReferenceValue) obj; + if (that.getId() != null && getId() != null) { + return that.getId().equals(getId()) + && Objects.deepEquals(that.getVersion(), this.getVersion()); + } else if (that.getName() != null && getName() != null) { + return that.getName().equals(getName()); + } + } + return false; + } +} diff --git a/src/main/java/caosdb/server/datatype/SQLiteDatatype.java b/src/main/java/org/caosdb/server/datatype/SQLiteDatatype.java similarity index 96% rename from src/main/java/caosdb/server/datatype/SQLiteDatatype.java rename to src/main/java/org/caosdb/server/datatype/SQLiteDatatype.java index 9a7c2f1cbbf7ca508690be9ac414bad56c01770b..ffd4341013176992e802e8e0c8c4bc2d58b78ad3 100644 --- a/src/main/java/caosdb/server/datatype/SQLiteDatatype.java +++ b/src/main/java/org/caosdb/server/datatype/SQLiteDatatype.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.datatype; +package org.caosdb.server.datatype; @DatatypeDefinition(name = "SQLite") public class SQLiteDatatype extends ReferenceDatatype {} diff --git a/src/main/java/caosdb/server/datatype/SingleValue.java b/src/main/java/org/caosdb/server/datatype/SingleValue.java similarity index 96% rename from src/main/java/caosdb/server/datatype/SingleValue.java rename to src/main/java/org/caosdb/server/datatype/SingleValue.java index 2ae17a6122035387f31466a74c0468d9fde80e36..cfe2b6404119265c9cccc74349553557467cff56 100644 --- a/src/main/java/caosdb/server/datatype/SingleValue.java +++ b/src/main/java/org/caosdb/server/datatype/SingleValue.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.datatype; +package org.caosdb.server.datatype; public interface SingleValue extends Value { diff --git a/src/main/java/caosdb/server/datatype/TextDatatype.java b/src/main/java/org/caosdb/server/datatype/TextDatatype.java similarity index 93% rename from src/main/java/caosdb/server/datatype/TextDatatype.java rename to src/main/java/org/caosdb/server/datatype/TextDatatype.java index f173243f1414bbcf02a0880b3b442eb70823a334..af06ed6de1f0f49b481b2a706f529037e555785e 100644 --- a/src/main/java/caosdb/server/datatype/TextDatatype.java +++ b/src/main/java/org/caosdb/server/datatype/TextDatatype.java @@ -20,9 +20,9 @@ * * ** end header */ -package caosdb.server.datatype; +package org.caosdb.server.datatype; -import caosdb.server.entity.Message; +import org.caosdb.server.entity.Message; @DatatypeDefinition(name = "Text") public class TextDatatype extends AbstractDatatype { diff --git a/src/main/java/caosdb/server/datatype/Value.java b/src/main/java/org/caosdb/server/datatype/Value.java similarity index 96% rename from src/main/java/caosdb/server/datatype/Value.java rename to src/main/java/org/caosdb/server/datatype/Value.java index 6030880dcf6cbcb50a43633c1317c6cae70fef05..540e6bc52b72744c4d7c1c651c40924d1da57c6d 100644 --- a/src/main/java/caosdb/server/datatype/Value.java +++ b/src/main/java/org/caosdb/server/datatype/Value.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.datatype; +package org.caosdb.server.datatype; import org.jdom2.Element; diff --git a/src/main/java/caosdb/server/entity/Affiliation.java b/src/main/java/org/caosdb/server/entity/Affiliation.java similarity index 96% rename from src/main/java/caosdb/server/entity/Affiliation.java rename to src/main/java/org/caosdb/server/entity/Affiliation.java index c51a9a279cfe2722d85124b3bde57fe08fd0baf3..f3e5ec73561760b889657ba20134d16aabf3e35a 100644 --- a/src/main/java/caosdb/server/entity/Affiliation.java +++ b/src/main/java/org/caosdb/server/entity/Affiliation.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.entity; +package org.caosdb.server.entity; public enum Affiliation { INSTANTIATION, // RECORD is-a RECORD TYPE diff --git a/src/main/java/caosdb/server/jobs/extension/JobException.java b/src/main/java/org/caosdb/server/entity/DeleteEntity.java similarity index 65% rename from src/main/java/caosdb/server/jobs/extension/JobException.java rename to src/main/java/org/caosdb/server/entity/DeleteEntity.java index e41475bb370334bb85f0ee8adfb14219d7ecf44d..37377534f721a3d93455473b7a8a58fb7d50f287 100644 --- a/src/main/java/caosdb/server/jobs/extension/JobException.java +++ b/src/main/java/org/caosdb/server/entity/DeleteEntity.java @@ -3,7 +3,9 @@ * This file is a part of the CaosDB Project. * * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -20,23 +22,16 @@ * * ** end header */ -package caosdb.server.jobs.extension; +package org.caosdb.server.entity; -import caosdb.server.jobs.Job; +public class DeleteEntity extends Entity { -public class JobException extends RuntimeException { - - /** */ - private static final long serialVersionUID = -2802983933079999366L; - - private final Job job; - - public JobException(final Job job, final Exception e) { - super(e); - this.job = job; + public DeleteEntity(final int id) { + super(id); } - public Job getJob() { - return this.job; + public DeleteEntity(int id, String version) { + super(id); + setVersion(new Version(version)); } } diff --git a/src/main/java/caosdb/server/entity/Entity.java b/src/main/java/org/caosdb/server/entity/Entity.java similarity index 90% rename from src/main/java/caosdb/server/entity/Entity.java rename to src/main/java/org/caosdb/server/entity/Entity.java index 5c997d7ff8f9f98191ba768c82569a79ca056cf2..845bb25a3cee665fd8f0985c6969f53dfc868025 100644 --- a/src/main/java/caosdb/server/entity/Entity.java +++ b/src/main/java/org/caosdb/server/entity/Entity.java @@ -3,7 +3,9 @@ * This file is a part of the CaosDB Project. * * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -20,33 +22,8 @@ * * ** end header */ -package caosdb.server.entity; - -import caosdb.server.CaosDBException; -import caosdb.server.database.proto.SparseEntity; -import caosdb.server.database.proto.VerySparseEntity; -import caosdb.server.datatype.AbstractCollectionDatatype; -import caosdb.server.datatype.AbstractDatatype; -import caosdb.server.datatype.CollectionValue; -import caosdb.server.datatype.GenericValue; -import caosdb.server.datatype.Value; -import caosdb.server.entity.Message.MessageType; -import caosdb.server.entity.container.ParentContainer; -import caosdb.server.entity.container.PropertyContainer; -import caosdb.server.entity.wrapper.Domain; -import caosdb.server.entity.wrapper.Parent; -import caosdb.server.entity.wrapper.Property; -import caosdb.server.entity.xml.EntityToElementStrategy; -import caosdb.server.entity.xml.SetFieldStrategy; -import caosdb.server.entity.xml.ToElementStrategy; -import caosdb.server.entity.xml.ToElementable; -import caosdb.server.permissions.EntityACL; -import caosdb.server.query.Query.Selection; -import caosdb.server.utils.AbstractObservable; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; -import caosdb.server.utils.TransactionLogMessage; -import caosdb.unit.Unit; +package org.caosdb.server.entity; + import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -57,6 +34,31 @@ import org.apache.shiro.SecurityUtils; import org.apache.shiro.authz.AuthorizationException; import org.apache.shiro.authz.Permission; import org.apache.shiro.subject.Subject; +import org.caosdb.server.CaosDBException; +import org.caosdb.server.database.proto.SparseEntity; +import org.caosdb.server.database.proto.VerySparseEntity; +import org.caosdb.server.datatype.AbstractCollectionDatatype; +import org.caosdb.server.datatype.AbstractDatatype; +import org.caosdb.server.datatype.CollectionValue; +import org.caosdb.server.datatype.GenericValue; +import org.caosdb.server.datatype.Value; +import org.caosdb.server.entity.Message.MessageType; +import org.caosdb.server.entity.container.ParentContainer; +import org.caosdb.server.entity.container.PropertyContainer; +import org.caosdb.server.entity.wrapper.Domain; +import org.caosdb.server.entity.wrapper.Parent; +import org.caosdb.server.entity.wrapper.Property; +import org.caosdb.server.entity.xml.EntityToElementStrategy; +import org.caosdb.server.entity.xml.SetFieldStrategy; +import org.caosdb.server.entity.xml.ToElementStrategy; +import org.caosdb.server.entity.xml.ToElementable; +import org.caosdb.server.permissions.EntityACL; +import org.caosdb.server.query.Query.Selection; +import org.caosdb.server.utils.AbstractObservable; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; +import org.caosdb.server.utils.TransactionLogMessage; +import org.caosdb.unit.Unit; import org.jdom2.Element; public class Entity extends AbstractObservable implements EntityInterface { @@ -521,6 +523,7 @@ public class Entity extends AbstractObservable implements EntityInterface { } } + // Strategy to convert this Entity to an XML element. private ToElementStrategy toElementStrategy = null; @Override @@ -535,7 +538,12 @@ public class Entity extends AbstractObservable implements EntityInterface { @Override public final void addToElement(final Element element) { - getToElementStrategy().addToElement(this, element, new SetFieldStrategy(getSelections())); + addToElement(element, new SetFieldStrategy(getSelections())); + } + + @Override + public void addToElement(Element element, SetFieldStrategy strategy) { + getToElementStrategy().addToElement(this, element, strategy); } /** @@ -794,7 +802,11 @@ public class Entity extends AbstractObservable implements EntityInterface { final CollectionValue vals = new CollectionValue(); int pidx = 0; for (final Element pe : element.getChildren()) { - if (pe.getName().equalsIgnoreCase("EmptyString")) { + if (pe.getName().equalsIgnoreCase("Version")) { + // IGNORE: Once it becomes allowed for clients to set a version id, parsing + // the Version element would be done here. Until this is the case, the + // Version tag is ignored. + } else if (pe.getName().equalsIgnoreCase("EmptyString")) { // special case: empty string which cannot be distinguished from null // values otherwise. setValue(new GenericValue("")); @@ -944,7 +956,8 @@ public class Entity extends AbstractObservable implements EntityInterface { @Override public String toString() { - return (hasId() ? "(" + getId().toString() + ")" : "()") + return (getRole().toString()) + + (hasId() ? "(" + getId().toString() + ")" : "()") + (hasCuid() ? "[" + getCuid() + "]" : "[]") + (hasName() ? "(" + getName() + ")" : "()") + (hasDatatype() ? "{" + getDatatype().toString() + "}" : "{}"); @@ -1020,6 +1033,7 @@ public class Entity extends AbstractObservable implements EntityInterface { } private boolean datatypeOverride = false; + private Version version = new Version(); @Override public EntityInterface setDatatypeOverride(final boolean b) { @@ -1060,10 +1074,13 @@ public class Entity extends AbstractObservable implements EntityInterface { } @Override - public EntityInterface parseSparseEntity(final SparseEntity spe) { + public final EntityInterface parseSparseEntity(final SparseEntity spe) { setId(spe.id); this.setRole(spe.role); setEntityACL(spe.acl); + if (spe.versionId != null) { + this.version = new Version(spe.versionId); + } if (!isNameOverride()) { setName(spe.name); @@ -1112,4 +1129,34 @@ public class Entity extends AbstractObservable implements EntityInterface { public boolean skipJob() { return false; } + + @Override + public Version getVersion() { + return this.version; + } + + @Override + public boolean hasVersion() { + return this.version.getId() != null; + } + + @Override + public void setVersion(Version version) { + this.version = version; + } + + /** Return "id@version" if there is versioning information, else only "id". */ + @Override + public String getIdVersion() { + if (!this.hasId()) { + return null; + } else if (this.hasVersion()) { + return new StringBuilder() + .append(getId()) + .append("@") + .append(getVersion().getId()) + .toString(); + } + return getId().toString(); + } } diff --git a/src/main/java/caosdb/server/entity/EntityInterface.java b/src/main/java/org/caosdb/server/entity/EntityInterface.java similarity index 81% rename from src/main/java/caosdb/server/entity/EntityInterface.java rename to src/main/java/org/caosdb/server/entity/EntityInterface.java index 21ed5cd85234bd633914302ce2982b2b6f4f9a66..ef97630808536f367869851c5be06d05e6247ac2 100644 --- a/src/main/java/caosdb/server/entity/EntityInterface.java +++ b/src/main/java/org/caosdb/server/entity/EntityInterface.java @@ -20,26 +20,28 @@ * * ** end header */ -package caosdb.server.entity; - -import caosdb.server.database.proto.SparseEntity; -import caosdb.server.database.proto.VerySparseEntity; -import caosdb.server.datatype.AbstractDatatype; -import caosdb.server.datatype.Value; -import caosdb.server.entity.container.ParentContainer; -import caosdb.server.entity.container.PropertyContainer; -import caosdb.server.entity.wrapper.Domain; -import caosdb.server.entity.wrapper.Parent; -import caosdb.server.entity.wrapper.Property; -import caosdb.server.entity.xml.ToElementable; -import caosdb.server.jobs.JobTarget; -import caosdb.server.permissions.EntityACL; -import caosdb.server.utils.Observable; -import caosdb.server.utils.TransactionLogMessage; -import caosdb.unit.Unit; +package org.caosdb.server.entity; + import java.util.List; import org.apache.shiro.authz.Permission; import org.apache.shiro.subject.Subject; +import org.caosdb.server.database.proto.SparseEntity; +import org.caosdb.server.database.proto.VerySparseEntity; +import org.caosdb.server.datatype.AbstractDatatype; +import org.caosdb.server.datatype.Value; +import org.caosdb.server.entity.container.ParentContainer; +import org.caosdb.server.entity.container.PropertyContainer; +import org.caosdb.server.entity.wrapper.Domain; +import org.caosdb.server.entity.wrapper.Parent; +import org.caosdb.server.entity.wrapper.Property; +import org.caosdb.server.entity.xml.SetFieldStrategy; +import org.caosdb.server.entity.xml.ToElementable; +import org.caosdb.server.jobs.JobTarget; +import org.caosdb.server.permissions.EntityACL; +import org.caosdb.server.utils.Observable; +import org.caosdb.server.utils.TransactionLogMessage; +import org.caosdb.unit.Unit; +import org.jdom2.Element; public interface EntityInterface extends JobTarget, Observable, ToElementable, WriteEntity, TransactionEntity { @@ -50,6 +52,8 @@ public interface EntityInterface public abstract Integer getId(); + public abstract String getIdVersion(); + public abstract void setId(Integer id); public abstract boolean hasId(); @@ -182,4 +186,12 @@ public interface EntityInterface public abstract String getQueryTemplateDefinition(); public abstract void setQueryTemplateDefinition(String query); + + public abstract Version getVersion(); + + public abstract boolean hasVersion(); + + public abstract void setVersion(Version version); + + public abstract void addToElement(Element element, SetFieldStrategy strategy); } diff --git a/src/main/java/caosdb/server/entity/FileProperties.java b/src/main/java/org/caosdb/server/entity/FileProperties.java similarity index 94% rename from src/main/java/caosdb/server/entity/FileProperties.java rename to src/main/java/org/caosdb/server/entity/FileProperties.java index fbf8031f56566ea5a6df263d97611812bab113d0..0c10288e0cbaa6a4f55a2959f72ac09db9d6f394 100644 --- a/src/main/java/caosdb/server/entity/FileProperties.java +++ b/src/main/java/org/caosdb/server/entity/FileProperties.java @@ -20,17 +20,17 @@ * * ** end header */ -package caosdb.server.entity; - -import caosdb.server.CaosDBException; -import caosdb.server.FileSystem; -import caosdb.server.utils.FileUtils; -import caosdb.server.utils.ServerMessages; -import caosdb.server.utils.UndoHandler; -import caosdb.server.utils.Undoable; +package org.caosdb.server.entity; + import java.io.File; import java.io.IOException; import java.security.NoSuchAlgorithmException; +import org.caosdb.server.CaosDBException; +import org.caosdb.server.FileSystem; +import org.caosdb.server.utils.FileUtils; +import org.caosdb.server.utils.ServerMessages; +import org.caosdb.server.utils.UndoHandler; +import org.caosdb.server.utils.Undoable; public class FileProperties { private File thumbnail = null; @@ -220,10 +220,10 @@ public class FileProperties { if (file.getAbsolutePath().startsWith(FileSystem.getBasepath())) { final Undoable d; final File parent = file.getParentFile(); - if (file.getCanonicalPath().startsWith(FileSystem.getBasepath())) { - d = FileUtils.delete(file, file.isDirectory()); - } else if (FileUtils.isSymlink(file)) { + if (FileUtils.isSymlink(file)) { d = FileUtils.unlink(file); + } else if (file.getCanonicalPath().startsWith(FileSystem.getBasepath())) { + d = FileUtils.delete(file, file.isDirectory()); } else { throw new CaosDBException( "File is in Filesystem, but it is neither a normal file nor a symlink."); diff --git a/src/main/java/caosdb/server/entity/InsertEntity.java b/src/main/java/org/caosdb/server/entity/InsertEntity.java similarity index 96% rename from src/main/java/caosdb/server/entity/InsertEntity.java rename to src/main/java/org/caosdb/server/entity/InsertEntity.java index 92f665e36cb0e0bce0243658e3148dd3b69b9ad4..56eeb12b1c2e7b9d5259a4d418e87c79e8068f51 100644 --- a/src/main/java/caosdb/server/entity/InsertEntity.java +++ b/src/main/java/org/caosdb/server/entity/InsertEntity.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.entity; +package org.caosdb.server.entity; import org.jdom2.Element; diff --git a/src/main/java/caosdb/server/entity/MagicTypes.java b/src/main/java/org/caosdb/server/entity/MagicTypes.java similarity index 94% rename from src/main/java/caosdb/server/entity/MagicTypes.java rename to src/main/java/org/caosdb/server/entity/MagicTypes.java index ddc57a58362f81c9f3c55a45dc2a069d4202c8af..cffdb0723588d3aaec31e24a39895e304aa2e18b 100644 --- a/src/main/java/caosdb/server/entity/MagicTypes.java +++ b/src/main/java/org/caosdb/server/entity/MagicTypes.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.entity; +package org.caosdb.server.entity; -import caosdb.server.entity.container.RetrieveContainer; -import caosdb.server.transaction.Retrieve; import java.util.HashMap; +import org.caosdb.server.entity.container.RetrieveContainer; +import org.caosdb.server.transaction.Retrieve; public enum MagicTypes { UNIT, diff --git a/src/main/java/caosdb/server/entity/Message.java b/src/main/java/org/caosdb/server/entity/Message.java similarity index 96% rename from src/main/java/caosdb/server/entity/Message.java rename to src/main/java/org/caosdb/server/entity/Message.java index 0ffedb4316fe372e09f3b69ca5824a72f98accaf..743a2b62fa87570e0dbca05a1f279e6764920f0b 100644 --- a/src/main/java/caosdb/server/entity/Message.java +++ b/src/main/java/org/caosdb/server/entity/Message.java @@ -20,9 +20,9 @@ * * ** end header */ -package caosdb.server.entity; +package org.caosdb.server.entity; -import caosdb.server.entity.xml.ToElementable; +import org.caosdb.server.entity.xml.ToElementable; import org.jdom2.Element; public class Message extends Exception implements Comparable<Message>, ToElementable { @@ -32,7 +32,7 @@ public class Message extends Exception implements Comparable<Message>, ToElement private final String description; private final String body; - private static final long serialVersionUID = -6527053191344766124L; + private static final long serialVersionUID = -3005017964769041935L; public enum MessageType { Warning, diff --git a/src/main/java/caosdb/server/entity/NoSuchRoleException.java b/src/main/java/org/caosdb/server/entity/NoSuchRoleException.java similarity index 90% rename from src/main/java/caosdb/server/entity/NoSuchRoleException.java rename to src/main/java/org/caosdb/server/entity/NoSuchRoleException.java index 783c2752143e7d1099808cf6ef9f19825d1a2836..31d79a6de6e9932b680b89b133363134cbdef4ef 100644 --- a/src/main/java/caosdb/server/entity/NoSuchRoleException.java +++ b/src/main/java/org/caosdb/server/entity/NoSuchRoleException.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.entity; +package org.caosdb.server.entity; public class NoSuchRoleException extends IllegalArgumentException { @@ -29,5 +29,5 @@ public class NoSuchRoleException extends IllegalArgumentException { } /** */ - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = -5647651111944453390L; } diff --git a/src/main/java/org/caosdb/server/entity/RetrieveEntity.java b/src/main/java/org/caosdb/server/entity/RetrieveEntity.java new file mode 100644 index 0000000000000000000000000000000000000000..35e34feda25c3ed7087c3c909a49a5833bce3698 --- /dev/null +++ b/src/main/java/org/caosdb/server/entity/RetrieveEntity.java @@ -0,0 +1,46 @@ +/* + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2018 Research Group Biomedical Physics, + * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * + * 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 <https://www.gnu.org/licenses/>. + * + * ** end header + */ +package org.caosdb.server.entity; + +public class RetrieveEntity extends Entity { + + public RetrieveEntity(final int id) { + super(id); + } + + public RetrieveEntity(final String name) { + super(name); + } + + public RetrieveEntity(int id, String version) { + super(id); + this.setVersion(new Version(version)); + } + + public RetrieveEntity(String name, String version) { + super(name); + this.setVersion(new Version(version)); + } +} diff --git a/src/main/java/caosdb/server/entity/Role.java b/src/main/java/org/caosdb/server/entity/Role.java similarity index 86% rename from src/main/java/caosdb/server/entity/Role.java rename to src/main/java/org/caosdb/server/entity/Role.java index 79b6548f82f41568ec44c574c4ad35502379e58b..0ce45641b5280bca29a0d61b66a9435b9e3297e6 100644 --- a/src/main/java/caosdb/server/entity/Role.java +++ b/src/main/java/org/caosdb/server/entity/Role.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.entity; +package org.caosdb.server.entity; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.transaction.GetIDByName; -import caosdb.server.entity.xml.EntityToElementStrategy; -import caosdb.server.entity.xml.FileToElementStrategy; -import caosdb.server.entity.xml.ToElementStrategy; import java.util.HashMap; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.transaction.GetIDByName; +import org.caosdb.server.entity.xml.EntityToElementStrategy; +import org.caosdb.server.entity.xml.FileToElementStrategy; +import org.caosdb.server.entity.xml.ToElementStrategy; public enum Role { RecordType, diff --git a/src/main/java/caosdb/server/entity/StatementStatus.java b/src/main/java/org/caosdb/server/entity/StatementStatus.java similarity index 62% rename from src/main/java/caosdb/server/entity/StatementStatus.java rename to src/main/java/org/caosdb/server/entity/StatementStatus.java index 122b31fccdf2682a3a1851a650ef116a7184ed49..b3d7a613d26eba432308272b3bd932d2fdb54b26 100644 --- a/src/main/java/caosdb/server/entity/StatementStatus.java +++ b/src/main/java/org/caosdb/server/entity/StatementStatus.java @@ -20,14 +20,23 @@ * * ** end header */ -package caosdb.server.entity; +package org.caosdb.server.entity; +/** + * The statement status has two purposes. + * + * <p>1. Storing the importance of an entity (any of OBLIGATORY, RECOMMENDED, SUGGESTED, or FIX). 2. + * Marking an entity as a REPLACEMENT which is needed for flat representation of deeply nested + * properties. This constant is only used for internal processes and has no meaning in the API. That + * is also the reason why this enum is not called "Importance". Apart from that, in most cases its + * meaning is identical to the importance of an entity. + * + * @author Timm Fitschen (t.fitschen@indiscale.com) + */ public enum StatementStatus { OBLIGATORY, RECOMMENDED, SUGGESTED, FIX, - SUBTYPING, - INHERITANCE, REPLACEMENT } diff --git a/src/main/java/caosdb/server/entity/TransactionEntity.java b/src/main/java/org/caosdb/server/entity/TransactionEntity.java similarity index 90% rename from src/main/java/caosdb/server/entity/TransactionEntity.java rename to src/main/java/org/caosdb/server/entity/TransactionEntity.java index 458a1031cf7039c66b3db228813c9a552d6cc53c..2883c076f437520581037219a724020b47893424 100644 --- a/src/main/java/caosdb/server/entity/TransactionEntity.java +++ b/src/main/java/org/caosdb/server/entity/TransactionEntity.java @@ -20,15 +20,15 @@ * * ** end header */ -package caosdb.server.entity; +package org.caosdb.server.entity; -import caosdb.server.entity.xml.ToElementStrategy; -import caosdb.server.entity.xml.ToElementable; -import caosdb.server.query.Query.Selection; -import caosdb.server.utils.EntityStatus; import java.util.List; import java.util.Map; import java.util.Set; +import org.caosdb.server.entity.xml.ToElementStrategy; +import org.caosdb.server.entity.xml.ToElementable; +import org.caosdb.server.query.Query.Selection; +import org.caosdb.server.utils.EntityStatus; import org.jdom2.Element; public interface TransactionEntity { diff --git a/src/main/java/caosdb/server/entity/UpdateEntity.java b/src/main/java/org/caosdb/server/entity/UpdateEntity.java similarity index 93% rename from src/main/java/caosdb/server/entity/UpdateEntity.java rename to src/main/java/org/caosdb/server/entity/UpdateEntity.java index 004eefaf5be7564329d9caba19536dbc54ab1f38..aa6d591602df66cc9317351cf6a1ea980bc53ea3 100644 --- a/src/main/java/caosdb/server/entity/UpdateEntity.java +++ b/src/main/java/org/caosdb/server/entity/UpdateEntity.java @@ -20,9 +20,9 @@ * * ** end header */ -package caosdb.server.entity; +package org.caosdb.server.entity; -import caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.EntityStatus; import org.jdom2.Element; public class UpdateEntity extends WritableEntity { diff --git a/src/main/java/caosdb/server/entity/DeleteEntity.java b/src/main/java/org/caosdb/server/entity/ValidEntity.java similarity index 88% rename from src/main/java/caosdb/server/entity/DeleteEntity.java rename to src/main/java/org/caosdb/server/entity/ValidEntity.java index 29b6a3a075b60e811cfb0e66d066278a47d2edcb..6378e044e65afe4b7340cefd04e0b09153e5ca94 100644 --- a/src/main/java/caosdb/server/entity/DeleteEntity.java +++ b/src/main/java/org/caosdb/server/entity/ValidEntity.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.entity; +package org.caosdb.server.entity; -public class DeleteEntity extends Entity { +public class ValidEntity extends Entity { - public DeleteEntity(final int id) { + public ValidEntity(final int id) { super(id); } } diff --git a/src/main/java/org/caosdb/server/entity/Version.java b/src/main/java/org/caosdb/server/entity/Version.java new file mode 100644 index 0000000000000000000000000000000000000000..5529c7c5f5e8c83d95ad5afae7c1ae786806df89 --- /dev/null +++ b/src/main/java/org/caosdb/server/entity/Version.java @@ -0,0 +1,130 @@ +/* + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * + * 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 <https://www.gnu.org/licenses/>. + */ + +package org.caosdb.server.entity; + +import java.util.List; +import org.caosdb.datetime.UTCDateTime; + +/** + * Plain old java object (POJO) for an entity's version. + * + * @author Timm Fitschen <t.fitschen@indiscale.com> + */ +public class Version { + + private String id = null; + private String username = null; + private String realm = null; + private List<Version> predecessors = null; + private List<Version> successors = null; + private UTCDateTime date = null; + private boolean isHead = false; + private boolean isCompleteHistory = false; + + public Version(String id, long seconds, int nanos) { + this(id, UTCDateTime.UTCSeconds(seconds, nanos), null, null); + } + + public Version(String id, UTCDateTime date, String username, String realm) { + this.id = id; + this.date = date; + this.username = username; + this.realm = realm; + } + + public Version(String id) { + this(id, null, null, null); + } + + public Version() {} + + public Version(String id, UTCDateTime timestamp) { + this(id, timestamp, null, null); + } + + public UTCDateTime getDate() { + return date; + } + + public void setDate(UTCDateTime date) { + this.date = date; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public List<Version> getSuccessors() { + return successors; + } + + public void setSuccessors(List<Version> successors) { + this.successors = successors; + } + + public List<Version> getPredecessors() { + return predecessors; + } + + public void setPredecessors(List<Version> predecessors) { + this.predecessors = predecessors; + } + + public String getRealm() { + return realm; + } + + public void setRealm(String realm) { + this.realm = realm; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public void setDate(Long timestamp) { + this.date = UTCDateTime.SystemMillisToUTCDateTime(timestamp); + } + + public boolean isHead() { + return isHead; + } + + public void setHead(boolean isHead) { + this.isHead = isHead; + } + + public boolean isCompleteHistory() { + return isCompleteHistory; + } + + public void setCompleteHistory(boolean isCompleteHistory) { + this.isCompleteHistory = isCompleteHistory; + } +} diff --git a/src/main/java/caosdb/server/entity/WritableEntity.java b/src/main/java/org/caosdb/server/entity/WritableEntity.java similarity index 96% rename from src/main/java/caosdb/server/entity/WritableEntity.java rename to src/main/java/org/caosdb/server/entity/WritableEntity.java index 6e1c21e27ffbb4ae76a31a6c0cd444c439325cb0..d9dc3edc4fc1fa886370bafb5c40ce0e732b3e4b 100644 --- a/src/main/java/caosdb/server/entity/WritableEntity.java +++ b/src/main/java/org/caosdb/server/entity/WritableEntity.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.entity; +package org.caosdb.server.entity; import org.jdom2.Element; diff --git a/src/main/java/caosdb/server/entity/WriteEntity.java b/src/main/java/org/caosdb/server/entity/WriteEntity.java similarity index 96% rename from src/main/java/caosdb/server/entity/WriteEntity.java rename to src/main/java/org/caosdb/server/entity/WriteEntity.java index b8c65596a86fdc3553d43f9ea04793c615df3fba..64cbbee8658148e81e09a623c3e235ea18555e5e 100644 --- a/src/main/java/caosdb/server/entity/WriteEntity.java +++ b/src/main/java/org/caosdb/server/entity/WriteEntity.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.entity; +package org.caosdb.server.entity; import org.jdom2.Element; diff --git a/src/main/java/caosdb/server/entity/container/Container.java b/src/main/java/org/caosdb/server/entity/container/Container.java similarity index 63% rename from src/main/java/caosdb/server/entity/container/Container.java rename to src/main/java/org/caosdb/server/entity/container/Container.java index 9ab0415d8c4ccc8767814eaa46a8cacfe74d594a..dc38041abe24d5b5d2e55e7ae698e092848b34c2 100644 --- a/src/main/java/caosdb/server/entity/container/Container.java +++ b/src/main/java/org/caosdb/server/entity/container/Container.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -20,12 +22,24 @@ * * ** end header */ -package caosdb.server.entity.container; +package org.caosdb.server.entity.container; -import caosdb.server.entity.EntityInterface; import java.util.ArrayList; +import org.caosdb.server.entity.EntityInterface; public class Container<T extends EntityInterface> extends ArrayList<T> { - private static final long serialVersionUID = 3476714088253567549L; + private static final long serialVersionUID = 3588262226883926066L; + + /** + * Return the entity with the matching id, if it can be found inside this Container, else null. + */ + public T getEntityById(final Integer id) { + for (final T e : this) { + if (e.hasId() && e.getId().equals(id)) { + return e; + } + } + return null; + } } diff --git a/src/main/java/caosdb/server/entity/container/DeleteContainer.java b/src/main/java/org/caosdb/server/entity/container/DeleteContainer.java similarity index 83% rename from src/main/java/caosdb/server/entity/container/DeleteContainer.java rename to src/main/java/org/caosdb/server/entity/container/DeleteContainer.java index c219ee5e4399caeee857006f995748435d023963..b0c2f21ff3b0e0dd96e24f0ef042a29e843c54f0 100644 --- a/src/main/java/caosdb/server/entity/container/DeleteContainer.java +++ b/src/main/java/org/caosdb/server/entity/container/DeleteContainer.java @@ -20,15 +20,15 @@ * * ** end header */ -package caosdb.server.entity.container; +package org.caosdb.server.entity.container; -import caosdb.server.entity.DeleteEntity; import java.util.HashMap; import org.apache.shiro.subject.Subject; +import org.caosdb.server.entity.DeleteEntity; public class DeleteContainer extends EntityByIdContainer { - private static final long serialVersionUID = 4113458285424498764L; + private static final long serialVersionUID = -1279198934417710461L; public DeleteContainer( final Subject user, @@ -42,4 +42,9 @@ public class DeleteContainer extends EntityByIdContainer { public void add(final int id) { add(new DeleteEntity(id)); } + + @Override + public void add(int id, String version) { + add(new DeleteEntity(id, version)); + } } diff --git a/src/main/java/caosdb/server/entity/container/EntityByIdContainer.java b/src/main/java/org/caosdb/server/entity/container/EntityByIdContainer.java similarity index 88% rename from src/main/java/caosdb/server/entity/container/EntityByIdContainer.java rename to src/main/java/org/caosdb/server/entity/container/EntityByIdContainer.java index 1bfda2024c4ff11375ad619d64946e1036c714b0..466a93091e1a55d7f9d59c7d3a941058e4204a2e 100644 --- a/src/main/java/caosdb/server/entity/container/EntityByIdContainer.java +++ b/src/main/java/org/caosdb/server/entity/container/EntityByIdContainer.java @@ -20,13 +20,13 @@ * * ** end header */ -package caosdb.server.entity.container; +package org.caosdb.server.entity.container; import java.util.HashMap; import org.apache.shiro.subject.Subject; public abstract class EntityByIdContainer extends TransactionContainer { - private static final long serialVersionUID = 5826139073962173660L; + private static final long serialVersionUID = 7997517210502207523L; public EntityByIdContainer( final Subject user, @@ -37,4 +37,6 @@ public abstract class EntityByIdContainer extends TransactionContainer { } public abstract void add(int id); + + public abstract void add(int id, String version); } diff --git a/src/main/java/caosdb/server/entity/container/InsertContainer.java b/src/main/java/org/caosdb/server/entity/container/InsertContainer.java similarity index 89% rename from src/main/java/caosdb/server/entity/container/InsertContainer.java rename to src/main/java/org/caosdb/server/entity/container/InsertContainer.java index 6810e053cc9234bb587ea35f2399e7ceaa04e408..99128a8a56758e67ce1529785de0151b1fe624d4 100644 --- a/src/main/java/caosdb/server/entity/container/InsertContainer.java +++ b/src/main/java/org/caosdb/server/entity/container/InsertContainer.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.entity.container; +package org.caosdb.server.entity.container; -import caosdb.server.entity.InsertEntity; import java.util.HashMap; import org.apache.shiro.subject.Subject; +import org.caosdb.server.entity.InsertEntity; import org.jdom2.Element; public class InsertContainer extends WritableContainer { @@ -37,7 +37,7 @@ public class InsertContainer extends WritableContainer { super(user, timestamp, srid, flags); } - private static final long serialVersionUID = -5264959991145009088L; + private static final long serialVersionUID = 8896630069350477274L; @Override public void add(final Element entity) { diff --git a/src/main/java/caosdb/server/entity/container/ParentContainer.java b/src/main/java/org/caosdb/server/entity/container/ParentContainer.java similarity index 83% rename from src/main/java/caosdb/server/entity/container/ParentContainer.java rename to src/main/java/org/caosdb/server/entity/container/ParentContainer.java index 461760b8a2d37f293a6bb0756cc79ff757f0dbcf..90c6078a47471712ac51448ac4aac3d05794f5a6 100644 --- a/src/main/java/caosdb/server/entity/container/ParentContainer.java +++ b/src/main/java/org/caosdb/server/entity/container/ParentContainer.java @@ -20,25 +20,25 @@ * * ** end header */ -package caosdb.server.entity.container; +package org.caosdb.server.entity.container; -import caosdb.server.entity.Entity; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.wrapper.Parent; -import caosdb.server.entity.xml.ParentToElementStrategy; -import caosdb.server.entity.xml.SetFieldStrategy; -import caosdb.server.entity.xml.ToElementStrategy; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.Observable; -import caosdb.server.utils.Observer; -import caosdb.server.utils.ServerMessages; +import org.caosdb.server.entity.Entity; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.wrapper.Parent; +import org.caosdb.server.entity.xml.ParentToElementStrategy; +import org.caosdb.server.entity.xml.SetFieldStrategy; +import org.caosdb.server.entity.xml.ToElementStrategy; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.Observable; +import org.caosdb.server.utils.Observer; +import org.caosdb.server.utils.ServerMessages; import org.jdom2.Element; public class ParentContainer extends Container<Parent> { static ToElementStrategy s = new ParentToElementStrategy(); - private static final long serialVersionUID = 4624224975178041002L; + private static final long serialVersionUID = 3334236170549992385L; private final EntityInterface child; diff --git a/src/main/java/caosdb/server/entity/container/PropertyContainer.java b/src/main/java/org/caosdb/server/entity/container/PropertyContainer.java similarity index 67% rename from src/main/java/caosdb/server/entity/container/PropertyContainer.java rename to src/main/java/org/caosdb/server/entity/container/PropertyContainer.java index a80e2bfccea9f4b9c5cbe17fc32f9dd20b74c995..f5cce963fa4611bbdebfacdb11f98497c2a68544 100644 --- a/src/main/java/caosdb/server/entity/container/PropertyContainer.java +++ b/src/main/java/org/caosdb/server/entity/container/PropertyContainer.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -20,28 +22,28 @@ * * ** end header */ -package caosdb.server.entity.container; +package org.caosdb.server.entity.container; -import caosdb.server.entity.Entity; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.wrapper.Property; -import caosdb.server.entity.xml.PropertyToElementStrategy; -import caosdb.server.entity.xml.SetFieldStrategy; -import caosdb.server.entity.xml.ToElementStrategy; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.Observable; -import caosdb.server.utils.Observer; -import caosdb.server.utils.ServerMessages; import java.util.Collection; import java.util.Collections; import java.util.Comparator; +import org.caosdb.server.entity.Entity; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.wrapper.Property; +import org.caosdb.server.entity.xml.PropertyToElementStrategy; +import org.caosdb.server.entity.xml.SetFieldStrategy; +import org.caosdb.server.entity.xml.ToElementStrategy; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.Observable; +import org.caosdb.server.utils.Observer; +import org.caosdb.server.utils.ServerMessages; import org.jdom2.Element; public class PropertyContainer extends Container<Property> { private final ToElementStrategy s; - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = -8452118156168954326L; private final EntityInterface domain; @@ -50,6 +52,7 @@ public class PropertyContainer extends Container<Property> { this.s = new PropertyToElementStrategy(); } + /** Sort the properties by their pidx (Property Index). */ public void sort() { Collections.sort( this, @@ -64,14 +67,32 @@ public class PropertyContainer extends Container<Property> { }); } - public Element addToElement(final Element element, final SetFieldStrategy setFieldStrategy) { + /** + * Add a single property to the element using the given setFieldStrategy. + * + * @param property + * @param element + * @param setFieldStrategy + */ + public void addToElement( + EntityInterface property, Element element, SetFieldStrategy setFieldStrategy) { + if (setFieldStrategy.isToBeSet(property.getName())) { + SetFieldStrategy strategy = setFieldStrategy.forProperty(property.getName()); + this.s.addToElement(property, element, strategy); + } + } + + /** + * Add all properties to the element using the given setFieldStrategy. + * + * @param element + * @param setFieldStrategy + */ + public void addToElement(final Element element, final SetFieldStrategy setFieldStrategy) { sort(); for (final EntityInterface property : this) { - if (setFieldStrategy.isToBeSet(property.getName())) { - this.s.addToElement(property, element, setFieldStrategy.forProperty(property.getName())); - } + addToElement(property, element, setFieldStrategy); } - return element; } @Override diff --git a/src/main/java/caosdb/server/entity/container/RetrieveContainer.java b/src/main/java/org/caosdb/server/entity/container/RetrieveContainer.java similarity index 79% rename from src/main/java/caosdb/server/entity/container/RetrieveContainer.java rename to src/main/java/org/caosdb/server/entity/container/RetrieveContainer.java index 9b4f7364d4ecdc63da1be8f1ead292545801a078..3b847f1af9d9d642c2606820dc2993f00911ed06 100644 --- a/src/main/java/caosdb/server/entity/container/RetrieveContainer.java +++ b/src/main/java/org/caosdb/server/entity/container/RetrieveContainer.java @@ -20,15 +20,15 @@ * * ** end header */ -package caosdb.server.entity.container; +package org.caosdb.server.entity.container; -import caosdb.server.entity.RetrieveEntity; import java.util.HashMap; import org.apache.shiro.subject.Subject; +import org.caosdb.server.entity.RetrieveEntity; public class RetrieveContainer extends EntityByIdContainer { - private static final long serialVersionUID = 2962487090601702116L; + private static final long serialVersionUID = 4816050921531043503L; public RetrieveContainer( final Subject user, @@ -46,4 +46,13 @@ public class RetrieveContainer extends EntityByIdContainer { public void add(final String name) { add(new RetrieveEntity(name)); } + + public void add(final String name, String version) { + add(new RetrieveEntity(name, version)); + } + + @Override + public void add(int id, String version) { + add(new RetrieveEntity(id, version)); + } } diff --git a/src/main/java/caosdb/server/entity/container/TransactionContainer.java b/src/main/java/org/caosdb/server/entity/container/TransactionContainer.java similarity index 88% rename from src/main/java/caosdb/server/entity/container/TransactionContainer.java rename to src/main/java/org/caosdb/server/entity/container/TransactionContainer.java index f0ac55fae7b57d24456728508baa7768b83a5711..18a7837df27b39efa92abb2b16943a3476dca9ec 100644 --- a/src/main/java/caosdb/server/entity/container/TransactionContainer.java +++ b/src/main/java/org/caosdb/server/entity/container/TransactionContainer.java @@ -20,19 +20,19 @@ * * ** end header */ -package caosdb.server.entity.container; - -import caosdb.server.CaosDBServer; -import caosdb.server.database.misc.TransactionBenchmark; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.FileProperties; -import caosdb.server.entity.xml.ToElementable; -import caosdb.server.jobs.JobTarget; -import caosdb.server.utils.EntityStatus; +package org.caosdb.server.entity.container; + import java.util.HashMap; import java.util.LinkedList; import java.util.List; import org.apache.shiro.subject.Subject; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.database.misc.TransactionBenchmark; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.FileProperties; +import org.caosdb.server.entity.xml.ToElementable; +import org.caosdb.server.jobs.JobTarget; +import org.caosdb.server.utils.EntityStatus; import org.jdom2.Element; public class TransactionContainer extends Container<EntityInterface> @@ -94,7 +94,7 @@ public class TransactionContainer extends Container<EntityInterface> return this.flags; } - private static final long serialVersionUID = 6344299811547235114L; + private static final long serialVersionUID = -6062911849319971397L; /** * @param element @@ -145,15 +145,6 @@ public class TransactionContainer extends Container<EntityInterface> } } - public EntityInterface getEntityById(final Integer id) { - for (final EntityInterface e : this) { - if (e.hasId() && e.getId().equals(id)) { - return e; - } - } - return null; - } - public Subject getOwner() { return this.owner; } diff --git a/src/main/java/caosdb/server/entity/container/UpdateContainer.java b/src/main/java/org/caosdb/server/entity/container/UpdateContainer.java similarity index 89% rename from src/main/java/caosdb/server/entity/container/UpdateContainer.java rename to src/main/java/org/caosdb/server/entity/container/UpdateContainer.java index 843e70cf8131428cfb4086c6ee0b6f30c32797cf..1c2a807b7759ff680d30ed0f1f9f14d5952e98f8 100644 --- a/src/main/java/caosdb/server/entity/container/UpdateContainer.java +++ b/src/main/java/org/caosdb/server/entity/container/UpdateContainer.java @@ -20,16 +20,16 @@ * * ** end header */ -package caosdb.server.entity.container; +package org.caosdb.server.entity.container; -import caosdb.server.entity.UpdateEntity; import java.util.HashMap; import org.apache.shiro.subject.Subject; +import org.caosdb.server.entity.UpdateEntity; import org.jdom2.Element; public class UpdateContainer extends WritableContainer { - private static final long serialVersionUID = -4571405395722707413L; + private static final long serialVersionUID = 8489287672264669883L; public UpdateContainer( final Subject user, diff --git a/src/main/java/caosdb/server/entity/container/WritableContainer.java b/src/main/java/org/caosdb/server/entity/container/WritableContainer.java similarity index 90% rename from src/main/java/caosdb/server/entity/container/WritableContainer.java rename to src/main/java/org/caosdb/server/entity/container/WritableContainer.java index 3000aa5a943ec767b5de889899e62ccae311fa8d..2f9148651c890a0e7188acb035bf8fc55609834b 100644 --- a/src/main/java/caosdb/server/entity/container/WritableContainer.java +++ b/src/main/java/org/caosdb/server/entity/container/WritableContainer.java @@ -20,15 +20,15 @@ * * ** end header */ -package caosdb.server.entity.container; +package org.caosdb.server.entity.container; -import caosdb.server.entity.FileProperties; import java.util.HashMap; import org.apache.shiro.subject.Subject; +import org.caosdb.server.entity.FileProperties; import org.jdom2.Element; public abstract class WritableContainer extends TransactionContainer { - private static final long serialVersionUID = -4097777313518959519L; + private static final long serialVersionUID = 3011242254959617091L; public WritableContainer( final Subject user, diff --git a/src/main/java/caosdb/server/entity/wrapper/Domain.java b/src/main/java/org/caosdb/server/entity/wrapper/Domain.java similarity index 78% rename from src/main/java/caosdb/server/entity/wrapper/Domain.java rename to src/main/java/org/caosdb/server/entity/wrapper/Domain.java index 5bd5c73b99579337e1f5ccd0a4e97c0011347b04..146706efd2caa74ff1399568bf499f37683bfdbe 100644 --- a/src/main/java/caosdb/server/entity/wrapper/Domain.java +++ b/src/main/java/org/caosdb/server/entity/wrapper/Domain.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.entity.wrapper; +package org.caosdb.server.entity.wrapper; -import caosdb.server.datatype.AbstractDatatype; -import caosdb.server.datatype.Value; -import caosdb.server.entity.Entity; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.Role; -import caosdb.server.entity.container.PropertyContainer; +import org.caosdb.server.datatype.AbstractDatatype; +import org.caosdb.server.datatype.Value; +import org.caosdb.server.entity.Entity; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Role; +import org.caosdb.server.entity.container.PropertyContainer; public class Domain extends Entity { @@ -37,7 +37,7 @@ public class Domain extends Entity { final PropertyContainer properties, final AbstractDatatype datatype, final Value value, - final caosdb.server.entity.StatementStatus statementStatus) { + final org.caosdb.server.entity.StatementStatus statementStatus) { setRole(Role.Domain); setProperties(properties); diff --git a/src/main/java/caosdb/server/entity/wrapper/EntityWrapper.java b/src/main/java/org/caosdb/server/entity/wrapper/EntityWrapper.java similarity index 87% rename from src/main/java/caosdb/server/entity/wrapper/EntityWrapper.java rename to src/main/java/org/caosdb/server/entity/wrapper/EntityWrapper.java index 4d419bbfc17aee5749db70976f1a510ae468032b..e042c2326cc43e5d98cc3a27b61c21301bf9e90d 100644 --- a/src/main/java/caosdb/server/entity/wrapper/EntityWrapper.java +++ b/src/main/java/org/caosdb/server/entity/wrapper/EntityWrapper.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -20,32 +22,34 @@ * * ** end header */ -package caosdb.server.entity.wrapper; - -import caosdb.server.database.proto.SparseEntity; -import caosdb.server.database.proto.VerySparseEntity; -import caosdb.server.datatype.AbstractDatatype; -import caosdb.server.datatype.Value; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.FileProperties; -import caosdb.server.entity.Message; -import caosdb.server.entity.Role; -import caosdb.server.entity.StatementStatus; -import caosdb.server.entity.container.ParentContainer; -import caosdb.server.entity.container.PropertyContainer; -import caosdb.server.entity.xml.ToElementStrategy; -import caosdb.server.entity.xml.ToElementable; -import caosdb.server.permissions.EntityACL; -import caosdb.server.query.Query.Selection; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.Observer; -import caosdb.server.utils.TransactionLogMessage; -import caosdb.unit.Unit; +package org.caosdb.server.entity.wrapper; + import java.util.List; import java.util.Map; import java.util.Set; import org.apache.shiro.authz.Permission; import org.apache.shiro.subject.Subject; +import org.caosdb.server.database.proto.SparseEntity; +import org.caosdb.server.database.proto.VerySparseEntity; +import org.caosdb.server.datatype.AbstractDatatype; +import org.caosdb.server.datatype.Value; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.FileProperties; +import org.caosdb.server.entity.Message; +import org.caosdb.server.entity.Role; +import org.caosdb.server.entity.StatementStatus; +import org.caosdb.server.entity.Version; +import org.caosdb.server.entity.container.ParentContainer; +import org.caosdb.server.entity.container.PropertyContainer; +import org.caosdb.server.entity.xml.SetFieldStrategy; +import org.caosdb.server.entity.xml.ToElementStrategy; +import org.caosdb.server.entity.xml.ToElementable; +import org.caosdb.server.permissions.EntityACL; +import org.caosdb.server.query.Query.Selection; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.Observer; +import org.caosdb.server.utils.TransactionLogMessage; +import org.caosdb.unit.Unit; import org.jdom2.Element; public class EntityWrapper implements EntityInterface { @@ -551,4 +555,29 @@ public class EntityWrapper implements EntityInterface { public boolean hasPermission(Subject subject, Permission permission) { return this.entity.hasPermission(subject, permission); } + + @Override + public Version getVersion() { + return this.entity.getVersion(); + } + + @Override + public boolean hasVersion() { + return this.entity.hasVersion(); + } + + @Override + public void setVersion(Version version) { + this.entity.setVersion(version); + } + + @Override + public String getIdVersion() { + return this.entity.getIdVersion(); + } + + @Override + public void addToElement(Element element, SetFieldStrategy strategy) { + this.entity.addToElement(element, strategy); + } } diff --git a/src/main/java/caosdb/server/entity/wrapper/Parent.java b/src/main/java/org/caosdb/server/entity/wrapper/Parent.java similarity index 81% rename from src/main/java/caosdb/server/entity/wrapper/Parent.java rename to src/main/java/org/caosdb/server/entity/wrapper/Parent.java index c36ffa9c2c1a16062add2eb912ca01132af9872c..00336f4a336ed3c7f35408e5996fa7adc936f42a 100644 --- a/src/main/java/caosdb/server/entity/wrapper/Parent.java +++ b/src/main/java/org/caosdb/server/entity/wrapper/Parent.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.entity.wrapper; +package org.caosdb.server.entity.wrapper; -import caosdb.server.entity.Affiliation; -import caosdb.server.entity.Entity; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.xml.ParentToElementStrategy; +import org.caosdb.server.entity.Affiliation; +import org.caosdb.server.entity.Entity; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.xml.ParentToElementStrategy; import org.jdom2.Element; public class Parent extends EntityWrapper { @@ -57,4 +57,10 @@ public class Parent extends EntityWrapper { public Affiliation getAffiliation() { return this.affiliation; } + + @Override + public boolean hasVersion() { + // parents are not versioned (yet). + return false; + } } diff --git a/src/main/java/caosdb/server/entity/wrapper/Property.java b/src/main/java/org/caosdb/server/entity/wrapper/Property.java similarity index 86% rename from src/main/java/caosdb/server/entity/wrapper/Property.java rename to src/main/java/org/caosdb/server/entity/wrapper/Property.java index f6bb840a75d9216ee3fd56f3d2bf95f701280492..b3ce45b56527e40382d3971a61b43f9bc054d21f 100644 --- a/src/main/java/caosdb/server/entity/wrapper/Property.java +++ b/src/main/java/org/caosdb/server/entity/wrapper/Property.java @@ -20,16 +20,16 @@ * * ** end header */ -package caosdb.server.entity.wrapper; +package org.caosdb.server.entity.wrapper; -import caosdb.server.database.proto.FlatProperty; -import caosdb.server.datatype.AbstractCollectionDatatype; -import caosdb.server.datatype.GenericValue; -import caosdb.server.entity.Entity; -import caosdb.server.entity.EntityInterface; import org.apache.shiro.authz.AuthorizationException; import org.apache.shiro.authz.Permission; import org.apache.shiro.subject.Subject; +import org.caosdb.server.database.proto.FlatProperty; +import org.caosdb.server.datatype.AbstractCollectionDatatype; +import org.caosdb.server.datatype.GenericValue; +import org.caosdb.server.entity.Entity; +import org.caosdb.server.entity.EntityInterface; import org.jdom2.Element; public class Property extends EntityWrapper { @@ -120,7 +120,7 @@ public class Property extends EntityWrapper { @Override public String toString() { - return "IMPLPROPERTY " + this.entity.toString(); + return "IMPLPROPERTY (" + this.getStatementStatus() + ")" + this.entity.toString(); } public void setIsName(final boolean b) { @@ -134,4 +134,10 @@ public class Property extends EntityWrapper { public EntityInterface getDomainEntity() { return this.domain; } + + @Override + public boolean hasVersion() { + // properties are not versioned (yet). + return false; + } } diff --git a/src/main/java/caosdb/server/entity/xml/DomainToElementStrategy.java b/src/main/java/org/caosdb/server/entity/xml/DomainToElementStrategy.java similarity index 67% rename from src/main/java/caosdb/server/entity/xml/DomainToElementStrategy.java rename to src/main/java/org/caosdb/server/entity/xml/DomainToElementStrategy.java index 2559cfd12d7ca03344d03fa025ff2078d1bbcca0..a8b600793a6fdaf8d15ec499112cc06771f66fc3 100644 --- a/src/main/java/caosdb/server/entity/xml/DomainToElementStrategy.java +++ b/src/main/java/org/caosdb/server/entity/xml/DomainToElementStrategy.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -20,16 +22,27 @@ * * ** end header */ -package caosdb.server.entity.xml; +package org.caosdb.server.entity.xml; -import caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.EntityInterface; import org.jdom2.Element; -public class DomainToElementStrategy implements ToElementStrategy { +/** + * Generates a JDOM (XML) representation of an entity with role "Domain". + * + * @author Timm Fitschen <t.fitschen@indiscale.com> + */ +public class DomainToElementStrategy extends EntityToElementStrategy { + + public DomainToElementStrategy() { + super("Domain"); + } @Override public Element toElement(final EntityInterface entity, final SetFieldStrategy setFieldStrategy) { - return EntityToElementStrategy.sparseEntityToElement("Domain", entity, setFieldStrategy); + Element element = new Element(tagName); + sparseEntityToElement(element, entity, setFieldStrategy); + return element; } @Override diff --git a/src/main/java/org/caosdb/server/entity/xml/EntityToElementStrategy.java b/src/main/java/org/caosdb/server/entity/xml/EntityToElementStrategy.java new file mode 100644 index 0000000000000000000000000000000000000000..a829d711aa6345a16c9c368db27cb2f146f044b8 --- /dev/null +++ b/src/main/java/org/caosdb/server/entity/xml/EntityToElementStrategy.java @@ -0,0 +1,199 @@ +/* + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2018 Research Group Biomedical Physics, + * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> + * + * 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 <https://www.gnu.org/licenses/>. + * + * ** end header + */ +package org.caosdb.server.entity.xml; + +import org.apache.shiro.SecurityUtils; +import org.caosdb.server.datatype.ReferenceValue; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Message; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.TransactionLogMessage; +import org.jdom2.Attribute; +import org.jdom2.Element; + +/** + * Base class for the generation of a JDOM (XML) representation for entities. + * + * <p>Record and RecordType entities use this class only. Properties, Parents, Files and other + * entities have specialized sub classes. + * + * @author Timm Fitschen <t.fitschen@indiscale.com> + */ +public class EntityToElementStrategy implements ToElementStrategy { + + protected final String tagName; + + public EntityToElementStrategy(final String tagName) { + this.tagName = tagName; + } + + /** + * Set the data type of this entity as a JDOM {@link Attribute} of the given element. + * + * <p>If the data type has a name, the name is used, otherwise the id is used. + * + * @param entity + * @param element + */ + public void setDatatype(EntityInterface entity, Element element) { + if (entity.getDatatype().getName() != null) { + element.setAttribute("datatype", entity.getDatatype().getName()); + } else { + element.setAttribute("datatype", entity.getDatatype().getId().toString()); + } + } + + /** + * Set all properties of the entity that are considered to be part of the sparse entity, e.g. + * name, description, etc, as {@link Attribute} of the given element. + * + * <p>The setFieldStrategy decides which attributes are set if present and which are omitted in + * any case. + * + * @param element + * @param entity + * @param setFieldStrategy + */ + public void sparseEntityToElement( + final Element element, + final EntityInterface entity, + final SetFieldStrategy setFieldStrategy) { + + if (entity.getEntityACL() != null) { + element.addContent(entity.getEntityACL().getPermissionsFor(SecurityUtils.getSubject())); + } + if (setFieldStrategy.isToBeSet("id") && entity.hasId()) { + element.setAttribute("id", Integer.toString(entity.getId())); + } + if (entity.hasVersion()) { + Element v = new VersionXMLSerializer().toElement(entity.getVersion()); + element.addContent(v); + } + if (setFieldStrategy.isToBeSet("cuid") && entity.hasCuid()) { + element.setAttribute("cuid", entity.getCuid()); + } + if (setFieldStrategy.isToBeSet("name") && entity.hasName()) { + element.setAttribute("name", entity.getName()); + } + if (setFieldStrategy.isToBeSet("description") && entity.hasDescription()) { + element.setAttribute("description", entity.getDescription()); + } + if (setFieldStrategy.isToBeSet("datatype") && entity.hasDatatype()) { + setDatatype(entity, element); + } + if (setFieldStrategy.isToBeSet("message") && entity.hasMessages()) { + for (final ToElementable m : entity.getMessages()) { + m.addToElement(element); + } + } + if (setFieldStrategy.isToBeSet("query") && entity.getQueryTemplateDefinition() != null) { + final Element q = new Element("Query"); + q.setText(entity.getQueryTemplateDefinition()); + element.addContent(q); + } + } + + /** + * Set the value of the entity. + * + * <p>The setFieldStrategy decides if the value is to be set at all. + * + * <p>If the value is a reference, the setFieldStrategy decides whether the referenced entity is + * added as a deep Element tree (as a whole, so to speak) or just the ID of the referenced entity. + * + * @param entity + * @param element + * @param setFieldStrategy + */ + public void setValue(EntityInterface entity, Element element, SetFieldStrategy setFieldStrategy) { + if (entity.hasValue()) { + try { + entity.parseValue(); + } catch (final Message | NullPointerException e) { + // Ignore. Parsing the value failed. But that does not concern us here, because this is the + // case when a write transaction failed. The error for that has already been handled by the + // CheckValueParsable job. + } + + if (entity.getValue() instanceof ReferenceValue + && setFieldStrategy.isToBeSet("_referenced")) { + // Append the complete entity. This needs to be done when we are + // processing SELECT Queries. + EntityInterface ref = ((ReferenceValue) entity.getValue()).getEntity(); + if (ref != null) { + if (entity.hasDatatype()) { + setDatatype(entity, element); + } + ref.addToElement(element, setFieldStrategy); + // the referenced entity has been appended. Return here to suppress + // adding the reference id as well. + return; + } + } + + if (setFieldStrategy.isToBeSet("value")) { + if (entity.hasDatatype()) { + setDatatype(entity, element); + } + entity.getValue().addToElement(element); + } + } + } + + @Override + public Element toElement(final EntityInterface entity, final SetFieldStrategy setFieldStrategy) { + final Element element = new Element(tagName); + + // always have the values at the beginning of the children + setValue(entity, element, setFieldStrategy); + + sparseEntityToElement(element, entity, setFieldStrategy); + + if (entity.hasStatementStatus() && setFieldStrategy.isToBeSet("importance")) { + element.setAttribute("importance", entity.getStatementStatus().toString()); + } + if (entity.hasParents() && setFieldStrategy.isToBeSet("parent")) { + entity.getParents().addToElement(element); + } + if (entity.hasProperties()) { + entity.getProperties().addToElement(element, setFieldStrategy); + } + if (entity.hasTransactionLogMessages() && setFieldStrategy.isToBeSet("history")) { + for (final TransactionLogMessage t : entity.getTransactionLogMessages()) { + t.xmlAppendTo(element); + } + } + return element; + } + + @Override + public Element addToElement( + final EntityInterface entity, final Element parent, final SetFieldStrategy setFieldStrategy) { + if (entity.getEntityStatus() != EntityStatus.IGNORE) { + parent.addContent(toElement(entity, setFieldStrategy)); + } + return parent; + } +} diff --git a/src/main/java/caosdb/server/entity/xml/FileToElementStrategy.java b/src/main/java/org/caosdb/server/entity/xml/FileToElementStrategy.java similarity index 95% rename from src/main/java/caosdb/server/entity/xml/FileToElementStrategy.java rename to src/main/java/org/caosdb/server/entity/xml/FileToElementStrategy.java index 82fb05218842675aacad177c364e74b3d4082546..7ac394a2e3f226afa6f4723daadc95c63db69b25 100644 --- a/src/main/java/caosdb/server/entity/xml/FileToElementStrategy.java +++ b/src/main/java/org/caosdb/server/entity/xml/FileToElementStrategy.java @@ -20,9 +20,9 @@ * * ** end header */ -package caosdb.server.entity.xml; +package org.caosdb.server.entity.xml; -import caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.EntityInterface; import org.jdom2.Attribute; import org.jdom2.Element; diff --git a/src/main/java/caosdb/server/entity/xml/ParentToElementStrategy.java b/src/main/java/org/caosdb/server/entity/xml/ParentToElementStrategy.java similarity index 64% rename from src/main/java/caosdb/server/entity/xml/ParentToElementStrategy.java rename to src/main/java/org/caosdb/server/entity/xml/ParentToElementStrategy.java index 0d79951f5554b4c2c346224f3b6e91c1c056a96e..29c163dc5ca55b731aa44a85224821c41356e35a 100644 --- a/src/main/java/caosdb/server/entity/xml/ParentToElementStrategy.java +++ b/src/main/java/org/caosdb/server/entity/xml/ParentToElementStrategy.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -20,24 +22,33 @@ * * ** end header */ -package caosdb.server.entity.xml; +package org.caosdb.server.entity.xml; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.wrapper.Parent; -import caosdb.server.utils.EntityStatus; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.wrapper.Parent; +import org.caosdb.server.utils.EntityStatus; import org.jdom2.Element; -public class ParentToElementStrategy implements ToElementStrategy { +/** + * Generates a JDOM (XML) representation of an entity's parent. + * + * @author Timm Fitschen <t.fitschen@indiscale.com> + */ +public class ParentToElementStrategy extends EntityToElementStrategy { + + public ParentToElementStrategy() { + super("Parent"); + } @Override public Element toElement(final EntityInterface entity, final SetFieldStrategy setFieldStrategy) { - final Element e = - EntityToElementStrategy.sparseEntityToElement("Parent", entity, setFieldStrategy); + final Element element = new Element(this.tagName); + sparseEntityToElement(element, entity, setFieldStrategy); final Parent parent = (Parent) entity; if (parent.getAffiliation() != null) { - e.setAttribute("affiliation", parent.getAffiliation().toString()); + element.setAttribute("affiliation", parent.getAffiliation().toString()); } - return e; + return element; } @Override diff --git a/src/main/java/caosdb/server/entity/xml/PropertyToElementStrategy.java b/src/main/java/org/caosdb/server/entity/xml/PropertyToElementStrategy.java similarity index 89% rename from src/main/java/caosdb/server/entity/xml/PropertyToElementStrategy.java rename to src/main/java/org/caosdb/server/entity/xml/PropertyToElementStrategy.java index a88b47cbd411d1b62764a2d6cc130b9ff7d04cae..60014d82b18da4e8dfdd5fe0bcf042171c2bdda7 100644 --- a/src/main/java/caosdb/server/entity/xml/PropertyToElementStrategy.java +++ b/src/main/java/org/caosdb/server/entity/xml/PropertyToElementStrategy.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.entity.xml; +package org.caosdb.server.entity.xml; -import caosdb.server.datatype.SingleValue; -import caosdb.server.datatype.Value; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.MagicTypes; +import org.caosdb.server.datatype.SingleValue; +import org.caosdb.server.datatype.Value; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.MagicTypes; import org.jdom2.Attribute; import org.jdom2.Element; diff --git a/src/main/java/caosdb/server/entity/xml/SetFieldStrategy.java b/src/main/java/org/caosdb/server/entity/xml/SetFieldStrategy.java similarity index 60% rename from src/main/java/caosdb/server/entity/xml/SetFieldStrategy.java rename to src/main/java/org/caosdb/server/entity/xml/SetFieldStrategy.java index 7299659900014c4800b3fe0b8864cd7d15409380..1d9f219086e5ddd921d9519d3391e1cca9fbffc9 100644 --- a/src/main/java/caosdb/server/entity/xml/SetFieldStrategy.java +++ b/src/main/java/org/caosdb/server/entity/xml/SetFieldStrategy.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -20,23 +22,37 @@ * * ** end header */ -package caosdb.server.entity.xml; +package org.caosdb.server.entity.xml; -import caosdb.server.entity.EntityInterface; -import caosdb.server.query.Query.Selection; import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.query.Query; +import org.caosdb.server.query.Query.Selection; +/** + * A class which decides whether the properties, parents, name, etc. of an entity are to be included + * into the serialization or not. + * + * <p>The decision is based on a list of {@link Query.Selection} or smart defaults. + * + * @author Timm Fitschen <t.fitschen@indiscale.com> + */ public class SetFieldStrategy { private final List<Selection> selections = new LinkedList<Selection>(); private HashMap<String, Boolean> cache = null; + + /** + * The default is: Any field should be included into the serialization, unless it is a referenced + * entity. + */ private static final SetFieldStrategy defaultSelections = new SetFieldStrategy(null) { @Override public boolean isToBeSet(final String field) { - return true; + return field == null || !field.equalsIgnoreCase("_referenced"); } }; @@ -68,8 +84,9 @@ public class SetFieldStrategy { return forProperty(property.getName()); } + /** Return the strategy for a property. */ public SetFieldStrategy forProperty(final String name) { - // if property is to be omitted. + // if property is to be omitted: always-false-strategy if (!isToBeSet(name)) { return new SetFieldStrategy() { @Override @@ -85,6 +102,23 @@ public class SetFieldStrategy { subselections.add(s.getSubselection()); } } + if (subselections.isEmpty() && this.isToBeSet("_referenced")) { + + /** + * If the super selection decided that the referenced entity is to be included into the + * serialization, while it doesn't specify the subselects, every field is to be included. + * + * <p>This is the case when the selections are deeply nested but only the very last segments + * are actually used, e.g ["a.b.c.d1", "a.b.c.d2"]. + */ + return new SetFieldStrategy() { + // Return true for everything except version fields. + @Override + public boolean isToBeSet(String field) { + return field == null || !field.equalsIgnoreCase("version"); + } + }; + } return new SetFieldStrategy(subselections); } @@ -94,13 +128,23 @@ public class SetFieldStrategy { return defaultSelections.isToBeSet(field); } + // There must be a least one selection defined, a null field won't match anything. + if (field == null) { + return false; + } + if (this.cache == null) { this.cache = new HashMap<String, Boolean>(); - // fill cache + // always include the id and the name this.cache.put("id", true); + this.cache.put("name", true); + + // ... and the referenced entity. + this.cache.put("_referenced", true); for (final Selection selection : this.selections) { - if (!selection.getSelector().equals("id")) { - this.cache.put("name", true); + if (selection.getSelector().equals("value")) { + // if the value is present, the data type is needed as well + this.cache.put("datatype", true); } this.cache.put(selection.getSelector().toLowerCase(), true); } diff --git a/src/main/java/caosdb/server/entity/xml/ToElementStrategy.java b/src/main/java/org/caosdb/server/entity/xml/ToElementStrategy.java similarity index 93% rename from src/main/java/caosdb/server/entity/xml/ToElementStrategy.java rename to src/main/java/org/caosdb/server/entity/xml/ToElementStrategy.java index 29ddc78c9eda0503ff63a903d5f8192bbf49135e..81a7074c90df84f88ff3104c84662cb9a7a56433 100644 --- a/src/main/java/caosdb/server/entity/xml/ToElementStrategy.java +++ b/src/main/java/org/caosdb/server/entity/xml/ToElementStrategy.java @@ -20,9 +20,9 @@ * * ** end header */ -package caosdb.server.entity.xml; +package org.caosdb.server.entity.xml; -import caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.EntityInterface; import org.jdom2.Element; public interface ToElementStrategy { diff --git a/src/main/java/caosdb/server/entity/xml/ToElementable.java b/src/main/java/org/caosdb/server/entity/xml/ToElementable.java similarity index 96% rename from src/main/java/caosdb/server/entity/xml/ToElementable.java rename to src/main/java/org/caosdb/server/entity/xml/ToElementable.java index 4e7b3696664501afd18250a5dc44b8b1321856da..4202111b89c91e38659f34bd6c4f89af80efd957 100644 --- a/src/main/java/caosdb/server/entity/xml/ToElementable.java +++ b/src/main/java/org/caosdb/server/entity/xml/ToElementable.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.entity.xml; +package org.caosdb.server.entity.xml; import org.jdom2.Element; diff --git a/src/main/java/org/caosdb/server/entity/xml/VersionXMLSerializer.java b/src/main/java/org/caosdb/server/entity/xml/VersionXMLSerializer.java new file mode 100644 index 0000000000000000000000000000000000000000..40d19a5f3a0ef6d9448ed8567840e610be712391 --- /dev/null +++ b/src/main/java/org/caosdb/server/entity/xml/VersionXMLSerializer.java @@ -0,0 +1,72 @@ +/* + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * + * 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 <https://www.gnu.org/licenses/>. + */ + +package org.caosdb.server.entity.xml; + +import java.util.TimeZone; +import org.caosdb.server.entity.Version; +import org.jdom2.Element; + +/** + * Creates a JDOM Element for a Version instance. + * + * @author Timm Fitschen <t.fitschen@indiscale.com> + */ +class VersionXMLSerializer { + + public Element toElement(Version version) { + return toElement(version, "Version"); + } + + private Element toElement(Version version, String tag) { + Element element = new Element(tag); + setAttributes(version, element); + if (version.getPredecessors() != null) { + for (Version p : version.getPredecessors()) { + element.addContent(toElement(p, "Predecessor")); + } + } + if (version.getSuccessors() != null) { + for (Version s : version.getSuccessors()) { + element.addContent(toElement(s, "Successor")); + } + } + return element; + } + + private void setAttributes(Version version, Element element) { + element.setAttribute("id", version.getId()); + if (version.getUsername() != null) { + element.setAttribute("username", version.getUsername()); + } + if (version.getRealm() != null) { + element.setAttribute("realm", version.getRealm()); + } + if (version.getDate() != null) { + element.setAttribute("date", version.getDate().toDateTimeString(TimeZone.getDefault())); + } + if (version.isHead()) { + element.setAttribute("head", "true"); + } + if (version.isCompleteHistory()) { + element.setAttribute("completeHistory", "true"); + } + } +} diff --git a/src/main/java/org/caosdb/server/grpc/EntityTransactionImpl.java b/src/main/java/org/caosdb/server/grpc/EntityTransactionImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..e03fd6333b75caf422b47043a8b5bdc195f7c2a9 --- /dev/null +++ b/src/main/java/org/caosdb/server/grpc/EntityTransactionImpl.java @@ -0,0 +1,20 @@ +package org.caosdb.server.grpc; + +import io.grpc.stub.StreamObserver; +import org.caosdb.grpc.Entity; +import org.caosdb.grpc.EntityTransactionServiceGrpc.EntityTransactionServiceImplBase; + +public class EntityTransactionImpl extends EntityTransactionServiceImplBase { + + @Override + public void retrieve(Entity request, StreamObserver<Entity> responseObserver) { + Entity response = + Entity.newBuilder(request) + .setName("EntityName") + .setDescription("EntityDescription") + .build(); + + responseObserver.onNext(response); + responseObserver.onCompleted(); + } +} diff --git a/src/main/java/caosdb/server/GRPCServer.java b/src/main/java/org/caosdb/server/grpc/GRPCServer.java similarity index 81% rename from src/main/java/caosdb/server/GRPCServer.java rename to src/main/java/org/caosdb/server/grpc/GRPCServer.java index 550505926ca68fde1593d216238de1bfe5e14751..ba9201993b5415cd69c08f91522e1c7372ecc46a 100644 --- a/src/main/java/caosdb/server/GRPCServer.java +++ b/src/main/java/org/caosdb/server/grpc/GRPCServer.java @@ -1,9 +1,8 @@ -package caosdb.server; +package org.caosdb.server.grpc; -import java.io.IOException; -import caosdb.server.grpc.EntityTransactionImpl; import io.grpc.Server; import io.grpc.ServerBuilder; +import java.io.IOException; public class GRPCServer { diff --git a/src/main/java/caosdb/server/jobs/ContainerJob.java b/src/main/java/org/caosdb/server/jobs/ContainerJob.java similarity index 87% rename from src/main/java/caosdb/server/jobs/ContainerJob.java rename to src/main/java/org/caosdb/server/jobs/ContainerJob.java index 26588b682501d6675d40f5a0bd41974409e1e5c3..205b28f6338434fc9edf636aaca2ae82ddd8a896 100644 --- a/src/main/java/caosdb/server/jobs/ContainerJob.java +++ b/src/main/java/org/caosdb/server/jobs/ContainerJob.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.jobs; +package org.caosdb.server.jobs; -import caosdb.server.entity.Message; -import caosdb.server.entity.container.TransactionContainer; -import caosdb.server.utils.EntityStatus; +import org.caosdb.server.entity.Message; +import org.caosdb.server.entity.container.TransactionContainer; +import org.caosdb.server.utils.EntityStatus; public abstract class ContainerJob extends Job { diff --git a/src/main/java/caosdb/server/jobs/EntityJob.java b/src/main/java/org/caosdb/server/jobs/EntityJob.java similarity index 93% rename from src/main/java/caosdb/server/jobs/EntityJob.java rename to src/main/java/org/caosdb/server/jobs/EntityJob.java index 8644724ea33b02e6e586339188ee8b8f105b9177..b0dd8ecc9b2eadf6342e29b7c1d82adce57fc767 100644 --- a/src/main/java/caosdb/server/jobs/EntityJob.java +++ b/src/main/java/org/caosdb/server/jobs/EntityJob.java @@ -20,9 +20,9 @@ * * ** end header */ -package caosdb.server.jobs; +package org.caosdb.server.jobs; -import caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.EntityInterface; public abstract class EntityJob extends Job { diff --git a/src/main/java/caosdb/server/jobs/FilesJob.java b/src/main/java/org/caosdb/server/jobs/FilesJob.java similarity index 93% rename from src/main/java/caosdb/server/jobs/FilesJob.java rename to src/main/java/org/caosdb/server/jobs/FilesJob.java index e9a02a35728b1613058402bd29bb9dc0fd31b3e3..43c89be9e8c6d35d124314050f332f7a43792496 100644 --- a/src/main/java/caosdb/server/jobs/FilesJob.java +++ b/src/main/java/org/caosdb/server/jobs/FilesJob.java @@ -20,9 +20,9 @@ * * ** end header */ -package caosdb.server.jobs; +package org.caosdb.server.jobs; -import caosdb.server.entity.FileProperties; +import org.caosdb.server.entity.FileProperties; public abstract class FilesJob extends EntityJob { diff --git a/src/main/java/caosdb/server/jobs/FlagJob.java b/src/main/java/org/caosdb/server/jobs/FlagJob.java similarity index 97% rename from src/main/java/caosdb/server/jobs/FlagJob.java rename to src/main/java/org/caosdb/server/jobs/FlagJob.java index 94ce2189033c4fff524907b3ed5e80de79207c55..5c039bb3601e078d6f5ebcb3a48d4c35b6c90229 100644 --- a/src/main/java/caosdb/server/jobs/FlagJob.java +++ b/src/main/java/org/caosdb/server/jobs/FlagJob.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.jobs; +package org.caosdb.server.jobs; public abstract class FlagJob extends ContainerJob { diff --git a/src/main/java/caosdb/server/jobs/Job.java b/src/main/java/org/caosdb/server/jobs/Job.java similarity index 81% rename from src/main/java/caosdb/server/jobs/Job.java rename to src/main/java/org/caosdb/server/jobs/Job.java index 110809e77ae0d40076642d953c15b0d9566eddd6..5d8dd5d98a00960561c6b97f8e1f4fa118eafd0b 100644 --- a/src/main/java/caosdb/server/jobs/Job.java +++ b/src/main/java/org/caosdb/server/jobs/Job.java @@ -3,7 +3,9 @@ * This file is a part of the CaosDB Project. * * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -20,30 +22,8 @@ * * ** end header */ -package caosdb.server.jobs; - -import caosdb.server.CaosDBException; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.backend.transaction.GetIDByName; -import caosdb.server.database.backend.transaction.IsSubType; -import caosdb.server.database.backend.transaction.RetrieveFullEntity; -import caosdb.server.database.backend.transaction.RetrieveParents; -import caosdb.server.database.backend.transaction.RetrieveSparseEntity; -import caosdb.server.database.backend.transaction.RuleLoader; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.datatype.AbstractCollectionDatatype; -import caosdb.server.datatype.AbstractDatatype; -import caosdb.server.datatype.ReferenceDatatype2; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.Message; -import caosdb.server.entity.container.TransactionContainer; -import caosdb.server.jobs.core.Mode; -import caosdb.server.transaction.Transaction; -import caosdb.server.utils.AbstractObservable; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.Observable; -import caosdb.server.utils.Observer; -import caosdb.server.utils.ServerMessages; +package org.caosdb.server.jobs; + import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.HashMap; @@ -53,8 +33,35 @@ import java.util.Set; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authz.Permission; import org.apache.shiro.subject.Subject; +import org.caosdb.server.CaosDBException; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.transaction.GetIDByName; +import org.caosdb.server.database.backend.transaction.IsSubType; +import org.caosdb.server.database.backend.transaction.RetrieveFullEntity; +import org.caosdb.server.database.backend.transaction.RetrieveParents; +import org.caosdb.server.database.backend.transaction.RetrieveSparseEntity; +import org.caosdb.server.database.backend.transaction.RuleLoader; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.datatype.AbstractCollectionDatatype; +import org.caosdb.server.datatype.AbstractDatatype; +import org.caosdb.server.datatype.ReferenceDatatype2; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Message; +import org.caosdb.server.entity.container.TransactionContainer; +import org.caosdb.server.jobs.core.Mode; +import org.caosdb.server.transaction.Transaction; +import org.caosdb.server.utils.AbstractObservable; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.Observable; +import org.caosdb.server.utils.Observer; +import org.caosdb.server.utils.ServerMessages; import org.reflections.Reflections; +/** + * This is a Job. + * + * @todo Describe me. + */ public abstract class Job extends AbstractObservable implements Observer { private Transaction<? extends TransactionContainer> transaction = null; private Mode mode = null; @@ -171,11 +178,39 @@ public abstract class Job extends AbstractObservable implements Observer { protected final EntityInterface retrieveValidSparseEntityByName(final String name) throws Message { - return retrieveValidSparseEntityById(retrieveValidIDByName(name)); + return retrieveValidSparseEntityById(retrieveValidIDByName(name), null); } - protected final EntityInterface retrieveValidSparseEntityById(final Integer id) throws Message { - final EntityInterface ret = execute(new RetrieveSparseEntity(id)).getEntity(); + protected final EntityInterface retrieveValidSparseEntityById( + final Integer id, final String version) throws Message { + + String resulting_version = version; + if (version == null || version.equals("HEAD")) { + // the targeted entity version is the entity after the transaction or the + // entity without a specific version. Thus we have to fetch the entity + // from the container if possible. + EntityInterface ret = getEntityById(id); + if (ret != null) { + return ret; + } + } else if (version.startsWith("HEAD~")) { + EntityInterface entById = getEntityById(id); + if (entById != null && entById.getEntityStatus() != EntityStatus.VALID) { + // if version is HEAD~{OFFSET} with {OFFSET} > 0 and the targeted entity is is to be + // updated, the actual offset has to be reduced by 1. HEAD always denotes the entity@HEAD + // *after* the successful transaction, so that it is consistent with subsequent retrieves. + int offset = Integer.parseInt(version.substring(5)) - 1; + if (offset == 0) { + // special case HEAD~1 + resulting_version = "HEAD"; + } else { + resulting_version = new StringBuilder().append("HEAD~").append(offset).toString(); + } + } + } + + final EntityInterface ret = + execute(new RetrieveSparseEntity(id, resulting_version)).getEntity(); if (ret.getEntityStatus() == EntityStatus.NONEXISTENT) { throw ServerMessages.ENTITY_DOES_NOT_EXIST; } @@ -229,7 +264,7 @@ public abstract class Job extends AbstractObservable implements Observer { if (allClasses == null || loadAlways == null) { allClasses = new HashMap<>(); loadAlways = new ArrayList<>(); - Reflections jobPackage = new Reflections("caosdb.server.jobs.core"); + Reflections jobPackage = new Reflections("org.caosdb.server.jobs.core"); Set<Class<? extends Job>> allClassesSet = jobPackage.getSubTypesOf(Job.class); allClassesSet.addAll(jobPackage.getSubTypesOf(FlagJob.class)); for (final Class<? extends Job> c : allClassesSet) { @@ -245,7 +280,7 @@ public abstract class Job extends AbstractObservable implements Observer { } } // TODO merge these two parts of this function. Its the same! - jobPackage = new Reflections("caosdb.server.jobs.extension"); + jobPackage = new Reflections("org.caosdb.server.jobs.extension"); allClassesSet = jobPackage.getSubTypesOf(Job.class); for (final Class<? extends Job> c : allClassesSet) { allClasses.put(c.getSimpleName().toLowerCase(), c); diff --git a/src/main/java/caosdb/server/jobs/JobAnnotation.java b/src/main/java/org/caosdb/server/jobs/JobAnnotation.java similarity index 94% rename from src/main/java/caosdb/server/jobs/JobAnnotation.java rename to src/main/java/org/caosdb/server/jobs/JobAnnotation.java index 96f4afcd46c2f80fe2c959bf815ca523a71cb52d..15193dcdd590745773f308c71b9ed3bb1351a413 100644 --- a/src/main/java/caosdb/server/jobs/JobAnnotation.java +++ b/src/main/java/org/caosdb/server/jobs/JobAnnotation.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.jobs; +package org.caosdb.server.jobs; -import caosdb.server.transaction.TransactionInterface; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import org.caosdb.server.transaction.TransactionInterface; @Retention(RetentionPolicy.RUNTIME) public @interface JobAnnotation { diff --git a/src/main/java/caosdb/server/jobs/JobExecutionTime.java b/src/main/java/org/caosdb/server/jobs/JobExecutionTime.java similarity index 97% rename from src/main/java/caosdb/server/jobs/JobExecutionTime.java rename to src/main/java/org/caosdb/server/jobs/JobExecutionTime.java index 81bb0d983de7fb920c1484fc899b91bd9abd12db..9374ab9b1c2f4c285b538b1721441f0bc7272600 100644 --- a/src/main/java/caosdb/server/jobs/JobExecutionTime.java +++ b/src/main/java/org/caosdb/server/jobs/JobExecutionTime.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.jobs; +package org.caosdb.server.jobs; public enum JobExecutionTime { INIT, diff --git a/src/main/java/caosdb/server/jobs/JobTarget.java b/src/main/java/org/caosdb/server/jobs/JobTarget.java similarity index 96% rename from src/main/java/caosdb/server/jobs/JobTarget.java rename to src/main/java/org/caosdb/server/jobs/JobTarget.java index ec31a33370f8dc1ba69621022c0e109714cfa73d..764c70250fd050bc5a1962db8bd5bc4006ae0a70 100644 --- a/src/main/java/caosdb/server/jobs/JobTarget.java +++ b/src/main/java/org/caosdb/server/jobs/JobTarget.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.jobs; +package org.caosdb.server.jobs; public interface JobTarget { diff --git a/src/main/java/caosdb/server/jobs/Schedule.java b/src/main/java/org/caosdb/server/jobs/Schedule.java similarity index 97% rename from src/main/java/caosdb/server/jobs/Schedule.java rename to src/main/java/org/caosdb/server/jobs/Schedule.java index 4e7f005f3d2f790008a991a0138d62013f6a545a..7f35106bcdda8ddc00512197091fa096a6bc157e 100644 --- a/src/main/java/caosdb/server/jobs/Schedule.java +++ b/src/main/java/org/caosdb/server/jobs/Schedule.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.jobs; +package org.caosdb.server.jobs; -import caosdb.server.entity.EntityInterface; import java.util.Collection; import java.util.concurrent.CopyOnWriteArrayList; +import org.caosdb.server.entity.EntityInterface; class ScheduledJob { diff --git a/src/main/java/caosdb/server/jobs/core/AccessControl.java b/src/main/java/org/caosdb/server/jobs/core/AccessControl.java similarity index 82% rename from src/main/java/caosdb/server/jobs/core/AccessControl.java rename to src/main/java/org/caosdb/server/jobs/core/AccessControl.java index 0dd2ef4740d1a17d6e6ed8b0cc04c8d66a56c918..d1a2113a2f87018cec63d381cce64ad6c8ad09f2 100644 --- a/src/main/java/caosdb/server/jobs/core/AccessControl.java +++ b/src/main/java/org/caosdb/server/jobs/core/AccessControl.java @@ -20,19 +20,19 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.database.backend.transaction.RetrieveSparseEntity; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.wrapper.Parent; -import caosdb.server.jobs.ContainerJob; -import caosdb.server.jobs.JobAnnotation; -import caosdb.server.jobs.JobExecutionTime; -import caosdb.server.transaction.Retrieve; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; import org.apache.shiro.SecurityUtils; import org.apache.shiro.subject.Subject; +import org.caosdb.server.database.backend.transaction.RetrieveSparseEntity; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.wrapper.Parent; +import org.caosdb.server.jobs.ContainerJob; +import org.caosdb.server.jobs.JobAnnotation; +import org.caosdb.server.jobs.JobExecutionTime; +import org.caosdb.server.transaction.Retrieve; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; @JobAnnotation(time = JobExecutionTime.INIT) public class AccessControl extends ContainerJob { diff --git a/src/main/java/caosdb/server/jobs/core/Atomic.java b/src/main/java/org/caosdb/server/jobs/core/Atomic.java similarity index 81% rename from src/main/java/caosdb/server/jobs/core/Atomic.java rename to src/main/java/org/caosdb/server/jobs/core/Atomic.java index cdc9f25d7367a9732dcdcc9a0e03dd5e359acaa2..509f87fc8515ca08daa1a5cb8ef6571dfe6fa441 100644 --- a/src/main/java/caosdb/server/jobs/core/Atomic.java +++ b/src/main/java/org/caosdb/server/jobs/core/Atomic.java @@ -20,17 +20,17 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.entity.Entity; -import caosdb.server.entity.EntityInterface; -import caosdb.server.jobs.ContainerJob; -import caosdb.server.jobs.JobAnnotation; -import caosdb.server.jobs.JobExecutionTime; -import caosdb.server.transaction.WriteTransaction; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.Observable; -import caosdb.server.utils.ServerMessages; +import org.caosdb.server.entity.Entity; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.jobs.ContainerJob; +import org.caosdb.server.jobs.JobAnnotation; +import org.caosdb.server.jobs.JobExecutionTime; +import org.caosdb.server.transaction.WriteTransaction; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.Observable; +import org.caosdb.server.utils.ServerMessages; @JobAnnotation( time = JobExecutionTime.POST_CHECK, diff --git a/src/main/java/caosdb/server/jobs/core/CheckChildDependencyExistent.java b/src/main/java/org/caosdb/server/jobs/core/CheckChildDependencyExistent.java similarity index 92% rename from src/main/java/caosdb/server/jobs/core/CheckChildDependencyExistent.java rename to src/main/java/org/caosdb/server/jobs/core/CheckChildDependencyExistent.java index a3d9f4e493b189e7fb49de69347c5b6149f9f885..01d5a2de394180ff474600b4597e28e5356d9b3d 100644 --- a/src/main/java/caosdb/server/jobs/core/CheckChildDependencyExistent.java +++ b/src/main/java/org/caosdb/server/jobs/core/CheckChildDependencyExistent.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.database.backend.transaction.GetChildren; -import caosdb.server.entity.EntityInterface; -import caosdb.server.jobs.EntityJob; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; import java.util.List; +import org.caosdb.server.database.backend.transaction.GetChildren; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.jobs.EntityJob; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; /** * Check whether any children of this entity do exist. There must not be any children left when an diff --git a/src/main/java/caosdb/server/jobs/core/CheckDatatypePresent.java b/src/main/java/org/caosdb/server/jobs/core/CheckDatatypePresent.java similarity index 89% rename from src/main/java/caosdb/server/jobs/core/CheckDatatypePresent.java rename to src/main/java/org/caosdb/server/jobs/core/CheckDatatypePresent.java index 69d36f42fa2f457b05dcc394659b5c088976bff4..ce9943ecbefb4d669003a097e74bf9baff078167 100644 --- a/src/main/java/caosdb/server/jobs/core/CheckDatatypePresent.java +++ b/src/main/java/org/caosdb/server/jobs/core/CheckDatatypePresent.java @@ -20,22 +20,22 @@ * * ** end header */ -package caosdb.server.jobs.core; - -import caosdb.server.database.exceptions.EntityDoesNotExistException; -import caosdb.server.database.exceptions.EntityWasNotUniqueException; -import caosdb.server.datatype.AbstractCollectionDatatype; -import caosdb.server.datatype.AbstractDatatype; -import caosdb.server.datatype.ReferenceDatatype2; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.Message; -import caosdb.server.entity.Role; -import caosdb.server.jobs.EntityJob; -import caosdb.server.jobs.Job; -import caosdb.server.permissions.EntityPermission; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; +package org.caosdb.server.jobs.core; + import java.util.List; +import org.caosdb.server.database.exceptions.EntityDoesNotExistException; +import org.caosdb.server.database.exceptions.EntityWasNotUniqueException; +import org.caosdb.server.datatype.AbstractCollectionDatatype; +import org.caosdb.server.datatype.AbstractDatatype; +import org.caosdb.server.datatype.ReferenceDatatype2; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Message; +import org.caosdb.server.entity.Role; +import org.caosdb.server.jobs.EntityJob; +import org.caosdb.server.jobs.Job; +import org.caosdb.server.permissions.EntityPermission; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; /** * Check whether the entity has a data type. Assign the data type of the abstract property if @@ -138,7 +138,8 @@ public final class CheckDatatypePresent extends EntityJob { } } else { - final EntityInterface validDatatypeEntity = retrieveValidSparseEntityById(datatype.getId()); + final EntityInterface validDatatypeEntity = + retrieveValidSparseEntityById(datatype.getId(), null); assertAllowedToUse(validDatatypeEntity); datatype.setEntity(validDatatypeEntity); } @@ -151,7 +152,7 @@ public final class CheckDatatypePresent extends EntityJob { private void checkIfOverride() throws Message { if (getEntity().hasId() && getEntity().getId() > 0) { // get data type from database - final EntityInterface foreign = retrieveValidSparseEntityById(getEntity().getId()); + final EntityInterface foreign = retrieveValidSparseEntityById(getEntity().getId(), null); if (foreign.hasDatatype() && !foreign.getDatatype().equals(getEntity().getDatatype())) { // is override! @@ -179,7 +180,7 @@ public final class CheckDatatypePresent extends EntityJob { // the data type of the corresponding abstract property. if (getEntity().hasId() && getEntity().getId() > 0) { // get from data base - final EntityInterface foreign = retrieveValidSparseEntityById(getEntity().getId()); + final EntityInterface foreign = retrieveValidSparseEntityById(getEntity().getId(), null); inheritDatatypeFromForeignEntity(foreign); } else if (getEntity().hasId() && getEntity().getId() < 0) { // get from container @@ -218,7 +219,7 @@ public final class CheckDatatypePresent extends EntityJob { for (final EntityInterface parent : getEntity().getParents()) { EntityInterface parentEntity = null; if (parent.getId() > 0) { - parentEntity = retrieveValidSparseEntityById(parent.getId()); + parentEntity = retrieveValidSparseEntityById(parent.getId(), null); } else { parentEntity = getEntityById(parent.getId()); runJobFromSchedule(parentEntity, CheckDatatypePresent.class); diff --git a/src/main/java/caosdb/server/jobs/core/CheckDescPresent.java b/src/main/java/org/caosdb/server/jobs/core/CheckDescPresent.java similarity index 89% rename from src/main/java/caosdb/server/jobs/core/CheckDescPresent.java rename to src/main/java/org/caosdb/server/jobs/core/CheckDescPresent.java index b055e8fa25669aadf6cb40d65d1eb949794e3e73..fc3a5114f240c796c114f92f8e6271e4fd3bd9ac 100644 --- a/src/main/java/caosdb/server/jobs/core/CheckDescPresent.java +++ b/src/main/java/org/caosdb/server/jobs/core/CheckDescPresent.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.jobs.EntityJob; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; +import org.caosdb.server.jobs.EntityJob; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; /** * Check whether an entity has a description. diff --git a/src/main/java/caosdb/server/jobs/core/CheckEntityACLRoles.java b/src/main/java/org/caosdb/server/jobs/core/CheckEntityACLRoles.java similarity index 79% rename from src/main/java/caosdb/server/jobs/core/CheckEntityACLRoles.java rename to src/main/java/org/caosdb/server/jobs/core/CheckEntityACLRoles.java index 1106a469efda9767e95076378eea958fd10c7b70..e2dd63b1d733d737e09a6b4e86f3fe4ae4bd0e30 100644 --- a/src/main/java/caosdb/server/jobs/core/CheckEntityACLRoles.java +++ b/src/main/java/org/caosdb/server/jobs/core/CheckEntityACLRoles.java @@ -20,18 +20,18 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; -import caosdb.server.accessControl.AuthenticationUtils; -import caosdb.server.entity.EntityInterface; -import caosdb.server.jobs.ContainerJob; -import caosdb.server.permissions.EntityACI; -import caosdb.server.transaction.Insert; -import caosdb.server.transaction.Update; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.ServerProperties; +import org.caosdb.server.accessControl.AuthenticationUtils; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.jobs.ContainerJob; +import org.caosdb.server.permissions.EntityACI; +import org.caosdb.server.transaction.Insert; +import org.caosdb.server.transaction.Update; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; public class CheckEntityACLRoles extends ContainerJob { diff --git a/src/main/java/caosdb/server/jobs/core/CheckFileStorageConsistency.java b/src/main/java/org/caosdb/server/jobs/core/CheckFileStorageConsistency.java similarity index 91% rename from src/main/java/caosdb/server/jobs/core/CheckFileStorageConsistency.java rename to src/main/java/org/caosdb/server/jobs/core/CheckFileStorageConsistency.java index 5af12ad71b4b3c5b12ac8321131b4d9cb29013d5..8dc6fc0c60bc234d65f576377a89244d0a7a673e 100644 --- a/src/main/java/caosdb/server/jobs/core/CheckFileStorageConsistency.java +++ b/src/main/java/org/caosdb/server/jobs/core/CheckFileStorageConsistency.java @@ -20,27 +20,27 @@ * * ** end header */ -package caosdb.server.jobs.core; - -import caosdb.server.CaosDBServer; -import caosdb.server.FileSystem; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.entity.Message; -import caosdb.server.jobs.FlagJob; -import caosdb.server.jobs.JobAnnotation; -import caosdb.server.transaction.FileStorageConsistencyCheck; -import caosdb.server.transaction.Retrieve; -import caosdb.server.transaction.Transaction; -import caosdb.server.utils.FileUtils; -import caosdb.server.utils.Observable; -import caosdb.server.utils.Observer; -import caosdb.server.utils.Undoable; +package org.caosdb.server.jobs.core; + import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintStream; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.FileSystem; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.entity.Message; +import org.caosdb.server.jobs.FlagJob; +import org.caosdb.server.jobs.JobAnnotation; +import org.caosdb.server.transaction.FileStorageConsistencyCheck; +import org.caosdb.server.transaction.Retrieve; +import org.caosdb.server.transaction.Transaction; +import org.caosdb.server.utils.FileUtils; +import org.caosdb.server.utils.Observable; +import org.caosdb.server.utils.Observer; +import org.caosdb.server.utils.Undoable; import org.jdom2.Document; import org.jdom2.output.Format; import org.jdom2.output.XMLOutputter; @@ -210,7 +210,7 @@ public class CheckFileStorageConsistency extends FlagJob { + "test_file_storage_consistecy" + Integer.toString(hashCode())); - final Undoable undo2 = caosdb.server.utils.FileUtils.rename(f2, tmp2); + final Undoable undo2 = org.caosdb.server.utils.FileUtils.rename(f2, tmp2); final File overridden = new File(oldPath2); overridden.createNewFile(); diff --git a/src/main/java/caosdb/server/jobs/core/CheckNamePresent.java b/src/main/java/org/caosdb/server/jobs/core/CheckNamePresent.java similarity index 89% rename from src/main/java/caosdb/server/jobs/core/CheckNamePresent.java rename to src/main/java/org/caosdb/server/jobs/core/CheckNamePresent.java index d63a9cc54d4c413a0c827a562afa023b610ff872..f1600ce42117ab5f37fccd33b79d821efeccb774 100644 --- a/src/main/java/caosdb/server/jobs/core/CheckNamePresent.java +++ b/src/main/java/org/caosdb/server/jobs/core/CheckNamePresent.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.jobs.EntityJob; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; +import org.caosdb.server.jobs.EntityJob; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; /** * Check whether an entity has a name. diff --git a/src/main/java/caosdb/server/jobs/core/CheckNoAdditionalPropertiesPresent.java b/src/main/java/org/caosdb/server/jobs/core/CheckNoAdditionalPropertiesPresent.java similarity index 83% rename from src/main/java/caosdb/server/jobs/core/CheckNoAdditionalPropertiesPresent.java rename to src/main/java/org/caosdb/server/jobs/core/CheckNoAdditionalPropertiesPresent.java index 1eb4941d47314f7f67bbe874784f2427cecdca92..b04a9151ab5c142e97a6efc9b19607896ab38daf 100644 --- a/src/main/java/caosdb/server/jobs/core/CheckNoAdditionalPropertiesPresent.java +++ b/src/main/java/org/caosdb/server/jobs/core/CheckNoAdditionalPropertiesPresent.java @@ -1,14 +1,14 @@ -package caosdb.server.jobs.core; - -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.Message; -import caosdb.server.jobs.EntityJob; -import caosdb.server.jobs.JobAnnotation; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; +package org.caosdb.server.jobs.core; + import java.util.HashSet; import java.util.Objects; import java.util.Set; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Message; +import org.caosdb.server.jobs.EntityJob; +import org.caosdb.server.jobs.JobAnnotation; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; @JobAnnotation( flag = "noAdditionalProperties", diff --git a/src/main/java/caosdb/server/jobs/core/CheckNoOverridesPresent.java b/src/main/java/org/caosdb/server/jobs/core/CheckNoOverridesPresent.java similarity index 76% rename from src/main/java/caosdb/server/jobs/core/CheckNoOverridesPresent.java rename to src/main/java/org/caosdb/server/jobs/core/CheckNoOverridesPresent.java index c6b16210e7517c69c26ed6f2e8c556bf5687f7f4..e439354e88f39675491682877dd27aa54fd7a3ef 100644 --- a/src/main/java/caosdb/server/jobs/core/CheckNoOverridesPresent.java +++ b/src/main/java/org/caosdb/server/jobs/core/CheckNoOverridesPresent.java @@ -1,10 +1,10 @@ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.entity.Message; -import caosdb.server.entity.wrapper.Property; -import caosdb.server.jobs.EntityJob; -import caosdb.server.jobs.JobAnnotation; -import caosdb.server.utils.ServerMessages; +import org.caosdb.server.entity.Message; +import org.caosdb.server.entity.wrapper.Property; +import org.caosdb.server.jobs.EntityJob; +import org.caosdb.server.jobs.JobAnnotation; +import org.caosdb.server.utils.ServerMessages; @JobAnnotation( flag = "noOverrides", diff --git a/src/main/java/caosdb/server/jobs/core/CheckParOblPropPresent.java b/src/main/java/org/caosdb/server/jobs/core/CheckParOblPropPresent.java similarity index 92% rename from src/main/java/caosdb/server/jobs/core/CheckParOblPropPresent.java rename to src/main/java/org/caosdb/server/jobs/core/CheckParOblPropPresent.java index bee056c5763593ce6ef6a71f713019fae30a8bb5..c592eca81394e4a92582fd3d2286b5ac0507dcce 100644 --- a/src/main/java/caosdb/server/jobs/core/CheckParOblPropPresent.java +++ b/src/main/java/org/caosdb/server/jobs/core/CheckParOblPropPresent.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.database.backend.transaction.RetrieveFullEntity; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.StatementStatus; -import caosdb.server.jobs.EntityJob; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; +import org.caosdb.server.database.backend.transaction.RetrieveFullEntity; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.StatementStatus; +import org.caosdb.server.jobs.EntityJob; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; /** * Check whether an entity implements all obligatory properties of all parents. diff --git a/src/main/java/caosdb/server/jobs/core/CheckParPresent.java b/src/main/java/org/caosdb/server/jobs/core/CheckParPresent.java similarity index 89% rename from src/main/java/caosdb/server/jobs/core/CheckParPresent.java rename to src/main/java/org/caosdb/server/jobs/core/CheckParPresent.java index 7318e45f62c02378aec36a36b6915223f745e79e..8851456c236c0afd9f922f187089adc5f4e35ab1 100644 --- a/src/main/java/caosdb/server/jobs/core/CheckParPresent.java +++ b/src/main/java/org/caosdb/server/jobs/core/CheckParPresent.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.jobs.EntityJob; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; +import org.caosdb.server.jobs.EntityJob; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; /** * Check whether an entity has at least one parent. diff --git a/src/main/java/caosdb/server/jobs/core/CheckParValid.java b/src/main/java/org/caosdb/server/jobs/core/CheckParValid.java similarity index 90% rename from src/main/java/caosdb/server/jobs/core/CheckParValid.java rename to src/main/java/org/caosdb/server/jobs/core/CheckParValid.java index 005053a4a7d59c6c9f1a05171085701c606970b5..c6d10a8f4f7cd0656f571a4cbf70385ab9cb7725 100644 --- a/src/main/java/caosdb/server/jobs/core/CheckParValid.java +++ b/src/main/java/org/caosdb/server/jobs/core/CheckParValid.java @@ -20,21 +20,21 @@ * * ** end header */ -package caosdb.server.jobs.core; - -import caosdb.server.database.exceptions.EntityDoesNotExistException; -import caosdb.server.database.exceptions.EntityWasNotUniqueException; -import caosdb.server.entity.Affiliation; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.Message; -import caosdb.server.entity.Role; -import caosdb.server.entity.wrapper.Parent; -import caosdb.server.entity.wrapper.Property; -import caosdb.server.jobs.EntityJob; -import caosdb.server.permissions.EntityPermission; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; +package org.caosdb.server.jobs.core; + import com.google.common.base.Objects; +import org.caosdb.server.database.exceptions.EntityDoesNotExistException; +import org.caosdb.server.database.exceptions.EntityWasNotUniqueException; +import org.caosdb.server.entity.Affiliation; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Message; +import org.caosdb.server.entity.Role; +import org.caosdb.server.entity.wrapper.Parent; +import org.caosdb.server.entity.wrapper.Property; +import org.caosdb.server.jobs.EntityJob; +import org.caosdb.server.permissions.EntityPermission; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; /** * Check whether all parents of an entity are valid/qualified. @@ -65,7 +65,7 @@ public class CheckParValid extends EntityJob { if (parent.getId() >= 0) { // id >= 0 (parent is yet in the database) // retrieve parent by id - final EntityInterface foreign = retrieveValidSparseEntityById(parent.getId()); + final EntityInterface foreign = retrieveValidSparseEntityById(parent.getId(), null); // check permissions for this // parentforeign.acceptObserver(o) assertAllowedToUse(foreign); diff --git a/src/main/java/caosdb/server/jobs/core/CheckPropPresent.java b/src/main/java/org/caosdb/server/jobs/core/CheckPropPresent.java similarity index 89% rename from src/main/java/caosdb/server/jobs/core/CheckPropPresent.java rename to src/main/java/org/caosdb/server/jobs/core/CheckPropPresent.java index 3d8c44fd824df8f00a021ba2098b58c65d7eac3f..31a460971bc80ccf61d775c96b4632fa38f14f66 100644 --- a/src/main/java/caosdb/server/jobs/core/CheckPropPresent.java +++ b/src/main/java/org/caosdb/server/jobs/core/CheckPropPresent.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.jobs.EntityJob; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; +import org.caosdb.server.jobs.EntityJob; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; /** * Check whether at least one property is present. diff --git a/src/main/java/caosdb/server/jobs/core/CheckPropValid.java b/src/main/java/org/caosdb/server/jobs/core/CheckPropValid.java similarity index 90% rename from src/main/java/caosdb/server/jobs/core/CheckPropValid.java rename to src/main/java/org/caosdb/server/jobs/core/CheckPropValid.java index 6a7cbb51556dd0b9c634da4c8a56d20204fc9f50..10ce6295a5b4910084d769278ca6348287e6223a 100644 --- a/src/main/java/caosdb/server/jobs/core/CheckPropValid.java +++ b/src/main/java/org/caosdb/server/jobs/core/CheckPropValid.java @@ -20,20 +20,20 @@ * * ** end header */ -package caosdb.server.jobs.core; - -import static caosdb.server.utils.ServerMessages.ENTITY_DOES_NOT_EXIST; - -import caosdb.server.database.exceptions.EntityDoesNotExistException; -import caosdb.server.database.exceptions.EntityWasNotUniqueException; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.Message; -import caosdb.server.entity.wrapper.Property; -import caosdb.server.jobs.EntityJob; -import caosdb.server.permissions.EntityPermission; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; +package org.caosdb.server.jobs.core; + +import static org.caosdb.server.utils.ServerMessages.ENTITY_DOES_NOT_EXIST; + import com.google.common.base.Objects; +import org.caosdb.server.database.exceptions.EntityDoesNotExistException; +import org.caosdb.server.database.exceptions.EntityWasNotUniqueException; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Message; +import org.caosdb.server.entity.wrapper.Property; +import org.caosdb.server.jobs.EntityJob; +import org.caosdb.server.permissions.EntityPermission; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; /** * Check whether all properties of an entity are valid or qualified. @@ -55,7 +55,7 @@ public class CheckPropValid extends EntityJob { if (property.getId() >= 0) { final EntityInterface abstractProperty = - retrieveValidSparseEntityById(property.getId()); + retrieveValidSparseEntityById(property.getId(), null); assertAllowedToUse(abstractProperty); diff --git a/src/main/java/caosdb/server/jobs/core/CheckQueryTemplate.java b/src/main/java/org/caosdb/server/jobs/core/CheckQueryTemplate.java similarity index 85% rename from src/main/java/caosdb/server/jobs/core/CheckQueryTemplate.java rename to src/main/java/org/caosdb/server/jobs/core/CheckQueryTemplate.java index e675accb6d571620dfb39df47f1104965cb8866b..1b5ccb41f58b92d2230fb99e5635ad02bd9922f5 100644 --- a/src/main/java/caosdb/server/jobs/core/CheckQueryTemplate.java +++ b/src/main/java/org/caosdb/server/jobs/core/CheckQueryTemplate.java @@ -20,15 +20,15 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.entity.Role; -import caosdb.server.jobs.EntityJob; -import caosdb.server.query.Query; -import caosdb.server.query.Query.ParsingException; -import caosdb.server.query.Query.Type; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; +import org.caosdb.server.entity.Role; +import org.caosdb.server.jobs.EntityJob; +import org.caosdb.server.query.Query; +import org.caosdb.server.query.Query.ParsingException; +import org.caosdb.server.query.Query.Type; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; public class CheckQueryTemplate extends EntityJob { diff --git a/src/main/java/caosdb/server/jobs/core/CheckReferenceDependencyExistent.java b/src/main/java/org/caosdb/server/jobs/core/CheckReferenceDependencyExistent.java similarity index 92% rename from src/main/java/caosdb/server/jobs/core/CheckReferenceDependencyExistent.java rename to src/main/java/org/caosdb/server/jobs/core/CheckReferenceDependencyExistent.java index fd5eaab0f0d302e9b5586693ef502c32d607d773..c59eededd391645737b614f5f2e97699160c8cf7 100644 --- a/src/main/java/caosdb/server/jobs/core/CheckReferenceDependencyExistent.java +++ b/src/main/java/org/caosdb/server/jobs/core/CheckReferenceDependencyExistent.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.database.backend.transaction.GetDependentEntities; -import caosdb.server.entity.EntityInterface; -import caosdb.server.jobs.EntityJob; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; import java.util.List; +import org.caosdb.server.database.backend.transaction.GetDependentEntities; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.jobs.EntityJob; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; /** * Check whether an entity is referenced by other entities. In the event that someone wants to diff --git a/src/main/java/caosdb/server/jobs/core/CheckRefidIsaParRefid.java b/src/main/java/org/caosdb/server/jobs/core/CheckRefidIsaParRefid.java similarity index 85% rename from src/main/java/caosdb/server/jobs/core/CheckRefidIsaParRefid.java rename to src/main/java/org/caosdb/server/jobs/core/CheckRefidIsaParRefid.java index fa2b21ccaea7ba3c8bd2b733f8420c213e4f03f7..59fcfe1d877ca61c98674ee85919f03b7bd4278e 100644 --- a/src/main/java/caosdb/server/jobs/core/CheckRefidIsaParRefid.java +++ b/src/main/java/org/caosdb/server/jobs/core/CheckRefidIsaParRefid.java @@ -20,24 +20,24 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.datatype.AbstractCollectionDatatype; -import caosdb.server.datatype.CollectionValue; -import caosdb.server.datatype.FileDatatype; -import caosdb.server.datatype.IndexedSingleValue; -import caosdb.server.datatype.ReferenceDatatype2; -import caosdb.server.datatype.ReferenceValue; -import caosdb.server.entity.Entity; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.Message; -import caosdb.server.entity.Message.MessageType; -import caosdb.server.entity.Role; -import caosdb.server.entity.wrapper.Parent; -import caosdb.server.jobs.EntityJob; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.Observable; -import caosdb.server.utils.ServerMessages; +import org.caosdb.server.datatype.AbstractCollectionDatatype; +import org.caosdb.server.datatype.CollectionValue; +import org.caosdb.server.datatype.FileDatatype; +import org.caosdb.server.datatype.IndexedSingleValue; +import org.caosdb.server.datatype.ReferenceDatatype2; +import org.caosdb.server.datatype.ReferenceValue; +import org.caosdb.server.entity.Entity; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Message; +import org.caosdb.server.entity.Message.MessageType; +import org.caosdb.server.entity.Role; +import org.caosdb.server.entity.wrapper.Parent; +import org.caosdb.server.jobs.EntityJob; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.Observable; +import org.caosdb.server.utils.ServerMessages; /** * Check if the referenced entity is in the scope of the data type. E.g. if the data type is @@ -94,7 +94,8 @@ public class CheckRefidIsaParRefid extends EntityJob { && getEntityByName(rv.getName()).getRole() == Role.File) { } else if (rv.getId() != null && rv.getId() > 0 - && retrieveValidSparseEntityById(rv.getId()).getRole() == Role.File) { + && retrieveValidSparseEntityById(rv.getId(), rv.getVersion()).getRole() + == Role.File) { } else if (rv.getName() != null && retrieveValidSparseEntityByName(rv.getName()).getRole() == Role.File) { } else { diff --git a/src/main/java/caosdb/server/jobs/core/CheckRefidPresent.java b/src/main/java/org/caosdb/server/jobs/core/CheckRefidPresent.java similarity index 93% rename from src/main/java/caosdb/server/jobs/core/CheckRefidPresent.java rename to src/main/java/org/caosdb/server/jobs/core/CheckRefidPresent.java index 7af03b314b6894269e62766b63adad08a13d1fe8..17d9bc7c9fbbfd37d64446a8b21ff65afca9391d 100644 --- a/src/main/java/caosdb/server/jobs/core/CheckRefidPresent.java +++ b/src/main/java/org/caosdb/server/jobs/core/CheckRefidPresent.java @@ -20,9 +20,9 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.jobs.EntityJob; +import org.caosdb.server.jobs.EntityJob; public class CheckRefidPresent extends EntityJob { @Override diff --git a/src/main/java/caosdb/server/jobs/core/CheckRefidValid.java b/src/main/java/org/caosdb/server/jobs/core/CheckRefidValid.java similarity index 75% rename from src/main/java/caosdb/server/jobs/core/CheckRefidValid.java rename to src/main/java/org/caosdb/server/jobs/core/CheckRefidValid.java index 14d98962f48c300ae77fe0811922bf3b1d7eb4ae..42476f87b43496e162b6eb036480b6b745ee91f2 100644 --- a/src/main/java/caosdb/server/jobs/core/CheckRefidValid.java +++ b/src/main/java/org/caosdb/server/jobs/core/CheckRefidValid.java @@ -3,7 +3,9 @@ * This file is a part of the CaosDB Project. * * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -20,23 +22,23 @@ * * ** end header */ -package caosdb.server.jobs.core; - -import caosdb.server.database.exceptions.EntityDoesNotExistException; -import caosdb.server.database.exceptions.EntityWasNotUniqueException; -import caosdb.server.datatype.AbstractCollectionDatatype; -import caosdb.server.datatype.CollectionValue; -import caosdb.server.datatype.IndexedSingleValue; -import caosdb.server.datatype.ReferenceDatatype; -import caosdb.server.datatype.ReferenceValue; -import caosdb.server.entity.Entity; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.Message; -import caosdb.server.jobs.EntityJob; -import caosdb.server.permissions.EntityPermission; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.Observable; -import caosdb.server.utils.ServerMessages; +package org.caosdb.server.jobs.core; + +import org.caosdb.server.database.exceptions.EntityDoesNotExistException; +import org.caosdb.server.database.exceptions.EntityWasNotUniqueException; +import org.caosdb.server.datatype.AbstractCollectionDatatype; +import org.caosdb.server.datatype.CollectionValue; +import org.caosdb.server.datatype.IndexedSingleValue; +import org.caosdb.server.datatype.ReferenceDatatype; +import org.caosdb.server.datatype.ReferenceValue; +import org.caosdb.server.entity.Entity; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Message; +import org.caosdb.server.jobs.EntityJob; +import org.caosdb.server.permissions.EntityPermission; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.Observable; +import org.caosdb.server.utils.ServerMessages; /** * Check whether a reference property is pointing to a valid entity. @@ -85,9 +87,12 @@ public class CheckRefidValid extends EntityJob { private void checkRefValue(final ReferenceValue ref) throws Message { if (ref.getId() != null) { if (ref.getId() >= 0) { - final EntityInterface referencedValidEntity = retrieveValidSparseEntityById(ref.getId()); + final EntityInterface referencedValidEntity = + retrieveValidSparseEntityById(ref.getId(), ref.getVersion()); assertAllowedToUse(referencedValidEntity); - ref.setEntity(referencedValidEntity); + + // link the entity as versioned entity iff the reference specified a version + ref.setEntity(referencedValidEntity, ref.getVersion() != null); } else { @@ -100,7 +105,9 @@ public class CheckRefidValid extends EntityJob { final EntityInterface referencedEntity = getEntityById(ref.getId()); if (referencedEntity != null) { assertAllowedToUse(referencedEntity); - ref.setEntity(referencedEntity); + + // link the entity as versioned entity iff the reference specified a version + ref.setEntity(referencedEntity, ref.getVersion() != null); } else { throw ServerMessages.REFERENCED_ENTITY_DOES_NOT_EXIST; } @@ -117,7 +124,9 @@ public class CheckRefidValid extends EntityJob { if (referencedEntity != null) { assertAllowedToUse(referencedEntity); - ref.setEntity(referencedEntity); + + // link the entity as versioned entity iff the reference specified a version + ref.setEntity(referencedEntity, ref.getVersion() != null); if (checkRefEntity(ref)) { ref.getEntity().acceptObserver(this); } @@ -125,7 +134,9 @@ public class CheckRefidValid extends EntityJob { final EntityInterface referencedValidEntity = retrieveValidSparseEntityByName(ref.getName()); assertAllowedToUse(referencedValidEntity); - ref.setEntity(referencedValidEntity); + + // link the entity as versioned entity iff the reference specified a version + ref.setEntity(referencedValidEntity, ref.getVersion() != null); } } } diff --git a/src/main/java/caosdb/server/jobs/core/CheckTargetPathValid.java b/src/main/java/org/caosdb/server/jobs/core/CheckTargetPathValid.java similarity index 87% rename from src/main/java/caosdb/server/jobs/core/CheckTargetPathValid.java rename to src/main/java/org/caosdb/server/jobs/core/CheckTargetPathValid.java index 404e6b3a0d82950061ba4168a7a6f32e5f847400..7d06498f5d9e4fbc382e7dde025983ceac6a7fdc 100644 --- a/src/main/java/caosdb/server/jobs/core/CheckTargetPathValid.java +++ b/src/main/java/org/caosdb/server/jobs/core/CheckTargetPathValid.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.FileSystem; -import caosdb.server.entity.FileProperties; -import caosdb.server.entity.Message; -import caosdb.server.jobs.EntityJob; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; +import org.caosdb.server.FileSystem; +import org.caosdb.server.entity.FileProperties; +import org.caosdb.server.entity.Message; +import org.caosdb.server.jobs.EntityJob; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; /** * Check whether the target path of a file entity is valid. That is, the target path is in the file diff --git a/src/main/java/caosdb/server/jobs/core/CheckUnitPresent.java b/src/main/java/org/caosdb/server/jobs/core/CheckUnitPresent.java similarity index 86% rename from src/main/java/caosdb/server/jobs/core/CheckUnitPresent.java rename to src/main/java/org/caosdb/server/jobs/core/CheckUnitPresent.java index 5b923769025dd49fb3ac0a9339f674edc37c022c..aa87ecfff69635407bc90d372c89f089e4f308dc 100644 --- a/src/main/java/caosdb/server/jobs/core/CheckUnitPresent.java +++ b/src/main/java/org/caosdb/server/jobs/core/CheckUnitPresent.java @@ -20,13 +20,13 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.MagicTypes; -import caosdb.server.jobs.EntityJob; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.MagicTypes; +import org.caosdb.server.jobs.EntityJob; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; /** * Check whether this entity has a unit property. diff --git a/src/main/java/caosdb/server/jobs/core/CheckValueParsable.java b/src/main/java/org/caosdb/server/jobs/core/CheckValueParsable.java similarity index 91% rename from src/main/java/caosdb/server/jobs/core/CheckValueParsable.java rename to src/main/java/org/caosdb/server/jobs/core/CheckValueParsable.java index 3140952d673798fdf120c721489be67ae31e0414..34e1960961f72118567653a77e4f48fe357dfedc 100644 --- a/src/main/java/caosdb/server/jobs/core/CheckValueParsable.java +++ b/src/main/java/org/caosdb/server/jobs/core/CheckValueParsable.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.entity.Entity; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.Message; -import caosdb.server.jobs.EntityJob; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.Observable; +import org.caosdb.server.entity.Entity; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Message; +import org.caosdb.server.jobs.EntityJob; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.Observable; /** * Check whether the value of an entity is parsable according to the entity's data type. This job diff --git a/src/main/java/caosdb/server/jobs/core/DebugCalls.java b/src/main/java/org/caosdb/server/jobs/core/DebugCalls.java similarity index 88% rename from src/main/java/caosdb/server/jobs/core/DebugCalls.java rename to src/main/java/org/caosdb/server/jobs/core/DebugCalls.java index b56fb6fbef4a2b3f53c0d5aa66f9bf244307be5e..8527560d02e498bf3812162a8b01b9641aad7260 100644 --- a/src/main/java/caosdb/server/jobs/core/DebugCalls.java +++ b/src/main/java/org/caosdb/server/jobs/core/DebugCalls.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.CaosDBServer; -import caosdb.server.jobs.FlagJob; -import caosdb.server.jobs.JobAnnotation; -import caosdb.server.jobs.JobExecutionTime; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.jobs.FlagJob; +import org.caosdb.server.jobs.JobAnnotation; +import org.caosdb.server.jobs.JobExecutionTime; @JobAnnotation( flag = "debug", diff --git a/src/main/java/caosdb/server/jobs/core/ExecuteQuery.java b/src/main/java/org/caosdb/server/jobs/core/ExecuteQuery.java similarity index 81% rename from src/main/java/caosdb/server/jobs/core/ExecuteQuery.java rename to src/main/java/org/caosdb/server/jobs/core/ExecuteQuery.java index 6de19d6006dd31bde9fcff033f1808e6e4aac276..b6583f024071e3c1151cf974b387ffe72d1579b7 100644 --- a/src/main/java/caosdb/server/jobs/core/ExecuteQuery.java +++ b/src/main/java/org/caosdb/server/jobs/core/ExecuteQuery.java @@ -20,16 +20,16 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.entity.Message; -import caosdb.server.jobs.FlagJob; -import caosdb.server.jobs.JobAnnotation; -import caosdb.server.jobs.JobExecutionTime; -import caosdb.server.query.Query; -import caosdb.server.query.Query.ParsingException; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; +import org.caosdb.server.entity.Message; +import org.caosdb.server.jobs.FlagJob; +import org.caosdb.server.jobs.JobAnnotation; +import org.caosdb.server.jobs.JobExecutionTime; +import org.caosdb.server.query.Query; +import org.caosdb.server.query.Query.ParsingException; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; @JobAnnotation(flag = "query", time = JobExecutionTime.INIT) public class ExecuteQuery extends FlagJob { diff --git a/src/main/java/caosdb/server/jobs/core/History.java b/src/main/java/org/caosdb/server/jobs/core/History.java similarity index 71% rename from src/main/java/caosdb/server/jobs/core/History.java rename to src/main/java/org/caosdb/server/jobs/core/History.java index ee72413a46e65f8b8a020315e3c2e93c7b8ccd97..5594b5afdb841436dbdd63f96b8e2c44faef51c6 100644 --- a/src/main/java/caosdb/server/jobs/core/History.java +++ b/src/main/java/org/caosdb/server/jobs/core/History.java @@ -20,18 +20,23 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.database.backend.transaction.RetrieveTransactionHistory; -import caosdb.server.entity.EntityInterface; -import caosdb.server.jobs.FlagJob; -import caosdb.server.jobs.JobAnnotation; -import caosdb.server.jobs.JobExecutionTime; -import caosdb.server.permissions.EntityPermission; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; import org.apache.shiro.authz.AuthorizationException; +import org.caosdb.server.database.backend.transaction.RetrieveVersionHistory; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.jobs.FlagJob; +import org.caosdb.server.jobs.JobAnnotation; +import org.caosdb.server.jobs.JobExecutionTime; +import org.caosdb.server.permissions.EntityPermission; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; +/** + * Retrieves the complete version history of each entity and appends it to the entity. + * + * @author Timm Fitschen (t.fitschen@indiscale.com) + */ @JobAnnotation(time = JobExecutionTime.POST_TRANSACTION, flag = "H") public class History extends FlagJob { @@ -42,7 +47,7 @@ public class History extends FlagJob { if (entity.getId() != null && entity.getId() > 0) { try { entity.checkPermission(EntityPermission.RETRIEVE_HISTORY); - final RetrieveTransactionHistory t = new RetrieveTransactionHistory(entity); + final RetrieveVersionHistory t = new RetrieveVersionHistory(entity); execute(t); } catch (final AuthorizationException e) { entity.setEntityStatus(EntityStatus.UNQUALIFIED); diff --git a/src/main/java/caosdb/server/jobs/core/Inheritance.java b/src/main/java/org/caosdb/server/jobs/core/Inheritance.java similarity index 56% rename from src/main/java/caosdb/server/jobs/core/Inheritance.java rename to src/main/java/org/caosdb/server/jobs/core/Inheritance.java index f7149eb3c74270012db011385e17bbf01fdd01a2..086787e8bd4752ccf0a25f8684afa5a5c4a33c82 100644 --- a/src/main/java/caosdb/server/jobs/core/Inheritance.java +++ b/src/main/java/org/caosdb/server/jobs/core/Inheritance.java @@ -20,29 +20,39 @@ * * ** end header */ -package caosdb.server.jobs.core; - -import caosdb.server.database.backend.transaction.RetrieveFullEntity; -import caosdb.server.entity.Entity; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.Message; -import caosdb.server.entity.Message.MessageType; -import caosdb.server.entity.wrapper.Property; -import caosdb.server.jobs.EntityJob; -import caosdb.server.transaction.Insert; -import caosdb.server.transaction.Update; -import caosdb.server.utils.EntityStatus; +package org.caosdb.server.jobs.core; + import java.util.ArrayList; +import java.util.List; +import org.caosdb.server.database.backend.transaction.RetrieveFullEntity; +import org.caosdb.server.entity.Entity; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Message; +import org.caosdb.server.entity.Message.MessageType; +import org.caosdb.server.entity.StatementStatus; +import org.caosdb.server.entity.wrapper.Property; +import org.caosdb.server.jobs.EntityJob; +import org.caosdb.server.transaction.Insert; +import org.caosdb.server.transaction.Update; +import org.caosdb.server.utils.EntityStatus; +/** + * Add all those properties from the parent to the child which have the same importance (or higher). + * + * @author Timm Fitschen (t.fitschen@indiscale.com) + */ public class Inheritance extends EntityJob { + /* + * Storing which properties of the properties of the parents should be inherited by the child. + */ public enum INHERITANCE_MODE { - NONE, - ALL, - OBLIGATORY, - FIX, - RECOMMENDED, - DONE + NONE, // inherit no properties from this parent + ALL, // inherit all inheritable properties, alias for suggested + OBLIGATORY, // inherit only obligatory properties + RECOMMENDED, // inherit obligatory and recommended properties + SUGGESTED, // inherit all inheritable properties, alias for all + FIX, // inherit fix properties only (deprecated) }; public static final Message ILLEGAL_INHERITANCE_MODE = @@ -66,51 +76,22 @@ public class Inheritance extends EntityJob { INHERITANCE_MODE.valueOf(parent.getFlags().get("inheritance").toUpperCase()); // mark inheritance flag as done - parent.setFlag("inheritance", "done"); - if (inheritance == INHERITANCE_MODE.NONE || inheritance == INHERITANCE_MODE.DONE) { + parent.setFlag("inheritance", null); + if (inheritance == INHERITANCE_MODE.NONE) { break parentLoop; } runJobFromSchedule(getEntity(), CheckParValid.class); - execute(new RetrieveFullEntity(parent)); - - if (parent.hasProperties()) { - // loop over all properties of the parent and - // collect - // properties to be transfered - for (final EntityInterface parProperty : parent.getProperties()) { - switch (inheritance) { - case ALL: - transfer.add(parProperty); - break; - case RECOMMENDED: - if (parProperty - .getStatementStatus() - .toString() - .equalsIgnoreCase(INHERITANCE_MODE.RECOMMENDED.toString())) { - transfer.add(parProperty); - } - case OBLIGATORY: - if (parProperty - .getStatementStatus() - .toString() - .equalsIgnoreCase(INHERITANCE_MODE.OBLIGATORY.toString())) { - transfer.add(parProperty); - } - case FIX: - if (parProperty - .getStatementStatus() - .toString() - .equalsIgnoreCase(INHERITANCE_MODE.FIX.toString())) { - transfer.add(parProperty); - } - break; - default: - break; - } - } + // try to get the parent entity from the current transaction container + EntityInterface foreign = getEntityByName(parent.getName()); + if (foreign == null) { + // was not in container -> retrieve from database. + execute(new RetrieveFullEntity(parent)); + foreign = parent; } + + collectInheritedProperties(transfer, foreign, inheritance); } catch (final IllegalArgumentException e) { parent.addWarning(ILLEGAL_INHERITANCE_MODE); break parentLoop; @@ -142,9 +123,10 @@ public class Inheritance extends EntityJob { } final INHERITANCE_MODE inheritance = INHERITANCE_MODE.valueOf(property.getFlags().get("inheritance").toUpperCase()); + // mark inheritance flag as done - property.setFlag("inheritance", "done"); - if (inheritance == INHERITANCE_MODE.NONE || inheritance == INHERITANCE_MODE.DONE) { + property.setFlag("inheritance", null); + if (inheritance == INHERITANCE_MODE.NONE) { break propertyLoop; } @@ -164,48 +146,14 @@ public class Inheritance extends EntityJob { } else { execute(new RetrieveFullEntity(validProperty)); } - - if (validProperty.getEntityStatus() == EntityStatus.VALID - && validProperty.hasProperties()) { - // loop over all properties of the property and - // collect - // properties to be transfered - for (final EntityInterface propProperty : validProperty.getProperties()) { - switch (inheritance) { - case ALL: - transfer.add(propProperty); - break; - case RECOMMENDED: - if (propProperty - .getStatementStatus() - .toString() - .equalsIgnoreCase(INHERITANCE_MODE.RECOMMENDED.toString())) { - transfer.add(propProperty); - } - case OBLIGATORY: - if (propProperty - .getStatementStatus() - .toString() - .equalsIgnoreCase(INHERITANCE_MODE.OBLIGATORY.toString())) { - transfer.add(propProperty); - } - case FIX: - if (propProperty - .getStatementStatus() - .toString() - .equalsIgnoreCase(INHERITANCE_MODE.FIX.toString())) { - transfer.add(propProperty); - } - break; - default: - break; - } - } + if (validProperty.getEntityStatus() == EntityStatus.VALID) { + collectInheritedProperties(transfer, validProperty, inheritance); } } catch (final IllegalArgumentException e) { property.addWarning(ILLEGAL_INHERITANCE_MODE); break propertyLoop; } + // transfer properties if they are not implemented yet outerLoop: for (final EntityInterface prop : transfer) { @@ -222,4 +170,52 @@ public class Inheritance extends EntityJob { } } } + + /** + * Put all those properties from the `from` entity into the `transfer` List which match the + * INHERITANCE_MODE. + * + * <p>That means: + * + * @param transfer + * @param from + * @param inheritance + */ + private void collectInheritedProperties( + List<EntityInterface> transfer, EntityInterface from, INHERITANCE_MODE inheritance) { + if (from.hasProperties()) { + for (final EntityInterface propProperty : from.getProperties()) { + switch (inheritance) { + // the following cases are ordered according to their importance level and use a + // fall-through. + case ALL: + case SUGGESTED: + if (propProperty.getStatementStatus() == StatementStatus.SUGGESTED) { + transfer.add(propProperty); + } + // fall-through! + case RECOMMENDED: + if (propProperty.getStatementStatus() == StatementStatus.RECOMMENDED) { + transfer.add(propProperty); + } + // fall-through! + case OBLIGATORY: + if (propProperty.getStatementStatus() == StatementStatus.OBLIGATORY) { + transfer.add(propProperty); + } + break; + case FIX: + if (propProperty.getStatementStatus() == StatementStatus.FIX) { + transfer.add(propProperty); + propProperty.addWarning( + new Message( + MessageType.Warning, + "DeprecationWarning: The inheritance of fix properties is deprecated and will be removed from the API in the near future. Clients have to copy fix properties by themselves, if necessary.")); + } + default: + break; + } + } + } + } } diff --git a/src/main/java/caosdb/server/jobs/core/InsertFilesInDir.java b/src/main/java/org/caosdb/server/jobs/core/InsertFilesInDir.java similarity index 93% rename from src/main/java/caosdb/server/jobs/core/InsertFilesInDir.java rename to src/main/java/org/caosdb/server/jobs/core/InsertFilesInDir.java index 6b3144eb08b471ea90b836978c76b4ff643c313d..73d7ee3f5be0b8847ce322f6774719b7f5a768c2 100644 --- a/src/main/java/caosdb/server/jobs/core/InsertFilesInDir.java +++ b/src/main/java/org/caosdb/server/jobs/core/InsertFilesInDir.java @@ -20,34 +20,34 @@ * * ** end header */ -package caosdb.server.jobs.core; - -import caosdb.server.CaosDBException; -import caosdb.server.CaosDBServer; -import caosdb.server.FileSystem; -import caosdb.server.ServerProperties; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.misc.RollBackHandler; -import caosdb.server.entity.Entity; -import caosdb.server.entity.FileProperties; -import caosdb.server.entity.Message; -import caosdb.server.entity.Message.MessageType; -import caosdb.server.entity.Role; -import caosdb.server.jobs.FlagJob; -import caosdb.server.jobs.Job; -import caosdb.server.jobs.JobAnnotation; -import caosdb.server.jobs.JobExecutionTime; -import caosdb.server.transaction.Retrieve; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.FileUtils; -import caosdb.server.utils.Undoable; -import caosdb.server.utils.Utils; +package org.caosdb.server.jobs.core; + import java.io.File; import java.io.IOException; import java.util.LinkedList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.caosdb.server.CaosDBException; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.FileSystem; +import org.caosdb.server.ServerProperties; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.misc.RollBackHandler; +import org.caosdb.server.entity.Entity; +import org.caosdb.server.entity.FileProperties; +import org.caosdb.server.entity.Message; +import org.caosdb.server.entity.Message.MessageType; +import org.caosdb.server.entity.Role; +import org.caosdb.server.jobs.FlagJob; +import org.caosdb.server.jobs.Job; +import org.caosdb.server.jobs.JobAnnotation; +import org.caosdb.server.jobs.JobExecutionTime; +import org.caosdb.server.transaction.Retrieve; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.FileUtils; +import org.caosdb.server.utils.Undoable; +import org.caosdb.server.utils.Utils; @JobAnnotation( flag = "InsertFilesInDir", diff --git a/src/main/java/caosdb/server/jobs/core/LoadContainerFlagJobs.java b/src/main/java/org/caosdb/server/jobs/core/LoadContainerFlagJobs.java similarity index 85% rename from src/main/java/caosdb/server/jobs/core/LoadContainerFlagJobs.java rename to src/main/java/org/caosdb/server/jobs/core/LoadContainerFlagJobs.java index 9df5e601afd7839887164b87ae1ea00a892d1bb7..89f381d648144e274325c5c71a57c9f4daf04895 100644 --- a/src/main/java/caosdb/server/jobs/core/LoadContainerFlagJobs.java +++ b/src/main/java/org/caosdb/server/jobs/core/LoadContainerFlagJobs.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.jobs.ContainerJob; -import caosdb.server.jobs.FlagJob; -import caosdb.server.jobs.Job; -import caosdb.server.jobs.JobAnnotation; -import caosdb.server.jobs.JobExecutionTime; import java.util.Map.Entry; +import org.caosdb.server.jobs.ContainerJob; +import org.caosdb.server.jobs.FlagJob; +import org.caosdb.server.jobs.Job; +import org.caosdb.server.jobs.JobAnnotation; +import org.caosdb.server.jobs.JobExecutionTime; @JobAnnotation(time = JobExecutionTime.INIT) public class LoadContainerFlagJobs extends ContainerJob { diff --git a/src/main/java/caosdb/server/jobs/core/MatchFileProp.java b/src/main/java/org/caosdb/server/jobs/core/MatchFileProp.java similarity index 92% rename from src/main/java/caosdb/server/jobs/core/MatchFileProp.java rename to src/main/java/org/caosdb/server/jobs/core/MatchFileProp.java index 7d193ebca7b3027b48edd55866526d8fb5025cb2..cef8b2b8ae9764ceb1e4bd2636c2b532d7e9415b 100644 --- a/src/main/java/caosdb/server/jobs/core/MatchFileProp.java +++ b/src/main/java/org/caosdb/server/jobs/core/MatchFileProp.java @@ -20,13 +20,13 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.entity.FileProperties; -import caosdb.server.jobs.FilesJob; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.FileUtils; -import caosdb.server.utils.ServerMessages; +import org.caosdb.server.entity.FileProperties; +import org.caosdb.server.jobs.FilesJob; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.FileUtils; +import org.caosdb.server.utils.ServerMessages; /** * Match the checksum and the size of a file record to the uploaded file's checksum and size. diff --git a/src/main/java/caosdb/server/jobs/core/Mode.java b/src/main/java/org/caosdb/server/jobs/core/Mode.java similarity index 96% rename from src/main/java/caosdb/server/jobs/core/Mode.java rename to src/main/java/org/caosdb/server/jobs/core/Mode.java index 9814caed2d5aaa790c5706d2ed9d116f3f1ff740..561a4b0c5fcb4e2c8c66a2b9f9a02ea91c44c119 100644 --- a/src/main/java/caosdb/server/jobs/core/Mode.java +++ b/src/main/java/org/caosdb/server/jobs/core/Mode.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; public enum Mode { MUST, diff --git a/src/main/java/caosdb/server/jobs/core/NoCache.java b/src/main/java/org/caosdb/server/jobs/core/NoCache.java similarity index 90% rename from src/main/java/caosdb/server/jobs/core/NoCache.java rename to src/main/java/org/caosdb/server/jobs/core/NoCache.java index f301e9b9819c002f67b059ea7415715fff3e9dd0..a4f639392ac63a97f2f025dfe6717a664114c561 100644 --- a/src/main/java/caosdb/server/jobs/core/NoCache.java +++ b/src/main/java/org/caosdb/server/jobs/core/NoCache.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.jobs.FlagJob; -import caosdb.server.jobs.JobAnnotation; -import caosdb.server.jobs.JobExecutionTime; +import org.caosdb.server.jobs.FlagJob; +import org.caosdb.server.jobs.JobAnnotation; +import org.caosdb.server.jobs.JobExecutionTime; @JobAnnotation( flag = "cache", diff --git a/src/main/java/caosdb/server/jobs/core/Paging.java b/src/main/java/org/caosdb/server/jobs/core/Paging.java similarity index 86% rename from src/main/java/caosdb/server/jobs/core/Paging.java rename to src/main/java/org/caosdb/server/jobs/core/Paging.java index f0d0d6a66d3f2f11788a1b52ab68e476b44b3c87..43683639f75c08be394a38ce03e91282405f333d 100644 --- a/src/main/java/caosdb/server/jobs/core/Paging.java +++ b/src/main/java/org/caosdb/server/jobs/core/Paging.java @@ -20,16 +20,16 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.entity.EntityInterface; -import caosdb.server.jobs.FlagJob; -import caosdb.server.jobs.JobAnnotation; -import caosdb.server.jobs.JobExecutionTime; -import caosdb.server.transaction.Retrieve; -import caosdb.server.utils.EntityStatus; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.jobs.FlagJob; +import org.caosdb.server.jobs.JobAnnotation; +import org.caosdb.server.jobs.JobExecutionTime; +import org.caosdb.server.transaction.Retrieve; +import org.caosdb.server.utils.EntityStatus; @JobAnnotation(flag = "P", time = JobExecutionTime.PRE_TRANSACTION) public class Paging extends FlagJob { diff --git a/src/main/java/caosdb/server/jobs/core/ParseUnit.java b/src/main/java/org/caosdb/server/jobs/core/ParseUnit.java similarity index 80% rename from src/main/java/caosdb/server/jobs/core/ParseUnit.java rename to src/main/java/org/caosdb/server/jobs/core/ParseUnit.java index 2dbde3111e3bd5a8552c43fe1c0e95a73294414a..8e0a7818ea3c7567456115dafe5b3b2593f7511b 100644 --- a/src/main/java/caosdb/server/jobs/core/ParseUnit.java +++ b/src/main/java/org/caosdb/server/jobs/core/ParseUnit.java @@ -20,18 +20,18 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.datatype.SingleValue; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.MagicTypes; -import caosdb.server.jobs.EntityJob; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; -import caosdb.unit.CaosDBSystemOfUnits; -import caosdb.unit.Unit; -import caosdb.unit.UnknownUnit; import de.timmfitschen.easyunits.parser.ParserException; +import org.caosdb.server.datatype.SingleValue; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.MagicTypes; +import org.caosdb.server.jobs.EntityJob; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; +import org.caosdb.unit.CaosDBSystemOfUnits; +import org.caosdb.unit.Unit; +import org.caosdb.unit.UnknownUnit; public class ParseUnit extends EntityJob { diff --git a/src/main/java/caosdb/server/jobs/core/PickUp.java b/src/main/java/org/caosdb/server/jobs/core/PickUp.java similarity index 85% rename from src/main/java/caosdb/server/jobs/core/PickUp.java rename to src/main/java/org/caosdb/server/jobs/core/PickUp.java index 542e7ee5cbb022c2456af0e305ef37ca02482dda..dff574a4ad0aa5199fe3ccdfdd9c72d2a7b2bb67 100644 --- a/src/main/java/caosdb/server/jobs/core/PickUp.java +++ b/src/main/java/org/caosdb/server/jobs/core/PickUp.java @@ -20,19 +20,19 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.FileSystem; -import caosdb.server.entity.Entity; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.FileProperties; -import caosdb.server.entity.Message; -import caosdb.server.jobs.EntityJob; -import caosdb.server.jobs.JobAnnotation; -import caosdb.server.jobs.JobExecutionTime; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.Observable; import java.io.File; +import org.caosdb.server.FileSystem; +import org.caosdb.server.entity.Entity; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.FileProperties; +import org.caosdb.server.entity.Message; +import org.caosdb.server.jobs.EntityJob; +import org.caosdb.server.jobs.JobAnnotation; +import org.caosdb.server.jobs.JobExecutionTime; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.Observable; @JobAnnotation(time = JobExecutionTime.INIT) public class PickUp extends EntityJob { diff --git a/src/main/java/caosdb/server/jobs/core/ProcessNameProperties.java b/src/main/java/org/caosdb/server/jobs/core/ProcessNameProperties.java similarity index 90% rename from src/main/java/caosdb/server/jobs/core/ProcessNameProperties.java rename to src/main/java/org/caosdb/server/jobs/core/ProcessNameProperties.java index 0a82c10108b054d45752756c14597d738b6a45f9..950c61d36255b68f52e3066616b1dee5d9f259c3 100644 --- a/src/main/java/caosdb/server/jobs/core/ProcessNameProperties.java +++ b/src/main/java/org/caosdb/server/jobs/core/ProcessNameProperties.java @@ -20,22 +20,22 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import static caosdb.server.entity.MagicTypes.NAME; +import static org.caosdb.server.entity.MagicTypes.NAME; -import caosdb.server.datatype.AbstractDatatype; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.Message; -import caosdb.server.entity.wrapper.Parent; -import caosdb.server.entity.wrapper.Property; -import caosdb.server.jobs.EntityJob; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Set; +import org.caosdb.server.datatype.AbstractDatatype; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Message; +import org.caosdb.server.entity.wrapper.Parent; +import org.caosdb.server.entity.wrapper.Property; +import org.caosdb.server.jobs.EntityJob; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; /** * To be called after CheckPropValid. diff --git a/src/main/java/caosdb/server/jobs/core/RemoveDuplicates.java b/src/main/java/org/caosdb/server/jobs/core/RemoveDuplicates.java similarity index 69% rename from src/main/java/caosdb/server/jobs/core/RemoveDuplicates.java rename to src/main/java/org/caosdb/server/jobs/core/RemoveDuplicates.java index a104c124293cf07ecc3b871c4bc6b31470ec2a15..3d3adcc1e1175d7aed95bba64d9d81d13b70f495 100644 --- a/src/main/java/caosdb/server/jobs/core/RemoveDuplicates.java +++ b/src/main/java/org/caosdb/server/jobs/core/RemoveDuplicates.java @@ -20,27 +20,30 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.entity.EntityInterface; -import caosdb.server.jobs.ContainerJob; import java.util.HashSet; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.jobs.ContainerJob; public class RemoveDuplicates extends ContainerJob { @Override protected void run() { - final HashSet<EntityInterface> rm = new HashSet<EntityInterface>(); + // collect duplicates + final HashSet<EntityInterface> duplicates = new HashSet<EntityInterface>(); for (final EntityInterface e : getContainer()) { - if (e.hasId() && !rm.contains(e)) { + if (e.hasId() && !duplicates.contains(e)) { for (final EntityInterface e2 : getContainer()) { - if (e2 != e && e.getId().equals(e2.getId())) { - rm.add(e2); + if (e2 != e && e.getIdVersion().equals(e2.getIdVersion())) { + // this is a duplicate of another entity in this container + duplicates.add(e2); } } } } - for (final EntityInterface e : rm) { + // remove duplicates. + for (final EntityInterface e : duplicates) { getContainer().remove(e); } } diff --git a/src/main/java/caosdb/server/jobs/core/ResolveNames.java b/src/main/java/org/caosdb/server/jobs/core/ResolveNames.java similarity index 80% rename from src/main/java/caosdb/server/jobs/core/ResolveNames.java rename to src/main/java/org/caosdb/server/jobs/core/ResolveNames.java index a7781fb4c1fd82d8a1f14df01da152b50ce86ae3..d0a1f0768b77fa7bd110019dd95220f65ad256f2 100644 --- a/src/main/java/caosdb/server/jobs/core/ResolveNames.java +++ b/src/main/java/org/caosdb/server/jobs/core/ResolveNames.java @@ -20,18 +20,18 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.database.backend.transaction.GetIDByName; -import caosdb.server.database.exceptions.EntityDoesNotExistException; -import caosdb.server.entity.Entity; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.container.TransactionContainer; -import caosdb.server.jobs.ContainerJob; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; import java.util.ArrayList; import java.util.List; +import org.caosdb.server.database.backend.transaction.GetIDByName; +import org.caosdb.server.database.exceptions.EntityDoesNotExistException; +import org.caosdb.server.entity.Entity; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.container.TransactionContainer; +import org.caosdb.server.jobs.ContainerJob; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; public class ResolveNames extends ContainerJob { diff --git a/src/main/java/caosdb/server/jobs/core/RetrieveACL.java b/src/main/java/org/caosdb/server/jobs/core/RetrieveACL.java similarity index 81% rename from src/main/java/caosdb/server/jobs/core/RetrieveACL.java rename to src/main/java/org/caosdb/server/jobs/core/RetrieveACL.java index 8446d586d9cac2043cda0ab1cd80732e83d96fda..f59b2c1ec94de846714575537516c41d18bf4629 100644 --- a/src/main/java/caosdb/server/jobs/core/RetrieveACL.java +++ b/src/main/java/org/caosdb/server/jobs/core/RetrieveACL.java @@ -20,18 +20,18 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.xml.ToElementable; -import caosdb.server.jobs.FlagJob; -import caosdb.server.jobs.JobAnnotation; -import caosdb.server.jobs.JobExecutionTime; -import caosdb.server.permissions.EntityPermission; -import caosdb.server.transaction.Retrieve; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; import org.apache.shiro.authz.AuthorizationException; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.xml.ToElementable; +import org.caosdb.server.jobs.FlagJob; +import org.caosdb.server.jobs.JobAnnotation; +import org.caosdb.server.jobs.JobExecutionTime; +import org.caosdb.server.permissions.EntityPermission; +import org.caosdb.server.transaction.Retrieve; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; import org.jdom2.Element; @JobAnnotation( diff --git a/src/main/java/caosdb/server/jobs/core/RetrieveAllJob.java b/src/main/java/org/caosdb/server/jobs/core/RetrieveAllJob.java similarity index 83% rename from src/main/java/caosdb/server/jobs/core/RetrieveAllJob.java rename to src/main/java/org/caosdb/server/jobs/core/RetrieveAllJob.java index 0fba1223a3bd0e984c5c2b6ff43dd58070b5bbc5..1ca43cec45413d80c307df2f4d09c6b8d34cfb49 100644 --- a/src/main/java/caosdb/server/jobs/core/RetrieveAllJob.java +++ b/src/main/java/org/caosdb/server/jobs/core/RetrieveAllJob.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.database.backend.transaction.RetrieveAll; -import caosdb.server.jobs.FlagJob; -import caosdb.server.jobs.JobAnnotation; -import caosdb.server.jobs.JobExecutionTime; +import org.caosdb.server.database.backend.transaction.RetrieveAll; +import org.caosdb.server.jobs.FlagJob; +import org.caosdb.server.jobs.JobAnnotation; +import org.caosdb.server.jobs.JobExecutionTime; @JobAnnotation(flag = "all", time = JobExecutionTime.INIT) public class RetrieveAllJob extends FlagJob { diff --git a/src/main/java/caosdb/server/jobs/core/RetrieveIdOnlyFlag.java b/src/main/java/org/caosdb/server/jobs/core/RetrieveIdOnlyFlag.java similarity index 83% rename from src/main/java/caosdb/server/jobs/core/RetrieveIdOnlyFlag.java rename to src/main/java/org/caosdb/server/jobs/core/RetrieveIdOnlyFlag.java index 04dbf3632439d590c36425d3d1d0499333f76a8c..1712950dff9403df54f26457d0b6a763d7ce4de8 100644 --- a/src/main/java/caosdb/server/jobs/core/RetrieveIdOnlyFlag.java +++ b/src/main/java/org/caosdb/server/jobs/core/RetrieveIdOnlyFlag.java @@ -20,13 +20,13 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.entity.EntityInterface; -import caosdb.server.jobs.FlagJob; -import caosdb.server.jobs.JobAnnotation; -import caosdb.server.jobs.JobExecutionTime; -import caosdb.server.utils.EntityStatus; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.jobs.FlagJob; +import org.caosdb.server.jobs.JobAnnotation; +import org.caosdb.server.jobs.JobExecutionTime; +import org.caosdb.server.utils.EntityStatus; @JobAnnotation(flag = "IdOnly", time = JobExecutionTime.PRE_TRANSACTION) public class RetrieveIdOnlyFlag extends FlagJob { diff --git a/src/main/java/caosdb/server/jobs/core/RetrieveOwner.java b/src/main/java/org/caosdb/server/jobs/core/RetrieveOwner.java similarity index 82% rename from src/main/java/caosdb/server/jobs/core/RetrieveOwner.java rename to src/main/java/org/caosdb/server/jobs/core/RetrieveOwner.java index 3c7fae64f16c3f7c0a6aa4791c404b640a26cb2b..7377805805ec55e2c3c3928cc42b0c053d8a9c9d 100644 --- a/src/main/java/caosdb/server/jobs/core/RetrieveOwner.java +++ b/src/main/java/org/caosdb/server/jobs/core/RetrieveOwner.java @@ -20,20 +20,20 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.xml.ToElementable; -import caosdb.server.jobs.FlagJob; -import caosdb.server.jobs.JobAnnotation; -import caosdb.server.jobs.JobExecutionTime; -import caosdb.server.permissions.EntityPermission; -import caosdb.server.permissions.ResponsibleAgent; -import caosdb.server.transaction.Retrieve; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; import java.util.List; import org.apache.shiro.authz.AuthorizationException; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.xml.ToElementable; +import org.caosdb.server.jobs.FlagJob; +import org.caosdb.server.jobs.JobAnnotation; +import org.caosdb.server.jobs.JobExecutionTime; +import org.caosdb.server.permissions.EntityPermission; +import org.caosdb.server.permissions.ResponsibleAgent; +import org.caosdb.server.transaction.Retrieve; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; import org.jdom2.Element; @JobAnnotation( diff --git a/src/main/java/caosdb/server/jobs/core/RetriveAllNames.java b/src/main/java/org/caosdb/server/jobs/core/RetriveAllNames.java similarity index 63% rename from src/main/java/caosdb/server/jobs/core/RetriveAllNames.java rename to src/main/java/org/caosdb/server/jobs/core/RetriveAllNames.java index d7f58e00c602d5ed9a79d9e03fa08d9941e64217..dfd69a5cb5a40a6e6be35e345f17e38f3dbb7e2e 100644 --- a/src/main/java/caosdb/server/jobs/core/RetriveAllNames.java +++ b/src/main/java/org/caosdb/server/jobs/core/RetriveAllNames.java @@ -1,12 +1,12 @@ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.database.backend.transaction.GetAllNames; -import caosdb.server.entity.EntityInterface; -import caosdb.server.jobs.FlagJob; -import caosdb.server.jobs.JobAnnotation; -import caosdb.server.jobs.JobExecutionTime; -import caosdb.server.permissions.EntityPermission; -import caosdb.server.utils.EntityStatus; +import org.caosdb.server.database.backend.transaction.GetAllNames; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.jobs.FlagJob; +import org.caosdb.server.jobs.JobAnnotation; +import org.caosdb.server.jobs.JobExecutionTime; +import org.caosdb.server.permissions.EntityPermission; +import org.caosdb.server.utils.EntityStatus; /** * A jobs which retrieves all known names for which the requesting user has the RETRIEVE_ENTITY diff --git a/src/main/java/caosdb/server/jobs/core/SetImpToFix.java b/src/main/java/org/caosdb/server/jobs/core/SetImpToFix.java similarity index 89% rename from src/main/java/caosdb/server/jobs/core/SetImpToFix.java rename to src/main/java/org/caosdb/server/jobs/core/SetImpToFix.java index 09566b337c695daf3694c31dc49f93cd4d10bc8a..f0047d02f861ef26cbad12b4e6a5963d51415eec 100644 --- a/src/main/java/caosdb/server/jobs/core/SetImpToFix.java +++ b/src/main/java/org/caosdb/server/jobs/core/SetImpToFix.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.StatementStatus; -import caosdb.server.jobs.EntityJob; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.StatementStatus; +import org.caosdb.server.jobs.EntityJob; /** * Set the statement status of all properties of an entity to the value "FIX". diff --git a/src/main/java/caosdb/server/jobs/core/SetImpToRecByDefault.java b/src/main/java/org/caosdb/server/jobs/core/SetImpToRecByDefault.java similarity index 91% rename from src/main/java/caosdb/server/jobs/core/SetImpToRecByDefault.java rename to src/main/java/org/caosdb/server/jobs/core/SetImpToRecByDefault.java index dbce7d873243fe136e1fd26e64c958b5ba7b345e..dd6cfc0820d9cd15281897a200f82d2c7d9d02bb 100644 --- a/src/main/java/caosdb/server/jobs/core/SetImpToRecByDefault.java +++ b/src/main/java/org/caosdb/server/jobs/core/SetImpToRecByDefault.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.StatementStatus; -import caosdb.server.jobs.EntityJob; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.StatementStatus; +import org.caosdb.server.jobs.EntityJob; /** * Set the statement status of all properties of an entity which do not have a statement status to diff --git a/src/main/java/caosdb/server/jobs/core/Strict.java b/src/main/java/org/caosdb/server/jobs/core/Strict.java similarity index 79% rename from src/main/java/caosdb/server/jobs/core/Strict.java rename to src/main/java/org/caosdb/server/jobs/core/Strict.java index bb8d9af2aa3eb402c05419144f2f3543017f3833..aebbecf86a89476339dbdef8892b074aebc8196d 100644 --- a/src/main/java/caosdb/server/jobs/core/Strict.java +++ b/src/main/java/org/caosdb/server/jobs/core/Strict.java @@ -20,16 +20,16 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.Message; -import caosdb.server.entity.xml.ToElementable; -import caosdb.server.jobs.ContainerJob; -import caosdb.server.jobs.JobAnnotation; -import caosdb.server.jobs.JobExecutionTime; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Message; +import org.caosdb.server.entity.xml.ToElementable; +import org.caosdb.server.jobs.ContainerJob; +import org.caosdb.server.jobs.JobAnnotation; +import org.caosdb.server.jobs.JobExecutionTime; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; @JobAnnotation(time = JobExecutionTime.POST_CHECK) public class Strict extends ContainerJob { diff --git a/src/main/java/caosdb/server/jobs/core/TestMail.java b/src/main/java/org/caosdb/server/jobs/core/TestMail.java similarity index 81% rename from src/main/java/caosdb/server/jobs/core/TestMail.java rename to src/main/java/org/caosdb/server/jobs/core/TestMail.java index e529265a36cac6b483215500edc5b9793ef60afc..fb3e87097fae44f3f1f609dd7e347c27c6d971c2 100644 --- a/src/main/java/caosdb/server/jobs/core/TestMail.java +++ b/src/main/java/org/caosdb/server/jobs/core/TestMail.java @@ -20,17 +20,17 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; -import caosdb.server.entity.Message; -import caosdb.server.entity.Message.MessageType; -import caosdb.server.jobs.FlagJob; -import caosdb.server.jobs.JobAnnotation; -import caosdb.server.utils.ServerMessages; -import caosdb.server.utils.Utils; -import caosdb.server.utils.mail.Mail; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.ServerProperties; +import org.caosdb.server.entity.Message; +import org.caosdb.server.entity.Message.MessageType; +import org.caosdb.server.jobs.FlagJob; +import org.caosdb.server.jobs.JobAnnotation; +import org.caosdb.server.utils.ServerMessages; +import org.caosdb.server.utils.Utils; +import org.caosdb.server.utils.mail.Mail; @JobAnnotation( flag = "testMail", diff --git a/src/main/java/caosdb/server/jobs/core/UniqueName.java b/src/main/java/org/caosdb/server/jobs/core/UniqueName.java similarity index 83% rename from src/main/java/caosdb/server/jobs/core/UniqueName.java rename to src/main/java/org/caosdb/server/jobs/core/UniqueName.java index 65b41253a34de0ad3e01b727e03fc4541746a222..300e32bf1662e4990f52bda0570a65c05e5d60b8 100644 --- a/src/main/java/caosdb/server/jobs/core/UniqueName.java +++ b/src/main/java/org/caosdb/server/jobs/core/UniqueName.java @@ -20,15 +20,15 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.database.exceptions.EntityDoesNotExistException; -import caosdb.server.database.exceptions.EntityWasNotUniqueException; -import caosdb.server.entity.EntityInterface; -import caosdb.server.jobs.FlagJob; -import caosdb.server.jobs.JobAnnotation; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; +import org.caosdb.server.database.exceptions.EntityDoesNotExistException; +import org.caosdb.server.database.exceptions.EntityWasNotUniqueException; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.jobs.FlagJob; +import org.caosdb.server.jobs.JobAnnotation; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; @JobAnnotation(flag = "uniquename") public class UniqueName extends FlagJob { diff --git a/src/main/java/caosdb/server/jobs/core/UpdateUnitConverters.java b/src/main/java/org/caosdb/server/jobs/core/UpdateUnitConverters.java similarity index 87% rename from src/main/java/caosdb/server/jobs/core/UpdateUnitConverters.java rename to src/main/java/org/caosdb/server/jobs/core/UpdateUnitConverters.java index 8d0118b80582e3a65b613caae2200719af428819..b3ef80adb64fcf3c1007a33a64bde691c9ff9c1d 100644 --- a/src/main/java/caosdb/server/jobs/core/UpdateUnitConverters.java +++ b/src/main/java/org/caosdb/server/jobs/core/UpdateUnitConverters.java @@ -20,15 +20,15 @@ * * ** end header */ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; -import caosdb.server.database.backend.transaction.InsertLinCon; -import caosdb.server.jobs.EntityJob; -import caosdb.server.jobs.JobAnnotation; -import caosdb.server.jobs.JobExecutionTime; -import caosdb.unit.Converter; -import caosdb.unit.LinearConverter; -import caosdb.unit.Unit; +import org.caosdb.server.database.backend.transaction.InsertLinCon; +import org.caosdb.server.jobs.EntityJob; +import org.caosdb.server.jobs.JobAnnotation; +import org.caosdb.server.jobs.JobExecutionTime; +import org.caosdb.unit.Converter; +import org.caosdb.unit.LinearConverter; +import org.caosdb.unit.Unit; @JobAnnotation(time = JobExecutionTime.PRE_TRANSACTION) public class UpdateUnitConverters extends EntityJob { diff --git a/src/main/java/caosdb/server/logging/RequestErrorLogMessage.java b/src/main/java/org/caosdb/server/logging/RequestErrorLogMessage.java similarity index 95% rename from src/main/java/caosdb/server/logging/RequestErrorLogMessage.java rename to src/main/java/org/caosdb/server/logging/RequestErrorLogMessage.java index ddffe7d512a7e31043883f238fd4fc2136d853bf..4f0e57a46155c51076d4a134c3559d0f773811a1 100644 --- a/src/main/java/caosdb/server/logging/RequestErrorLogMessage.java +++ b/src/main/java/org/caosdb/server/logging/RequestErrorLogMessage.java @@ -20,13 +20,13 @@ * * ** end header */ -package caosdb.server.logging; +package org.caosdb.server.logging; -import caosdb.server.resource.ReReadableRepresentation; import java.io.IOException; import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; +import org.caosdb.server.resource.ReReadableRepresentation; import org.restlet.Message; import org.restlet.Request; import org.restlet.Response; @@ -37,7 +37,7 @@ import org.restlet.util.Series; public class RequestErrorLogMessage implements Serializable { /** */ - private static final long serialVersionUID = 4683559833384175003L; + private static final long serialVersionUID = 2798857225464412730L; public String request = null; public String response = null; diff --git a/src/main/java/caosdb/server/logging/log4j/CustomConfigurationFactory.java b/src/main/java/org/caosdb/server/logging/log4j/CustomConfigurationFactory.java similarity index 98% rename from src/main/java/caosdb/server/logging/log4j/CustomConfigurationFactory.java rename to src/main/java/org/caosdb/server/logging/log4j/CustomConfigurationFactory.java index 6b7a456909074080f6e99670e1eed9b934653977..62722317f882dffae4168808514a6d972ae8bfe6 100644 --- a/src/main/java/caosdb/server/logging/log4j/CustomConfigurationFactory.java +++ b/src/main/java/org/caosdb/server/logging/log4j/CustomConfigurationFactory.java @@ -1,4 +1,4 @@ -package caosdb.server.logging.log4j; +package org.caosdb.server.logging.log4j; import java.io.File; import java.net.URI; diff --git a/src/main/java/caosdb/server/permissions/AbstractEntityACLFactory.java b/src/main/java/org/caosdb/server/permissions/AbstractEntityACLFactory.java similarity index 99% rename from src/main/java/caosdb/server/permissions/AbstractEntityACLFactory.java rename to src/main/java/org/caosdb/server/permissions/AbstractEntityACLFactory.java index 5d8174711c2dfd06798c5f5690b61540f55e5c56..3a3d03d18bc7b0913a522e2edd6c235f9a7d39a7 100644 --- a/src/main/java/caosdb/server/permissions/AbstractEntityACLFactory.java +++ b/src/main/java/org/caosdb/server/permissions/AbstractEntityACLFactory.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.permissions; +package org.caosdb.server.permissions; import java.util.ArrayList; import java.util.Collection; diff --git a/src/main/java/caosdb/server/permissions/CaosPermission.java b/src/main/java/org/caosdb/server/permissions/CaosPermission.java similarity index 95% rename from src/main/java/caosdb/server/permissions/CaosPermission.java rename to src/main/java/org/caosdb/server/permissions/CaosPermission.java index 71d5403848a44f02220d84237171e43a6406c492..1b793bb27f6a14bcf7fd0c5f828c20b73f3d11e5 100644 --- a/src/main/java/caosdb/server/permissions/CaosPermission.java +++ b/src/main/java/org/caosdb/server/permissions/CaosPermission.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.permissions; +package org.caosdb.server.permissions; import java.util.HashSet; import java.util.Map; @@ -45,7 +45,7 @@ public class CaosPermission extends HashSet<PermissionRule> implements Permissio return ret; } - private static final long serialVersionUID = -2730907147406500598L; + private static final long serialVersionUID = 2136265443788256009L; @Override public boolean implies(final Permission p) { diff --git a/src/main/java/caosdb/server/permissions/EntityACI.java b/src/main/java/org/caosdb/server/permissions/EntityACI.java similarity index 98% rename from src/main/java/caosdb/server/permissions/EntityACI.java rename to src/main/java/org/caosdb/server/permissions/EntityACI.java index 4b960f49beedec9df2a15084ac77e9508670df0f..ccc889decafc941484432c99bf48908c21dff209 100644 --- a/src/main/java/caosdb/server/permissions/EntityACI.java +++ b/src/main/java/org/caosdb/server/permissions/EntityACI.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.permissions; +package org.caosdb.server.permissions; import java.util.HashMap; diff --git a/src/main/java/caosdb/server/permissions/EntityACL.java b/src/main/java/org/caosdb/server/permissions/EntityACL.java similarity index 94% rename from src/main/java/caosdb/server/permissions/EntityACL.java rename to src/main/java/org/caosdb/server/permissions/EntityACL.java index 34ef34351826facfa7d342d6c8b06e8d8c27cf74..df1915bd460079eb52dfc6d4f3bbf4fe42795918 100644 --- a/src/main/java/caosdb/server/permissions/EntityACL.java +++ b/src/main/java/org/caosdb/server/permissions/EntityACL.java @@ -20,16 +20,11 @@ * * ** end header */ -package caosdb.server.permissions; +package org.caosdb.server.permissions; -import static caosdb.server.permissions.Role.OTHER_ROLE; -import static caosdb.server.permissions.Role.OWNER_ROLE; +import static org.caosdb.server.permissions.Role.OTHER_ROLE; +import static org.caosdb.server.permissions.Role.OWNER_ROLE; -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; -import caosdb.server.accessControl.AuthenticationUtils; -import caosdb.server.accessControl.Principal; -import caosdb.server.database.exceptions.TransactionException; import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -41,6 +36,11 @@ import java.util.List; import java.util.Map; import java.util.Set; import org.apache.shiro.subject.Subject; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.ServerProperties; +import org.caosdb.server.accessControl.AuthenticationUtils; +import org.caosdb.server.accessControl.Principal; +import org.caosdb.server.database.exceptions.TransactionException; import org.eclipse.jetty.util.ajax.JSON; import org.jdom2.DataConversionException; import org.jdom2.Document; @@ -92,7 +92,11 @@ public class EntityACL { } public static final EntityACL getOwnerACLFor(final Subject subject) { - if (subject.getPrincipal() == AuthenticationUtils.ANONYMOUS_USER.getPrincipal()) { + // TODO handle the case where a valid non-guest user (e.g. me@PAM, + // you@CaosDB) is (just temporarily) authenticated via a + // OneTimeAuthenticationToken + if (AuthenticationUtils.isAnonymous(subject) + || AuthenticationUtils.isFromOneTimeTokenRealm(subject)) { return new EntityACLFactory().create(); } return getOwnerACLFor((Principal) subject.getPrincipal()); diff --git a/src/main/java/caosdb/server/permissions/EntityACLFactory.java b/src/main/java/org/caosdb/server/permissions/EntityACLFactory.java similarity index 85% rename from src/main/java/caosdb/server/permissions/EntityACLFactory.java rename to src/main/java/org/caosdb/server/permissions/EntityACLFactory.java index eeacb1260729f78f490e592891c0a93a334b42fa..08e4ae45cf07baac91b98205c1098d823b878b21 100644 --- a/src/main/java/caosdb/server/permissions/EntityACLFactory.java +++ b/src/main/java/org/caosdb/server/permissions/EntityACLFactory.java @@ -1,4 +1,4 @@ -package caosdb.server.permissions; +package org.caosdb.server.permissions; import java.util.Collection; diff --git a/src/main/java/caosdb/server/permissions/EntityPermission.java b/src/main/java/org/caosdb/server/permissions/EntityPermission.java similarity index 97% rename from src/main/java/caosdb/server/permissions/EntityPermission.java rename to src/main/java/org/caosdb/server/permissions/EntityPermission.java index 1747a55810cf9718abc9627cad8102f88b2a5cac..1f84dce34a611f3b25bea5ddaab0d40c9723a280 100644 --- a/src/main/java/caosdb/server/permissions/EntityPermission.java +++ b/src/main/java/org/caosdb/server/permissions/EntityPermission.java @@ -20,21 +20,21 @@ * * ** end header */ -package caosdb.server.permissions; +package org.caosdb.server.permissions; -import caosdb.server.CaosDBException; -import caosdb.server.entity.xml.ToElementable; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.caosdb.server.CaosDBException; +import org.caosdb.server.entity.xml.ToElementable; import org.jdom2.Element; public class EntityPermission extends Permission { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = -8935713878537140286L; private static List<EntityPermission> instances = new ArrayList<>(); private final int bitNumber; diff --git a/src/main/java/caosdb/server/permissions/Permission.java b/src/main/java/org/caosdb/server/permissions/Permission.java similarity index 94% rename from src/main/java/caosdb/server/permissions/Permission.java rename to src/main/java/org/caosdb/server/permissions/Permission.java index e58329ee38e45c9bc053ca5cc60b258838116271..44eee1c68a073c405233195aee491bcf10fcd38c 100644 --- a/src/main/java/caosdb/server/permissions/Permission.java +++ b/src/main/java/org/caosdb/server/permissions/Permission.java @@ -20,13 +20,13 @@ * * ** end header */ -package caosdb.server.permissions; +package org.caosdb.server.permissions; import org.apache.shiro.authz.permission.WildcardPermission; public class Permission extends WildcardPermission { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = -7471830472441416012L; public static final org.apache.shiro.authz.Permission EDIT_PRIORITY_ACL = new Permission( diff --git a/src/main/java/caosdb/server/permissions/PermissionRule.java b/src/main/java/org/caosdb/server/permissions/PermissionRule.java similarity index 98% rename from src/main/java/caosdb/server/permissions/PermissionRule.java rename to src/main/java/org/caosdb/server/permissions/PermissionRule.java index bcbd3a27abb6781613f2afef450b2ce2eed24feb..b6ee915156771e1164f3a0ee221d3e14ab964833 100644 --- a/src/main/java/caosdb/server/permissions/PermissionRule.java +++ b/src/main/java/org/caosdb/server/permissions/PermissionRule.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.permissions; +package org.caosdb.server.permissions; import java.util.HashMap; import java.util.Map; diff --git a/src/main/java/caosdb/server/permissions/ResponsibleAgent.java b/src/main/java/org/caosdb/server/permissions/ResponsibleAgent.java similarity index 96% rename from src/main/java/caosdb/server/permissions/ResponsibleAgent.java rename to src/main/java/org/caosdb/server/permissions/ResponsibleAgent.java index b29675ecd16f6872e2aa03ba5e70c8e5699cd613..3f8fd3bbbe800b1ce43d240da53344512feb5e01 100644 --- a/src/main/java/caosdb/server/permissions/ResponsibleAgent.java +++ b/src/main/java/org/caosdb/server/permissions/ResponsibleAgent.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.permissions; +package org.caosdb.server.permissions; import java.util.HashMap; import org.jdom2.Element; diff --git a/src/main/java/caosdb/server/permissions/Role.java b/src/main/java/org/caosdb/server/permissions/Role.java similarity index 92% rename from src/main/java/caosdb/server/permissions/Role.java rename to src/main/java/org/caosdb/server/permissions/Role.java index 70e1a61f754b4beeffe8f8fe203b42842d49cb6d..54afefc664c330dfc4465285347a1463d9df0d5e 100644 --- a/src/main/java/caosdb/server/permissions/Role.java +++ b/src/main/java/org/caosdb/server/permissions/Role.java @@ -20,9 +20,8 @@ * * ** end header */ -package caosdb.server.permissions; +package org.caosdb.server.permissions; -import caosdb.server.accessControl.UserSources; import java.util.HashMap; import org.jdom2.Attribute; import org.jdom2.Element; @@ -31,7 +30,7 @@ public class Role implements ResponsibleAgent { public static final Role OWNER_ROLE = new Role("?OWNER?"); public static final Role OTHER_ROLE = new Role("?OTHER?"); - public static final Role ANONYMOUS_ROLE = new Role(UserSources.ANONYMOUS_ROLE); + public static final Role ANONYMOUS_ROLE = new Role("anonymous"); private final String role; diff --git a/src/main/java/caosdb/server/query/Backreference.java b/src/main/java/org/caosdb/server/query/Backreference.java similarity index 92% rename from src/main/java/caosdb/server/query/Backreference.java rename to src/main/java/org/caosdb/server/query/Backreference.java index c39ce43923372811caf8607550a9852d1a518c63..b9114ad55147ca92163a55cf374d3b13093ead98 100644 --- a/src/main/java/caosdb/server/query/Backreference.java +++ b/src/main/java/org/caosdb/server/query/Backreference.java @@ -20,15 +20,11 @@ * * ** end header */ -package caosdb.server.query; +package org.caosdb.server.query; -import static caosdb.server.database.DatabaseUtils.bytes2UTF8; import static java.sql.Types.VARCHAR; +import static org.caosdb.server.database.DatabaseUtils.bytes2UTF8; -import caosdb.server.database.access.Access; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.query.Query.Pattern; -import caosdb.server.query.Query.QueryException; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.PreparedStatement; @@ -38,6 +34,10 @@ import java.sql.Types; import java.util.HashMap; import java.util.Map.Entry; import org.apache.shiro.subject.Subject; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.query.Query.Pattern; +import org.caosdb.server.query.Query.QueryException; import org.jdom2.Element; public class Backreference implements EntityFilterInterface, QueryInterface { @@ -103,9 +103,12 @@ public class Backreference implements EntityFilterInterface, QueryInterface { return "@(" + getEntity() + "," + getProperty() + ")"; } - /** */ @Override public void apply(final QueryInterface query) throws QueryException { + if (query.isVersioned() && hasSubProperty()) { + throw new UnsupportedOperationException( + "Versioned queries are not supported for subqueries yet. Please file a feature request."); + } final long t1 = System.currentTimeMillis(); this.query = query; this.targetSet = query.getTargetSet(); @@ -113,7 +116,7 @@ public class Backreference implements EntityFilterInterface, QueryInterface { initBackRef(query); final CallableStatement callApplyBackRef = - getConnection().prepareCall("call applyBackReference(?,?,?,?,?)"); + getConnection().prepareCall("call applyBackReference(?,?,?,?,?,?)"); callApplyBackRef.setString(1, getSourceSet()); // sourceSet this.statistics.put("sourceSet", getSourceSet()); this.statistics.put( @@ -145,6 +148,7 @@ public class Backreference implements EntityFilterInterface, QueryInterface { callApplyBackRef.setNull(4, VARCHAR); } callApplyBackRef.setBoolean(5, hasSubProperty()); // subQuery? + callApplyBackRef.setBoolean(6, this.isVersioned()); executeStmt(query, callApplyBackRef); callApplyBackRef.close(); @@ -214,7 +218,7 @@ public class Backreference implements EntityFilterInterface, QueryInterface { final long t3 = System.currentTimeMillis(); try (final PreparedStatement callFinishSubProperty = - getConnection().prepareCall("call finishSubProperty(?,?,?)")) { + getConnection().prepareCall("call finishSubProperty(?,?,?,?)")) { callFinishSubProperty.setString(1, query.getSourceSet()); // sourceSet if (query.getTargetSet() != null) { // targetSet callFinishSubProperty.setString(2, query.getTargetSet()); @@ -222,6 +226,7 @@ public class Backreference implements EntityFilterInterface, QueryInterface { callFinishSubProperty.setNull(2, VARCHAR); } callFinishSubProperty.setString(3, this.sourceSet); // list + callFinishSubProperty.setBoolean(4, this.isVersioned()); final ResultSet rs2 = callFinishSubProperty.executeQuery(); rs2.next(); this.statistics.put("finishSubPropertyStmt", rs2.getString("finishSubPropertyStmt")); @@ -320,4 +325,9 @@ public class Backreference implements EntityFilterInterface, QueryInterface { public void addBenchmark(final String str, final long time) { this.query.addBenchmark(this.getClass().getSimpleName() + "." + str, time); } + + @Override + public boolean isVersioned() { + return this.query.isVersioned(); + } } diff --git a/src/main/java/caosdb/server/query/CQLLexer.g4 b/src/main/java/org/caosdb/server/query/CQLLexer.g4 similarity index 96% rename from src/main/java/caosdb/server/query/CQLLexer.g4 rename to src/main/java/org/caosdb/server/query/CQLLexer.g4 index 62cb12c09c00a2f0005a8b9e2b7d5cc8f6b753e5..ec363be59893ad72cf412dbdc9d1f6d6644da5be 100644 --- a/src/main/java/caosdb/server/query/CQLLexer.g4 +++ b/src/main/java/org/caosdb/server/query/CQLLexer.g4 @@ -34,6 +34,25 @@ BY: [Bb][Yy] ; +fragment +OF_f: + [Oo][Ff] +; + +fragment +ANY_f: + [Aa][Nn][Yy] +; + +fragment +VERSION_f: + [Vv][Ee][Rr][Ss][Ii][Oo][Nn] +; + +ANY_VERSION_OF: + (ANY_f EMPTY_SPACE VERSION_f EMPTY_SPACE OF_f) +; + SELECT: [Ss][Ee][Ll][Ee][Cc][Tt] -> pushMode(SELECT_MODE) ; diff --git a/src/main/java/caosdb/server/query/CQLParser.g4 b/src/main/java/org/caosdb/server/query/CQLParser.g4 similarity index 91% rename from src/main/java/caosdb/server/query/CQLParser.g4 rename to src/main/java/org/caosdb/server/query/CQLParser.g4 index af981d6a2d027892c144070323aa924a5d7674a5..0daeff47a95ff38391ce3f9b8004bec642b0ccb2 100644 --- a/src/main/java/caosdb/server/query/CQLParser.g4 +++ b/src/main/java/org/caosdb/server/query/CQLParser.g4 @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2020 Indiscale GmbH <info@indiscale.com> + * Copyright (C) 2020 Florian Spreckelsen <f.spreckelsen@indiscale.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -29,11 +31,12 @@ options { tokenVocab = CQLLexer; } import java.util.List; } -cq returns [Query.Type t, List<Query.Selection> s, Query.Pattern e, Query.Role r, EntityFilterInterface filter] +cq returns [Query.Type t, List<Query.Selection> s, Query.Pattern e, Query.Role r, EntityFilterInterface filter, VersionFilter v] @init{ $s = null; $e = null; $r = null; + $v = VersionFilter.UNVERSIONED; $filter = null; } : @@ -42,6 +45,7 @@ cq returns [Query.Type t, List<Query.Selection> s, Query.Pattern e, Query.Role r SELECT prop_sel {$s = $prop_sel.s;} FROM {$t = Query.Type.FIND;} | FIND {$t = Query.Type.FIND;} | COUNT {$t = Query.Type.COUNT;}) + (version {$v = $version.v;})? ( ( role {$r = $role.r;} @@ -54,6 +58,14 @@ cq returns [Query.Type t, List<Query.Selection> s, Query.Pattern e, Query.Role r EOF ; +version returns [VersionFilter v] + @init{ + $v = null; + } +: + ANY_VERSION_OF {$v = VersionFilter.ANY_VERSION;} +; + prop_sel returns [List<Query.Selection> s] @init{ $s = new LinkedList<Query.Selection>(); @@ -188,11 +200,11 @@ username returns [Query.Pattern ep] locals [int type] transaction_time returns [String tqp] : - ( - (ON | IN) - (datetime {$tqp = $datetime.text;} - | entity {$tqp = $entity.ep.toString();}) - ) | TODAY {$tqp = TransactionFilter.TODAY;} + ( + (ON | IN) + (value {$tqp = $value.text;} + | entity {$tqp = $entity.ep.toString();}) + ) | TODAY {$tqp = TransactionFilter.TODAY;} ; /* @@ -244,8 +256,8 @@ pov returns [POV filter] locals [Query.Pattern p, String o, String v, String a] ) | IS_NULL {$o = "0";} | IS_NOT_NULL {$o = "!0";} - | IN datetime {$o = "("; $v=$datetime.text;} - | NEGATION IN datetime {$o = "!("; $v=$datetime.text;} + | IN value {$o = "("; $v=$value.str;} + | NEGATION IN value {$o = "!("; $v=$value.str;} )? ) | @@ -310,7 +322,11 @@ conjunction returns [Conjunction c] locals [Conjunction dummy] f1 = filter_expression {$c.add($f1.efi);} | LPAREN - f4 = filter_expression {$c.add($f4.efi);} + ( + f4 = filter_expression {$c.add($f4.efi);} + | disjunction {$c.add($disjunction.d);} + | c3=conjunction {$c.addAll($c3.c);} + ) RPAREN ) ( @@ -325,7 +341,7 @@ conjunction returns [Conjunction c] locals [Conjunction dummy] ( f3 = filter_expression {$c.add($f3.efi);} | disjunction {$c.add($disjunction.d);} - | c2=conjunction {$c.addAll($c2.c);} + | c2=conjunction {$c.addAll($c2.c);} ) RPAREN ) @@ -342,7 +358,11 @@ disjunction returns [Disjunction d] f1 = filter_expression {$d.add($f1.efi);} | LPAREN - f4 = filter_expression {$d.add($f4.efi);} + ( + f4 = filter_expression {$d.add($f4.efi);} + | conjunction {$d.add($conjunction.c);} + | d3 = disjunction {$d.addAll($d3.d);} + ) RPAREN ) ( @@ -443,7 +463,7 @@ minmax returns [String agg] value returns [String str] : number {$str = $text;} - | datetime {$str = $text;} + | datetime {$str = $datetime.text;} | atom {$str = $atom.ep.toString();} ; diff --git a/src/main/java/caosdb/server/query/CQLParsingErrorListener.java b/src/main/java/org/caosdb/server/query/CQLParsingErrorListener.java similarity index 99% rename from src/main/java/caosdb/server/query/CQLParsingErrorListener.java rename to src/main/java/org/caosdb/server/query/CQLParsingErrorListener.java index 5dcec8eb2cd1772978aca87e3b630ee34d0e6812..c2b453e5836a18628904302f2157f0a41a190068 100644 --- a/src/main/java/caosdb/server/query/CQLParsingErrorListener.java +++ b/src/main/java/org/caosdb/server/query/CQLParsingErrorListener.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.query; +package org.caosdb.server.query; import java.util.ArrayList; import java.util.BitSet; diff --git a/src/main/java/caosdb/server/query/Conjunction.java b/src/main/java/org/caosdb/server/query/Conjunction.java similarity index 92% rename from src/main/java/caosdb/server/query/Conjunction.java rename to src/main/java/org/caosdb/server/query/Conjunction.java index 297f781bdc0de1ecf6de69ade12c25cba5efc8c9..2e44aea4f64a43ebb2a1c1edb153c6f68c172f8e 100644 --- a/src/main/java/caosdb/server/query/Conjunction.java +++ b/src/main/java/org/caosdb/server/query/Conjunction.java @@ -20,18 +20,18 @@ * * ** end header */ -package caosdb.server.query; +package org.caosdb.server.query; -import static caosdb.server.database.DatabaseUtils.bytes2UTF8; +import static org.caosdb.server.database.DatabaseUtils.bytes2UTF8; -import caosdb.server.database.access.Access; -import caosdb.server.query.Query.QueryException; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import org.apache.shiro.subject.Subject; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.query.Query.QueryException; import org.jdom2.Element; public class Conjunction extends EntityFilterContainer implements QueryInterface { @@ -63,8 +63,9 @@ public class Conjunction extends EntityFilterContainer implements QueryInterface // generate empty temporary targetSet if query.getTargetSet() is not // empty anyways. final PreparedStatement callInitEmptyTarget = - getConnection().prepareStatement("call initEmptyTargetSet(?)"); + getConnection().prepareStatement("call initEmptyTargetSet(?,?)"); callInitEmptyTarget.setString(1, query.getTargetSet()); + callInitEmptyTarget.setBoolean(2, query.isVersioned()); final ResultSet initEmptyTargetResultSet = callInitEmptyTarget.executeQuery(); if (initEmptyTargetResultSet.next()) { this.targetSet = bytes2UTF8(initEmptyTargetResultSet.getBytes("newTableName")); @@ -149,4 +150,9 @@ public class Conjunction extends EntityFilterContainer implements QueryInterface public void addBenchmark(final String str, final long time) { this.query.addBenchmark(this.getClass().getSimpleName() + "." + str, time); } + + @Override + public boolean isVersioned() { + return this.query.isVersioned(); + } } diff --git a/src/main/java/caosdb/server/query/Disjunction.java b/src/main/java/org/caosdb/server/query/Disjunction.java similarity index 84% rename from src/main/java/caosdb/server/query/Disjunction.java rename to src/main/java/org/caosdb/server/query/Disjunction.java index b9515c6b2ea263090ca224c8de3a625167666090..31288f2f169d4ebce1cf3d4da5b2ab369fcd5e1f 100644 --- a/src/main/java/caosdb/server/query/Disjunction.java +++ b/src/main/java/org/caosdb/server/query/Disjunction.java @@ -20,18 +20,18 @@ * * ** end header */ -package caosdb.server.query; +package org.caosdb.server.query; -import static caosdb.server.database.DatabaseUtils.bytes2UTF8; +import static org.caosdb.server.database.DatabaseUtils.bytes2UTF8; -import caosdb.server.database.access.Access; -import caosdb.server.query.Query.QueryException; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import org.apache.shiro.subject.Subject; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.query.Query.QueryException; import org.jdom2.Element; public class Disjunction extends EntityFilterContainer implements QueryInterface { @@ -51,7 +51,8 @@ public class Disjunction extends EntityFilterContainer implements QueryInterface // targetTable // which will be used to collect the entities. final PreparedStatement callInitDisjunctionFilter = - getConnection().prepareStatement("call initDisjunctionFilter()"); + getConnection().prepareStatement("call initDisjunctionFilter(?)"); + callInitDisjunctionFilter.setBoolean(1, this.isVersioned()); final ResultSet initDisjuntionFilterResultSet = callInitDisjunctionFilter.executeQuery(); if (initDisjuntionFilterResultSet.next()) { this.targetSet = bytes2UTF8(initDisjuntionFilterResultSet.getBytes("newTableName")); @@ -69,11 +70,12 @@ public class Disjunction extends EntityFilterContainer implements QueryInterface if (query.getTargetSet() == null) { // calculate the difference and store to sourceSet - final CallableStatement callFinishNegationFilter = - getConnection().prepareCall("call calcIntersection(?,?)"); - callFinishNegationFilter.setString(1, getSourceSet()); - callFinishNegationFilter.setString(2, this.targetSet); - callFinishNegationFilter.execute(); + final CallableStatement callFinishDisjunctionFilter = + getConnection().prepareCall("call calcIntersection(?,?,?)"); + callFinishDisjunctionFilter.setString(1, getSourceSet()); + callFinishDisjunctionFilter.setString(2, this.targetSet); + callFinishDisjunctionFilter.setBoolean(3, this.isVersioned()); + callFinishDisjunctionFilter.execute(); } // ELSE: the query.getTargetSet() is identical to targetSet and is // not @@ -136,4 +138,9 @@ public class Disjunction extends EntityFilterContainer implements QueryInterface public void addBenchmark(final String str, final long time) { this.query.addBenchmark(this.getClass().getSimpleName() + "." + str, time); } + + @Override + public boolean isVersioned() { + return this.query.isVersioned(); + } } diff --git a/src/main/java/caosdb/server/query/EntityFilterContainer.java b/src/main/java/org/caosdb/server/query/EntityFilterContainer.java similarity index 97% rename from src/main/java/caosdb/server/query/EntityFilterContainer.java rename to src/main/java/org/caosdb/server/query/EntityFilterContainer.java index 712ed7182cf681c6d4f0a465e94e0c6161b290e6..c2409f90ecc43cfb318a17cc8a9f3ba6df60beb0 100644 --- a/src/main/java/caosdb/server/query/EntityFilterContainer.java +++ b/src/main/java/org/caosdb/server/query/EntityFilterContainer.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.query; +package org.caosdb.server.query; import java.util.LinkedList; diff --git a/src/main/java/caosdb/server/query/EntityFilterInterface.java b/src/main/java/org/caosdb/server/query/EntityFilterInterface.java similarity index 92% rename from src/main/java/caosdb/server/query/EntityFilterInterface.java rename to src/main/java/org/caosdb/server/query/EntityFilterInterface.java index 813f3ef00e780128fcc457dd34895441b1700cb5..3bf113edbfa6aeb3bbe1c4ead7c2bbca0aca0d03 100644 --- a/src/main/java/caosdb/server/query/EntityFilterInterface.java +++ b/src/main/java/org/caosdb/server/query/EntityFilterInterface.java @@ -20,9 +20,9 @@ * * ** end header */ -package caosdb.server.query; +package org.caosdb.server.query; -import caosdb.server.query.Query.QueryException; +import org.caosdb.server.query.Query.QueryException; import org.jdom2.Element; public interface EntityFilterInterface { diff --git a/src/main/java/caosdb/server/query/IDFilter.java b/src/main/java/org/caosdb/server/query/IDFilter.java similarity index 93% rename from src/main/java/caosdb/server/query/IDFilter.java rename to src/main/java/org/caosdb/server/query/IDFilter.java index 556ba1c0ef64a73518cfea957c5ab5d1401a47eb..12f53b44472d5b897c3d8b2a065388969c1edcbc 100644 --- a/src/main/java/caosdb/server/query/IDFilter.java +++ b/src/main/java/org/caosdb/server/query/IDFilter.java @@ -20,16 +20,16 @@ * * ** end header */ -package caosdb.server.query; +package org.caosdb.server.query; import static java.sql.Types.CHAR; import static java.sql.Types.INTEGER; import static java.sql.Types.VARCHAR; -import caosdb.server.query.Query.QueryException; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.SQLException; +import org.caosdb.server.query.Query.QueryException; import org.jdom2.Element; public class IDFilter implements EntityFilterInterface { @@ -59,7 +59,7 @@ public class IDFilter implements EntityFilterInterface { final Connection connection = query.getConnection(); // applyIDFilter(sourceSet, targetSet, o, vInt, agg) final CallableStatement callIDFilter = - connection.prepareCall("call applyIDFilter(?,?,?,?,?)"); + connection.prepareCall("call applyIDFilter(?,?,?,?,?,?)"); callIDFilter.setString(1, query.getSourceSet()); // sourceSet if (query.getTargetSet() != null) { // targetSet @@ -89,6 +89,8 @@ public class IDFilter implements EntityFilterInterface { callIDFilter.setString(5, getAggregate()); } + // versioning + callIDFilter.setBoolean(6, query.isVersioned()); callIDFilter.execute(); callIDFilter.close(); } catch (final SQLException e) { diff --git a/src/main/java/caosdb/server/query/Negation.java b/src/main/java/org/caosdb/server/query/Negation.java similarity index 85% rename from src/main/java/caosdb/server/query/Negation.java rename to src/main/java/org/caosdb/server/query/Negation.java index c54d4b8f931c4ba21622db7b35bdd00c33d86334..981b4c8f2ca19a1a6ec47df9e85f108ab7bb01ac 100644 --- a/src/main/java/caosdb/server/query/Negation.java +++ b/src/main/java/org/caosdb/server/query/Negation.java @@ -20,18 +20,18 @@ * * ** end header */ -package caosdb.server.query; +package org.caosdb.server.query; -import static caosdb.server.database.DatabaseUtils.bytes2UTF8; +import static org.caosdb.server.database.DatabaseUtils.bytes2UTF8; -import caosdb.server.database.access.Access; -import caosdb.server.query.Query.QueryException; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import org.apache.shiro.subject.Subject; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.query.Query.QueryException; import org.jdom2.Element; public class Negation implements EntityFilterInterface, QueryInterface { @@ -90,8 +90,8 @@ public class Negation implements EntityFilterInterface, QueryInterface { // generate empty temporary targetSet if query.getTargetSet() is not // empty anyways. final PreparedStatement callInitEmptyTarget = - getConnection().prepareStatement("call initEmptyTargetSet(?)"); - callInitEmptyTarget.setString(1, query.getTargetSet()); + getConnection().prepareStatement("call initDisjunctionFilter(?)"); + callInitEmptyTarget.setBoolean(1, query.isVersioned()); final ResultSet initEmptyTargetResultSet = callInitEmptyTarget.executeQuery(); if (initEmptyTargetResultSet.next()) { this.targetSet = bytes2UTF8(initEmptyTargetResultSet.getBytes("newTableName")); @@ -100,19 +100,22 @@ public class Negation implements EntityFilterInterface, QueryInterface { this.filter.apply(this); - if (query.getTargetSet() != null && !this.targetSet.equalsIgnoreCase(query.getTargetSet())) { - // merge temporary targetSet with query.getTargetSet() + if (query.getTargetSet() == null) { + // intersect temporary targetSet with query.getSourceSet() final CallableStatement callFinishConjunctionFilter = - query.getConnection().prepareCall("call calcUnion(?,?)"); - callFinishConjunctionFilter.setString(1, query.getTargetSet()); + query.getConnection().prepareCall("call calcDifference(?,?,?)"); + callFinishConjunctionFilter.setString(1, query.getSourceSet()); callFinishConjunctionFilter.setString(2, this.targetSet); + callFinishConjunctionFilter.setBoolean(3, this.isVersioned()); callFinishConjunctionFilter.execute(); - } else if (query.getTargetSet() == null) { - // intersect temporary targetSet with query.getSourceSet() + } else { + // merge temporary targetSet with query.getTargetSet() final CallableStatement callFinishConjunctionFilter = - query.getConnection().prepareCall("call calcDifference(?,?)"); - callFinishConjunctionFilter.setString(1, query.getSourceSet()); + query.getConnection().prepareCall("call calcComplementUnion(?,?,?,?)"); + callFinishConjunctionFilter.setString(1, query.getTargetSet()); callFinishConjunctionFilter.setString(2, this.targetSet); + callFinishConjunctionFilter.setString(3, query.getSourceSet()); + callFinishConjunctionFilter.setBoolean(4, this.isVersioned()); callFinishConjunctionFilter.execute(); } } catch (final SQLException e) { @@ -167,4 +170,9 @@ public class Negation implements EntityFilterInterface, QueryInterface { public void addBenchmark(final String str, final long time) { this.query.addBenchmark(this.getClass().getSimpleName() + "." + str, time); } + + @Override + public boolean isVersioned() { + return this.query.isVersioned(); + } } diff --git a/src/main/java/caosdb/server/query/POV.java b/src/main/java/org/caosdb/server/query/POV.java similarity index 92% rename from src/main/java/caosdb/server/query/POV.java rename to src/main/java/org/caosdb/server/query/POV.java index a50be918da30d6cb69b457ef4b7801ea3019d58d..fcc719e6ff24299d0b5a62a241442e08fa33962f 100644 --- a/src/main/java/caosdb/server/query/POV.java +++ b/src/main/java/org/caosdb/server/query/POV.java @@ -20,20 +20,13 @@ * * ** end header */ -package caosdb.server.query; +package org.caosdb.server.query; -import static caosdb.server.database.DatabaseUtils.bytes2UTF8; import static java.sql.Types.DOUBLE; import static java.sql.Types.INTEGER; import static java.sql.Types.VARCHAR; +import static org.caosdb.server.database.DatabaseUtils.bytes2UTF8; -import caosdb.datetime.DateTimeFactory2; -import caosdb.datetime.DateTimeInterface; -import caosdb.datetime.Interval; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.query.Query.QueryException; -import caosdb.unit.CaosDBSystemOfUnits; -import caosdb.unit.Unit; import de.timmfitschen.easyunits.parser.ParserException; import java.sql.CallableStatement; import java.sql.Connection; @@ -46,6 +39,13 @@ import java.util.Map.Entry; import java.util.Stack; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.caosdb.datetime.DateTimeFactory2; +import org.caosdb.datetime.DateTimeInterface; +import org.caosdb.datetime.Interval; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.query.Query.QueryException; +import org.caosdb.unit.CaosDBSystemOfUnits; +import org.caosdb.unit.Unit; import org.jdom2.Element; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -155,7 +155,7 @@ public class POV implements EntityFilterInterface { this.unit = getUnit(unitStr); } catch (final ParserException e) { e.printStackTrace(); - throw new UnsupportedOperationException(); + throw new UnsupportedOperationException("Could not parse the unit."); } this.stdUnitSig = this.unit.normalize().getSignature(); @@ -167,6 +167,9 @@ public class POV implements EntityFilterInterface { } catch (final ClassCastException e) { this.vDatetime = null; } catch (final IllegalArgumentException e) { + if (this.operator.contains("(")) { + throw new Query.ParsingException("the value is expected to be a date time"); + } this.vDatetime = null; } } else { @@ -211,6 +214,10 @@ public class POV implements EntityFilterInterface { @Override public void apply(final QueryInterface query) throws QueryException { + if (query.isVersioned() && hasSubProperty()) { + throw new UnsupportedOperationException( + "Versioned queries are not supported for subqueries yet. Please file a feature request."); + } final long t1 = System.currentTimeMillis(); try { this.connection = query.getConnection(); @@ -223,9 +230,9 @@ public class POV implements EntityFilterInterface { // applyPOV(sourceSet, targetSet, propertiesTable, refIdsTable, o, // vText, vInt, // vDouble, - // vDatetime, vDateTimeDotNotation, agg, pname) + // vDatetime, vDateTimeDotNotation, agg, pname, versioned) final CallableStatement callPOV = - this.connection.prepareCall("call applyPOV(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); + this.connection.prepareCall("call applyPOV(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); callPOV.setString(1, query.getSourceSet()); // sourceSet this.statistics.put("sourceSet", query.getSourceSet()); this.statistics.put( @@ -310,6 +317,10 @@ public class POV implements EntityFilterInterface { } if (getAggregate() != null) { // agg + if (query.isVersioned()) { + throw new UnsupportedOperationException( + "Versioned queries are not supported for aggregate functions like GREATES or SMALLEST in the filters."); + } callPOV.setString(14, getAggregate()); } else { callPOV.setNull(14, VARCHAR); @@ -320,6 +331,7 @@ public class POV implements EntityFilterInterface { } else { callPOV.setNull(15, VARCHAR); } + callPOV.setBoolean(16, query.isVersioned()); prefix.add("#executeStmt"); executeStmt(callPOV, query); prefix.pop(); @@ -417,7 +429,9 @@ public class POV implements EntityFilterInterface { if (hasSubProperty() && this.targetSet != null) { try (PreparedStatement stmt = - query.getConnection().prepareStatement("call initEmptyTargetSet(NULL)")) { + query.getConnection().prepareStatement("call initEmptyTargetSet(?, ?)")) { + stmt.setNull(1, VARCHAR); + stmt.setBoolean(2, query.isVersioned()); // generate new targetSet final ResultSet rs = stmt.executeQuery(); if (rs.next()) { diff --git a/src/main/java/caosdb/server/query/Query.java b/src/main/java/org/caosdb/server/query/Query.java similarity index 82% rename from src/main/java/caosdb/server/query/Query.java rename to src/main/java/org/caosdb/server/query/Query.java index 1f85826967cf5020cdbdb6ecbbfe4e9452b9d929..695a295da5f64ec788c4dfbb3332734ead44b289 100644 --- a/src/main/java/caosdb/server/query/Query.java +++ b/src/main/java/org/caosdb/server/query/Query.java @@ -20,31 +20,10 @@ * * ** end header */ -package caosdb.server.query; - -import static caosdb.server.database.DatabaseUtils.bytes2UTF8; - -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.implementation.MySQL.ConnectionException; -import caosdb.server.database.backend.implementation.MySQL.MySQLHelper; -import caosdb.server.database.backend.transaction.RetrieveSparseEntity; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.misc.DBHelper; -import caosdb.server.database.misc.TransactionBenchmark; -import caosdb.server.entity.Entity; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.Message; -import caosdb.server.entity.Message.MessageType; -import caosdb.server.entity.RetrieveEntity; -import caosdb.server.entity.container.TransactionContainer; -import caosdb.server.entity.xml.ToElementable; -import caosdb.server.permissions.EntityACL; -import caosdb.server.permissions.EntityPermission; -import caosdb.server.query.CQLParser.CqContext; -import caosdb.server.query.CQLParsingErrorListener.ParsingError; -import caosdb.server.transaction.TransactionInterface; +package org.caosdb.server.query; + +import static org.caosdb.server.database.DatabaseUtils.bytes2UTF8; + import java.sql.CallableStatement; import java.sql.Connection; import java.sql.PreparedStatement; @@ -62,22 +41,45 @@ import java.util.Map.Entry; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.apache.shiro.subject.Subject; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.ServerProperties; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.implementation.MySQL.ConnectionException; +import org.caosdb.server.database.backend.implementation.MySQL.MySQLHelper; +import org.caosdb.server.database.backend.transaction.RetrieveSparseEntity; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.misc.DBHelper; +import org.caosdb.server.database.misc.TransactionBenchmark; +import org.caosdb.server.entity.Entity; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Message; +import org.caosdb.server.entity.Message.MessageType; +import org.caosdb.server.entity.RetrieveEntity; +import org.caosdb.server.entity.container.TransactionContainer; +import org.caosdb.server.entity.xml.ToElementable; +import org.caosdb.server.permissions.EntityACL; +import org.caosdb.server.permissions.EntityPermission; +import org.caosdb.server.query.CQLParser.CqContext; +import org.caosdb.server.query.CQLParsingErrorListener.ParsingError; +import org.caosdb.server.transaction.TransactionInterface; import org.jdom2.Element; public class Query implements QueryInterface, ToElementable, TransactionInterface { + /** Class which represents the selection of (sub)properties. */ public static class Selection { private final String selector; private Selection subselection = null; public Selection setSubSelection(final Selection sub) { if (this.subselection != null) { - throw new UnsupportedOperationException("subselection is immutble!"); + throw new UnsupportedOperationException("SubSelection is immutable!"); } this.subselection = sub; return this; } + /** No parsing, just sets the selector string. */ public Selection(final String selector) { this.selector = selector.trim(); } @@ -151,12 +153,12 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac } /** */ - private static final long serialVersionUID = 8984839198803429114L; + private static final long serialVersionUID = -7142620266283649346L; } public static class QueryException extends RuntimeException { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = -7142620266283649346L; public QueryException(final String string) { super(string); @@ -167,12 +169,22 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac } } + public static class IdVersionPair { + public IdVersionPair(Integer id, String version) { + this.id = id; + this.version = version; + } + + public Integer id; + public String version; + } + private static boolean filterEntitiesWithoutRetrievePermisions = !CaosDBServer.getServerProperty( ServerProperties.KEY_QUERY_FILTER_ENTITIES_WITHOUT_RETRIEVE_PERMISSIONS) .equalsIgnoreCase("FALSE"); - List<Integer> resultSet = null; + List<IdVersionPair> resultSet = null; private final String query; private Pattern entity = null; private Role role = null; @@ -187,6 +199,7 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac private Type type = null; private final ArrayList<ToElementable> messages = new ArrayList<>(); private Access access; + private boolean versioned = false; public Type getType() { return this.type; @@ -214,7 +227,7 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac */ private void initResultSetWithNameIDAndChildren() throws SQLException { final CallableStatement callInitEntity = - getConnection().prepareCall("call initEntity(?,?,?,?,?)"); + getConnection().prepareCall("call initEntity(?,?,?,?,?,?)"); try { callInitEntity.setInt(1, Integer.parseInt(this.entity.toString())); @@ -241,6 +254,7 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac break; } callInitEntity.setString(5, this.sourceSet); + callInitEntity.setBoolean(6, this.versioned); callInitEntity.execute(); callInitEntity.close(); } @@ -258,8 +272,8 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac applyQueryTemplates(this, getSourceSet()); } - if (this.role != null) { - final RoleFilter roleFilter = new RoleFilter(this.role, "="); + if (this.role != null && this.role != Role.ENTITY) { + final RoleFilter roleFilter = new RoleFilter(this.role, "=", this.versioned); roleFilter.apply(this); } @@ -299,7 +313,7 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac // ... check for RETRIEVE:ENTITY permission... final EntityInterface e = - execute(new RetrieveSparseEntity(q.getKey()), query.getAccess()).getEntity(); + execute(new RetrieveSparseEntity(q.getKey(), null), query.getAccess()).getEntity(); final EntityACL entityACL = e.getEntityACL(); if (!entityACL.isPermitted(query.getUser(), EntityPermission.RETRIEVE_ENTITY)) { // ... and ignore if not. @@ -310,7 +324,9 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac final Query subQuery = new Query(q.getValue(), query.getUser()); subQuery.setAccess(query.getAccess()); subQuery.parse(); - final String subResultSet = subQuery.executeStrategy(); + + // versioning for QueryTemplates is not supported and probably never will. + final String subResultSet = subQuery.executeStrategy(false); // ... and merge the resultSets. union(query, resultSet, subResultSet); @@ -382,7 +398,7 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac // filter by role if (this.role != null && this.role != Role.ENTITY) { - final RoleFilter roleFilter = new RoleFilter(this.role, "="); + final RoleFilter roleFilter = new RoleFilter(this.role, "=", this.versioned); roleFilter.apply(this); } @@ -400,8 +416,9 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac } } - private String initQuery() throws QueryException { - try (final CallableStatement callInitQuery = getConnection().prepareCall("call initQuery()")) { + private String initQuery(boolean versioned) throws QueryException { + String sql = "call initQuery(" + versioned + ")"; + try (final CallableStatement callInitQuery = getConnection().prepareCall(sql)) { ResultSet initQueryResult = null; initQueryResult = callInitQuery.executeQuery(); if (!initQueryResult.next()) { @@ -429,6 +446,7 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac } this.entity = cq.e; + this.versioned = cq.v != VersionFilter.UNVERSIONED; this.role = cq.r; this.parseTree = cq.toStringTree(parser); this.type = cq.t; @@ -440,23 +458,33 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac } } - private String executeStrategy() throws QueryException { + private String executeStrategy(boolean versioned) throws QueryException { if (this.entity != null) { - return sourceStrategy(initQuery()); + return sourceStrategy(initQuery(versioned)); } else { - return targetStrategy(initQuery()); + return targetStrategy(initQuery(versioned)); } } - private LinkedList<Integer> getResultSet(final String resultSetTableName) throws QueryException { + private List<IdVersionPair> getResultSet(final String resultSetTableName, boolean versioned) + throws QueryException { ResultSet finishResultSet = null; try { - final PreparedStatement finish = - getConnection().prepareStatement("Select id from `" + resultSetTableName + "`"); + final String sql = + "Select results.id AS id" + + (versioned ? ", ev.version AS version" : "") + + " from `" + + resultSetTableName + + "` AS results" + + (versioned + ? " JOIN entity_version AS ev ON (results.id = ev.entity_id AND results._iversion = ev._iversion)" + : ""); + final PreparedStatement finish = getConnection().prepareStatement(sql); finishResultSet = finish.executeQuery(); - final LinkedList<Integer> rs = new LinkedList<Integer>(); + final List<IdVersionPair> rs = new LinkedList<>(); while (finishResultSet.next()) { - rs.add(finishResultSet.getInt("id")); + final String version = versioned ? finishResultSet.getString("version") : null; + rs.add(new IdVersionPair(finishResultSet.getInt("id"), version)); } return rs; } catch (final SQLException e) { @@ -478,15 +506,15 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac try { - this.resultSet = getResultSet(executeStrategy()); + this.resultSet = getResultSet(executeStrategy(this.versioned), this.versioned); filterEntitiesWithoutRetrievePermission(this.resultSet); // Fill resulting entities into container if (this.container != null && this.type == Type.FIND) { - for (final int id : this.resultSet) { + for (final IdVersionPair p : this.resultSet) { - final Entity e = new RetrieveEntity(id); + final Entity e = new RetrieveEntity(p.id, p.version); // if query has select-clause: if (this.selections != null && !this.selections.isEmpty()) { @@ -553,7 +581,7 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac while (rs.next()) { final long t1 = System.currentTimeMillis(); final Integer id = rs.getInt("id"); - if (!execute(new RetrieveSparseEntity(id), query.getAccess()) + if (!execute(new RetrieveSparseEntity(id, null), query.getAccess()) .getEntity() .getEntityACL() .isPermitted(query.getUser(), EntityPermission.RETRIEVE_ENTITY)) { @@ -577,16 +605,16 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac * @param entities * @throws TransactionException */ - private void filterEntitiesWithoutRetrievePermission(final List<Integer> entities) + private void filterEntitiesWithoutRetrievePermission(final List<IdVersionPair> entities) throws TransactionException { if (!filterEntitiesWithoutRetrievePermisions) { return; } - final Iterator<Integer> iterator = entities.iterator(); + final Iterator<IdVersionPair> iterator = entities.iterator(); while (iterator.hasNext()) { final long t1 = System.currentTimeMillis(); - final Integer id = iterator.next(); - if (!execute(new RetrieveSparseEntity(id), getAccess()) + final IdVersionPair next = iterator.next(); + if (!execute(new RetrieveSparseEntity(next.id, next.version), getAccess()) .getEntity() .getEntityACL() .isPermitted(getUser(), EntityPermission.RETRIEVE_ENTITY)) { @@ -602,10 +630,6 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac return this.query; } - public List<Integer> getResultSet() { - return this.resultSet; - } - @Override public String getSourceSet() { return this.sourceSet; @@ -740,4 +764,9 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac } return benchmark; } + + @Override + public boolean isVersioned() { + return this.versioned; + } } diff --git a/src/main/java/caosdb/server/query/QueryInterface.java b/src/main/java/org/caosdb/server/query/QueryInterface.java similarity index 91% rename from src/main/java/caosdb/server/query/QueryInterface.java rename to src/main/java/org/caosdb/server/query/QueryInterface.java index d42243ba2de45e7d369b733f6d1fbe26bce45fbd..0f2db9a97094ddc26062a9c9922907c183a26413 100644 --- a/src/main/java/caosdb/server/query/QueryInterface.java +++ b/src/main/java/org/caosdb/server/query/QueryInterface.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.query; +package org.caosdb.server.query; -import caosdb.server.database.access.Access; import java.sql.Connection; import org.apache.shiro.subject.Subject; +import org.caosdb.server.database.access.Access; public interface QueryInterface { @@ -43,4 +43,6 @@ public interface QueryInterface { public Subject getUser(); public void addBenchmark(final String str, final long time); + + public boolean isVersioned(); } diff --git a/src/main/java/caosdb/server/query/RoleFilter.java b/src/main/java/org/caosdb/server/query/RoleFilter.java similarity index 74% rename from src/main/java/caosdb/server/query/RoleFilter.java rename to src/main/java/org/caosdb/server/query/RoleFilter.java index 97f73114a4bba08829046c81d77f964aee3ecaa9..48c8372014c6e702be8b88113102da030dbc6046 100644 --- a/src/main/java/caosdb/server/query/RoleFilter.java +++ b/src/main/java/org/caosdb/server/query/RoleFilter.java @@ -20,19 +20,20 @@ * * ** end header */ -package caosdb.server.query; +package org.caosdb.server.query; -import caosdb.server.query.Query.QueryException; -import caosdb.server.query.Query.Role; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; +import org.caosdb.server.query.Query.QueryException; +import org.caosdb.server.query.Query.Role; import org.jdom2.Element; public class RoleFilter implements EntityFilterInterface { private final Role role; private final String operator; + private boolean versioned; /** * Guarantees that all entities in the result set do have ("=") or do not have ("!=") the role in @@ -43,7 +44,8 @@ public class RoleFilter implements EntityFilterInterface { * @throws NullPointerException If role or operator is null. * @throws IllegalArgumentException If operator is not "=" or "!=". */ - public RoleFilter(final Role role, final String operator) { + public RoleFilter(final Role role, final String operator, final boolean versioned) { + this.versioned = versioned; if (role == null) { throw new NullPointerException("The role must not be null."); } @@ -72,7 +74,8 @@ public class RoleFilter implements EntityFilterInterface { getOperator(), getRole(), query.getSourceSet(), - query.getTargetSet()); + query.getTargetSet(), + this.versioned); } } catch (final SQLException e) { throw new QueryException(e); @@ -85,20 +88,28 @@ public class RoleFilter implements EntityFilterInterface { final String operator, final String role, final String sourceSet, - final String targetSet) + final String targetSet, + final boolean versioned) throws SQLException { - final PreparedStatement filterRoleStmt = - connection.prepareCall( - "INSERT IGNORE INTO `" - + targetSet - + "` (id) SELECT id FROM `" - + sourceSet - + (sourceSet.equals("entities") - ? "` AS s WHERE EXISTS (SELECT * FROM entities AS e WHERE e.id=s.id AND e.role" - : "` AS e WHERE NOT (e.role") - + operator - + "?);"); - filterRoleStmt.setString(1, role); + if (!sourceSet.equals("entities")) { + throw new UnsupportedOperationException("SourceSet is supposed to be the `entities` table."); + } + final String sql = + ("INSERT IGNORE INTO `" + + targetSet + + (versioned + ? "` (id, _iversion) SELECT e.id, _get_head_iversion(e.id) FROM `entities` AS e WHERE e.role " + + operator + + " ? UNION SELECT a.id, a._iversion FROM `archive_entities` AS a WHERE a.role" + + operator + + "?" + : "` (id) SELECT e.id FROM `entities` AS e WHERE e.role" + operator + "?")); + final PreparedStatement filterRoleStmt = connection.prepareCall(sql); + int params = (versioned ? 2 : 1); + while (params > 0) { + filterRoleStmt.setString(params, role); + params--; + } filterRoleStmt.execute(); } @@ -109,7 +120,7 @@ public class RoleFilter implements EntityFilterInterface { connection.prepareCall( "DELETE FROM `" + sourceSet - + "` WHERE EXISTS (SELECT * FROM entities AS e WHERE e.id=`" + + "` WHERE EXISTS (SELECT 1 FROM entities AS e WHERE e.id=`" + sourceSet + "`.id AND NOT e.role" + operator diff --git a/src/main/java/caosdb/server/query/StoredAt.java b/src/main/java/org/caosdb/server/query/StoredAt.java similarity index 98% rename from src/main/java/caosdb/server/query/StoredAt.java rename to src/main/java/org/caosdb/server/query/StoredAt.java index b16bb83f2f95c4da1f86292a7d0f17e73f8150d4..84a12d2c6b5b7ca3c3b0644eef4ea72a200cc328 100644 --- a/src/main/java/caosdb/server/query/StoredAt.java +++ b/src/main/java/org/caosdb/server/query/StoredAt.java @@ -20,17 +20,17 @@ * * ** end header */ -package caosdb.server.query; +package org.caosdb.server.query; import static java.sql.Types.VARCHAR; -import caosdb.server.query.Query.QueryException; import java.nio.file.Path; import java.nio.file.Paths; import java.sql.CallableStatement; import java.sql.SQLException; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.caosdb.server.query.Query.QueryException; import org.jdom2.Element; public class StoredAt implements EntityFilterInterface { diff --git a/src/main/java/caosdb/server/query/SubProperty.java b/src/main/java/org/caosdb/server/query/SubProperty.java similarity index 91% rename from src/main/java/caosdb/server/query/SubProperty.java rename to src/main/java/org/caosdb/server/query/SubProperty.java index 12629640ec4e7780c1b1d5933e7d6e1711f635f7..4668935e56f0057d3d0fe927aa0a729669e7e0f6 100644 --- a/src/main/java/caosdb/server/query/SubProperty.java +++ b/src/main/java/org/caosdb/server/query/SubProperty.java @@ -20,18 +20,18 @@ * * ** end header */ -package caosdb.server.query; +package org.caosdb.server.query; -import static caosdb.server.database.DatabaseUtils.bytes2UTF8; import static java.sql.Types.VARCHAR; +import static org.caosdb.server.database.DatabaseUtils.bytes2UTF8; -import caosdb.server.database.access.Access; -import caosdb.server.query.Query.QueryException; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import org.apache.shiro.subject.Subject; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.query.Query.QueryException; import org.jdom2.Element; public class SubProperty implements QueryInterface, EntityFilterInterface { @@ -90,18 +90,15 @@ public class SubProperty implements QueryInterface, EntityFilterInterface { getQuery().filterEntitiesWithoutRetrievePermission(this, this.sourceSet); final CallableStatement callFinishSubProperty = - getConnection().prepareCall("call finishSubProperty(?,?,?)"); - callFinishSubProperty.setString(1, query.getSourceSet()); // sourceSet - // of - // parent - // query + getConnection().prepareCall("call finishSubProperty(?,?,?,?)"); + callFinishSubProperty.setString(1, query.getSourceSet()); // sourceSet of parent query if (query.getTargetSet() != null) { // targetSet callFinishSubProperty.setString(2, query.getTargetSet()); } else { callFinishSubProperty.setNull(2, VARCHAR); } - callFinishSubProperty.setString(3, this.sourceSet); // sub query - // sourceSet + callFinishSubProperty.setString(3, this.sourceSet); // sub query sourceSet + callFinishSubProperty.setBoolean(4, this.isVersioned()); callFinishSubProperty.execute(); callFinishSubProperty.close(); } else { @@ -165,4 +162,9 @@ public class SubProperty implements QueryInterface, EntityFilterInterface { public void addBenchmark(final String str, final long time) { this.query.addBenchmark(this.getClass().getSimpleName() + "." + str, time); } + + @Override + public boolean isVersioned() { + return this.query.isVersioned(); + } } diff --git a/src/main/java/caosdb/server/query/TransactionFilter.java b/src/main/java/org/caosdb/server/query/TransactionFilter.java similarity index 95% rename from src/main/java/caosdb/server/query/TransactionFilter.java rename to src/main/java/org/caosdb/server/query/TransactionFilter.java index 3f4af80ee8eb2f484f23d1ace2f8f1a24e7909d6..55176594f5d17fdb726b82f37e5d3eb83944e611 100644 --- a/src/main/java/caosdb/server/query/TransactionFilter.java +++ b/src/main/java/org/caosdb/server/query/TransactionFilter.java @@ -20,20 +20,20 @@ * * ** end header */ -package caosdb.server.query; - -import caosdb.datetime.Date; -import caosdb.datetime.DateTimeFactory2; -import caosdb.datetime.Interval; -import caosdb.datetime.SemiCompleteDateTime; -import caosdb.datetime.UTCDateTime; -import caosdb.server.accessControl.Principal; -import caosdb.server.accessControl.UserSources; -import caosdb.server.query.Query.QueryException; +package org.caosdb.server.query; + import java.sql.CallableStatement; import java.sql.Connection; import java.sql.SQLException; import java.sql.Types; +import org.caosdb.datetime.Date; +import org.caosdb.datetime.DateTimeFactory2; +import org.caosdb.datetime.Interval; +import org.caosdb.datetime.SemiCompleteDateTime; +import org.caosdb.datetime.UTCDateTime; +import org.caosdb.server.accessControl.Principal; +import org.caosdb.server.accessControl.UserSources; +import org.caosdb.server.query.Query.QueryException; import org.jdom2.Element; public class TransactionFilter implements EntityFilterInterface { diff --git a/src/main/java/caosdb/server/query/Utils.java b/src/main/java/org/caosdb/server/query/Utils.java similarity index 98% rename from src/main/java/caosdb/server/query/Utils.java rename to src/main/java/org/caosdb/server/query/Utils.java index 5c1c74345f989958053ca069dd4d206a3429e5d2..661cee12585d8f4b07ca3a9fea364943aa1d9c6b 100644 --- a/src/main/java/caosdb/server/query/Utils.java +++ b/src/main/java/org/caosdb/server/query/Utils.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.query; +package org.caosdb.server.query; import java.io.PrintStream; import java.sql.Connection; diff --git a/src/main/java/org/caosdb/server/query/VersionFilter.java b/src/main/java/org/caosdb/server/query/VersionFilter.java new file mode 100644 index 0000000000000000000000000000000000000000..aa391778ce20c089a9fa6dae88caf77e0f797703 --- /dev/null +++ b/src/main/java/org/caosdb/server/query/VersionFilter.java @@ -0,0 +1,7 @@ +package org.caosdb.server.query; + +public class VersionFilter { + + public static final VersionFilter ANY_VERSION = new VersionFilter(); + public static final VersionFilter UNVERSIONED = new VersionFilter(); +} diff --git a/src/main/java/caosdb/server/resource/AbstractCaosDBServerResource.java b/src/main/java/org/caosdb/server/resource/AbstractCaosDBServerResource.java similarity index 85% rename from src/main/java/caosdb/server/resource/AbstractCaosDBServerResource.java rename to src/main/java/org/caosdb/server/resource/AbstractCaosDBServerResource.java index ea4e65f0a60d72cb5da6cb03b2cec44848dbc3c6..c7ecd4deb76117474adc188c3f8a7d0f6064a3b8 100644 --- a/src/main/java/caosdb/server/resource/AbstractCaosDBServerResource.java +++ b/src/main/java/org/caosdb/server/resource/AbstractCaosDBServerResource.java @@ -4,7 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * Copyright (C) 2019 IndiScale GmbH + * Copyright (C) 2019,2020 IndiScale GmbH <info@indiscale.com> + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -21,25 +22,15 @@ * * ** end header */ -package caosdb.server.resource; +package org.caosdb.server.resource; -import static caosdb.server.utils.Utils.isNonNullInteger; import static java.net.URLDecoder.decode; -import caosdb.server.CaosDBException; -import caosdb.server.accessControl.AuthenticationUtils; -import caosdb.server.accessControl.Principal; -import caosdb.server.accessControl.UserSources; -import caosdb.server.database.backend.implementation.MySQL.ConnectionException; -import caosdb.server.entity.Message; -import caosdb.server.utils.ServerMessages; -import caosdb.server.utils.WebinterfaceUtils; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.security.NoSuchAlgorithmException; import java.sql.SQLException; -import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.LinkedList; @@ -50,6 +41,13 @@ import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authz.AuthorizationException; import org.apache.shiro.subject.Subject; +import org.caosdb.server.CaosDBException; +import org.caosdb.server.accessControl.AuthenticationUtils; +import org.caosdb.server.accessControl.Principal; +import org.caosdb.server.database.backend.implementation.MySQL.ConnectionException; +import org.caosdb.server.entity.Message; +import org.caosdb.server.utils.ServerMessages; +import org.caosdb.server.utils.WebinterfaceUtils; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.JDOMException; @@ -78,9 +76,7 @@ public abstract class AbstractCaosDBServerResource extends ServerResource { private static final XMLParser xmlparser = new XMLParser(); protected String sRID = null; // Server side request ID private String cRID = null; // Client side request ID - private String[] requestedItems = null; - private ArrayList<Integer> requestedIDs = new ArrayList<Integer>(); - private ArrayList<String> requestedNames = new ArrayList<String>(); + private String[] requestedItems = {}; private WebinterfaceUtils utils; /** Return the {@link WebinterfaceUtils} instance for this resource. */ @@ -89,7 +85,7 @@ public abstract class AbstractCaosDBServerResource extends ServerResource { } public static class xmlNotWellFormedException extends Exception { - private static final long serialVersionUID = -6836378704013776849L; + private static final long serialVersionUID = 1716868119917270990L; } /** @@ -142,21 +138,6 @@ public abstract class AbstractCaosDBServerResource extends ServerResource { } this.requestedItems = specifier.split("&"); - for (final String requestedItem : this.requestedItems) { - if (isNonNullInteger(requestedItem)) { - final int id = Integer.parseInt(requestedItem); - if (id > 0) { - getRequestedIDs().add(id); - } - } else if (requestedItem.equalsIgnoreCase("all")) { - getRequestedNames().clear(); - getRequestedIDs().clear(); - getRequestedNames().add("all"); - break; - } else { - getRequestedNames().add(requestedItem); - } - } } // flags @@ -210,13 +191,11 @@ public abstract class AbstractCaosDBServerResource extends ServerResource { if (user != null && user.isAuthenticated()) { Element userInfo = new Element("UserInfo"); - if (!user.getPrincipal().equals(AuthenticationUtils.ANONYMOUS_USER.getPrincipal())) { - // TODO: deprecated - addNameAndRealm(retRoot, user); + // TODO: deprecated, needs refactoring in the webui first + addNameAndRealm(retRoot, user); - // this is the new, correct way - addNameAndRealm(userInfo, user); - } + // this is the new, correct way + addNameAndRealm(userInfo, user); addRoles(userInfo, user); retRoot.addContent(userInfo); @@ -231,7 +210,7 @@ public abstract class AbstractCaosDBServerResource extends ServerResource { * @param user */ private void addRoles(Element userInfo, Subject user) { - Collection<String> roles = UserSources.resolve(user.getPrincipals()); + Collection<String> roles = AuthenticationUtils.getRoles(user); if (roles == null) return; Element rs = new Element("Roles"); for (String role : roles) { @@ -248,8 +227,10 @@ public abstract class AbstractCaosDBServerResource extends ServerResource { * @param userInfo */ private void addNameAndRealm(Element userInfo, Subject user) { - userInfo.setAttribute("username", ((Principal) user.getPrincipal()).getUsername()); - userInfo.setAttribute("realm", ((Principal) user.getPrincipal()).getRealm()); + if (!AuthenticationUtils.isAnonymous((Principal) user.getPrincipal())) { + userInfo.setAttribute("username", ((Principal) user.getPrincipal()).getUsername()); + userInfo.setAttribute("realm", ((Principal) user.getPrincipal()).getRealm()); + } } @Get @@ -409,11 +390,9 @@ public abstract class AbstractCaosDBServerResource extends ServerResource { getRequest().getAttributes().put("THROWN", t); throw t; } catch (final AuthenticationException e) { - getResponse().setStatus(Status.CLIENT_ERROR_FORBIDDEN); - return null; + return error(ServerMessages.UNAUTHENTICATED, Status.CLIENT_ERROR_UNAUTHORIZED); } catch (final AuthorizationException e) { - getResponse().setStatus(Status.CLIENT_ERROR_FORBIDDEN); - return null; + return error(ServerMessages.AUTHORIZATION_ERROR, Status.CLIENT_ERROR_FORBIDDEN); } catch (final Message m) { return error(m, Status.CLIENT_ERROR_BAD_REQUEST); } catch (final FileUploadException e) { @@ -430,16 +409,8 @@ public abstract class AbstractCaosDBServerResource extends ServerResource { } } - public ArrayList<Integer> getRequestedIDs() { - return this.requestedIDs; - } - - public ArrayList<String> getRequestedNames() { - return this.requestedNames; - } - - public void setRequestedNames(final ArrayList<String> requestedNames) { - this.requestedNames = requestedNames; + public String[] getRequestedItems() { + return this.requestedItems; } public HashMap<String, String> getFlags() { diff --git a/src/main/java/caosdb/server/resource/AuthenticationResource.java b/src/main/java/org/caosdb/server/resource/AuthenticationResource.java similarity index 90% rename from src/main/java/caosdb/server/resource/AuthenticationResource.java rename to src/main/java/org/caosdb/server/resource/AuthenticationResource.java index d3b49580cf1a86347398ef7d36f6021f710e7da3..ed60d7906b1cda003ed2a84f0e22200049d96c25 100644 --- a/src/main/java/caosdb/server/resource/AuthenticationResource.java +++ b/src/main/java/org/caosdb/server/resource/AuthenticationResource.java @@ -20,16 +20,8 @@ * * ** end header */ -package caosdb.server.resource; - -import caosdb.server.CaosDBException; -import caosdb.server.CaosDBServer; -import caosdb.server.accessControl.AuthenticationUtils; -import caosdb.server.accessControl.RealmUsernamePasswordToken; -import caosdb.server.accessControl.UserSources; -import caosdb.server.database.backend.implementation.MySQL.ConnectionException; -import caosdb.server.entity.xml.ToElementable; -import caosdb.server.utils.ServerMessages; +package org.caosdb.server.resource; + import java.io.IOException; import java.security.NoSuchAlgorithmException; import java.sql.SQLException; @@ -39,6 +31,14 @@ import org.apache.shiro.authc.AccountException; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.CredentialsException; import org.apache.shiro.subject.Subject; +import org.caosdb.server.CaosDBException; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.accessControl.AuthenticationUtils; +import org.caosdb.server.accessControl.RealmUsernamePasswordToken; +import org.caosdb.server.accessControl.UserSources; +import org.caosdb.server.database.backend.implementation.MySQL.ConnectionException; +import org.caosdb.server.entity.xml.ToElementable; +import org.caosdb.server.utils.ServerMessages; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.JDOMException; diff --git a/src/main/java/caosdb/server/resource/DefaultResource.java b/src/main/java/org/caosdb/server/resource/DefaultResource.java similarity index 91% rename from src/main/java/caosdb/server/resource/DefaultResource.java rename to src/main/java/org/caosdb/server/resource/DefaultResource.java index e26171f04fa24cea607288c2ee37ba713d47234f..488cd667c8832e4b90277e07144c65cbb7e4036d 100644 --- a/src/main/java/caosdb/server/resource/DefaultResource.java +++ b/src/main/java/org/caosdb/server/resource/DefaultResource.java @@ -20,13 +20,13 @@ * * ** end header */ -package caosdb.server.resource; +package org.caosdb.server.resource; -import caosdb.server.CaosDBException; -import caosdb.server.database.backend.implementation.MySQL.ConnectionException; import java.io.IOException; import java.security.NoSuchAlgorithmException; import java.sql.SQLException; +import org.caosdb.server.CaosDBException; +import org.caosdb.server.database.backend.implementation.MySQL.ConnectionException; import org.jdom2.Document; import org.jdom2.Element; import org.restlet.representation.Representation; diff --git a/src/main/java/caosdb/server/resource/EntityOwnerResource.java b/src/main/java/org/caosdb/server/resource/EntityOwnerResource.java similarity index 79% rename from src/main/java/caosdb/server/resource/EntityOwnerResource.java rename to src/main/java/org/caosdb/server/resource/EntityOwnerResource.java index 5841eeb541be111720379008c5144ef82c6b9a01..f20a4ab042bd996ef7e7d004e9246935cf034b64 100644 --- a/src/main/java/caosdb/server/resource/EntityOwnerResource.java +++ b/src/main/java/org/caosdb/server/resource/EntityOwnerResource.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.resource; +package org.caosdb.server.resource; -import caosdb.server.entity.container.RetrieveContainer; -import caosdb.server.resource.transaction.EntityResource; -import caosdb.server.resource.transaction.handlers.RequestHandler; -import caosdb.server.resource.transaction.handlers.RetriveOwnerRequestHandler; +import org.caosdb.server.entity.container.RetrieveContainer; +import org.caosdb.server.resource.transaction.EntityResource; +import org.caosdb.server.resource.transaction.handlers.RequestHandler; +import org.caosdb.server.resource.transaction.handlers.RetriveOwnerRequestHandler; public class EntityOwnerResource extends EntityResource { diff --git a/src/main/java/caosdb/server/resource/EntityPermissionsResource.java b/src/main/java/org/caosdb/server/resource/EntityPermissionsResource.java similarity index 78% rename from src/main/java/caosdb/server/resource/EntityPermissionsResource.java rename to src/main/java/org/caosdb/server/resource/EntityPermissionsResource.java index b29d6c5eab1a21e8e86a56fbc3c806c97c426769..ffce6fe18378ec2586276cd69124cfaeaf8f29fc 100644 --- a/src/main/java/caosdb/server/resource/EntityPermissionsResource.java +++ b/src/main/java/org/caosdb/server/resource/EntityPermissionsResource.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.resource; +package org.caosdb.server.resource; -import caosdb.server.entity.container.RetrieveContainer; -import caosdb.server.resource.transaction.EntityResource; -import caosdb.server.resource.transaction.handlers.RequestHandler; -import caosdb.server.resource.transaction.handlers.RetrieveGlobalEntityPermissionsHandler; +import org.caosdb.server.entity.container.RetrieveContainer; +import org.caosdb.server.resource.transaction.EntityResource; +import org.caosdb.server.resource.transaction.handlers.RequestHandler; +import org.caosdb.server.resource.transaction.handlers.RetrieveGlobalEntityPermissionsHandler; public class EntityPermissionsResource extends EntityResource { diff --git a/src/main/java/caosdb/server/resource/FileSystemResource.java b/src/main/java/org/caosdb/server/resource/FileSystemResource.java similarity index 87% rename from src/main/java/caosdb/server/resource/FileSystemResource.java rename to src/main/java/org/caosdb/server/resource/FileSystemResource.java index ecaa97fe93cb59fe6a4c58fb60d99a5dca373080..f09f97eab5fbb1ea49930bc8cae227cb2b5fba05 100644 --- a/src/main/java/caosdb/server/resource/FileSystemResource.java +++ b/src/main/java/org/caosdb/server/resource/FileSystemResource.java @@ -20,27 +20,27 @@ * * ** end header */ -package caosdb.server.resource; +package org.caosdb.server.resource; -import static caosdb.server.FileSystem.getFromFileSystem; import static java.net.URLDecoder.decode; +import static org.caosdb.server.FileSystem.getFromFileSystem; -import caosdb.server.database.backend.implementation.MySQL.ConnectionException; -import caosdb.server.database.exceptions.EntityDoesNotExistException; -import caosdb.server.database.misc.TransactionBenchmark; -import caosdb.server.entity.Entity; -import caosdb.server.entity.FileProperties; -import caosdb.server.entity.Message; -import caosdb.server.entity.Message.MessageType; -import caosdb.server.entity.RetrieveEntity; -import caosdb.server.entity.container.TransactionContainer; -import caosdb.server.permissions.EntityPermission; -import caosdb.server.transaction.RetrieveSparseEntityByPath; -import caosdb.server.transaction.Transaction; -import caosdb.server.utils.FileUtils; -import caosdb.server.utils.ServerMessages; import java.io.File; import java.io.IOException; +import org.caosdb.server.database.backend.implementation.MySQL.ConnectionException; +import org.caosdb.server.database.exceptions.EntityDoesNotExistException; +import org.caosdb.server.database.misc.TransactionBenchmark; +import org.caosdb.server.entity.Entity; +import org.caosdb.server.entity.FileProperties; +import org.caosdb.server.entity.Message; +import org.caosdb.server.entity.Message.MessageType; +import org.caosdb.server.entity.RetrieveEntity; +import org.caosdb.server.entity.container.TransactionContainer; +import org.caosdb.server.permissions.EntityPermission; +import org.caosdb.server.transaction.RetrieveSparseEntityByPath; +import org.caosdb.server.transaction.Transaction; +import org.caosdb.server.utils.FileUtils; +import org.caosdb.server.utils.ServerMessages; import org.jdom2.Attribute; import org.jdom2.Document; import org.jdom2.Element; @@ -135,8 +135,9 @@ public class FileSystemResource extends AbstractCaosDBServerResource { try { getEntity(specifier).checkPermission(EntityPermission.RETRIEVE_FILE); } catch (EntityDoesNotExistException exception) { - // This file in the file system has no corresponding File record. - return error(ServerMessages.NOT_PERMITTED, Status.CLIENT_ERROR_FORBIDDEN); + // This file in the file system has no corresponding File record. It + // shall not be retrieved by anyone. + return error(ServerMessages.AUTHORIZATION_ERROR, Status.CLIENT_ERROR_FORBIDDEN); } final MediaType mt = MediaType.valueOf(FileUtils.getMimeType(file)); diff --git a/src/main/java/caosdb/server/resource/InfoResource.java b/src/main/java/org/caosdb/server/resource/InfoResource.java similarity index 88% rename from src/main/java/caosdb/server/resource/InfoResource.java rename to src/main/java/org/caosdb/server/resource/InfoResource.java index 4beb9757cff83696a546eb174fbb0f21453029b7..25e8842b40df2d64c3dd628116ad958eb45bdb11 100644 --- a/src/main/java/caosdb/server/resource/InfoResource.java +++ b/src/main/java/org/caosdb/server/resource/InfoResource.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.resource; +package org.caosdb.server.resource; -import caosdb.datetime.UTCTimeZoneShift; -import caosdb.server.database.backend.implementation.MySQL.ConnectionException; -import caosdb.server.database.misc.TransactionBenchmark; -import caosdb.server.utils.FlagInfo; -import caosdb.server.utils.Info; import java.util.TimeZone; +import org.caosdb.datetime.UTCTimeZoneShift; +import org.caosdb.server.database.backend.implementation.MySQL.ConnectionException; +import org.caosdb.server.database.misc.TransactionBenchmark; +import org.caosdb.server.utils.FlagInfo; +import org.caosdb.server.utils.Info; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.JDOMException; diff --git a/src/main/java/caosdb/server/resource/JdomRepresentation.java b/src/main/java/org/caosdb/server/resource/JdomRepresentation.java similarity index 97% rename from src/main/java/caosdb/server/resource/JdomRepresentation.java rename to src/main/java/org/caosdb/server/resource/JdomRepresentation.java index 04fbdac3fdd13f9e5c4f025cb2364386deac71f0..1af634b0ae784ccaf4aff4aac399771cb4774f60 100644 --- a/src/main/java/caosdb/server/resource/JdomRepresentation.java +++ b/src/main/java/org/caosdb/server/resource/JdomRepresentation.java @@ -20,13 +20,13 @@ * * ** end header */ -package caosdb.server.resource; +package org.caosdb.server.resource; -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; import java.io.IOException; import java.io.OutputStream; import java.io.Writer; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.ServerProperties; import org.jdom2.Document; import org.jdom2.ProcessingInstruction; import org.jdom2.output.Format; diff --git a/src/main/java/caosdb/server/resource/LogoutResource.java b/src/main/java/org/caosdb/server/resource/LogoutResource.java similarity index 89% rename from src/main/java/caosdb/server/resource/LogoutResource.java rename to src/main/java/org/caosdb/server/resource/LogoutResource.java index 79489413d163d38c669f2cb7f04c5d437b2f11c5..1659f751a4710fbf99fc473b586cc3b180c8a62c 100644 --- a/src/main/java/caosdb/server/resource/LogoutResource.java +++ b/src/main/java/org/caosdb/server/resource/LogoutResource.java @@ -20,13 +20,13 @@ * * ** end header */ -package caosdb.server.resource; +package org.caosdb.server.resource; -import caosdb.server.CaosDBException; -import caosdb.server.database.backend.implementation.MySQL.ConnectionException; import java.io.IOException; import java.security.NoSuchAlgorithmException; import java.sql.SQLException; +import org.caosdb.server.CaosDBException; +import org.caosdb.server.database.backend.implementation.MySQL.ConnectionException; import org.restlet.representation.Representation; public class LogoutResource extends AuthenticationResource { diff --git a/src/main/java/caosdb/server/resource/PermissionRulesResource.java b/src/main/java/org/caosdb/server/resource/PermissionRulesResource.java similarity index 83% rename from src/main/java/caosdb/server/resource/PermissionRulesResource.java rename to src/main/java/org/caosdb/server/resource/PermissionRulesResource.java index 1610ba372def0b758b76d15d6d839b825a9d96c6..8d2aa1720aaefcdbaccee18c6a1626a912319b6a 100644 --- a/src/main/java/caosdb/server/resource/PermissionRulesResource.java +++ b/src/main/java/org/caosdb/server/resource/PermissionRulesResource.java @@ -20,20 +20,20 @@ * * ** end header */ -package caosdb.server.resource; +package org.caosdb.server.resource; -import caosdb.server.CaosDBException; -import caosdb.server.accessControl.ACMPermissions; -import caosdb.server.database.backend.implementation.MySQL.ConnectionException; -import caosdb.server.entity.Message; -import caosdb.server.permissions.PermissionRule; -import caosdb.server.transaction.RetrievePermissionRulesTransaction; -import caosdb.server.transaction.UpdatePermissionRulesTransaction; -import caosdb.server.utils.ServerMessages; import java.io.IOException; import java.security.NoSuchAlgorithmException; import java.sql.SQLException; import java.util.HashSet; +import org.caosdb.server.CaosDBException; +import org.caosdb.server.accessControl.ACMPermissions; +import org.caosdb.server.database.backend.implementation.MySQL.ConnectionException; +import org.caosdb.server.entity.Message; +import org.caosdb.server.permissions.PermissionRule; +import org.caosdb.server.transaction.RetrievePermissionRulesTransaction; +import org.caosdb.server.transaction.UpdatePermissionRulesTransaction; +import org.caosdb.server.utils.ServerMessages; import org.jdom2.Document; import org.jdom2.Element; import org.restlet.data.Status; @@ -46,7 +46,7 @@ public class PermissionRulesResource extends AbstractCaosDBServerResource { protected Representation httpGetInChildClass() throws ConnectionException, IOException, SQLException, CaosDBException, NoSuchAlgorithmException, Exception { - final String role = getRequestedNames().get(0); + final String role = getRequestedItems()[0]; getUser().checkPermission(ACMPermissions.PERMISSION_RETRIEVE_ROLE_PERMISSIONS(role)); @@ -73,7 +73,7 @@ public class PermissionRulesResource extends AbstractCaosDBServerResource { public Representation httpPutInChildClass(final Representation entity) throws Exception { final Element root = parseEntity(entity).getRootElement(); - final String role = getRequestedNames().get(0); + final String role = getRequestedItems()[0]; final HashSet<PermissionRule> rules = new HashSet<PermissionRule>(); for (final Element e : root.getChildren()) { diff --git a/src/main/java/caosdb/server/resource/ReReadableRepresentation.java b/src/main/java/org/caosdb/server/resource/ReReadableRepresentation.java similarity index 99% rename from src/main/java/caosdb/server/resource/ReReadableRepresentation.java rename to src/main/java/org/caosdb/server/resource/ReReadableRepresentation.java index df5f7e55b0734877ad6f32dbc553d2a570685a34..3620eef2167073f479c9df63c415e01857db3ea1 100644 --- a/src/main/java/caosdb/server/resource/ReReadableRepresentation.java +++ b/src/main/java/org/caosdb/server/resource/ReReadableRepresentation.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.resource; +package org.caosdb.server.resource; import com.google.common.base.Charsets; import java.io.IOException; diff --git a/src/main/java/caosdb/server/resource/RolesResource.java b/src/main/java/org/caosdb/server/resource/RolesResource.java similarity index 72% rename from src/main/java/caosdb/server/resource/RolesResource.java rename to src/main/java/org/caosdb/server/resource/RolesResource.java index ef9b30f5b831454fac392317e2c57833657c62d6..a89a731950d09a7edbce0a5f67a3e81287c07b2a 100644 --- a/src/main/java/caosdb/server/resource/RolesResource.java +++ b/src/main/java/org/caosdb/server/resource/RolesResource.java @@ -20,21 +20,21 @@ * * ** end header */ -package caosdb.server.resource; - -import caosdb.server.CaosDBException; -import caosdb.server.accessControl.ACMPermissions; -import caosdb.server.accessControl.Role; -import caosdb.server.database.backend.implementation.MySQL.ConnectionException; -import caosdb.server.entity.Message; -import caosdb.server.transaction.DeleteRoleTransaction; -import caosdb.server.transaction.InsertRoleTransaction; -import caosdb.server.transaction.RetrieveRoleTransaction; -import caosdb.server.transaction.UpdateRoleTransaction; -import caosdb.server.utils.ServerMessages; +package org.caosdb.server.resource; + import java.io.IOException; import java.security.NoSuchAlgorithmException; import java.sql.SQLException; +import org.caosdb.server.CaosDBException; +import org.caosdb.server.accessControl.ACMPermissions; +import org.caosdb.server.accessControl.Role; +import org.caosdb.server.database.backend.implementation.MySQL.ConnectionException; +import org.caosdb.server.entity.Message; +import org.caosdb.server.transaction.DeleteRoleTransaction; +import org.caosdb.server.transaction.InsertRoleTransaction; +import org.caosdb.server.transaction.RetrieveRoleTransaction; +import org.caosdb.server.transaction.UpdateRoleTransaction; +import org.caosdb.server.utils.ServerMessages; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.JDOMException; @@ -52,8 +52,8 @@ public class RolesResource extends AbstractCaosDBServerResource { final Element root = generateRootElement(); final Document document = new Document(); - if (!getRequestedNames().isEmpty()) { - final String name = getRequestedNames().get(0); + if (getRequestedItems().length > 0) { + final String name = getRequestedItems()[0]; if (name != null) { getUser().checkPermission(ACMPermissions.PERMISSION_RETRIEVE_ROLE_DESCRIPTION(name)); final RetrieveRoleTransaction t = new RetrieveRoleTransaction(name); @@ -78,8 +78,8 @@ public class RolesResource extends AbstractCaosDBServerResource { protected Representation httpDeleteInChildClass() throws ConnectionException, SQLException, CaosDBException, IOException, NoSuchAlgorithmException, Exception { - if (!getRequestedNames().isEmpty()) { - final String name = getRequestedNames().get(0); + if (getRequestedItems().length > 0) { + final String name = getRequestedItems()[0]; if (name != null) { final DeleteRoleTransaction t = new DeleteRoleTransaction(name); try { @@ -133,26 +133,28 @@ public class RolesResource extends AbstractCaosDBServerResource { protected Representation httpPutInChildClass(final Representation entity) throws ConnectionException, JDOMException, Exception, xmlNotWellFormedException { - final String name = getRequestedNames().get(0); - String description = null; + if (getRequestedItems().length > 0) { + final String name = getRequestedItems()[0]; + String description = null; - final Form f = new Form(entity); - if (!f.isEmpty()) { - description = f.getFirstValue("role_description"); - } + final Form f = new Form(entity); + if (!f.isEmpty()) { + description = f.getFirstValue("role_description"); + } - if (name != null && description != null) { - final Role role = new Role(); - role.name = name; - role.description = description; - final UpdateRoleTransaction t = new UpdateRoleTransaction(role); - try { - t.execute(); - } catch (final Message m) { - if (m == ServerMessages.ROLE_DOES_NOT_EXIST) { - return error(m, Status.CLIENT_ERROR_NOT_FOUND); - } else { - throw m; + if (name != null && description != null) { + final Role role = new Role(); + role.name = name; + role.description = description; + final UpdateRoleTransaction t = new UpdateRoleTransaction(role); + try { + t.execute(); + } catch (final Message m) { + if (m == ServerMessages.ROLE_DOES_NOT_EXIST) { + return error(m, Status.CLIENT_ERROR_NOT_FOUND); + } else { + throw m; + } } } } diff --git a/src/main/java/caosdb/server/resource/ScriptingResource.java b/src/main/java/org/caosdb/server/resource/ScriptingResource.java similarity index 82% rename from src/main/java/caosdb/server/resource/ScriptingResource.java rename to src/main/java/org/caosdb/server/resource/ScriptingResource.java index b23a9593918ead75a6b38216838995e09ac67bc7..35885bb4376b26fc04977389f4dbf1cd7c40decd 100644 --- a/src/main/java/caosdb/server/resource/ScriptingResource.java +++ b/src/main/java/org/caosdb/server/resource/ScriptingResource.java @@ -22,19 +22,8 @@ * ** end header */ -package caosdb.server.resource; - -import caosdb.server.FileSystem; -import caosdb.server.accessControl.Principal; -import caosdb.server.accessControl.SessionToken; -import caosdb.server.accessControl.UserSources; -import caosdb.server.entity.FileProperties; -import caosdb.server.entity.Message; -import caosdb.server.scripting.CallerSerializer; -import caosdb.server.scripting.ServerSideScriptingCaller; -import caosdb.server.utils.Serializer; -import caosdb.server.utils.ServerMessages; -import caosdb.server.utils.Utils; +package org.caosdb.server.resource; + import com.ibm.icu.text.Collator; import java.io.IOException; import java.security.NoSuchAlgorithmException; @@ -48,6 +37,19 @@ import org.apache.commons.fileupload.FileItemIterator; import org.apache.commons.fileupload.FileItemStream; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.shiro.subject.Subject; +import org.caosdb.server.FileSystem; +import org.caosdb.server.accessControl.AuthenticationUtils; +import org.caosdb.server.accessControl.OneTimeAuthenticationToken; +import org.caosdb.server.accessControl.SessionToken; +import org.caosdb.server.entity.FileProperties; +import org.caosdb.server.entity.Message; +import org.caosdb.server.scripting.CallerSerializer; +import org.caosdb.server.scripting.ScriptingPermissions; +import org.caosdb.server.scripting.ServerSideScriptingCaller; +import org.caosdb.server.utils.Serializer; +import org.caosdb.server.utils.ServerMessages; +import org.caosdb.server.utils.Utils; import org.jdom2.Element; import org.restlet.data.CharacterSet; import org.restlet.data.Form; @@ -83,9 +85,6 @@ public class ScriptingResource extends AbstractCaosDBServerResource { @Override protected Representation httpPostInChildClass(Representation entity) throws Exception { - if (isAnonymous()) { - return error(ServerMessages.AUTHORIZATION_ERROR, Status.CLIENT_ERROR_FORBIDDEN); - } MediaType mediaType = entity.getMediaType(); try { if (mediaType.equals(MediaType.MULTIPART_FORM_DATA, true)) { @@ -193,28 +192,42 @@ public class ScriptingResource extends AbstractCaosDBServerResource { public int callScript(Form form, List<FileProperties> files) throws Message { List<String> commandLine = form2CommandLine(form); + String call = commandLine.get(0); + + checkExecutionPermission(getUser(), call); Integer timeoutMs = Integer.valueOf(form.getFirstValue("timeout", "-1")); return callScript(commandLine, timeoutMs, files); } public int callScript(List<String> commandLine, Integer timeoutMs, List<FileProperties> files) throws Message { - return callScript(commandLine, timeoutMs, files, generateAuthToken()); + return callScript(commandLine, timeoutMs, files, generateAuthToken(commandLine.get(0))); + } + + public boolean isAnonymous() { + return AuthenticationUtils.isAnonymous(getUser()); } - public Object generateAuthToken() { - return SessionToken.generate((Principal) getUser().getPrincipal(), null); + /** + * Generate and return a token for the purpose of the given call. If the user is not anonymous and + * the call is not configured to be called by everyone, a SessionToken is returned instead. + */ + public Object generateAuthToken(String call) { + String purpose = "SCRIPTING:EXECUTE:" + call; + Object authtoken = OneTimeAuthenticationToken.generateForPurpose(purpose, getUser()); + if (authtoken != null || isAnonymous()) { + return authtoken; + } + return SessionToken.generate(getUser()); } - boolean isAnonymous() { - boolean ret = getUser().hasRole(UserSources.ANONYMOUS_ROLE); - return ret; + public void checkExecutionPermission(Subject user, String call) { + user.checkPermission(ScriptingPermissions.PERMISSION_EXECUTION(call)); } public int callScript( List<String> commandLine, Integer timeoutMs, List<FileProperties> files, Object authToken) throws Message { - // TODO getUser().checkPermission("SCRIPTING:EXECUTE:" + commandLine.get(0)); caller = new ServerSideScriptingCaller( commandLine.toArray(new String[commandLine.size()]), timeoutMs, files, authToken); diff --git a/src/main/java/caosdb/server/resource/ServerLogsResource.java b/src/main/java/org/caosdb/server/resource/ServerLogsResource.java similarity index 91% rename from src/main/java/caosdb/server/resource/ServerLogsResource.java rename to src/main/java/org/caosdb/server/resource/ServerLogsResource.java index b63de6e0f7fd0d95dd315db47fe6a6c88833f648..f304f10062209d62855a0bff21e0c8cad54e1962 100644 --- a/src/main/java/caosdb/server/resource/ServerLogsResource.java +++ b/src/main/java/org/caosdb/server/resource/ServerLogsResource.java @@ -20,11 +20,8 @@ * * ** end header */ -package caosdb.server.resource; +package org.caosdb.server.resource; -import caosdb.server.CaosDBException; -import caosdb.server.database.backend.implementation.MySQL.ConnectionException; -import caosdb.server.transaction.RetrieveLogRecordTransaction; import java.io.IOException; import java.security.NoSuchAlgorithmException; import java.sql.SQLException; @@ -32,6 +29,9 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.XMLFormatter; +import org.caosdb.server.CaosDBException; +import org.caosdb.server.database.backend.implementation.MySQL.ConnectionException; +import org.caosdb.server.transaction.RetrieveLogRecordTransaction; import org.restlet.data.Form; import org.restlet.data.MediaType; import org.restlet.representation.Representation; diff --git a/src/main/java/caosdb/server/resource/ServerPropertiesResource.java b/src/main/java/org/caosdb/server/resource/ServerPropertiesResource.java similarity index 87% rename from src/main/java/caosdb/server/resource/ServerPropertiesResource.java rename to src/main/java/org/caosdb/server/resource/ServerPropertiesResource.java index 347919d9c7d0f604734790f2ea09b5e2bac54042..5b4e83162ab2e2a701a8497eeb85225def94cff1 100644 --- a/src/main/java/caosdb/server/resource/ServerPropertiesResource.java +++ b/src/main/java/org/caosdb/server/resource/ServerPropertiesResource.java @@ -1,8 +1,8 @@ -package caosdb.server.resource; +package org.caosdb.server.resource; -import caosdb.server.CaosDBServer; -import caosdb.server.ServerPropertiesSerializer; -import caosdb.server.accessControl.ACMPermissions; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.ServerPropertiesSerializer; +import org.caosdb.server.accessControl.ACMPermissions; import org.restlet.data.Form; import org.restlet.data.Parameter; import org.restlet.data.Status; diff --git a/src/main/java/caosdb/server/resource/SharedFileResource.java b/src/main/java/org/caosdb/server/resource/SharedFileResource.java similarity index 92% rename from src/main/java/caosdb/server/resource/SharedFileResource.java rename to src/main/java/org/caosdb/server/resource/SharedFileResource.java index 71cf089ddc4246196b8299502b1f15969183f372..971dff6901e771cce13dac87d1d0a1ac30dde83e 100644 --- a/src/main/java/caosdb/server/resource/SharedFileResource.java +++ b/src/main/java/org/caosdb/server/resource/SharedFileResource.java @@ -22,16 +22,16 @@ * ** end header */ -package caosdb.server.resource; +package org.caosdb.server.resource; import static java.net.URLDecoder.decode; -import caosdb.server.FileSystem; -import caosdb.server.database.backend.implementation.MySQL.ConnectionException; -import caosdb.server.utils.FileUtils; -import caosdb.server.utils.ServerMessages; import java.io.File; import java.io.IOException; +import org.caosdb.server.FileSystem; +import org.caosdb.server.database.backend.implementation.MySQL.ConnectionException; +import org.caosdb.server.utils.FileUtils; +import org.caosdb.server.utils.ServerMessages; import org.jdom2.JDOMException; import org.restlet.data.Disposition; import org.restlet.data.MediaType; diff --git a/src/main/java/caosdb/server/resource/ThumbnailsResource.java b/src/main/java/org/caosdb/server/resource/ThumbnailsResource.java similarity index 93% rename from src/main/java/caosdb/server/resource/ThumbnailsResource.java rename to src/main/java/org/caosdb/server/resource/ThumbnailsResource.java index e08378c5a4e766f8f84d9d383207e461868bc422..c74251a1c31b2b3ec13bb72618b9c53d222e0cdf 100644 --- a/src/main/java/caosdb/server/resource/ThumbnailsResource.java +++ b/src/main/java/org/caosdb/server/resource/ThumbnailsResource.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.resource; +package org.caosdb.server.resource; -import static caosdb.server.FileSystem.getFromFileSystem; +import static org.caosdb.server.FileSystem.getFromFileSystem; -import caosdb.server.database.backend.implementation.MySQL.ConnectionException; -import caosdb.server.utils.ServerMessages; import java.io.File; import java.io.IOException; +import org.caosdb.server.database.backend.implementation.MySQL.ConnectionException; +import org.caosdb.server.utils.ServerMessages; import org.jdom2.JDOMException; import org.restlet.data.Disposition; import org.restlet.data.MediaType; diff --git a/src/main/java/caosdb/server/resource/UserResource.java b/src/main/java/org/caosdb/server/resource/UserResource.java similarity index 83% rename from src/main/java/caosdb/server/resource/UserResource.java rename to src/main/java/org/caosdb/server/resource/UserResource.java index b77ff8a49035d2be930a3f957e743ed2f0dae067..2c463e0e4bf7a640adc2a8368f74d798f69d0fd5 100644 --- a/src/main/java/caosdb/server/resource/UserResource.java +++ b/src/main/java/org/caosdb/server/resource/UserResource.java @@ -20,24 +20,24 @@ * * ** end header */ -package caosdb.server.resource; - -import caosdb.server.CaosDBException; -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; -import caosdb.server.accessControl.ACMPermissions; -import caosdb.server.accessControl.UserSources; -import caosdb.server.accessControl.UserStatus; -import caosdb.server.database.backend.implementation.MySQL.ConnectionException; -import caosdb.server.entity.Message; -import caosdb.server.transaction.DeleteUserTransaction; -import caosdb.server.transaction.InsertUserTransaction; -import caosdb.server.transaction.RetrieveUserTransaction; -import caosdb.server.transaction.UpdateUserTransaction; -import caosdb.server.utils.ServerMessages; +package org.caosdb.server.resource; + import java.io.IOException; import java.security.NoSuchAlgorithmException; import java.sql.SQLException; +import org.caosdb.server.CaosDBException; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.ServerProperties; +import org.caosdb.server.accessControl.ACMPermissions; +import org.caosdb.server.accessControl.UserSources; +import org.caosdb.server.accessControl.UserStatus; +import org.caosdb.server.database.backend.implementation.MySQL.ConnectionException; +import org.caosdb.server.entity.Message; +import org.caosdb.server.transaction.DeleteUserTransaction; +import org.caosdb.server.transaction.InsertUserTransaction; +import org.caosdb.server.transaction.RetrieveUserTransaction; +import org.caosdb.server.transaction.UpdateUserTransaction; +import org.caosdb.server.utils.ServerMessages; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.JDOMException; @@ -60,9 +60,9 @@ public class UserResource extends AbstractCaosDBServerResource { final Document doc = new Document(); final Element rootElem = generateRootElement(); - if (!getRequestedNames().isEmpty()) { + if (getRequestedItems().length > 0) { try { - final String username = getRequestedNames().get(0); + final String username = getRequestedItems()[0]; final String realm = (getRequestAttributes().containsKey("realm") ? (String) getRequestAttributes().get("realm") @@ -92,20 +92,18 @@ public class UserResource extends AbstractCaosDBServerResource { try { final Form form = new Form(entity); - final String username = getRequestedNames().get(0); + final String username = getRequestedItems()[0]; final String realm = (getRequestAttributes().containsKey("realm") ? (String) getRequestAttributes().get("realm") : UserSources.guessRealm(username)); final String password = form.getFirstValue("password"); final String email = form.getFirstValue("email"); + final UserStatus status = - UserStatus.valueOf( - form.getFirstValue( - "status", - CaosDBServer.getServerProperty( - ServerProperties.KEY_NEW_USER_DEFAULT_ACTIVITY)) - .toUpperCase()); + form.getFirstValue("status") != null + ? UserStatus.valueOf(form.getFirstValue("status").toUpperCase()) + : null; Integer userEntity = null; if (form.getFirst("entity") != null) { if (form.getFirstValue("entity").isEmpty()) { @@ -187,7 +185,8 @@ public class UserResource extends AbstractCaosDBServerResource { final Document doc = new Document(); final Element rootElem = generateRootElement(); - final DeleteUserTransaction t = new DeleteUserTransaction(getRequestedNames().get(0)); + final String username = getRequestedItems()[0]; + final DeleteUserTransaction t = new DeleteUserTransaction(username); try { t.execute(); } catch (final Message m) { diff --git a/src/main/java/caosdb/server/resource/UserRolesResource.java b/src/main/java/org/caosdb/server/resource/UserRolesResource.java similarity index 85% rename from src/main/java/caosdb/server/resource/UserRolesResource.java rename to src/main/java/org/caosdb/server/resource/UserRolesResource.java index 27e147157675982f036b88981b1dce221abae754..4eb7f6143038bb6e4b0c3fda4646e2730acfea04 100644 --- a/src/main/java/caosdb/server/resource/UserRolesResource.java +++ b/src/main/java/org/caosdb/server/resource/UserRolesResource.java @@ -20,21 +20,21 @@ * * ** end header */ -package caosdb.server.resource; +package org.caosdb.server.resource; -import caosdb.server.CaosDBException; -import caosdb.server.accessControl.ACMPermissions; -import caosdb.server.accessControl.UserSources; -import caosdb.server.database.backend.implementation.MySQL.ConnectionException; -import caosdb.server.entity.Message; -import caosdb.server.transaction.RetrieveUserRolesTransaction; -import caosdb.server.transaction.UpdateUserRolesTransaction; -import caosdb.server.utils.ServerMessages; import java.io.IOException; import java.security.NoSuchAlgorithmException; import java.sql.SQLException; import java.util.HashSet; import java.util.List; +import org.caosdb.server.CaosDBException; +import org.caosdb.server.accessControl.ACMPermissions; +import org.caosdb.server.accessControl.UserSources; +import org.caosdb.server.database.backend.implementation.MySQL.ConnectionException; +import org.caosdb.server.entity.Message; +import org.caosdb.server.transaction.RetrieveUserRolesTransaction; +import org.caosdb.server.transaction.UpdateUserRolesTransaction; +import org.caosdb.server.utils.ServerMessages; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.JDOMException; @@ -47,7 +47,7 @@ public class UserRolesResource extends AbstractCaosDBServerResource { protected Representation httpGetInChildClass() throws ConnectionException, IOException, SQLException, CaosDBException, NoSuchAlgorithmException, Exception { - final String user = getRequestedNames().get(0); + final String user = getRequestedItems()[0]; final String realm = (getRequestAttributes().get("realm") != null ? (String) getRequestAttributes().get("realm") @@ -73,7 +73,7 @@ public class UserRolesResource extends AbstractCaosDBServerResource { @Override protected Representation httpPutInChildClass(final Representation entity) throws ConnectionException, JDOMException, Exception, xmlNotWellFormedException { - final String user = getRequestedNames().get(0); + final String user = getRequestedItems()[0]; final String realm = (getRequestAttributes().get("realm") != null ? (String) getRequestAttributes().get("realm") diff --git a/src/main/java/caosdb/server/resource/Webinterface.java b/src/main/java/org/caosdb/server/resource/Webinterface.java similarity index 95% rename from src/main/java/caosdb/server/resource/Webinterface.java rename to src/main/java/org/caosdb/server/resource/Webinterface.java index f05ae4e6b9a98aba1c925677e0fc8e90a74e57e6..bba1fb09c7f2c0a14b95b7314832b6ff174cef6b 100644 --- a/src/main/java/caosdb/server/resource/Webinterface.java +++ b/src/main/java/org/caosdb/server/resource/Webinterface.java @@ -20,15 +20,15 @@ * * ** end header */ -package caosdb.server.resource; +package org.caosdb.server.resource; -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; -import caosdb.server.utils.WebinterfaceUtils; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.ServerProperties; +import org.caosdb.server.utils.WebinterfaceUtils; import org.restlet.data.CacheDirective; import org.restlet.data.Header; import org.restlet.data.MediaType; diff --git a/src/main/java/caosdb/server/resource/WebinterfaceBuildNumber.java b/src/main/java/org/caosdb/server/resource/WebinterfaceBuildNumber.java similarity index 96% rename from src/main/java/caosdb/server/resource/WebinterfaceBuildNumber.java rename to src/main/java/org/caosdb/server/resource/WebinterfaceBuildNumber.java index bb0e47f40164a7480a547b74cda33c83d375fb76..0fe186a0426002071e0b6c6a5ebe0b3f234e9b2a 100644 --- a/src/main/java/caosdb/server/resource/WebinterfaceBuildNumber.java +++ b/src/main/java/org/caosdb/server/resource/WebinterfaceBuildNumber.java @@ -16,9 +16,9 @@ * * <p>** end header */ -package caosdb.server.resource; +package org.caosdb.server.resource; -import caosdb.server.utils.WebinterfaceUtils; +import org.caosdb.server.utils.WebinterfaceUtils; import org.restlet.data.Status; import org.restlet.resource.Get; import org.restlet.resource.ResourceException; diff --git a/src/main/java/caosdb/server/resource/transaction/EntityNamesResource.java b/src/main/java/org/caosdb/server/resource/transaction/EntityNamesResource.java similarity index 53% rename from src/main/java/caosdb/server/resource/transaction/EntityNamesResource.java rename to src/main/java/org/caosdb/server/resource/transaction/EntityNamesResource.java index 2bfca90bf8e0c060caf7ca97b85ceaf7d0d35f5c..0b3f8b7aa4f4a7724b9b6646e7ecb72330293980 100644 --- a/src/main/java/caosdb/server/resource/transaction/EntityNamesResource.java +++ b/src/main/java/org/caosdb/server/resource/transaction/EntityNamesResource.java @@ -1,8 +1,8 @@ -package caosdb.server.resource.transaction; +package org.caosdb.server.resource.transaction; -import caosdb.server.entity.container.RetrieveContainer; -import caosdb.server.resource.transaction.handlers.GetNamesRequestHandler; -import caosdb.server.resource.transaction.handlers.RequestHandler; +import org.caosdb.server.entity.container.RetrieveContainer; +import org.caosdb.server.resource.transaction.handlers.GetNamesRequestHandler; +import org.caosdb.server.resource.transaction.handlers.RequestHandler; public class EntityNamesResource extends EntityResource { diff --git a/src/main/java/caosdb/server/resource/transaction/EntityResource.java b/src/main/java/org/caosdb/server/resource/transaction/EntityResource.java similarity index 85% rename from src/main/java/caosdb/server/resource/transaction/EntityResource.java rename to src/main/java/org/caosdb/server/resource/transaction/EntityResource.java index dc25bcff3418b3f46f90e965a6b80cdf3111c07f..12659362e0a9a82e8cbb95e73e4d6ac6c2d27c6c 100644 --- a/src/main/java/caosdb/server/resource/transaction/EntityResource.java +++ b/src/main/java/org/caosdb/server/resource/transaction/EntityResource.java @@ -20,27 +20,27 @@ * * ** end header */ -package caosdb.server.resource.transaction; - -import caosdb.server.CaosDBException; -import caosdb.server.database.backend.implementation.MySQL.ConnectionException; -import caosdb.server.entity.container.DeleteContainer; -import caosdb.server.entity.container.InsertContainer; -import caosdb.server.entity.container.RetrieveContainer; -import caosdb.server.entity.container.UpdateContainer; -import caosdb.server.resource.AbstractCaosDBServerResource; -import caosdb.server.resource.transaction.handlers.FileUploadHandler; -import caosdb.server.resource.transaction.handlers.IDHandler; -import caosdb.server.resource.transaction.handlers.RequestHandler; -import caosdb.server.resource.transaction.handlers.SimpleGetRequestHandler; -import caosdb.server.resource.transaction.handlers.SimpleWriteHandler; -import caosdb.server.transaction.Delete; -import caosdb.server.transaction.Insert; -import caosdb.server.transaction.Retrieve; -import caosdb.server.transaction.Update; +package org.caosdb.server.resource.transaction; + import java.io.IOException; import java.security.NoSuchAlgorithmException; import java.sql.SQLException; +import org.caosdb.server.CaosDBException; +import org.caosdb.server.database.backend.implementation.MySQL.ConnectionException; +import org.caosdb.server.entity.container.DeleteContainer; +import org.caosdb.server.entity.container.InsertContainer; +import org.caosdb.server.entity.container.RetrieveContainer; +import org.caosdb.server.entity.container.UpdateContainer; +import org.caosdb.server.resource.AbstractCaosDBServerResource; +import org.caosdb.server.resource.transaction.handlers.FileUploadHandler; +import org.caosdb.server.resource.transaction.handlers.RequestHandler; +import org.caosdb.server.resource.transaction.handlers.SimpleDeleteRequestHandler; +import org.caosdb.server.resource.transaction.handlers.SimpleGetRequestHandler; +import org.caosdb.server.resource.transaction.handlers.SimpleWriteHandler; +import org.caosdb.server.transaction.Delete; +import org.caosdb.server.transaction.Insert; +import org.caosdb.server.transaction.Retrieve; +import org.caosdb.server.transaction.Update; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.JDOMException; @@ -72,7 +72,7 @@ public class EntityResource extends AbstractCaosDBServerResource { } protected RequestHandler<DeleteContainer> getDeleteRequestHandler() { - return new IDHandler<DeleteContainer>(); + return new SimpleDeleteRequestHandler(); } protected RequestHandler<InsertContainer> getPostRequestHandler() { diff --git a/src/main/java/caosdb/server/resource/transaction/handlers/FileUploadHandler.java b/src/main/java/org/caosdb/server/resource/transaction/handlers/FileUploadHandler.java similarity index 90% rename from src/main/java/caosdb/server/resource/transaction/handlers/FileUploadHandler.java rename to src/main/java/org/caosdb/server/resource/transaction/handlers/FileUploadHandler.java index 48003f1525f006960cf155591bc14d9d684c1888..ec5c5bc4d144af9ce99f7b27915a52420c331bb5 100644 --- a/src/main/java/caosdb/server/resource/transaction/handlers/FileUploadHandler.java +++ b/src/main/java/org/caosdb/server/resource/transaction/handlers/FileUploadHandler.java @@ -20,18 +20,18 @@ * * ** end header */ -package caosdb.server.resource.transaction.handlers; +package org.caosdb.server.resource.transaction.handlers; -import caosdb.server.FileSystem; -import caosdb.server.entity.FileProperties; -import caosdb.server.entity.container.WritableContainer; -import caosdb.server.resource.transaction.EntityResource; -import caosdb.server.utils.ServerMessages; import java.io.IOException; import org.apache.commons.fileupload.FileItemIterator; import org.apache.commons.fileupload.FileItemStream; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.caosdb.server.FileSystem; +import org.caosdb.server.entity.FileProperties; +import org.caosdb.server.entity.container.WritableContainer; +import org.caosdb.server.resource.transaction.EntityResource; +import org.caosdb.server.utils.ServerMessages; import org.jdom2.Element; import org.restlet.data.MediaType; import org.restlet.ext.fileupload.RestletFileUpload; diff --git a/src/main/java/caosdb/server/resource/transaction/handlers/GetNamesRequestHandler.java b/src/main/java/org/caosdb/server/resource/transaction/handlers/GetNamesRequestHandler.java similarity index 64% rename from src/main/java/caosdb/server/resource/transaction/handlers/GetNamesRequestHandler.java rename to src/main/java/org/caosdb/server/resource/transaction/handlers/GetNamesRequestHandler.java index f69c112880e833d0c981b903562889e377fe6f23..c327c6833d281c07148c59be689ddfac25b33f4d 100644 --- a/src/main/java/caosdb/server/resource/transaction/handlers/GetNamesRequestHandler.java +++ b/src/main/java/org/caosdb/server/resource/transaction/handlers/GetNamesRequestHandler.java @@ -1,7 +1,7 @@ -package caosdb.server.resource.transaction.handlers; +package org.caosdb.server.resource.transaction.handlers; -import caosdb.server.entity.container.RetrieveContainer; -import caosdb.server.resource.transaction.EntityResource; +import org.caosdb.server.entity.container.RetrieveContainer; +import org.caosdb.server.resource.transaction.EntityResource; public class GetNamesRequestHandler extends RequestHandler<RetrieveContainer> { diff --git a/src/main/java/caosdb/server/resource/transaction/handlers/RequestHandler.java b/src/main/java/org/caosdb/server/resource/transaction/handlers/RequestHandler.java similarity index 85% rename from src/main/java/caosdb/server/resource/transaction/handlers/RequestHandler.java rename to src/main/java/org/caosdb/server/resource/transaction/handlers/RequestHandler.java index e1390fe81782b353ccf2e401a9918747c6084ab3..fc49cc518db12e1f750716372f94b808dcb3874b 100644 --- a/src/main/java/caosdb/server/resource/transaction/handlers/RequestHandler.java +++ b/src/main/java/org/caosdb/server/resource/transaction/handlers/RequestHandler.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.resource.transaction.handlers; +package org.caosdb.server.resource.transaction.handlers; -import caosdb.server.entity.container.TransactionContainer; -import caosdb.server.resource.transaction.EntityResource; +import org.caosdb.server.entity.container.TransactionContainer; +import org.caosdb.server.resource.transaction.EntityResource; public abstract class RequestHandler<T extends TransactionContainer> { diff --git a/src/main/java/caosdb/server/resource/transaction/handlers/RetrieveGlobalEntityPermissionsHandler.java b/src/main/java/org/caosdb/server/resource/transaction/handlers/RetrieveGlobalEntityPermissionsHandler.java similarity index 83% rename from src/main/java/caosdb/server/resource/transaction/handlers/RetrieveGlobalEntityPermissionsHandler.java rename to src/main/java/org/caosdb/server/resource/transaction/handlers/RetrieveGlobalEntityPermissionsHandler.java index a1882857801659449516992b4a4cca34d643379c..6801e804a8bcb721e2c7170ad857126579cbfb46 100644 --- a/src/main/java/caosdb/server/resource/transaction/handlers/RetrieveGlobalEntityPermissionsHandler.java +++ b/src/main/java/org/caosdb/server/resource/transaction/handlers/RetrieveGlobalEntityPermissionsHandler.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.resource.transaction.handlers; +package org.caosdb.server.resource.transaction.handlers; -import caosdb.server.entity.container.RetrieveContainer; -import caosdb.server.permissions.EntityPermission; -import caosdb.server.resource.transaction.EntityResource; +import org.caosdb.server.entity.container.RetrieveContainer; +import org.caosdb.server.permissions.EntityPermission; +import org.caosdb.server.resource.transaction.EntityResource; public class RetrieveGlobalEntityPermissionsHandler extends SimpleGetRequestHandler { diff --git a/src/main/java/caosdb/server/resource/transaction/handlers/RetriveOwnerRequestHandler.java b/src/main/java/org/caosdb/server/resource/transaction/handlers/RetriveOwnerRequestHandler.java similarity index 84% rename from src/main/java/caosdb/server/resource/transaction/handlers/RetriveOwnerRequestHandler.java rename to src/main/java/org/caosdb/server/resource/transaction/handlers/RetriveOwnerRequestHandler.java index d942389a359b2c24eafc6ec4a98b230cbe33f226..7b2d698cb4673ba7e4ed30fc81fc249e89632734 100644 --- a/src/main/java/caosdb/server/resource/transaction/handlers/RetriveOwnerRequestHandler.java +++ b/src/main/java/org/caosdb/server/resource/transaction/handlers/RetriveOwnerRequestHandler.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.resource.transaction.handlers; +package org.caosdb.server.resource.transaction.handlers; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.container.RetrieveContainer; -import caosdb.server.resource.transaction.EntityResource; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.container.RetrieveContainer; +import org.caosdb.server.resource.transaction.EntityResource; public class RetriveOwnerRequestHandler extends SimpleGetRequestHandler { diff --git a/src/main/java/org/caosdb/server/resource/transaction/handlers/SimpleDeleteRequestHandler.java b/src/main/java/org/caosdb/server/resource/transaction/handlers/SimpleDeleteRequestHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..34c1a3836290f4e90fde5a1ec10a2818b7b63fae --- /dev/null +++ b/src/main/java/org/caosdb/server/resource/transaction/handlers/SimpleDeleteRequestHandler.java @@ -0,0 +1,55 @@ +/* + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2018 Research Group Biomedical Physics, + * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * + * 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 <https://www.gnu.org/licenses/>. + * + * ** end header + */ +package org.caosdb.server.resource.transaction.handlers; + +import org.caosdb.server.entity.container.DeleteContainer; +import org.caosdb.server.resource.transaction.EntityResource; + +public class SimpleDeleteRequestHandler extends RequestHandler<DeleteContainer> { + + @Override + public void handle(final EntityResource t, final DeleteContainer container) throws Exception { + // TODO a lot of code duplication, see SimpleGetRequestHandle#handle. + // However, this is about to be changed again when string ids are + // introduced, anyways. So we just leave it. + for (final String item : t.getRequestedItems()) { + String[] elem = item.split("@", 1); + Integer id = null; + String version = null; + try { + id = Integer.parseInt(elem[0]); + } catch (NumberFormatException e) { + // pass + } + if (elem.length > 1) { + version = elem[1]; + } + + if (id != null) { + container.add(id, version); + } + } + } +} diff --git a/src/main/java/caosdb/server/resource/transaction/handlers/SimpleGetRequestHandler.java b/src/main/java/org/caosdb/server/resource/transaction/handlers/SimpleGetRequestHandler.java similarity index 57% rename from src/main/java/caosdb/server/resource/transaction/handlers/SimpleGetRequestHandler.java rename to src/main/java/org/caosdb/server/resource/transaction/handlers/SimpleGetRequestHandler.java index 8fbb9d25cb33d2d0a75ce8405a164c1e8c9ce0fd..b80d9c219e2cbda1e012c9c73993b5ea427c6ccf 100644 --- a/src/main/java/caosdb/server/resource/transaction/handlers/SimpleGetRequestHandler.java +++ b/src/main/java/org/caosdb/server/resource/transaction/handlers/SimpleGetRequestHandler.java @@ -20,18 +20,34 @@ * * ** end header */ -package caosdb.server.resource.transaction.handlers; +package org.caosdb.server.resource.transaction.handlers; -import caosdb.server.entity.container.RetrieveContainer; -import caosdb.server.resource.transaction.EntityResource; +import org.caosdb.server.entity.container.RetrieveContainer; +import org.caosdb.server.resource.transaction.EntityResource; -public class SimpleGetRequestHandler extends IDHandler<RetrieveContainer> { +public class SimpleGetRequestHandler extends RequestHandler<RetrieveContainer> { @Override public void handle(final EntityResource t, final RetrieveContainer container) throws Exception { - super.handle(t, container); - for (final String name : t.getRequestedNames()) { - container.add(name); + for (final String item : t.getRequestedItems()) { + String[] elem = item.split("@", 2); + Integer id = null; + String name = null; + String version = null; + try { + id = Integer.parseInt(elem[0]); + } catch (NumberFormatException e) { + name = elem[0]; + } + if (elem.length > 1) { + version = elem[1]; + } + + if (id != null) { + container.add(id, version); + } else { + container.add(name); + } } } } diff --git a/src/main/java/caosdb/server/resource/transaction/handlers/SimpleWriteHandler.java b/src/main/java/org/caosdb/server/resource/transaction/handlers/SimpleWriteHandler.java similarity index 91% rename from src/main/java/caosdb/server/resource/transaction/handlers/SimpleWriteHandler.java rename to src/main/java/org/caosdb/server/resource/transaction/handlers/SimpleWriteHandler.java index 71afcc91321f8d9853cd18ae3ca12022501416ff..feb784da2f1ab9dcc09942a108bcce6bd073e128 100644 --- a/src/main/java/caosdb/server/resource/transaction/handlers/SimpleWriteHandler.java +++ b/src/main/java/org/caosdb/server/resource/transaction/handlers/SimpleWriteHandler.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.resource.transaction.handlers; +package org.caosdb.server.resource.transaction.handlers; -import caosdb.server.entity.container.WritableContainer; -import caosdb.server.resource.transaction.EntityResource; import java.util.List; +import org.caosdb.server.entity.container.WritableContainer; +import org.caosdb.server.resource.transaction.EntityResource; import org.jdom2.Element; public class SimpleWriteHandler<T extends WritableContainer> extends RequestHandler<T> { diff --git a/src/main/java/caosdb/server/scripting/CallerSerializer.java b/src/main/java/org/caosdb/server/scripting/CallerSerializer.java similarity index 95% rename from src/main/java/caosdb/server/scripting/CallerSerializer.java rename to src/main/java/org/caosdb/server/scripting/CallerSerializer.java index 3ffb941d9d4fe40a48b849c1de44b8349645d62f..b133ad5cf02afa0194beb175883b999e75810efe 100644 --- a/src/main/java/caosdb/server/scripting/CallerSerializer.java +++ b/src/main/java/org/caosdb/server/scripting/CallerSerializer.java @@ -21,11 +21,11 @@ * * ** end header */ -package caosdb.server.scripting; +package org.caosdb.server.scripting; -import caosdb.server.CaosDBException; -import caosdb.server.utils.Serializer; import java.io.IOException; +import org.caosdb.server.CaosDBException; +import org.caosdb.server.utils.Serializer; import org.jdom2.Element; /** diff --git a/src/main/java/org/caosdb/server/scripting/ScriptingPermissions.java b/src/main/java/org/caosdb/server/scripting/ScriptingPermissions.java new file mode 100644 index 0000000000000000000000000000000000000000..78ad99d77d06b681838e455ad391c62e7ce85ca6 --- /dev/null +++ b/src/main/java/org/caosdb/server/scripting/ScriptingPermissions.java @@ -0,0 +1,11 @@ +package org.caosdb.server.scripting; + +public class ScriptingPermissions { + + public static final String PERMISSION_EXECUTION(final String call) { + StringBuilder ret = new StringBuilder(18 + call.length()); + ret.append("SCRIPTING:EXECUTE:"); + ret.append(call.replace("/", ":")); + return ret.toString(); + } +} diff --git a/src/main/java/org/caosdb/server/scripting/ScriptingUtils.java b/src/main/java/org/caosdb/server/scripting/ScriptingUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..c9a0b522d949a4ba3c36ae4f867661263a0185d3 --- /dev/null +++ b/src/main/java/org/caosdb/server/scripting/ScriptingUtils.java @@ -0,0 +1,145 @@ +/* + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2018 Research Group Biomedical Physics, + * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * + * 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 <https://www.gnu.org/licenses/>. + * + * ** end header + */ +package org.caosdb.server.scripting; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.ServerProperties; +import org.caosdb.server.entity.Message; +import org.caosdb.server.utils.ConfigurationException; +import org.caosdb.server.utils.ServerMessages; +import org.caosdb.server.utils.Utils; + +public class ScriptingUtils { + + private File[] bin_dirs; + private File working; + + public ScriptingUtils() { + ArrayList<File> new_bin_dirs = new ArrayList<>(); + String bin_dirs_str = + CaosDBServer.getServerProperty(ServerProperties.KEY_SERVER_SIDE_SCRIPTING_BIN_DIRS); + if (bin_dirs_str == null) { + // fall-back for old server property + bin_dirs_str = + CaosDBServer.getServerProperty(ServerProperties.KEY_SERVER_SIDE_SCRIPTING_BIN_DIR); + } + + // split and process + if (bin_dirs_str != null) { + for (String dir : bin_dirs_str.split("\\s+|\\s*,\\s*")) { + + File bin; + try { + bin = new File(dir).getCanonicalFile(); + } catch (IOException e) { + throw new ConfigurationException( + "Scripting bin dir `" + dir + "` cannot be resolved to a real path."); + } + if (!bin.exists()) { + bin.mkdirs(); + } + if (!bin.isDirectory()) { + throw new ConfigurationException( + "The ServerProperty `" + + ServerProperties.KEY_SERVER_SIDE_SCRIPTING_BIN_DIRS + + "` must point to directories"); + } + new_bin_dirs.add(bin); + } + } + + bin_dirs = new_bin_dirs.toArray(new File[new_bin_dirs.size()]); + + this.working = + new File( + CaosDBServer.getServerProperty(ServerProperties.KEY_SERVER_SIDE_SCRIPTING_WORKING_DIR)); + + if (!working.exists()) { + working.mkdirs(); + } + if (!working.isDirectory()) { + throw new ConfigurationException( + "The ServerProperty `" + + ServerProperties.KEY_SERVER_SIDE_SCRIPTING_WORKING_DIR + + "` must point to a directory"); + } + } + + /** + * Get the script file by the relative path. + * + * <p>Run through all registered bin_dirs and try to resolve the command relative to them. The + * first matching file is used. When it is not executable throw a + * SERVER_SIDE_SCRIPT_NOT_EXECUTABLE message. When no matching file exists throw a + * SERVER_SIDE_SCRIPT_DOES_NOT_EXIST message. + * + * @param command The relative path + * @return The script File object. + * @throws Message + */ + public File getScriptFile(final String command) throws Message { + for (File bin_dir : bin_dirs) { + File script = bin_dir.toPath().resolve(command).toFile(); + + try { + script = script.getCanonicalFile(); + if (!script.toPath().startsWith(bin_dir.toPath())) { + // not below the allowed directory tree + continue; + } + } catch (IOException e) { + // cannot be resolved to canonical file - we treat it as non-existing. + continue; + } + + if (!script.exists()) { + // doesn't exist. + continue; + } + + if (!script.canExecute()) { + throw ServerMessages.SERVER_SIDE_SCRIPT_NOT_EXECUTABLE; + } + + // we found it! + return script; + } + throw ServerMessages.SERVER_SIDE_SCRIPT_DOES_NOT_EXIST; + } + + public File getTmpWorkingDir() { + String uid = Utils.getUID(); + return working.toPath().resolve(uid).toFile(); + } + + public File getStdOutFile(File workingDir) { + return workingDir.toPath().resolve(".STDOUT").toFile(); + } + + public File getStdErrFile(File workingDir) { + return workingDir.toPath().resolve(".STDERR").toFile(); + } +} diff --git a/src/main/java/caosdb/server/scripting/ServerSideScriptingCaller.java b/src/main/java/org/caosdb/server/scripting/ServerSideScriptingCaller.java similarity index 80% rename from src/main/java/caosdb/server/scripting/ServerSideScriptingCaller.java rename to src/main/java/org/caosdb/server/scripting/ServerSideScriptingCaller.java index 6fa5d1a479df47c20d9d3a5d3a7134e1c0898ad1..4f5f81e248e17f6344d8523286828ce7142c529a 100644 --- a/src/main/java/caosdb/server/scripting/ServerSideScriptingCaller.java +++ b/src/main/java/org/caosdb/server/scripting/ServerSideScriptingCaller.java @@ -22,24 +22,25 @@ * ** end header */ -package caosdb.server.scripting; - -import caosdb.server.CaosDBException; -import caosdb.server.CaosDBServer; -import caosdb.server.FileSystem; -import caosdb.server.ServerProperties; -import caosdb.server.entity.FileProperties; -import caosdb.server.entity.Message; -import caosdb.server.utils.ServerMessages; +package org.caosdb.server.scripting; + import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.lang.ProcessBuilder.Redirect; +import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.io.FileUtils; +import org.caosdb.server.CaosDBException; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.FileSystem; +import org.caosdb.server.ServerProperties; +import org.caosdb.server.entity.FileProperties; +import org.caosdb.server.entity.Message; +import org.caosdb.server.utils.ServerMessages; /** * Calls server-side scripting scripts. @@ -53,6 +54,7 @@ public class ServerSideScriptingCaller { public static final Integer STARTED = -1; private final String[] commandLine; private final int timeoutMs; + private String absoluteScriptPath = null; private ScriptingUtils utils; private List<FileProperties> files; private File workingDir; @@ -121,7 +123,7 @@ public class ServerSideScriptingCaller { /** Does some final preparation, then calls the script and cleans up. */ public int invoke() throws Message { try { - checkCommandLine(commandLine); + this.absoluteScriptPath = getAbsoluteScriptPath(commandLine); try { createWorkingDir(); putFilesInWorkingDir(files); @@ -134,7 +136,8 @@ public class ServerSideScriptingCaller { } try { - return callScript(); + code = callScript(this.absoluteScriptPath, this.commandLine, this.authToken, this.env); + return code; } catch (TimeoutException e) { throw ServerMessages.SERVER_SIDE_SCRIPT_TIMEOUT; } catch (final Throwable e) { @@ -146,9 +149,17 @@ public class ServerSideScriptingCaller { } } - void checkCommandLine(String[] commandLine) throws Message { - utils.checkScriptExists(commandLine[0]); - utils.checkScriptExecutable(commandLine[0]); + /** + * Returns the absolute script path. + * + * <p>Throws Message when the script does not exist or when the script is not executable. + * + * @param commandLine + * @return The absolute script path. + * @throws Message + */ + String getAbsoluteScriptPath(String[] commandLine) throws Message { + return utils.getScriptFile(commandLine[0]).getAbsolutePath(); } void putFilesInWorkingDir(final Collection<FileProperties> files) @@ -165,8 +176,11 @@ public class ServerSideScriptingCaller { if (f.getPath() == null || f.getPath().isEmpty()) { throw new CaosDBException("The path must not be null or empty!"); } - caosdb.server.utils.FileUtils.createSymlink( - getUploadFilesDir().toPath().resolve(f.getPath()).toFile(), f.getFile()); + File link = getUploadFilesDir().toPath().resolve(f.getPath()).toFile(); + if (!link.getParentFile().exists()) { + link.getParentFile().mkdirs(); + } + org.caosdb.server.utils.FileUtils.createSymlink(link, f.getFile()); } } @@ -239,10 +253,6 @@ public class ServerSideScriptingCaller { if (pwd.exists()) FileUtils.forceDelete(pwd); } - String makeCallAbsolute(String call) { - return utils.getScriptFile(call).getAbsolutePath(); - } - /** @fixme Should be injected into environment instead. Will be changed in v0.4 of SSS-API */ String[] injectAuthToken(String[] commandLine) { String[] newCommandLine = new String[commandLine.length + 1]; @@ -254,9 +264,31 @@ public class ServerSideScriptingCaller { return newCommandLine; } - int callScript() throws IOException, InterruptedException, TimeoutException { - String[] effectiveCommandLine = injectAuthToken(getCommandLine()); - effectiveCommandLine[0] = makeCallAbsolute(effectiveCommandLine[0]); + /** + * Call the script. + * + * <p>The absoluteScriptPath is called with all remaining parameters from the commandLine arrays, + * an optional additional authToken and environment variables. + * + * @param absoluteScriptPath + * @param commandLine + * @param authToken + * @param env - environment variables + * @return the exit code of the script call + * @throws IOException + * @throws InterruptedException + * @throws TimeoutException + */ + int callScript( + String absoluteScriptPath, String[] commandLine, Object authToken, Map<String, String> env) + throws IOException, InterruptedException, TimeoutException { + String[] effectiveCommandLine; + if (authToken != null) { + effectiveCommandLine = injectAuthToken(commandLine); + } else { + effectiveCommandLine = Arrays.copyOf(commandLine, commandLine.length); + } + effectiveCommandLine[0] = absoluteScriptPath; final ProcessBuilder pb = new ProcessBuilder(effectiveCommandLine); // inject environment variables @@ -269,7 +301,7 @@ public class ServerSideScriptingCaller { pb.redirectError(Redirect.to(getStdErrFile())); pb.directory(getTmpWorkingDir()); - code = STARTED; + int code = STARTED; final TimeoutProcess process = new TimeoutProcess(pb.start(), getTimeoutMs()); code = process.waitFor(); diff --git a/src/main/java/caosdb/server/scripting/TimeoutException.java b/src/main/java/org/caosdb/server/scripting/TimeoutException.java similarity index 90% rename from src/main/java/caosdb/server/scripting/TimeoutException.java rename to src/main/java/org/caosdb/server/scripting/TimeoutException.java index 655cb6a7782c29a894607db0373a4baa7b98611e..31b9b7e989989677653e5938cc6bd531878f5299 100644 --- a/src/main/java/caosdb/server/scripting/TimeoutException.java +++ b/src/main/java/org/caosdb/server/scripting/TimeoutException.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.scripting; +package org.caosdb.server.scripting; public class TimeoutException extends Exception { @@ -28,5 +28,5 @@ public class TimeoutException extends Exception { super(string); } - private static final long serialVersionUID = 4871406372815136756L; + private static final long serialVersionUID = 3609100971776091914L; } diff --git a/src/main/java/caosdb/server/scripting/TimeoutProcess.java b/src/main/java/org/caosdb/server/scripting/TimeoutProcess.java similarity index 98% rename from src/main/java/caosdb/server/scripting/TimeoutProcess.java rename to src/main/java/org/caosdb/server/scripting/TimeoutProcess.java index f41a2663c6aae169b0ce28d4e14ab43135653237..c867ca3b7f0190b1cd5d6b6be4f595be10d2891a 100644 --- a/src/main/java/caosdb/server/scripting/TimeoutProcess.java +++ b/src/main/java/org/caosdb/server/scripting/TimeoutProcess.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.scripting; +package org.caosdb.server.scripting; import java.io.InputStream; diff --git a/src/main/java/caosdb/server/terminal/CaosDBTerminal.java b/src/main/java/org/caosdb/server/terminal/CaosDBTerminal.java similarity index 93% rename from src/main/java/caosdb/server/terminal/CaosDBTerminal.java rename to src/main/java/org/caosdb/server/terminal/CaosDBTerminal.java index 8113d4e1e7c36adb517543b778d03ec9a0970598..96bd6315b7e32c03273a8b65bd489bfc061e0ef1 100644 --- a/src/main/java/caosdb/server/terminal/CaosDBTerminal.java +++ b/src/main/java/org/caosdb/server/terminal/CaosDBTerminal.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.terminal; +package org.caosdb.server.terminal; import com.googlecode.lanterna.TerminalFacade; import com.googlecode.lanterna.gui.GUIScreen; @@ -30,6 +30,11 @@ import com.googlecode.lanterna.terminal.Terminal; import com.googlecode.lanterna.terminal.text.UnixTerminal; import java.nio.charset.Charset; +/** + * @deprecated Soon to be removed + * @author Timm Fitschen (t.fitschen@indiscale.com) + */ +@Deprecated public class CaosDBTerminal extends Thread { public CaosDBTerminal() { diff --git a/src/main/java/caosdb/server/terminal/DatabaseAccessPanel.java b/src/main/java/org/caosdb/server/terminal/DatabaseAccessPanel.java similarity index 94% rename from src/main/java/caosdb/server/terminal/DatabaseAccessPanel.java rename to src/main/java/org/caosdb/server/terminal/DatabaseAccessPanel.java index 49a6e35de195d3d5ae78821db4cfe5e6f4aa283d..6877049605888682bd003f8382a931661e79602c 100644 --- a/src/main/java/caosdb/server/terminal/DatabaseAccessPanel.java +++ b/src/main/java/org/caosdb/server/terminal/DatabaseAccessPanel.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.terminal; +package org.caosdb.server.terminal; -import caosdb.server.database.DatabaseMonitor; -import caosdb.server.utils.Observable; -import caosdb.server.utils.Observer; import com.googlecode.lanterna.gui.component.Label; import com.googlecode.lanterna.gui.component.Panel; import com.googlecode.lanterna.gui.component.Table; +import org.caosdb.server.database.DatabaseMonitor; +import org.caosdb.server.utils.Observable; +import org.caosdb.server.utils.Observer; public final class DatabaseAccessPanel extends Panel implements Observer { diff --git a/src/main/java/caosdb/server/terminal/EntitiesPanel.java b/src/main/java/org/caosdb/server/terminal/EntitiesPanel.java similarity index 97% rename from src/main/java/caosdb/server/terminal/EntitiesPanel.java rename to src/main/java/org/caosdb/server/terminal/EntitiesPanel.java index 10c5296eba2f75e360d0621d96392528f66f5475..b2f7489de66eeae9771e911b45e7d4546cb4f5b9 100644 --- a/src/main/java/caosdb/server/terminal/EntitiesPanel.java +++ b/src/main/java/org/caosdb/server/terminal/EntitiesPanel.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.terminal; +package org.caosdb.server.terminal; -import caosdb.server.utils.Info; import com.googlecode.lanterna.gui.component.Label; import com.googlecode.lanterna.gui.component.Panel; import com.googlecode.lanterna.gui.component.Table; +import org.caosdb.server.utils.Info; public final class EntitiesPanel extends Panel implements StatComponent { diff --git a/src/main/java/caosdb/server/terminal/MainWindow.java b/src/main/java/org/caosdb/server/terminal/MainWindow.java similarity index 98% rename from src/main/java/caosdb/server/terminal/MainWindow.java rename to src/main/java/org/caosdb/server/terminal/MainWindow.java index 7bdfefc21f167d68a687acfcded550aabe0432cd..aa22f12b23bed00dfb46db8c7cd140fb05551eec 100644 --- a/src/main/java/caosdb/server/terminal/MainWindow.java +++ b/src/main/java/org/caosdb/server/terminal/MainWindow.java @@ -20,9 +20,8 @@ * * ** end header */ -package caosdb.server.terminal; +package org.caosdb.server.terminal; -import caosdb.server.utils.Observer; import com.googlecode.lanterna.gui.Action; import com.googlecode.lanterna.gui.Border; import com.googlecode.lanterna.gui.Window; @@ -35,6 +34,7 @@ import com.googlecode.lanterna.gui.dialog.MessageBox; import com.googlecode.lanterna.gui.layout.LinearLayout; import com.googlecode.lanterna.input.Key; import com.googlecode.lanterna.input.Key.Kind; +import org.caosdb.server.utils.Observer; public class MainWindow extends Window { diff --git a/src/main/java/caosdb/server/terminal/OutputStreamPanel.java b/src/main/java/org/caosdb/server/terminal/OutputStreamPanel.java similarity index 99% rename from src/main/java/caosdb/server/terminal/OutputStreamPanel.java rename to src/main/java/org/caosdb/server/terminal/OutputStreamPanel.java index 235a927cbbaca07e9433a88180269226d8ab88c7..50284f8a88e7d30596cc901be24108f3ea201d0a 100644 --- a/src/main/java/caosdb/server/terminal/OutputStreamPanel.java +++ b/src/main/java/org/caosdb/server/terminal/OutputStreamPanel.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.terminal; +package org.caosdb.server.terminal; import com.googlecode.lanterna.gui.Action; import com.googlecode.lanterna.gui.component.Button; diff --git a/src/main/java/caosdb/server/terminal/StatComponent.java b/src/main/java/org/caosdb/server/terminal/StatComponent.java similarity index 96% rename from src/main/java/caosdb/server/terminal/StatComponent.java rename to src/main/java/org/caosdb/server/terminal/StatComponent.java index 24f9fa57e72f6422d4c342f02aa4d765fe0a7dc8..90a9ac1125425bd23415abf3e4186f00695b9b2f 100644 --- a/src/main/java/caosdb/server/terminal/StatComponent.java +++ b/src/main/java/org/caosdb/server/terminal/StatComponent.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.terminal; +package org.caosdb.server.terminal; import com.googlecode.lanterna.gui.Component; diff --git a/src/main/java/caosdb/server/terminal/StatLabel.java b/src/main/java/org/caosdb/server/terminal/StatLabel.java similarity index 93% rename from src/main/java/caosdb/server/terminal/StatLabel.java rename to src/main/java/org/caosdb/server/terminal/StatLabel.java index 70568a924448379750d7a04d21b96ba0d0759c29..73a03ac31ed8874fc936807393701995130eaf7f 100644 --- a/src/main/java/caosdb/server/terminal/StatLabel.java +++ b/src/main/java/org/caosdb/server/terminal/StatLabel.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.terminal; +package org.caosdb.server.terminal; -import caosdb.server.utils.Observable; -import caosdb.server.utils.Observer; import com.googlecode.lanterna.gui.component.Label; +import org.caosdb.server.utils.Observable; +import org.caosdb.server.utils.Observer; public class StatLabel extends Label implements Observer, StatComponent { diff --git a/src/main/java/caosdb/server/terminal/StatTable.java b/src/main/java/org/caosdb/server/terminal/StatTable.java similarity index 97% rename from src/main/java/caosdb/server/terminal/StatTable.java rename to src/main/java/org/caosdb/server/terminal/StatTable.java index 5d2ecb29204b63705e499b8ab71bea8d8c2b2255..e7234cdb8000a7c4dcc98463c3e9ca6cc8c9f19c 100644 --- a/src/main/java/caosdb/server/terminal/StatTable.java +++ b/src/main/java/org/caosdb/server/terminal/StatTable.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.terminal; +package org.caosdb.server.terminal; import com.googlecode.lanterna.gui.Component; import com.googlecode.lanterna.gui.component.Panel; diff --git a/src/main/java/caosdb/server/terminal/StatsPanel.java b/src/main/java/org/caosdb/server/terminal/StatsPanel.java similarity index 98% rename from src/main/java/caosdb/server/terminal/StatsPanel.java rename to src/main/java/org/caosdb/server/terminal/StatsPanel.java index aa0f4a64926d5af851ed7b323d410d70a845957e..3b41ac6a9c4ae7366e85cffedbd71f83b30c6438 100644 --- a/src/main/java/caosdb/server/terminal/StatsPanel.java +++ b/src/main/java/org/caosdb/server/terminal/StatsPanel.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.terminal; +package org.caosdb.server.terminal; import com.googlecode.lanterna.gui.Action; import com.googlecode.lanterna.gui.Border; diff --git a/src/main/java/caosdb/server/terminal/SystemErrPanel.java b/src/main/java/org/caosdb/server/terminal/SystemErrPanel.java similarity index 97% rename from src/main/java/caosdb/server/terminal/SystemErrPanel.java rename to src/main/java/org/caosdb/server/terminal/SystemErrPanel.java index 75e4291ac041d1c5ecc3b9d38fe024619750dbb8..9bf800fdb3c755cd8ea2b2a55119cf4e093fde09 100644 --- a/src/main/java/caosdb/server/terminal/SystemErrPanel.java +++ b/src/main/java/org/caosdb/server/terminal/SystemErrPanel.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.terminal; +package org.caosdb.server.terminal; import com.googlecode.lanterna.gui.component.Label; import java.io.IOException; diff --git a/src/main/java/caosdb/server/terminal/SystemOutPanel.java b/src/main/java/org/caosdb/server/terminal/SystemOutPanel.java similarity index 97% rename from src/main/java/caosdb/server/terminal/SystemOutPanel.java rename to src/main/java/org/caosdb/server/terminal/SystemOutPanel.java index 48e16cc5f9365d57a7d9bc05a388a554bff388f3..b34cdaf97d8088a97ea66932d9abc96d6e1589be 100644 --- a/src/main/java/caosdb/server/terminal/SystemOutPanel.java +++ b/src/main/java/org/caosdb/server/terminal/SystemOutPanel.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.terminal; +package org.caosdb.server.terminal; import com.googlecode.lanterna.gui.component.Label; import java.io.IOException; diff --git a/src/main/java/caosdb/server/transaction/AccessControlTransaction.java b/src/main/java/org/caosdb/server/transaction/AccessControlTransaction.java similarity index 87% rename from src/main/java/caosdb/server/transaction/AccessControlTransaction.java rename to src/main/java/org/caosdb/server/transaction/AccessControlTransaction.java index ac5e3030c5b39aa49f2eb332e050a7b58b157fb0..0a2d1363427d9e21504b421c88e7605af59634ac 100644 --- a/src/main/java/caosdb/server/transaction/AccessControlTransaction.java +++ b/src/main/java/org/caosdb/server/transaction/AccessControlTransaction.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.transaction; +package org.caosdb.server.transaction; -import caosdb.server.database.DatabaseMonitor; -import caosdb.server.database.access.Access; -import caosdb.server.database.misc.RollBackHandler; -import caosdb.server.entity.Message; +import org.caosdb.server.database.DatabaseMonitor; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.misc.RollBackHandler; +import org.caosdb.server.entity.Message; public abstract class AccessControlTransaction implements TransactionInterface { diff --git a/src/main/java/caosdb/server/transaction/ChecksumUpdater.java b/src/main/java/org/caosdb/server/transaction/ChecksumUpdater.java similarity index 85% rename from src/main/java/caosdb/server/transaction/ChecksumUpdater.java rename to src/main/java/org/caosdb/server/transaction/ChecksumUpdater.java index 30313478c263a131658005daa39da3b495c85eb2..b9d350719f13b5bd26e44f7d2b959a428adf5793 100644 --- a/src/main/java/caosdb/server/transaction/ChecksumUpdater.java +++ b/src/main/java/org/caosdb/server/transaction/ChecksumUpdater.java @@ -20,22 +20,22 @@ * * ** end header */ -package caosdb.server.transaction; - -import caosdb.server.CaosDBException; -import caosdb.server.database.DatabaseMonitor; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.transaction.GetUpdateableChecksums; -import caosdb.server.database.backend.transaction.RetrieveSparseEntity; -import caosdb.server.database.backend.transaction.UpdateSparseEntity; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.FileProperties; -import caosdb.server.entity.Message; -import caosdb.server.entity.container.TransactionContainer; -import caosdb.server.utils.FileUtils; +package org.caosdb.server.transaction; + import java.io.IOException; import java.security.NoSuchAlgorithmException; +import org.caosdb.server.CaosDBException; +import org.caosdb.server.database.DatabaseMonitor; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.transaction.GetUpdateableChecksums; +import org.caosdb.server.database.backend.transaction.RetrieveSparseEntity; +import org.caosdb.server.database.backend.transaction.SetFileChecksum; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.FileProperties; +import org.caosdb.server.entity.Message; +import org.caosdb.server.entity.container.TransactionContainer; +import org.caosdb.server.utils.FileUtils; /** * Retrieves all file without a checksum, calculates one and stores it to the database (method @@ -46,6 +46,7 @@ import java.security.NoSuchAlgorithmException; public class ChecksumUpdater extends WriteTransaction<TransactionContainer> implements Runnable { private Boolean running = false; + private static final ChecksumUpdater instance = new ChecksumUpdater(); private ChecksumUpdater() { @@ -85,7 +86,7 @@ public class ChecksumUpdater extends WriteTransaction<TransactionContainer> impl DatabaseMonitor.getInstance().acquireStrongAccess(this); // update - execute(new UpdateSparseEntity(fileEntity), strongAccess); + execute(new SetFileChecksum(fileEntity), strongAccess); strongAccess.commit(); } catch (final InterruptedException e) { @@ -141,10 +142,11 @@ public class ChecksumUpdater extends WriteTransaction<TransactionContainer> impl instance.running = false; return null; } - return execute(new RetrieveSparseEntity(id), weakAccess).getEntity(); + return execute(new RetrieveSparseEntity(id, null), weakAccess).getEntity(); } } catch (final Exception e) { e.printStackTrace(); + instance.running = false; return null; } finally { weakAccess.release(); diff --git a/src/main/java/caosdb/server/transaction/Delete.java b/src/main/java/org/caosdb/server/transaction/Delete.java similarity index 85% rename from src/main/java/caosdb/server/transaction/Delete.java rename to src/main/java/org/caosdb/server/transaction/Delete.java index 1d3aacbc78043fef6982b2b7663dc5d033e50e50..44e68b3afe6225f286ab76329b699f0cf0f10670 100644 --- a/src/main/java/caosdb/server/transaction/Delete.java +++ b/src/main/java/org/caosdb/server/transaction/Delete.java @@ -20,19 +20,19 @@ * * ** end header */ -package caosdb.server.transaction; +package org.caosdb.server.transaction; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.transaction.DeleteEntity; -import caosdb.server.database.backend.transaction.RetrieveFullEntity; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.container.DeleteContainer; -import caosdb.server.entity.container.TransactionContainer; -import caosdb.server.jobs.JobExecutionTime; -import caosdb.server.permissions.EntityPermission; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; import org.apache.shiro.authz.AuthorizationException; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.transaction.DeleteEntity; +import org.caosdb.server.database.backend.transaction.RetrieveFullEntity; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.container.DeleteContainer; +import org.caosdb.server.entity.container.TransactionContainer; +import org.caosdb.server.jobs.JobExecutionTime; +import org.caosdb.server.permissions.EntityPermission; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; public class Delete extends WriteTransaction<DeleteContainer> { diff --git a/src/main/java/caosdb/server/transaction/DeleteRoleTransaction.java b/src/main/java/org/caosdb/server/transaction/DeleteRoleTransaction.java similarity index 81% rename from src/main/java/caosdb/server/transaction/DeleteRoleTransaction.java rename to src/main/java/org/caosdb/server/transaction/DeleteRoleTransaction.java index e1ba3bec80663cb3b30d2dbdc48d9f9024c8f2d7..ad9a9925f8bed2ef03a1bcf9cd6b8c79adca6345 100644 --- a/src/main/java/caosdb/server/transaction/DeleteRoleTransaction.java +++ b/src/main/java/org/caosdb/server/transaction/DeleteRoleTransaction.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.transaction; +package org.caosdb.server.transaction; -import caosdb.server.accessControl.ACMPermissions; -import caosdb.server.database.backend.transaction.DeleteRole; -import caosdb.server.database.backend.transaction.RetrieveRole; -import caosdb.server.database.backend.transaction.SetPermissionRules; -import caosdb.server.utils.ServerMessages; import org.apache.shiro.SecurityUtils; +import org.caosdb.server.accessControl.ACMPermissions; +import org.caosdb.server.database.backend.transaction.DeleteRole; +import org.caosdb.server.database.backend.transaction.RetrieveRole; +import org.caosdb.server.database.backend.transaction.SetPermissionRules; +import org.caosdb.server.utils.ServerMessages; public class DeleteRoleTransaction extends AccessControlTransaction { diff --git a/src/main/java/caosdb/server/transaction/DeleteUserTransaction.java b/src/main/java/org/caosdb/server/transaction/DeleteUserTransaction.java similarity index 78% rename from src/main/java/caosdb/server/transaction/DeleteUserTransaction.java rename to src/main/java/org/caosdb/server/transaction/DeleteUserTransaction.java index cdedce31b34153494ceb0be28e4c3a9da360bb6e..0f2f5b7fb676e436b131ca69678214c2e34b974c 100644 --- a/src/main/java/caosdb/server/transaction/DeleteUserTransaction.java +++ b/src/main/java/org/caosdb/server/transaction/DeleteUserTransaction.java @@ -20,18 +20,18 @@ * * ** end header */ -package caosdb.server.transaction; +package org.caosdb.server.transaction; -import caosdb.server.accessControl.ACMPermissions; -import caosdb.server.accessControl.CredentialsValidator; -import caosdb.server.accessControl.UserSources; -import caosdb.server.database.backend.transaction.DeletePassword; -import caosdb.server.database.backend.transaction.DeleteUser; -import caosdb.server.database.backend.transaction.RetrievePasswordValidator; -import caosdb.server.entity.Message; -import caosdb.server.entity.Message.MessageType; -import caosdb.server.utils.ServerMessages; import org.apache.shiro.SecurityUtils; +import org.caosdb.server.accessControl.ACMPermissions; +import org.caosdb.server.accessControl.CredentialsValidator; +import org.caosdb.server.accessControl.UserSources; +import org.caosdb.server.database.backend.transaction.DeletePassword; +import org.caosdb.server.database.backend.transaction.DeleteUser; +import org.caosdb.server.database.backend.transaction.RetrievePasswordValidator; +import org.caosdb.server.entity.Message; +import org.caosdb.server.entity.Message.MessageType; +import org.caosdb.server.utils.ServerMessages; import org.jdom2.Element; public class DeleteUserTransaction extends AccessControlTransaction { diff --git a/src/main/java/caosdb/server/transaction/FileStorageConsistencyCheck.java b/src/main/java/org/caosdb/server/transaction/FileStorageConsistencyCheck.java similarity index 89% rename from src/main/java/caosdb/server/transaction/FileStorageConsistencyCheck.java rename to src/main/java/org/caosdb/server/transaction/FileStorageConsistencyCheck.java index 26cab30e898d2cd9f163ba3c9773b96c02110cbb..5d2a04b1e9f45360f47a93889f638eab23fbd512 100644 --- a/src/main/java/caosdb/server/transaction/FileStorageConsistencyCheck.java +++ b/src/main/java/org/caosdb/server/transaction/FileStorageConsistencyCheck.java @@ -20,27 +20,27 @@ * * ** end header */ -package caosdb.server.transaction; - -import caosdb.datetime.UTCDateTime; -import caosdb.server.database.DatabaseMonitor; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.transaction.FileConsistencyCheck; -import caosdb.server.database.backend.transaction.GetFileIterator; -import caosdb.server.database.backend.transaction.GetFileRecordByPath; -import caosdb.server.database.backend.transaction.RetrieveAllUncheckedFiles; -import caosdb.server.database.backend.transaction.SetFileCheckedTimestamp; -import caosdb.server.database.exceptions.EntityDoesNotExistException; -import caosdb.server.database.proto.SparseEntity; -import caosdb.server.entity.Message; -import caosdb.server.entity.xml.ToElementable; -import caosdb.server.utils.SHA512; +package org.caosdb.server.transaction; + import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map.Entry; import java.util.TimeZone; +import org.caosdb.datetime.UTCDateTime; +import org.caosdb.server.database.DatabaseMonitor; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.transaction.FileConsistencyCheck; +import org.caosdb.server.database.backend.transaction.GetFileIterator; +import org.caosdb.server.database.backend.transaction.GetFileRecordByPath; +import org.caosdb.server.database.backend.transaction.RetrieveAllUncheckedFiles; +import org.caosdb.server.database.backend.transaction.SetFileCheckedTimestamp; +import org.caosdb.server.database.exceptions.EntityDoesNotExistException; +import org.caosdb.server.database.proto.SparseEntity; +import org.caosdb.server.entity.Message; +import org.caosdb.server.entity.xml.ToElementable; +import org.caosdb.server.utils.SHA512; import org.jdom2.Element; public class FileStorageConsistencyCheck extends Thread diff --git a/src/main/java/caosdb/server/transaction/Insert.java b/src/main/java/org/caosdb/server/transaction/Insert.java similarity index 87% rename from src/main/java/caosdb/server/transaction/Insert.java rename to src/main/java/org/caosdb/server/transaction/Insert.java index 627ada52655c5e7802e98172d1c32f8280a95fb4..d37f7ce516f36252466555ea18fe249f2730fea1 100644 --- a/src/main/java/caosdb/server/transaction/Insert.java +++ b/src/main/java/org/caosdb/server/transaction/Insert.java @@ -20,18 +20,18 @@ * * ** end header */ -package caosdb.server.transaction; +package org.caosdb.server.transaction; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.transaction.InsertEntity; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.FileProperties; -import caosdb.server.entity.container.InsertContainer; -import caosdb.server.entity.container.TransactionContainer; -import caosdb.server.permissions.EntityACL; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; import org.apache.shiro.SecurityUtils; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.transaction.InsertEntity; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.FileProperties; +import org.caosdb.server.entity.container.InsertContainer; +import org.caosdb.server.entity.container.TransactionContainer; +import org.caosdb.server.permissions.EntityACL; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; public class Insert extends WriteTransaction<InsertContainer> { diff --git a/src/main/java/caosdb/server/transaction/InsertLogRecordTransaction.java b/src/main/java/org/caosdb/server/transaction/InsertLogRecordTransaction.java similarity index 87% rename from src/main/java/caosdb/server/transaction/InsertLogRecordTransaction.java rename to src/main/java/org/caosdb/server/transaction/InsertLogRecordTransaction.java index 3762b0bed3f726dd521f754043d0e99a5d2a3913..be01d93086e65694313c0d97c6b1603aef6a6bc7 100644 --- a/src/main/java/caosdb/server/transaction/InsertLogRecordTransaction.java +++ b/src/main/java/org/caosdb/server/transaction/InsertLogRecordTransaction.java @@ -20,13 +20,13 @@ * * ** end header */ -package caosdb.server.transaction; +package org.caosdb.server.transaction; -import caosdb.server.database.DatabaseMonitor; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.transaction.InsertLogRecord; import java.util.List; import java.util.logging.LogRecord; +import org.caosdb.server.database.DatabaseMonitor; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.transaction.InsertLogRecord; public class InsertLogRecordTransaction implements TransactionInterface { diff --git a/src/main/java/caosdb/server/transaction/InsertRoleTransaction.java b/src/main/java/org/caosdb/server/transaction/InsertRoleTransaction.java similarity index 82% rename from src/main/java/caosdb/server/transaction/InsertRoleTransaction.java rename to src/main/java/org/caosdb/server/transaction/InsertRoleTransaction.java index 8377210690692c8819e5197e35a8e549d27f2a30..b70e2bd71259645a8f619cb25d36998579e3dca7 100644 --- a/src/main/java/caosdb/server/transaction/InsertRoleTransaction.java +++ b/src/main/java/org/caosdb/server/transaction/InsertRoleTransaction.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.transaction; +package org.caosdb.server.transaction; -import caosdb.server.accessControl.ACMPermissions; -import caosdb.server.accessControl.Role; -import caosdb.server.database.backend.transaction.InsertRole; -import caosdb.server.database.backend.transaction.RetrieveRole; -import caosdb.server.utils.ServerMessages; import org.apache.shiro.SecurityUtils; +import org.caosdb.server.accessControl.ACMPermissions; +import org.caosdb.server.accessControl.Role; +import org.caosdb.server.database.backend.transaction.InsertRole; +import org.caosdb.server.database.backend.transaction.RetrieveRole; +import org.caosdb.server.utils.ServerMessages; public class InsertRoleTransaction extends AccessControlTransaction { diff --git a/src/main/java/caosdb/server/transaction/InsertUserTransaction.java b/src/main/java/org/caosdb/server/transaction/InsertUserTransaction.java similarity index 81% rename from src/main/java/caosdb/server/transaction/InsertUserTransaction.java rename to src/main/java/org/caosdb/server/transaction/InsertUserTransaction.java index 75b876b8bc291ea246746b4a8e85ccd26055c173..b91b1aa6b31911822ed9df4c1eaffa87374ede82 100644 --- a/src/main/java/caosdb/server/transaction/InsertUserTransaction.java +++ b/src/main/java/org/caosdb/server/transaction/InsertUserTransaction.java @@ -20,18 +20,18 @@ * * ** end header */ -package caosdb.server.transaction; +package org.caosdb.server.transaction; -import caosdb.server.accessControl.ACMPermissions; -import caosdb.server.accessControl.UserSources; -import caosdb.server.accessControl.UserStatus; -import caosdb.server.database.backend.transaction.RetrievePasswordValidator; -import caosdb.server.database.backend.transaction.SetPassword; -import caosdb.server.database.backend.transaction.UpdateUser; -import caosdb.server.database.proto.ProtoUser; -import caosdb.server.utils.ServerMessages; -import caosdb.server.utils.Utils; import org.apache.shiro.SecurityUtils; +import org.caosdb.server.accessControl.ACMPermissions; +import org.caosdb.server.accessControl.UserSources; +import org.caosdb.server.accessControl.UserStatus; +import org.caosdb.server.database.backend.transaction.RetrievePasswordValidator; +import org.caosdb.server.database.backend.transaction.SetPassword; +import org.caosdb.server.database.backend.transaction.UpdateUser; +import org.caosdb.server.database.proto.ProtoUser; +import org.caosdb.server.utils.ServerMessages; +import org.caosdb.server.utils.Utils; import org.jdom2.Element; public class InsertUserTransaction extends AccessControlTransaction { diff --git a/src/main/java/caosdb/server/transaction/Retrieve.java b/src/main/java/org/caosdb/server/transaction/Retrieve.java similarity index 85% rename from src/main/java/caosdb/server/transaction/Retrieve.java rename to src/main/java/org/caosdb/server/transaction/Retrieve.java index 0de1b8e06b66a4293668fb499fb28f33fa398187..5b01657a9c0df55f2b93fe83532b074543debff9 100644 --- a/src/main/java/caosdb/server/transaction/Retrieve.java +++ b/src/main/java/org/caosdb/server/transaction/Retrieve.java @@ -20,22 +20,22 @@ * * ** end header */ -package caosdb.server.transaction; - -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.transaction.RetrieveFullEntity; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.container.RetrieveContainer; -import caosdb.server.entity.xml.SetFieldStrategy; -import caosdb.server.entity.xml.ToElementStrategy; -import caosdb.server.entity.xml.ToElementable; -import caosdb.server.jobs.core.Mode; -import caosdb.server.jobs.core.RemoveDuplicates; -import caosdb.server.jobs.core.ResolveNames; -import caosdb.server.permissions.EntityPermission; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; +package org.caosdb.server.transaction; + import org.apache.shiro.authz.AuthorizationException; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.transaction.RetrieveFullEntity; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.container.RetrieveContainer; +import org.caosdb.server.entity.xml.SetFieldStrategy; +import org.caosdb.server.entity.xml.ToElementStrategy; +import org.caosdb.server.entity.xml.ToElementable; +import org.caosdb.server.jobs.core.Mode; +import org.caosdb.server.jobs.core.RemoveDuplicates; +import org.caosdb.server.jobs.core.ResolveNames; +import org.caosdb.server.permissions.EntityPermission; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; import org.jdom2.Element; public class Retrieve extends Transaction<RetrieveContainer> { diff --git a/src/main/java/caosdb/server/transaction/RetrieveLogRecordTransaction.java b/src/main/java/org/caosdb/server/transaction/RetrieveLogRecordTransaction.java similarity index 89% rename from src/main/java/caosdb/server/transaction/RetrieveLogRecordTransaction.java rename to src/main/java/org/caosdb/server/transaction/RetrieveLogRecordTransaction.java index bbe2e1f11a7bd4c7705a790dec78903fb0e7c20a..49d850dbcb672767da33a7c855063b04e1099f29 100644 --- a/src/main/java/caosdb/server/transaction/RetrieveLogRecordTransaction.java +++ b/src/main/java/org/caosdb/server/transaction/RetrieveLogRecordTransaction.java @@ -20,16 +20,16 @@ * * ** end header */ -package caosdb.server.transaction; +package org.caosdb.server.transaction; -import caosdb.server.accessControl.ACMPermissions; -import caosdb.server.database.DatabaseMonitor; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.transaction.RetrieveLogRecord; import java.util.List; import java.util.logging.Level; import java.util.logging.LogRecord; import org.apache.shiro.SecurityUtils; +import org.caosdb.server.accessControl.ACMPermissions; +import org.caosdb.server.database.DatabaseMonitor; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.transaction.RetrieveLogRecord; public class RetrieveLogRecordTransaction implements TransactionInterface { diff --git a/src/main/java/caosdb/server/transaction/RetrievePasswordValidatorTransaction.java b/src/main/java/org/caosdb/server/transaction/RetrievePasswordValidatorTransaction.java similarity index 86% rename from src/main/java/caosdb/server/transaction/RetrievePasswordValidatorTransaction.java rename to src/main/java/org/caosdb/server/transaction/RetrievePasswordValidatorTransaction.java index d18b5c306373d6b89aa924bd154db444fbdb8f9a..bb1e136bcb62c28800d0b7c2c0d88c9a2ee34634 100644 --- a/src/main/java/caosdb/server/transaction/RetrievePasswordValidatorTransaction.java +++ b/src/main/java/org/caosdb/server/transaction/RetrievePasswordValidatorTransaction.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.transaction; +package org.caosdb.server.transaction; -import caosdb.server.accessControl.CredentialsValidator; -import caosdb.server.database.backend.transaction.RetrievePasswordValidator; -import caosdb.server.utils.ServerMessages; +import org.caosdb.server.accessControl.CredentialsValidator; +import org.caosdb.server.database.backend.transaction.RetrievePasswordValidator; +import org.caosdb.server.utils.ServerMessages; public class RetrievePasswordValidatorTransaction extends AccessControlTransaction { diff --git a/src/main/java/caosdb/server/transaction/RetrievePermissionRulesTransaction.java b/src/main/java/org/caosdb/server/transaction/RetrievePermissionRulesTransaction.java similarity index 84% rename from src/main/java/caosdb/server/transaction/RetrievePermissionRulesTransaction.java rename to src/main/java/org/caosdb/server/transaction/RetrievePermissionRulesTransaction.java index d02722fd9e89e70c26e8782252c65fb9e199158c..225d068895d6484448b149d6b925facaabbf75fb 100644 --- a/src/main/java/caosdb/server/transaction/RetrievePermissionRulesTransaction.java +++ b/src/main/java/org/caosdb/server/transaction/RetrievePermissionRulesTransaction.java @@ -20,13 +20,13 @@ * * ** end header */ -package caosdb.server.transaction; +package org.caosdb.server.transaction; -import caosdb.server.database.backend.transaction.RetrievePermissionRules; -import caosdb.server.database.backend.transaction.RetrieveRole; -import caosdb.server.permissions.PermissionRule; -import caosdb.server.utils.ServerMessages; import java.util.HashSet; +import org.caosdb.server.database.backend.transaction.RetrievePermissionRules; +import org.caosdb.server.database.backend.transaction.RetrieveRole; +import org.caosdb.server.permissions.PermissionRule; +import org.caosdb.server.utils.ServerMessages; public class RetrievePermissionRulesTransaction extends AccessControlTransaction { diff --git a/src/main/java/caosdb/server/transaction/RetrieveRoleTransaction.java b/src/main/java/org/caosdb/server/transaction/RetrieveRoleTransaction.java similarity index 87% rename from src/main/java/caosdb/server/transaction/RetrieveRoleTransaction.java rename to src/main/java/org/caosdb/server/transaction/RetrieveRoleTransaction.java index 4d019f87fb572ce8e75393302764e8146034ee22..c7c251ba9847fe29f84589297f846f436f2a1309 100644 --- a/src/main/java/caosdb/server/transaction/RetrieveRoleTransaction.java +++ b/src/main/java/org/caosdb/server/transaction/RetrieveRoleTransaction.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.transaction; +package org.caosdb.server.transaction; -import caosdb.server.accessControl.Role; -import caosdb.server.database.backend.transaction.RetrieveRole; -import caosdb.server.utils.ServerMessages; +import org.caosdb.server.accessControl.Role; +import org.caosdb.server.database.backend.transaction.RetrieveRole; +import org.caosdb.server.utils.ServerMessages; public class RetrieveRoleTransaction extends AccessControlTransaction { diff --git a/src/main/java/caosdb/server/transaction/RetrieveSparseEntityByPath.java b/src/main/java/org/caosdb/server/transaction/RetrieveSparseEntityByPath.java similarity index 86% rename from src/main/java/caosdb/server/transaction/RetrieveSparseEntityByPath.java rename to src/main/java/org/caosdb/server/transaction/RetrieveSparseEntityByPath.java index 2b936247bba9ece2d4bb9ab5cb1a5a1b2cbada74..d82985fe8060b3919d48c17a6bbd2994fc92c5bf 100644 --- a/src/main/java/caosdb/server/transaction/RetrieveSparseEntityByPath.java +++ b/src/main/java/org/caosdb/server/transaction/RetrieveSparseEntityByPath.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.transaction; +package org.caosdb.server.transaction; -import caosdb.server.database.backend.transaction.GetFileRecordByPath; -import caosdb.server.database.backend.transaction.RetrieveSparseEntity; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.container.TransactionContainer; +import org.caosdb.server.database.backend.transaction.GetFileRecordByPath; +import org.caosdb.server.database.backend.transaction.RetrieveSparseEntity; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.container.TransactionContainer; public class RetrieveSparseEntityByPath extends Transaction<TransactionContainer> { diff --git a/src/main/java/caosdb/server/transaction/RetrieveUserRolesTransaction.java b/src/main/java/org/caosdb/server/transaction/RetrieveUserRolesTransaction.java similarity index 88% rename from src/main/java/caosdb/server/transaction/RetrieveUserRolesTransaction.java rename to src/main/java/org/caosdb/server/transaction/RetrieveUserRolesTransaction.java index 76740a73c9439e4ea9e45479e57501c4c4e1a0d0..97e518d06ac9ad5766b3801be8b1f1403cf8af3f 100644 --- a/src/main/java/caosdb/server/transaction/RetrieveUserRolesTransaction.java +++ b/src/main/java/org/caosdb/server/transaction/RetrieveUserRolesTransaction.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.transaction; +package org.caosdb.server.transaction; -import caosdb.server.accessControl.Principal; -import caosdb.server.accessControl.UserSources; -import caosdb.server.utils.ServerMessages; import java.util.Set; +import org.caosdb.server.accessControl.Principal; +import org.caosdb.server.accessControl.UserSources; +import org.caosdb.server.utils.ServerMessages; import org.jdom2.Element; public class RetrieveUserRolesTransaction implements TransactionInterface { @@ -58,7 +58,7 @@ public class RetrieveUserRolesTransaction implements TransactionInterface { @Override public void execute() throws Exception { if (UserSources.isUserExisting(new Principal(this.realm, this.user))) { - this.roles = UserSources.resolve(this.realm, this.user); + this.roles = UserSources.resolveRoles(this.realm, this.user); } else { throw ServerMessages.ACCOUNT_DOES_NOT_EXIST; } diff --git a/src/main/java/caosdb/server/transaction/RetrieveUserTransaction.java b/src/main/java/org/caosdb/server/transaction/RetrieveUserTransaction.java similarity index 88% rename from src/main/java/caosdb/server/transaction/RetrieveUserTransaction.java rename to src/main/java/org/caosdb/server/transaction/RetrieveUserTransaction.java index f2728a64664ad72f113e55a91ef87496810ad7c6..228b1585233ae71d3b7130196f68c3b9f83f5ed2 100644 --- a/src/main/java/caosdb/server/transaction/RetrieveUserTransaction.java +++ b/src/main/java/org/caosdb/server/transaction/RetrieveUserTransaction.java @@ -20,15 +20,15 @@ * * ** end header */ -package caosdb.server.transaction; +package org.caosdb.server.transaction; -import caosdb.server.accessControl.Principal; -import caosdb.server.accessControl.UserSources; -import caosdb.server.accessControl.UserStatus; -import caosdb.server.database.backend.transaction.RetrieveUser; -import caosdb.server.database.proto.ProtoUser; -import caosdb.server.utils.ServerMessages; import java.util.Set; +import org.caosdb.server.accessControl.Principal; +import org.caosdb.server.accessControl.UserSources; +import org.caosdb.server.accessControl.UserStatus; +import org.caosdb.server.database.backend.transaction.RetrieveUser; +import org.caosdb.server.database.proto.ProtoUser; +import org.caosdb.server.utils.ServerMessages; import org.jdom2.Element; public class RetrieveUserTransaction extends AccessControlTransaction { diff --git a/src/main/java/caosdb/server/transaction/Transaction.java b/src/main/java/org/caosdb/server/transaction/Transaction.java similarity index 84% rename from src/main/java/caosdb/server/transaction/Transaction.java rename to src/main/java/org/caosdb/server/transaction/Transaction.java index 28b8276e2b93699f2315fb754303194208bb37e5..0235b8a25cd1d7df9f923023b1be2d5597038b0e 100644 --- a/src/main/java/caosdb/server/transaction/Transaction.java +++ b/src/main/java/org/caosdb/server/transaction/Transaction.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2020 Indiscale GmbH <info@indiscale.com> + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -20,34 +22,33 @@ * * ** end header */ -package caosdb.server.transaction; - -import caosdb.datetime.UTCDateTime; -import caosdb.server.accessControl.AuthenticationUtils; -import caosdb.server.accessControl.Principal; -import caosdb.server.database.DatabaseMonitor; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.transaction.InsertTransactionHistory; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.misc.TransactionBenchmark; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.Message; -import caosdb.server.entity.Message.MessageType; -import caosdb.server.entity.container.TransactionContainer; -import caosdb.server.jobs.Job; -import caosdb.server.jobs.JobExecutionTime; -import caosdb.server.jobs.Schedule; -import caosdb.server.jobs.core.AccessControl; -import caosdb.server.jobs.core.CheckDatatypePresent; -import caosdb.server.jobs.core.CheckEntityACLRoles; -import caosdb.server.jobs.core.Mode; -import caosdb.server.jobs.core.PickUp; -import caosdb.server.utils.AbstractObservable; -import caosdb.server.utils.Info; -import caosdb.server.utils.Observer; +package org.caosdb.server.transaction; + import java.util.HashMap; import java.util.List; import org.apache.shiro.subject.Subject; +import org.caosdb.datetime.UTCDateTime; +import org.caosdb.server.accessControl.Principal; +import org.caosdb.server.database.DatabaseMonitor; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.transaction.InsertTransactionHistory; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.misc.TransactionBenchmark; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Message; +import org.caosdb.server.entity.Message.MessageType; +import org.caosdb.server.entity.container.TransactionContainer; +import org.caosdb.server.jobs.Job; +import org.caosdb.server.jobs.JobExecutionTime; +import org.caosdb.server.jobs.Schedule; +import org.caosdb.server.jobs.core.AccessControl; +import org.caosdb.server.jobs.core.CheckDatatypePresent; +import org.caosdb.server.jobs.core.CheckEntityACLRoles; +import org.caosdb.server.jobs.core.Mode; +import org.caosdb.server.jobs.core.PickUp; +import org.caosdb.server.utils.AbstractObservable; +import org.caosdb.server.utils.Info; +import org.caosdb.server.utils.Observer; public abstract class Transaction<C extends TransactionContainer> extends AbstractObservable implements TransactionInterface { @@ -227,14 +228,8 @@ public abstract class Transaction<C extends TransactionContainer> extends Abstra // TODO move to post-transaction job private void writeHistory() throws TransactionException, Message { if (logHistory()) { - String realm = - getTransactor().getPrincipal() == AuthenticationUtils.ANONYMOUS_USER.getPrincipal() - ? "" - : ((Principal) getTransactor().getPrincipal()).getRealm(); - String username = - getTransactor().getPrincipal() == AuthenticationUtils.ANONYMOUS_USER.getPrincipal() - ? "anonymous" - : ((Principal) getTransactor().getPrincipal()).getUsername(); + String realm = ((Principal) getTransactor().getPrincipal()).getRealm(); + String username = ((Principal) getTransactor().getPrincipal()).getUsername(); execute( new InsertTransactionHistory( getContainer(), this.getClass().getSimpleName(), realm, username, getTimestamp()), diff --git a/src/main/java/caosdb/server/transaction/TransactionInterface.java b/src/main/java/org/caosdb/server/transaction/TransactionInterface.java similarity index 85% rename from src/main/java/caosdb/server/transaction/TransactionInterface.java rename to src/main/java/org/caosdb/server/transaction/TransactionInterface.java index 1aaf2786cc613709c59c92b7102474cead00ca1c..1aa41b2bbc31063b2978aa9c141e75c98799f124 100644 --- a/src/main/java/caosdb/server/transaction/TransactionInterface.java +++ b/src/main/java/org/caosdb/server/transaction/TransactionInterface.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.transaction; +package org.caosdb.server.transaction; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.access.Access; -import caosdb.server.database.misc.RollBackHandler; -import caosdb.server.database.misc.TransactionBenchmark; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.misc.RollBackHandler; +import org.caosdb.server.database.misc.TransactionBenchmark; public interface TransactionInterface { diff --git a/src/main/java/caosdb/server/transaction/Update.java b/src/main/java/org/caosdb/server/transaction/Update.java similarity index 94% rename from src/main/java/caosdb/server/transaction/Update.java rename to src/main/java/org/caosdb/server/transaction/Update.java index b9e6e8de19f137014d10d1c6516c07ca2acabf8e..f5a9a7ffd8b32e4b8d220ea6bba44731b51047ef 100644 --- a/src/main/java/caosdb/server/transaction/Update.java +++ b/src/main/java/org/caosdb/server/transaction/Update.java @@ -20,30 +20,30 @@ * * ** end header */ -package caosdb.server.transaction; - -import caosdb.server.CaosDBException; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.transaction.RetrieveFullEntity; -import caosdb.server.database.backend.transaction.UpdateEntity; -import caosdb.server.entity.Entity; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.FileProperties; -import caosdb.server.entity.RetrieveEntity; -import caosdb.server.entity.container.TransactionContainer; -import caosdb.server.entity.container.UpdateContainer; -import caosdb.server.entity.wrapper.Parent; -import caosdb.server.entity.wrapper.Property; -import caosdb.server.permissions.EntityPermission; -import caosdb.server.permissions.Permission; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; +package org.caosdb.server.transaction; + import com.google.common.base.Objects; import java.io.IOException; import java.security.NoSuchAlgorithmException; import java.util.HashSet; import java.util.Set; import org.apache.shiro.authz.AuthorizationException; +import org.caosdb.server.CaosDBException; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.transaction.RetrieveFullEntity; +import org.caosdb.server.database.backend.transaction.UpdateEntity; +import org.caosdb.server.entity.Entity; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.FileProperties; +import org.caosdb.server.entity.RetrieveEntity; +import org.caosdb.server.entity.container.TransactionContainer; +import org.caosdb.server.entity.container.UpdateContainer; +import org.caosdb.server.entity.wrapper.Parent; +import org.caosdb.server.entity.wrapper.Property; +import org.caosdb.server.permissions.EntityPermission; +import org.caosdb.server.permissions.Permission; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; public class Update extends WriteTransaction<UpdateContainer> { diff --git a/src/main/java/caosdb/server/transaction/UpdatePermissionRulesTransaction.java b/src/main/java/org/caosdb/server/transaction/UpdatePermissionRulesTransaction.java similarity index 83% rename from src/main/java/caosdb/server/transaction/UpdatePermissionRulesTransaction.java rename to src/main/java/org/caosdb/server/transaction/UpdatePermissionRulesTransaction.java index e537b001f2af65e35c65e8c8ad88d37a2fd2bc01..4f8c9369fe915675e24c55e9fc7e0052ede360b3 100644 --- a/src/main/java/caosdb/server/transaction/UpdatePermissionRulesTransaction.java +++ b/src/main/java/org/caosdb/server/transaction/UpdatePermissionRulesTransaction.java @@ -20,15 +20,15 @@ * * ** end header */ -package caosdb.server.transaction; +package org.caosdb.server.transaction; -import caosdb.server.accessControl.ACMPermissions; -import caosdb.server.database.backend.transaction.RetrieveRole; -import caosdb.server.database.backend.transaction.SetPermissionRules; -import caosdb.server.permissions.PermissionRule; -import caosdb.server.utils.ServerMessages; import java.util.Set; import org.apache.shiro.SecurityUtils; +import org.caosdb.server.accessControl.ACMPermissions; +import org.caosdb.server.database.backend.transaction.RetrieveRole; +import org.caosdb.server.database.backend.transaction.SetPermissionRules; +import org.caosdb.server.permissions.PermissionRule; +import org.caosdb.server.utils.ServerMessages; public class UpdatePermissionRulesTransaction extends AccessControlTransaction { diff --git a/src/main/java/caosdb/server/transaction/UpdateRoleTransaction.java b/src/main/java/org/caosdb/server/transaction/UpdateRoleTransaction.java similarity index 80% rename from src/main/java/caosdb/server/transaction/UpdateRoleTransaction.java rename to src/main/java/org/caosdb/server/transaction/UpdateRoleTransaction.java index dfec776005800469654f144a0c5ae6f0213a04ad..7e1632f8a0a9252c6e400d352bb63e133f6ae9e6 100644 --- a/src/main/java/caosdb/server/transaction/UpdateRoleTransaction.java +++ b/src/main/java/org/caosdb/server/transaction/UpdateRoleTransaction.java @@ -20,15 +20,15 @@ * * ** end header */ -package caosdb.server.transaction; +package org.caosdb.server.transaction; -import caosdb.server.accessControl.ACMPermissions; -import caosdb.server.accessControl.Role; -import caosdb.server.accessControl.UserSources; -import caosdb.server.database.backend.transaction.InsertRole; -import caosdb.server.database.backend.transaction.RetrieveRole; -import caosdb.server.utils.ServerMessages; import org.apache.shiro.SecurityUtils; +import org.caosdb.server.accessControl.ACMPermissions; +import org.caosdb.server.accessControl.Role; +import org.caosdb.server.accessControl.UserSources; +import org.caosdb.server.database.backend.transaction.InsertRole; +import org.caosdb.server.database.backend.transaction.RetrieveRole; +import org.caosdb.server.utils.ServerMessages; public class UpdateRoleTransaction extends AccessControlTransaction { diff --git a/src/main/java/caosdb/server/transaction/UpdateUserRolesTransaction.java b/src/main/java/org/caosdb/server/transaction/UpdateUserRolesTransaction.java similarity index 84% rename from src/main/java/caosdb/server/transaction/UpdateUserRolesTransaction.java rename to src/main/java/org/caosdb/server/transaction/UpdateUserRolesTransaction.java index 257e8c06cc9d9c9f24774e541cea611663f5ff0d..a74d875fc8b4d14821de24522e8b9bc531416ee5 100644 --- a/src/main/java/caosdb/server/transaction/UpdateUserRolesTransaction.java +++ b/src/main/java/org/caosdb/server/transaction/UpdateUserRolesTransaction.java @@ -20,17 +20,17 @@ * * ** end header */ -package caosdb.server.transaction; +package org.caosdb.server.transaction; -import caosdb.server.accessControl.ACMPermissions; -import caosdb.server.accessControl.Principal; -import caosdb.server.accessControl.UserSources; -import caosdb.server.database.backend.transaction.RetrieveRole; -import caosdb.server.database.backend.transaction.UpdateUserRoles; -import caosdb.server.utils.ServerMessages; import java.util.HashSet; import java.util.Set; import org.apache.shiro.SecurityUtils; +import org.caosdb.server.accessControl.ACMPermissions; +import org.caosdb.server.accessControl.Principal; +import org.caosdb.server.accessControl.UserSources; +import org.caosdb.server.database.backend.transaction.RetrieveRole; +import org.caosdb.server.database.backend.transaction.UpdateUserRoles; +import org.caosdb.server.utils.ServerMessages; import org.jdom2.Element; public class UpdateUserRolesTransaction extends AccessControlTransaction { @@ -68,7 +68,7 @@ public class UpdateUserRolesTransaction extends AccessControlTransaction { } public Element getUserRolesElement() { - final Set<String> resulting_roles = UserSources.resolve(this.realm, this.user); + final Set<String> resulting_roles = UserSources.resolveRoles(this.realm, this.user); final Element rolesElem = RetrieveUserRolesTransaction.getUserRolesElement(resulting_roles); if (!this.roles.equals(resulting_roles) && resulting_roles != null) { final Element warning = new Element("Warning"); diff --git a/src/main/java/caosdb/server/transaction/UpdateUserTransaction.java b/src/main/java/org/caosdb/server/transaction/UpdateUserTransaction.java similarity index 84% rename from src/main/java/caosdb/server/transaction/UpdateUserTransaction.java rename to src/main/java/org/caosdb/server/transaction/UpdateUserTransaction.java index ca29bb7977da8fc677c774b30a1f3fa78879c5a7..330ce5907f601b4b4345c26b1d483029f7d049b1 100644 --- a/src/main/java/caosdb/server/transaction/UpdateUserTransaction.java +++ b/src/main/java/org/caosdb/server/transaction/UpdateUserTransaction.java @@ -20,24 +20,24 @@ * * ** end header */ -package caosdb.server.transaction; +package org.caosdb.server.transaction; -import caosdb.server.accessControl.ACMPermissions; -import caosdb.server.accessControl.Principal; -import caosdb.server.accessControl.UserSources; -import caosdb.server.accessControl.UserStatus; -import caosdb.server.database.backend.transaction.RetrieveUser; -import caosdb.server.database.backend.transaction.SetPassword; -import caosdb.server.database.backend.transaction.UpdateUser; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.ProtoUser; -import caosdb.server.entity.Entity; -import caosdb.server.entity.RetrieveEntity; -import caosdb.server.entity.container.RetrieveContainer; -import caosdb.server.utils.EntityStatus; -import caosdb.server.utils.ServerMessages; -import caosdb.server.utils.Utils; import org.apache.shiro.SecurityUtils; +import org.caosdb.server.accessControl.ACMPermissions; +import org.caosdb.server.accessControl.Principal; +import org.caosdb.server.accessControl.UserSources; +import org.caosdb.server.accessControl.UserStatus; +import org.caosdb.server.database.backend.transaction.RetrieveUser; +import org.caosdb.server.database.backend.transaction.SetPassword; +import org.caosdb.server.database.backend.transaction.UpdateUser; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.ProtoUser; +import org.caosdb.server.entity.Entity; +import org.caosdb.server.entity.RetrieveEntity; +import org.caosdb.server.entity.container.RetrieveContainer; +import org.caosdb.server.utils.EntityStatus; +import org.caosdb.server.utils.ServerMessages; +import org.caosdb.server.utils.Utils; import org.jdom2.Element; public class UpdateUserTransaction extends AccessControlTransaction { @@ -78,7 +78,7 @@ public class UpdateUserTransaction extends AccessControlTransaction { + this.user.realm + "' cannot be updated. Only the users from the realm '" + UserSources.getInternalRealm().getName() - + "' can change their passwords from withing caosdb."); + + "' can change their passwords from within caosdb."); } SecurityUtils.getSubject() diff --git a/src/main/java/caosdb/server/transaction/WriteTransaction.java b/src/main/java/org/caosdb/server/transaction/WriteTransaction.java similarity index 87% rename from src/main/java/caosdb/server/transaction/WriteTransaction.java rename to src/main/java/org/caosdb/server/transaction/WriteTransaction.java index e67ae0600bc573efbdf67b9b341299fe1fe3ca00..04c3834caad3264d6c1b8e5c99cf5b17a513e403 100644 --- a/src/main/java/caosdb/server/transaction/WriteTransaction.java +++ b/src/main/java/org/caosdb/server/transaction/WriteTransaction.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.transaction; +package org.caosdb.server.transaction; -import caosdb.server.database.misc.RollBackHandler; -import caosdb.server.entity.FileProperties; -import caosdb.server.entity.container.TransactionContainer; +import org.caosdb.server.database.misc.RollBackHandler; +import org.caosdb.server.entity.FileProperties; +import org.caosdb.server.entity.container.TransactionContainer; public abstract class WriteTransaction<C extends TransactionContainer> extends Transaction<C> { @@ -64,4 +64,8 @@ public abstract class WriteTransaction<C extends TransactionContainer> extends T } } } + + public String getSRID() { + return getContainer().getRequestId(); + } } diff --git a/src/main/java/caosdb/server/utils/AbstractObservable.java b/src/main/java/org/caosdb/server/utils/AbstractObservable.java similarity index 98% rename from src/main/java/caosdb/server/utils/AbstractObservable.java rename to src/main/java/org/caosdb/server/utils/AbstractObservable.java index d52a51bfef0375cad9069d57b744c0618813aae3..a19fff9d44ce7339a9cdc6712e0806ef42bdfd40 100644 --- a/src/main/java/caosdb/server/utils/AbstractObservable.java +++ b/src/main/java/org/caosdb/server/utils/AbstractObservable.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; import java.util.Iterator; import org.eclipse.jetty.util.ConcurrentHashSet; diff --git a/src/main/java/caosdb/server/utils/AsynchronousHasher.java b/src/main/java/org/caosdb/server/utils/AsynchronousHasher.java similarity index 97% rename from src/main/java/caosdb/server/utils/AsynchronousHasher.java rename to src/main/java/org/caosdb/server/utils/AsynchronousHasher.java index 3c504c3f4b0532f692431c83b7ca441bfd8808f3..47dad864835e8c370ddef31988205a113665b6c1 100644 --- a/src/main/java/caosdb/server/utils/AsynchronousHasher.java +++ b/src/main/java/org/caosdb/server/utils/AsynchronousHasher.java @@ -1,3 +1,4 @@ +package org.caosdb.server.utils; /* * ** header v3.0 * This file is a part of the CaosDB Project. @@ -20,7 +21,7 @@ * * ** end header */ -// package caosdb.server.utils; +// package org.caosdb.server.utils; // // import java.io.File; // diff --git a/src/main/java/caosdb/server/utils/ConfigurationException.java b/src/main/java/org/caosdb/server/utils/ConfigurationException.java similarity index 90% rename from src/main/java/caosdb/server/utils/ConfigurationException.java rename to src/main/java/org/caosdb/server/utils/ConfigurationException.java index 74a741873b3d4e53f6d5af1dfcf2bc0bda1b125b..517c11677c73d9624b93df18fb5196e2f4578024 100644 --- a/src/main/java/caosdb/server/utils/ConfigurationException.java +++ b/src/main/java/org/caosdb/server/utils/ConfigurationException.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; public class ConfigurationException extends RuntimeException { - private static final long serialVersionUID = -8445574584694720914L; + private static final long serialVersionUID = -8973694831724941007L; public ConfigurationException(String reason) { super(reason); diff --git a/src/main/java/caosdb/server/utils/CronJob.java b/src/main/java/org/caosdb/server/utils/CronJob.java similarity index 97% rename from src/main/java/caosdb/server/utils/CronJob.java rename to src/main/java/org/caosdb/server/utils/CronJob.java index a6608b1020df2796839ec419203630db4a1ee921..8110a51752d996fc2f4fd2af3e5b7350f3e4d01f 100644 --- a/src/main/java/caosdb/server/utils/CronJob.java +++ b/src/main/java/org/caosdb/server/utils/CronJob.java @@ -20,10 +20,10 @@ * * ** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; -import caosdb.server.CaosDBServer; import java.util.HashMap; +import org.caosdb.server.CaosDBServer; public class CronJob { diff --git a/src/main/java/caosdb/server/utils/EntityStatus.java b/src/main/java/org/caosdb/server/utils/EntityStatus.java similarity index 98% rename from src/main/java/caosdb/server/utils/EntityStatus.java rename to src/main/java/org/caosdb/server/utils/EntityStatus.java index 3e906302c45623ae0cacba7f45c20dd5f560a7fb..ef8bdc101c61e216c9aa448d667b59dfa5107672 100644 --- a/src/main/java/caosdb/server/utils/EntityStatus.java +++ b/src/main/java/org/caosdb/server/utils/EntityStatus.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; /** * IGNORE - This instance must be ignored during further processing. <br> diff --git a/src/main/java/caosdb/server/utils/FileUtils.java b/src/main/java/org/caosdb/server/utils/FileUtils.java similarity index 97% rename from src/main/java/caosdb/server/utils/FileUtils.java rename to src/main/java/org/caosdb/server/utils/FileUtils.java index 824646caab6983863acd7d35a276a1213b393235..70ba003018e3ccc7831bf9f536e827552445ec6a 100644 --- a/src/main/java/caosdb/server/utils/FileUtils.java +++ b/src/main/java/org/caosdb/server/utils/FileUtils.java @@ -20,18 +20,12 @@ * * ** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; import static java.nio.file.Files.isSameFile; import static java.nio.file.Files.isSymbolicLink; import static java.nio.file.Files.readSymbolicLink; -import caosdb.server.CaosDBException; -import caosdb.server.CaosDBServer; -import caosdb.server.FileSystem; -import caosdb.server.ServerProperties; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.entity.Message; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; @@ -43,6 +37,12 @@ import java.nio.file.LinkOption; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; +import org.caosdb.server.CaosDBException; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.FileSystem; +import org.caosdb.server.ServerProperties; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.entity.Message; import org.eclipse.jetty.io.RuntimeIOException; public class FileUtils { @@ -218,6 +218,13 @@ public class FileUtils { } } + /** + * @deprecated Soon to be removed. + * @throws IOException + * @throws InterruptedException + * @throws CaosDBException + */ + @Deprecated public static void testChownScript() throws IOException, InterruptedException, CaosDBException { final String sudopw = CaosDBServer.getServerProperty(ServerProperties.KEY_SUDO_PASSWORD); final Process cmd = diff --git a/src/main/java/caosdb/server/utils/FlagInfo.java b/src/main/java/org/caosdb/server/utils/FlagInfo.java similarity index 89% rename from src/main/java/caosdb/server/utils/FlagInfo.java rename to src/main/java/org/caosdb/server/utils/FlagInfo.java index 6a94194ba401e36c3c4e2fbc41c939b0c3aa6a43..164c6aabe9c4fafff26f93db30d791fa91389eee 100644 --- a/src/main/java/caosdb/server/utils/FlagInfo.java +++ b/src/main/java/org/caosdb/server/utils/FlagInfo.java @@ -20,15 +20,15 @@ * * ** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; -import caosdb.server.jobs.FlagJob; -import caosdb.server.jobs.Job; -import caosdb.server.jobs.JobAnnotation; -import caosdb.server.transaction.TransactionInterface; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Set; +import org.caosdb.server.jobs.FlagJob; +import org.caosdb.server.jobs.Job; +import org.caosdb.server.jobs.JobAnnotation; +import org.caosdb.server.transaction.TransactionInterface; import org.jdom2.Element; import org.reflections.Reflections; @@ -38,7 +38,7 @@ public class FlagInfo { public static ArrayList<JobAnnotation> scan() { final ArrayList<JobAnnotation> as = new ArrayList<JobAnnotation>(); - final Reflections jobPackage = new Reflections("caosdb.server.jobs.core"); + final Reflections jobPackage = new Reflections("org.caosdb.server.jobs.core"); final Set<Class<? extends FlagJob>> allClassesSet = jobPackage.getSubTypesOf(FlagJob.class); for (final Class<? extends Job> c : allClassesSet) { for (final Annotation a : c.getAnnotations()) { diff --git a/src/main/java/caosdb/server/utils/HashAlgorithm.java b/src/main/java/org/caosdb/server/utils/HashAlgorithm.java similarity index 96% rename from src/main/java/caosdb/server/utils/HashAlgorithm.java rename to src/main/java/org/caosdb/server/utils/HashAlgorithm.java index d6155a854aa8944fc7eeb861007b5aed8f3a7946..6bf517fc5b906b4199219bde5654dbdebf3c5ecb 100644 --- a/src/main/java/caosdb/server/utils/HashAlgorithm.java +++ b/src/main/java/org/caosdb/server/utils/HashAlgorithm.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; import java.io.File; diff --git a/src/main/java/caosdb/server/utils/HashException.java b/src/main/java/org/caosdb/server/utils/HashException.java similarity index 88% rename from src/main/java/caosdb/server/utils/HashException.java rename to src/main/java/org/caosdb/server/utils/HashException.java index 6df49b0a1fc28dd37c315bd05047db2750709fa8..46c3ecc6fba5cceac03605f80f4154e8f6a97594 100644 --- a/src/main/java/caosdb/server/utils/HashException.java +++ b/src/main/java/org/caosdb/server/utils/HashException.java @@ -20,14 +20,14 @@ * * ** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; -import caosdb.server.CaosDBException; +import org.caosdb.server.CaosDBException; public class HashException extends CaosDBException { /** */ - private static final long serialVersionUID = 4842032786089373949L; + private static final long serialVersionUID = 5478908505951882613L; public HashException(final String string) { super(string); diff --git a/src/main/java/caosdb/server/utils/HashNotReadyException.java b/src/main/java/org/caosdb/server/utils/HashNotReadyException.java similarity index 90% rename from src/main/java/caosdb/server/utils/HashNotReadyException.java rename to src/main/java/org/caosdb/server/utils/HashNotReadyException.java index 2638f6121b21dfa47ab1792ddbeb1f0e5c1664c5..7b52a92406d53f54ba11c257353c255bded46696 100644 --- a/src/main/java/caosdb/server/utils/HashNotReadyException.java +++ b/src/main/java/org/caosdb/server/utils/HashNotReadyException.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; public class HashNotReadyException extends HashException { @@ -29,5 +29,5 @@ public class HashNotReadyException extends HashException { } /** */ - private static final long serialVersionUID = 2389389859670664559L; + private static final long serialVersionUID = 7709720557931578533L; } diff --git a/src/main/java/caosdb/server/utils/HashTimeoutException.java b/src/main/java/org/caosdb/server/utils/HashTimeoutException.java similarity index 90% rename from src/main/java/caosdb/server/utils/HashTimeoutException.java rename to src/main/java/org/caosdb/server/utils/HashTimeoutException.java index 03423c5e1d20631ae6f1e0ab2abff0272f432124..4733ae5314d235cab9c7ee3e98400bd90483f277 100644 --- a/src/main/java/caosdb/server/utils/HashTimeoutException.java +++ b/src/main/java/org/caosdb/server/utils/HashTimeoutException.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; public class HashTimeoutException extends HashException { @@ -29,5 +29,5 @@ public class HashTimeoutException extends HashException { } /** */ - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = -1616384952193042048L; } diff --git a/src/main/java/caosdb/server/utils/Hasher.java b/src/main/java/org/caosdb/server/utils/Hasher.java similarity index 97% rename from src/main/java/caosdb/server/utils/Hasher.java rename to src/main/java/org/caosdb/server/utils/Hasher.java index 0d01e3f7cf572596323a5949dfd3d192a6c7d6bf..9eb009cd6e3445f3cc87639e8fc6d14793f386f2 100644 --- a/src/main/java/caosdb/server/utils/Hasher.java +++ b/src/main/java/org/caosdb/server/utils/Hasher.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; import java.io.File; import java.io.IOException; diff --git a/src/main/java/caosdb/server/utils/Info.java b/src/main/java/org/caosdb/server/utils/Info.java similarity index 93% rename from src/main/java/caosdb/server/utils/Info.java rename to src/main/java/org/caosdb/server/utils/Info.java index bf85546d8303c072a322afcb9433c77eda928fec..19f792cf625765924f02a7b734f2e57849584ffc 100644 --- a/src/main/java/caosdb/server/utils/Info.java +++ b/src/main/java/org/caosdb/server/utils/Info.java @@ -20,24 +20,24 @@ * * ** end header */ -package caosdb.server.utils; - -import caosdb.server.CaosDBServer; -import caosdb.server.FileSystem; -import caosdb.server.database.DatabaseMonitor; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.transaction.GetInfo; -import caosdb.server.database.backend.transaction.SyncStats; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.proto.ProtoInfo; -import caosdb.server.entity.Message; -import caosdb.server.transaction.TransactionInterface; +package org.caosdb.server.utils; + import java.io.File; import java.io.IOException; import java.sql.SQLException; import java.util.LinkedList; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.FileSystem; +import org.caosdb.server.database.DatabaseMonitor; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.transaction.GetInfo; +import org.caosdb.server.database.backend.transaction.SyncStats; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.proto.ProtoInfo; +import org.caosdb.server.entity.Message; +import org.caosdb.server.transaction.TransactionInterface; import org.jdom2.Element; public class Info extends AbstractObservable implements Observer, TransactionInterface { diff --git a/src/main/java/caosdb/server/utils/Initialization.java b/src/main/java/org/caosdb/server/utils/Initialization.java similarity index 78% rename from src/main/java/caosdb/server/utils/Initialization.java rename to src/main/java/org/caosdb/server/utils/Initialization.java index e77922a417c1a2ef9542cb3dc9b8971ca10b332a..baae53804f57433aa58da1ae1b9c58060c3db160 100644 --- a/src/main/java/caosdb/server/utils/Initialization.java +++ b/src/main/java/org/caosdb/server/utils/Initialization.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2020 Indiscale GmbH <info@indiscale.com> + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -20,13 +22,13 @@ * * ** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; -import caosdb.server.database.DatabaseMonitor; -import caosdb.server.database.access.Access; -import caosdb.server.transaction.TransactionInterface; +import org.caosdb.server.database.DatabaseMonitor; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.transaction.TransactionInterface; -public final class Initialization implements TransactionInterface { +public final class Initialization implements TransactionInterface, AutoCloseable { private Access access; private static final Initialization instance = new Initialization(); @@ -43,13 +45,14 @@ public final class Initialization implements TransactionInterface { return this.access; } - public final void release() { + @Override + public void execute() throws Exception {} + + @Override + public void close() throws Exception { if (this.access != null) { this.access.release(); this.access = null; } } - - @Override - public void execute() throws Exception {} } diff --git a/src/main/java/caosdb/server/utils/NullPrintStream.java b/src/main/java/org/caosdb/server/utils/NullPrintStream.java similarity index 97% rename from src/main/java/caosdb/server/utils/NullPrintStream.java rename to src/main/java/org/caosdb/server/utils/NullPrintStream.java index b6b7211b4493762473cad5a8a3edfa4bb89f6618..9256bdee5af75af1a141c2f1dbdbee54cf1b64e2 100644 --- a/src/main/java/caosdb/server/utils/NullPrintStream.java +++ b/src/main/java/org/caosdb/server/utils/NullPrintStream.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; import java.io.PrintStream; import org.apache.commons.io.output.NullOutputStream; diff --git a/src/main/java/caosdb/server/utils/Observable.java b/src/main/java/org/caosdb/server/utils/Observable.java similarity index 96% rename from src/main/java/caosdb/server/utils/Observable.java rename to src/main/java/org/caosdb/server/utils/Observable.java index f75e040111eab3b32269897bc04f4e8bee1744c3..a43822eb9725232f068c6cdb26764994033366a3 100644 --- a/src/main/java/caosdb/server/utils/Observable.java +++ b/src/main/java/org/caosdb/server/utils/Observable.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; public interface Observable { public boolean acceptObserver(Observer o); diff --git a/src/main/java/caosdb/server/utils/ObservableWrapper.java b/src/main/java/org/caosdb/server/utils/ObservableWrapper.java similarity index 95% rename from src/main/java/caosdb/server/utils/ObservableWrapper.java rename to src/main/java/org/caosdb/server/utils/ObservableWrapper.java index a7bdede91f528f847b193b326d559b79cbdf6a05..9a1833db95220919102b7ec434971ce9057d86dd 100644 --- a/src/main/java/caosdb/server/utils/ObservableWrapper.java +++ b/src/main/java/org/caosdb/server/utils/ObservableWrapper.java @@ -1,3 +1,4 @@ +package org.caosdb.server.utils; /* * ** header v3.0 * This file is a part of the CaosDB Project. @@ -20,7 +21,7 @@ * * ** end header */ -// package caosdb.server.utils; +// package org.caosdb.server.utils; // // // public class ObservableWrapper<T> extends AbstractObservable { diff --git a/src/main/java/caosdb/server/utils/Observer.java b/src/main/java/org/caosdb/server/utils/Observer.java similarity index 97% rename from src/main/java/caosdb/server/utils/Observer.java rename to src/main/java/org/caosdb/server/utils/Observer.java index bb1599d5f1ec4d248473d477e508cfc04200c90f..be89dff4b882adf24bcfd250c3dea1387997360d 100644 --- a/src/main/java/caosdb/server/utils/Observer.java +++ b/src/main/java/org/caosdb/server/utils/Observer.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; public interface Observer { diff --git a/src/main/java/caosdb/server/utils/Releasable.java b/src/main/java/org/caosdb/server/utils/Releasable.java similarity index 96% rename from src/main/java/caosdb/server/utils/Releasable.java rename to src/main/java/org/caosdb/server/utils/Releasable.java index 36b293e0e46fbd16a7ac811e49f989e9e6c9ca7d..f81a029ae319af057c4bc06e3d0501b6eedbe38c 100644 --- a/src/main/java/caosdb/server/utils/Releasable.java +++ b/src/main/java/org/caosdb/server/utils/Releasable.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; public interface Releasable { diff --git a/src/main/java/caosdb/server/utils/SHA512.java b/src/main/java/org/caosdb/server/utils/SHA512.java similarity index 97% rename from src/main/java/caosdb/server/utils/SHA512.java rename to src/main/java/org/caosdb/server/utils/SHA512.java index 07d56bd81435e36b0ddb4dbad16ec703f6d37a4f..a461d95ed9e38baf350b0ee53e059b10ee13a177 100644 --- a/src/main/java/caosdb/server/utils/SHA512.java +++ b/src/main/java/org/caosdb/server/utils/SHA512.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; import java.io.File; import java.io.IOException; diff --git a/src/main/java/caosdb/server/utils/Serializer.java b/src/main/java/org/caosdb/server/utils/Serializer.java similarity index 96% rename from src/main/java/caosdb/server/utils/Serializer.java rename to src/main/java/org/caosdb/server/utils/Serializer.java index 26cd970c54d2bc4efcb7742ab9405a717e3ef112..c58ca23ebfd439e5681289e451da5651d459abc7 100644 --- a/src/main/java/caosdb/server/utils/Serializer.java +++ b/src/main/java/org/caosdb/server/utils/Serializer.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; public interface Serializer<T, S> { diff --git a/src/main/java/caosdb/server/utils/ServerMessages.java b/src/main/java/org/caosdb/server/utils/ServerMessages.java similarity index 98% rename from src/main/java/caosdb/server/utils/ServerMessages.java rename to src/main/java/org/caosdb/server/utils/ServerMessages.java index c2f3a302d270a3f16616c00b41ec9118862d4605..2801218aa47a18ec1494ee8ef76607eb9b962130 100644 --- a/src/main/java/caosdb/server/utils/ServerMessages.java +++ b/src/main/java/org/caosdb/server/utils/ServerMessages.java @@ -17,12 +17,12 @@ * * ** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; -import caosdb.server.entity.Message; -import caosdb.server.entity.Message.MessageType; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.ServerProperties; +import org.caosdb.server.entity.Message; +import org.caosdb.server.entity.Message.MessageType; public class ServerMessages { @@ -133,8 +133,6 @@ public class ServerMessages { 0, "Cannot parse value to boolean (either 'true' or 'false', ignoring case)."); - public static final Message NOT_PERMITTED = new Message(MessageType.Error, 0, "Not permitted."); - public static final Message CANNOT_CONNECT_TO_DATABASE = new Message(MessageType.Error, 0, "Could not connect to MySQL server."); @@ -257,6 +255,9 @@ public class ServerMessages { 0, "User has been activated. You can now log in with your username and password."); + public static final Message UNAUTHENTICATED = + new Message(MessageType.Error, 401, "Sign in, please."); + public static final Message AUTHORIZATION_ERROR = new Message(MessageType.Error, 403, "You are not allowed to do this."); diff --git a/src/main/java/caosdb/server/utils/ServerStat.java b/src/main/java/org/caosdb/server/utils/ServerStat.java similarity index 96% rename from src/main/java/caosdb/server/utils/ServerStat.java rename to src/main/java/org/caosdb/server/utils/ServerStat.java index c0b95d790cd724cddb0af4a934eac7a60047d13a..8b5526335208f07b084e8d61e5d4244b3c235da2 100644 --- a/src/main/java/caosdb/server/utils/ServerStat.java +++ b/src/main/java/org/caosdb/server/utils/ServerStat.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; import java.io.Serializable; diff --git a/src/main/java/caosdb/server/utils/TransactionLogMessage.java b/src/main/java/org/caosdb/server/utils/TransactionLogMessage.java similarity index 94% rename from src/main/java/caosdb/server/utils/TransactionLogMessage.java rename to src/main/java/org/caosdb/server/utils/TransactionLogMessage.java index fbc5e7c05c0a5812ed33879ad0ebcfb6c11dae57..368e09085fce6cc77ac703cd7e2f51f9f4f32d22 100644 --- a/src/main/java/caosdb/server/utils/TransactionLogMessage.java +++ b/src/main/java/org/caosdb/server/utils/TransactionLogMessage.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; -import caosdb.datetime.UTCDateTime; -import caosdb.server.entity.EntityInterface; import java.util.TimeZone; +import org.caosdb.datetime.UTCDateTime; +import org.caosdb.server.entity.EntityInterface; import org.jdom2.Element; public class TransactionLogMessage { diff --git a/src/main/java/caosdb/server/utils/UncloseableOutputStream.java b/src/main/java/org/caosdb/server/utils/UncloseableOutputStream.java similarity index 97% rename from src/main/java/caosdb/server/utils/UncloseableOutputStream.java rename to src/main/java/org/caosdb/server/utils/UncloseableOutputStream.java index 1918c9c8130fecab0906d7cc34ffd1fa32e0d3d7..3f70f2826cbed4547282d2e809ccdaa0068e3ebe 100644 --- a/src/main/java/caosdb/server/utils/UncloseableOutputStream.java +++ b/src/main/java/org/caosdb/server/utils/UncloseableOutputStream.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; import java.io.IOException; import java.io.OutputStream; diff --git a/src/main/java/caosdb/server/utils/UndoHandler.java b/src/main/java/org/caosdb/server/utils/UndoHandler.java similarity index 98% rename from src/main/java/caosdb/server/utils/UndoHandler.java rename to src/main/java/org/caosdb/server/utils/UndoHandler.java index d5c2806f7fa12ad2a223eb99dd17adf569779203..2102784711a1ebd5e879d1562eda26715a19f6b2 100644 --- a/src/main/java/caosdb/server/utils/UndoHandler.java +++ b/src/main/java/org/caosdb/server/utils/UndoHandler.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; import java.util.ArrayDeque; import java.util.Deque; diff --git a/src/main/java/caosdb/server/utils/Undoable.java b/src/main/java/org/caosdb/server/utils/Undoable.java similarity index 96% rename from src/main/java/caosdb/server/utils/Undoable.java rename to src/main/java/org/caosdb/server/utils/Undoable.java index 2a1d3c1c5234ecc34d3bbf02b5e0e8bf0bed84d2..2bbbcb17abf77556cbc6160cfe60335364c61de3 100644 --- a/src/main/java/caosdb/server/utils/Undoable.java +++ b/src/main/java/org/caosdb/server/utils/Undoable.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; public interface Undoable { diff --git a/src/main/java/caosdb/server/utils/Utils.java b/src/main/java/org/caosdb/server/utils/Utils.java similarity index 95% rename from src/main/java/caosdb/server/utils/Utils.java rename to src/main/java/org/caosdb/server/utils/Utils.java index 6c48906a40fd299379e91446516a9c0325200f81..b21ba0f550e1f855ca21e26c1cfd04bb75107223 100644 --- a/src/main/java/caosdb/server/utils/Utils.java +++ b/src/main/java/org/caosdb/server/utils/Utils.java @@ -20,12 +20,11 @@ * * ** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; import static java.net.URLDecoder.decode; import static java.net.URLEncoder.encode; -import caosdb.server.entity.Message; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.UnsupportedEncodingException; @@ -33,10 +32,10 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.text.DecimalFormat; -import java.util.Random; import java.util.Scanner; import java.util.regex.Pattern; import org.apache.commons.codec.binary.Base32; +import org.caosdb.server.entity.Message; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.output.Format; @@ -45,30 +44,9 @@ import org.jdom2.output.XMLOutputter; /** Utility functions. */ public class Utils { - /** Random number generator initialized with the system time and used for generating UIDs. */ - private static Random rand = new Random(System.currentTimeMillis()); - /** Secure random number generator, for secret random numbers. */ private static final SecureRandom srand = new SecureRandom(); - /** - * Check whether obj is non-null and can be parsed to an integer. - * - * @param obj The object to check. - * @return true if obj is not null and obj.toString() can be parsed as an integer - */ - public static boolean isNonNullInteger(final Object obj) { - if (obj == null) { - return false; - } - try { - Integer.parseInt(obj.toString()); - } catch (final NumberFormatException e) { - return false; - } - return true; - } - /** * Regular expression pattern that checks a mail for RFC822 compliance. * @@ -185,16 +163,14 @@ public class Utils { * @return The UID as a String. */ public static String getUID() { - synchronized (rand) { - return Long.toHexString(rand.nextLong()) + Long.toHexString(rand.nextLong()); - } + return Long.toHexString(srand.nextLong()) + Long.toHexString(srand.nextLong()); } /** * Generate a secure filename (base32 letters and numbers). * - * <p>Very similar to getUID, but uses cryptographic random number instead, also also nicely - * formats the resulting string. + * <p>Very similar to getUID, but uses cryptographic random number instead, also nicely formats + * the resulting string. * * @param byteSize How many bytes of random bits shall be generated. * @return The filename as a String. @@ -205,6 +181,7 @@ public class Utils { srand.nextBytes(bytes); // Encode to nice letters + // TODO use StringBuilder and iterate over filename.charArray String filename = (new Base32()).encodeToString(bytes); filename = filename.replaceAll("=+", ""); diff --git a/src/main/java/caosdb/server/utils/WebinterfaceUtils.java b/src/main/java/org/caosdb/server/utils/WebinterfaceUtils.java similarity index 97% rename from src/main/java/caosdb/server/utils/WebinterfaceUtils.java rename to src/main/java/org/caosdb/server/utils/WebinterfaceUtils.java index 2fef9ecaa4972bb12ddfccae4df3f57f493bbe08..1aff4de329bf3f32ba599a449c101b7fbe30423f 100644 --- a/src/main/java/caosdb/server/utils/WebinterfaceUtils.java +++ b/src/main/java/org/caosdb/server/utils/WebinterfaceUtils.java @@ -16,12 +16,8 @@ * * <p>** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; -import caosdb.server.resource.AbstractCaosDBServerResource; -import caosdb.server.resource.Webinterface; import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -33,6 +29,10 @@ import java.util.Map; import java.util.stream.Stream; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.ServerProperties; +import org.caosdb.server.resource.AbstractCaosDBServerResource; +import org.caosdb.server.resource.Webinterface; import org.restlet.data.Reference; /** diff --git a/src/main/java/caosdb/server/utils/fsm/ActionNotAllowedException.java b/src/main/java/org/caosdb/server/utils/fsm/ActionNotAllowedException.java similarity index 91% rename from src/main/java/caosdb/server/utils/fsm/ActionNotAllowedException.java rename to src/main/java/org/caosdb/server/utils/fsm/ActionNotAllowedException.java index eedd272c5d18fae84dd17b1f2eec0e24aa0730e9..ad643a0aade5e8285fa0aea7a92026995b9ccd61 100644 --- a/src/main/java/caosdb/server/utils/fsm/ActionNotAllowedException.java +++ b/src/main/java/org/caosdb/server/utils/fsm/ActionNotAllowedException.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils.fsm; +package org.caosdb.server.utils.fsm; public class ActionNotAllowedException extends RuntimeException { @@ -30,7 +30,7 @@ public class ActionNotAllowedException extends RuntimeException { this.action = action; } - private static final long serialVersionUID = -7723481489788838572L; + private static final long serialVersionUID = -4324962066954446942L; @Override public String getMessage() { diff --git a/src/main/java/caosdb/server/utils/fsm/FiniteStateMachine.java b/src/main/java/org/caosdb/server/utils/fsm/FiniteStateMachine.java similarity index 98% rename from src/main/java/caosdb/server/utils/fsm/FiniteStateMachine.java rename to src/main/java/org/caosdb/server/utils/fsm/FiniteStateMachine.java index 7439d95a1820c91e93290b805de4fa0bdb31c273..f8bdccac726bfe25d7644f6dc689b54113f981c7 100644 --- a/src/main/java/caosdb/server/utils/fsm/FiniteStateMachine.java +++ b/src/main/java/org/caosdb/server/utils/fsm/FiniteStateMachine.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils.fsm; +package org.caosdb.server.utils.fsm; import java.util.List; import java.util.Map; diff --git a/src/main/java/caosdb/server/utils/fsm/MissingImplementationException.java b/src/main/java/org/caosdb/server/utils/fsm/MissingImplementationException.java similarity index 91% rename from src/main/java/caosdb/server/utils/fsm/MissingImplementationException.java rename to src/main/java/org/caosdb/server/utils/fsm/MissingImplementationException.java index 761abf2fe7d8e45438ae06717d7de63ac56afb45..8282e5dd7e7bea4368acf2c7e77b536fab301ad6 100644 --- a/src/main/java/caosdb/server/utils/fsm/MissingImplementationException.java +++ b/src/main/java/org/caosdb/server/utils/fsm/MissingImplementationException.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils.fsm; +package org.caosdb.server.utils.fsm; public class MissingImplementationException extends Exception { @@ -28,5 +28,5 @@ public class MissingImplementationException extends Exception { super("The state `" + s.toString() + "` has no implementation."); } - private static final long serialVersionUID = -1844861392151564478L; + private static final long serialVersionUID = -1138551658177420875L; } diff --git a/src/main/java/caosdb/server/utils/fsm/State.java b/src/main/java/org/caosdb/server/utils/fsm/State.java similarity index 96% rename from src/main/java/caosdb/server/utils/fsm/State.java rename to src/main/java/org/caosdb/server/utils/fsm/State.java index 66073d4d6b2e092d24cf94a18d73216d461f53c9..81b76aa599a90de2c8b3c8ddd295e62ce47dae12 100644 --- a/src/main/java/caosdb/server/utils/fsm/State.java +++ b/src/main/java/org/caosdb/server/utils/fsm/State.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils.fsm; +package org.caosdb.server.utils.fsm; import java.util.List; diff --git a/src/main/java/caosdb/server/utils/fsm/StateNotReachableException.java b/src/main/java/org/caosdb/server/utils/fsm/StateNotReachableException.java similarity index 90% rename from src/main/java/caosdb/server/utils/fsm/StateNotReachableException.java rename to src/main/java/org/caosdb/server/utils/fsm/StateNotReachableException.java index 9dbafcd940d5d07bc89d0aa110a39224a760c340..3970f60e5cf6e86096b0992419b14350c43b42ee 100644 --- a/src/main/java/caosdb/server/utils/fsm/StateNotReachableException.java +++ b/src/main/java/org/caosdb/server/utils/fsm/StateNotReachableException.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils.fsm; +package org.caosdb.server.utils.fsm; public class StateNotReachableException extends Exception { @@ -28,5 +28,5 @@ public class StateNotReachableException extends Exception { super("The state `" + s.toString() + "` is not reachable."); } - private static final long serialVersionUID = -162428821672960032L; + private static final long serialVersionUID = -1826791324169513493L; } diff --git a/src/main/java/caosdb/server/utils/fsm/StrategyFiniteStateMachine.java b/src/main/java/org/caosdb/server/utils/fsm/StrategyFiniteStateMachine.java similarity index 98% rename from src/main/java/caosdb/server/utils/fsm/StrategyFiniteStateMachine.java rename to src/main/java/org/caosdb/server/utils/fsm/StrategyFiniteStateMachine.java index ad5d50dc49d9e0feca0586ccfdb620c26b5d483d..d37d83783bd7f4aaa1db573f76315d0b51bd5fbb 100644 --- a/src/main/java/caosdb/server/utils/fsm/StrategyFiniteStateMachine.java +++ b/src/main/java/org/caosdb/server/utils/fsm/StrategyFiniteStateMachine.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils.fsm; +package org.caosdb.server.utils.fsm; import java.util.Map; diff --git a/src/main/java/caosdb/server/utils/fsm/Transition.java b/src/main/java/org/caosdb/server/utils/fsm/Transition.java similarity index 96% rename from src/main/java/caosdb/server/utils/fsm/Transition.java rename to src/main/java/org/caosdb/server/utils/fsm/Transition.java index 432adc17b9e1c664b95c0e85f4f6918793bf39ae..41921b76cfc7ceed6e396551807e4b199486f0cf 100644 --- a/src/main/java/caosdb/server/utils/fsm/Transition.java +++ b/src/main/java/org/caosdb/server/utils/fsm/Transition.java @@ -20,6 +20,6 @@ * * ** end header */ -package caosdb.server.utils.fsm; +package org.caosdb.server.utils.fsm; public interface Transition {} diff --git a/src/main/java/caosdb/server/utils/fsm/TransitionNotAllowedException.java b/src/main/java/org/caosdb/server/utils/fsm/TransitionNotAllowedException.java similarity index 91% rename from src/main/java/caosdb/server/utils/fsm/TransitionNotAllowedException.java rename to src/main/java/org/caosdb/server/utils/fsm/TransitionNotAllowedException.java index e5b56f7f55438b1b40ee153c65eeafc60e959448..f0547704e250db5c5088c5019a85974c2f4e6254 100644 --- a/src/main/java/caosdb/server/utils/fsm/TransitionNotAllowedException.java +++ b/src/main/java/org/caosdb/server/utils/fsm/TransitionNotAllowedException.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.utils.fsm; +package org.caosdb.server.utils.fsm; public class TransitionNotAllowedException extends Exception { - private static final long serialVersionUID = -7688041374190101361L; + private static final long serialVersionUID = -7236981582249457939L; public TransitionNotAllowedException(final State state, final Transition transition) { super( diff --git a/src/main/java/caosdb/server/utils/mail/Mail.java b/src/main/java/org/caosdb/server/utils/mail/Mail.java similarity index 96% rename from src/main/java/caosdb/server/utils/mail/Mail.java rename to src/main/java/org/caosdb/server/utils/mail/Mail.java index c2036f909009a5ac0f294c6b0abed572e2d45790..36588fc1b3611efad17b80c9122208aa2292870f 100644 --- a/src/main/java/caosdb/server/utils/mail/Mail.java +++ b/src/main/java/org/caosdb/server/utils/mail/Mail.java @@ -20,11 +20,11 @@ * * ** end header */ -package caosdb.server.utils.mail; +package org.caosdb.server.utils.mail; -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; import java.util.Date; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.ServerProperties; public class Mail { diff --git a/src/main/java/caosdb/server/utils/mail/MailFormatter.java b/src/main/java/org/caosdb/server/utils/mail/MailFormatter.java similarity index 96% rename from src/main/java/caosdb/server/utils/mail/MailFormatter.java rename to src/main/java/org/caosdb/server/utils/mail/MailFormatter.java index 31ff4777d3c9969f36d1c03512f7c9059d8c0fcf..2e31724d32527a3f171285513b2014be123e0921 100644 --- a/src/main/java/caosdb/server/utils/mail/MailFormatter.java +++ b/src/main/java/org/caosdb/server/utils/mail/MailFormatter.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils.mail; +package org.caosdb.server.utils.mail; public interface MailFormatter { diff --git a/src/main/java/caosdb/server/utils/mail/MailHandler.java b/src/main/java/org/caosdb/server/utils/mail/MailHandler.java similarity index 96% rename from src/main/java/caosdb/server/utils/mail/MailHandler.java rename to src/main/java/org/caosdb/server/utils/mail/MailHandler.java index 24395e5935f8bb8887a23f16c95b74fc07a15b90..ebdf88dad42028c223784501216002cb5f5196a9 100644 --- a/src/main/java/caosdb/server/utils/mail/MailHandler.java +++ b/src/main/java/org/caosdb/server/utils/mail/MailHandler.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils.mail; +package org.caosdb.server.utils.mail; public interface MailHandler { diff --git a/src/main/java/caosdb/server/utils/mail/Mailable.java b/src/main/java/org/caosdb/server/utils/mail/Mailable.java similarity index 96% rename from src/main/java/caosdb/server/utils/mail/Mailable.java rename to src/main/java/org/caosdb/server/utils/mail/Mailable.java index 6a2362c75b0ba10dc09358fc64d15aa807e45979..fc679aac61afee3cc8d5d47610a6c84ed0be36c0 100644 --- a/src/main/java/caosdb/server/utils/mail/Mailable.java +++ b/src/main/java/org/caosdb/server/utils/mail/Mailable.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils.mail; +package org.caosdb.server.utils.mail; public interface Mailable { diff --git a/src/main/java/caosdb/server/utils/mail/SendMailHandler.java b/src/main/java/org/caosdb/server/utils/mail/SendMailHandler.java similarity index 97% rename from src/main/java/caosdb/server/utils/mail/SendMailHandler.java rename to src/main/java/org/caosdb/server/utils/mail/SendMailHandler.java index fdf060e6f12a5f7939252e968bfe070c788b01b8..88a487c5b02ed9279520d5584fc13582e967a770 100644 --- a/src/main/java/caosdb/server/utils/mail/SendMailHandler.java +++ b/src/main/java/org/caosdb/server/utils/mail/SendMailHandler.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils.mail; +package org.caosdb.server.utils.mail; import java.io.BufferedWriter; import java.io.IOException; diff --git a/src/main/java/caosdb/server/utils/mail/SimpleMailFormatter.java b/src/main/java/org/caosdb/server/utils/mail/SimpleMailFormatter.java similarity index 98% rename from src/main/java/caosdb/server/utils/mail/SimpleMailFormatter.java rename to src/main/java/org/caosdb/server/utils/mail/SimpleMailFormatter.java index 0241c13304b3f2e9b632033d8f0fafe1a6500a87..c1d5ce6b9967c41f82ecf24539f435af87a0899c 100644 --- a/src/main/java/caosdb/server/utils/mail/SimpleMailFormatter.java +++ b/src/main/java/org/caosdb/server/utils/mail/SimpleMailFormatter.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils.mail; +package org.caosdb.server.utils.mail; import javax.mail.internet.MailDateFormat; diff --git a/src/main/java/caosdb/server/utils/mail/ToFileHandler.java b/src/main/java/org/caosdb/server/utils/mail/ToFileHandler.java similarity index 94% rename from src/main/java/caosdb/server/utils/mail/ToFileHandler.java rename to src/main/java/org/caosdb/server/utils/mail/ToFileHandler.java index 8a7a012bc6e2f5b9dbf02ca9286c2c2c5ee3c6d5..24a6da787925a352b2675edf3000ad7f5d1f8dbb 100644 --- a/src/main/java/caosdb/server/utils/mail/ToFileHandler.java +++ b/src/main/java/org/caosdb/server/utils/mail/ToFileHandler.java @@ -20,15 +20,15 @@ * * ** end header */ -package caosdb.server.utils.mail; +package org.caosdb.server.utils.mail; -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.ServerProperties; public class ToFileHandler implements MailHandler { diff --git a/src/main/java/caosdb/unit/CaosDBSystemOfUnits.java b/src/main/java/org/caosdb/unit/CaosDBSystemOfUnits.java similarity index 99% rename from src/main/java/caosdb/unit/CaosDBSystemOfUnits.java rename to src/main/java/org/caosdb/unit/CaosDBSystemOfUnits.java index be7d5a0e023b21966feac0e590d848c1c67fcd4b..ed78c5cf41225ddc7adb36869a779d1c4ec57d67 100644 --- a/src/main/java/caosdb/unit/CaosDBSystemOfUnits.java +++ b/src/main/java/org/caosdb/unit/CaosDBSystemOfUnits.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.unit; +package org.caosdb.unit; import de.timmfitschen.easyunits.BaseUnit; import de.timmfitschen.easyunits.DefaultSystemOfUnitsFactory; diff --git a/src/main/java/caosdb/unit/Converter.java b/src/main/java/org/caosdb/unit/Converter.java similarity index 97% rename from src/main/java/caosdb/unit/Converter.java rename to src/main/java/org/caosdb/unit/Converter.java index db42c12e4bb3ece5291e90b4f013184223b94d14..dfe63477d9c3e9639a58845b8034028befb039bb 100644 --- a/src/main/java/caosdb/unit/Converter.java +++ b/src/main/java/org/caosdb/unit/Converter.java @@ -20,6 +20,6 @@ * * ** end header */ -package caosdb.unit; +package org.caosdb.unit; public interface Converter {} diff --git a/src/main/java/caosdb/unit/LinearConverter.java b/src/main/java/org/caosdb/unit/LinearConverter.java similarity index 97% rename from src/main/java/caosdb/unit/LinearConverter.java rename to src/main/java/org/caosdb/unit/LinearConverter.java index 7d792d220f3ca878b002c045e3f0f3b0b9a4c3dc..8eac2d7e07dbe9f1594b368968b06d00034ea95e 100644 --- a/src/main/java/caosdb/unit/LinearConverter.java +++ b/src/main/java/org/caosdb/unit/LinearConverter.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.unit; +package org.caosdb.unit; public interface LinearConverter extends Converter { diff --git a/src/main/java/caosdb/unit/Unit.java b/src/main/java/org/caosdb/unit/Unit.java similarity index 97% rename from src/main/java/caosdb/unit/Unit.java rename to src/main/java/org/caosdb/unit/Unit.java index d816369b105e4e0b5a7cffd994c4873bb101d046..9e676773013f30d5aa30b60a1357a130f3c5a941 100644 --- a/src/main/java/caosdb/unit/Unit.java +++ b/src/main/java/org/caosdb/unit/Unit.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.unit; +package org.caosdb.unit; public interface Unit { diff --git a/src/main/java/caosdb/unit/UnknownUnit.java b/src/main/java/org/caosdb/unit/UnknownUnit.java similarity index 97% rename from src/main/java/caosdb/unit/UnknownUnit.java rename to src/main/java/org/caosdb/unit/UnknownUnit.java index 592b78a2673aee7720892952eb5c119bf5f7235c..70ad3546ece269efbdc224b7d6d12f9448a21938 100644 --- a/src/main/java/caosdb/unit/UnknownUnit.java +++ b/src/main/java/org/caosdb/unit/UnknownUnit.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.unit; +package org.caosdb.unit; public class UnknownUnit extends WrappedUnit implements Unit { diff --git a/src/main/java/caosdb/unit/WrappedConverter.java b/src/main/java/org/caosdb/unit/WrappedConverter.java similarity index 97% rename from src/main/java/caosdb/unit/WrappedConverter.java rename to src/main/java/org/caosdb/unit/WrappedConverter.java index 91868cc36c9a07ba688f8b9a40896de6d07d89c1..f23be0394daa4a680e642a3d5f018e8b21db4235 100644 --- a/src/main/java/caosdb/unit/WrappedConverter.java +++ b/src/main/java/org/caosdb/unit/WrappedConverter.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.unit; +package org.caosdb.unit; public class WrappedConverter implements Converter { diff --git a/src/main/java/caosdb/unit/WrappedLinearConverter.java b/src/main/java/org/caosdb/unit/WrappedLinearConverter.java similarity index 99% rename from src/main/java/caosdb/unit/WrappedLinearConverter.java rename to src/main/java/org/caosdb/unit/WrappedLinearConverter.java index de9590c391e96706666acdea298a2115d672e58c..b90b32ccee7395800f62ad91cdc960c4b93d0813 100644 --- a/src/main/java/caosdb/unit/WrappedLinearConverter.java +++ b/src/main/java/org/caosdb/unit/WrappedLinearConverter.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.unit; +package org.caosdb.unit; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; diff --git a/src/main/java/caosdb/unit/WrappedUnit.java b/src/main/java/org/caosdb/unit/WrappedUnit.java similarity index 98% rename from src/main/java/caosdb/unit/WrappedUnit.java rename to src/main/java/org/caosdb/unit/WrappedUnit.java index b5f5eb8beb0e7c9ea990484695a33460fb04d7bd..c29ee5b5853423d14cd602c393c779673f6b0ed4 100644 --- a/src/main/java/caosdb/unit/WrappedUnit.java +++ b/src/main/java/org/caosdb/unit/WrappedUnit.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.unit; +package org.caosdb.unit; import de.timmfitschen.easyunits.conversion.LinearConverter; diff --git a/src/main/proto/EntityService.proto b/src/main/proto/EntityService.proto index 259fae6b6e15c085fa620928bf463ee849bf1902..08351f2fe285dac4a4733a4436666936b079e259 100644 --- a/src/main/proto/EntityService.proto +++ b/src/main/proto/EntityService.proto @@ -1,6 +1,6 @@ syntax = "proto3"; option java_multiple_files = true; -package caosdb.grpc; +package org.caosdb.grpc; message Entity { string eid = 1; diff --git a/src/test/docker/Dockerfile b/src/test/docker/Dockerfile index ecc6b332b2d88e0d587fdb3df0fc13cdfd0c159a..08a2a0884d1f154bb941388075b2bdd915125f99 100644 --- a/src/test/docker/Dockerfile +++ b/src/test/docker/Dockerfile @@ -1,5 +1,16 @@ FROM debian:buster RUN apt-get update && \ - apt-get install \ - git make mariadb-server maven openjdk-11-jdk-headless \ - python3-pip screen libpam0g-dev unzip curl shunit2 -y + apt-get install -y \ + git make mariadb-server maven openjdk-11-jdk-headless \ + python3-pip screen libpam0g-dev unzip curl shunit2 \ + python3-sphinx \ + && \ + pip3 install javasphinx recommonmark sphinx-rtd-theme + +# Alternative, if javasphinx fails because python3-sphinx is too recent: +# (`_l` not found): +# +# git clone git@github.com:simgrid/javasphinx.git +# cd javasphinx +# git checkout 659209069603a +# pip3 install . diff --git a/src/test/java/caosdb/server/authentication/AuthTokenTest.java b/src/test/java/caosdb/server/authentication/AuthTokenTest.java deleted file mode 100644 index 9937dc60b1a33cc421a74661bed028ae5e24522a..0000000000000000000000000000000000000000 --- a/src/test/java/caosdb/server/authentication/AuthTokenTest.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * 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 <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package caosdb.server.authentication; - -import caosdb.server.CaosDBServer; -import caosdb.server.accessControl.AuthenticationUtils; -import caosdb.server.accessControl.OneTimeAuthenticationToken; -import caosdb.server.accessControl.Principal; -import caosdb.server.accessControl.SessionToken; -import java.io.IOException; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -public class AuthTokenTest { - - @BeforeClass - public static void initServerProperties() throws IOException { - CaosDBServer.initServerProperties(); - } - - @Test - public void testSessionToken() throws InterruptedException { - final String curry = "somecurry"; - final SessionToken t1 = - new SessionToken( - new Principal("somerealm", "someuser1"), - System.currentTimeMillis(), - 60000, - "345sdf56sdf", - curry, - "wrong checksum"); - Assert.assertFalse(t1.isExpired()); - Assert.assertFalse(t1.isHashValid()); - Assert.assertFalse(t1.isValid()); - - final SessionToken t2 = - new SessionToken( - new Principal("somerealm", "someuser1"), - System.currentTimeMillis(), - 60000, - "345sdf56sdf", - null, - "wrong checksum"); - Assert.assertFalse(t2.isExpired()); - Assert.assertFalse(t2.isHashValid()); - Assert.assertFalse(t2.isValid()); - - final SessionToken t3 = - new SessionToken( - new Principal("somerealm", "someuser2"), - System.currentTimeMillis(), - 60000, - "72723gsdg", - curry); - Assert.assertFalse(t3.isExpired()); - Assert.assertTrue(t3.isHashValid()); - Assert.assertTrue(t3.isValid()); - - final SessionToken t4 = - new SessionToken( - new Principal("somerealm", "someuser2"), - System.currentTimeMillis(), - 60000, - "72723gsdg", - null); - Assert.assertFalse(t4.isExpired()); - Assert.assertTrue(t4.isHashValid()); - Assert.assertTrue(t4.isValid()); - - final SessionToken t5 = - new SessionToken( - new Principal("somerealm", "someuser3"), - System.currentTimeMillis(), - 2000, - "23sdfsg34", - curry); - Assert.assertFalse(t5.isExpired()); - Assert.assertTrue(t5.isHashValid()); - Assert.assertTrue(t5.isValid()); - // wait until expired - Thread.sleep(2001); - Assert.assertTrue(t5.isExpired()); - Assert.assertTrue(t5.isHashValid()); - Assert.assertFalse(t5.isValid()); - - final SessionToken t6 = - new SessionToken( - new Principal("somerealm", "someuser3"), - System.currentTimeMillis(), - 0, - "23sdfsg34", - null); - Assert.assertTrue(t6.isExpired()); - Assert.assertTrue(t6.isHashValid()); - Assert.assertFalse(t6.isValid()); - - Assert.assertEquals(t1.toString(), SessionToken.parse(t1.toString(), curry).toString()); - Assert.assertEquals(t2.toString(), SessionToken.parse(t2.toString(), curry).toString()); - Assert.assertEquals(t3.toString(), SessionToken.parse(t3.toString(), curry).toString()); - Assert.assertEquals(t4.toString(), SessionToken.parse(t4.toString(), curry).toString()); - Assert.assertEquals(t5.toString(), SessionToken.parse(t5.toString(), curry).toString()); - Assert.assertEquals(t6.toString(), SessionToken.parse(t6.toString(), curry).toString()); - Assert.assertEquals(t1.toString(), SessionToken.parse(t1.toString(), null).toString()); - Assert.assertEquals(t2.toString(), SessionToken.parse(t2.toString(), null).toString()); - Assert.assertEquals(t3.toString(), SessionToken.parse(t3.toString(), null).toString()); - Assert.assertEquals(t4.toString(), SessionToken.parse(t4.toString(), null).toString()); - Assert.assertEquals(t5.toString(), SessionToken.parse(t5.toString(), null).toString()); - Assert.assertEquals(t6.toString(), SessionToken.parse(t6.toString(), null).toString()); - - Assert.assertFalse(SessionToken.parse(t1.toString(), curry).isHashValid()); - Assert.assertFalse(SessionToken.parse(t2.toString(), null).isHashValid()); - Assert.assertTrue(SessionToken.parse(t3.toString(), curry).isHashValid()); - Assert.assertTrue(SessionToken.parse(t4.toString(), null).isHashValid()); - Assert.assertTrue(SessionToken.parse(t5.toString(), curry).isHashValid()); - Assert.assertTrue(SessionToken.parse(t6.toString(), null).isHashValid()); - Assert.assertFalse(SessionToken.parse(t1.toString(), null).isHashValid()); - Assert.assertFalse(SessionToken.parse(t2.toString(), curry).isHashValid()); - Assert.assertFalse(SessionToken.parse(t3.toString(), null).isHashValid()); - Assert.assertFalse(SessionToken.parse(t4.toString(), curry).isHashValid()); - Assert.assertFalse(SessionToken.parse(t5.toString(), null).isHashValid()); - Assert.assertFalse(SessionToken.parse(t6.toString(), curry).isHashValid()); - - Assert.assertFalse( - AuthenticationUtils.parseSessionTokenCookie( - AuthenticationUtils.createSessionTokenCookie(t4), null) - .isExpired()); - Assert.assertTrue( - AuthenticationUtils.parseSessionTokenCookie( - AuthenticationUtils.createSessionTokenCookie(t4), null) - .isHashValid()); - Assert.assertTrue( - AuthenticationUtils.parseSessionTokenCookie( - AuthenticationUtils.createSessionTokenCookie(t4), null) - .isValid()); - Assert.assertFalse( - AuthenticationUtils.parseSessionTokenCookie( - AuthenticationUtils.createSessionTokenCookie(t4), curry) - .isExpired()); - Assert.assertFalse( - AuthenticationUtils.parseSessionTokenCookie( - AuthenticationUtils.createSessionTokenCookie(t4), curry) - .isHashValid()); - Assert.assertFalse( - AuthenticationUtils.parseSessionTokenCookie( - AuthenticationUtils.createSessionTokenCookie(t4), curry) - .isValid()); - Assert.assertFalse( - AuthenticationUtils.parseSessionTokenCookie( - AuthenticationUtils.createSessionTokenCookie(t3), null) - .isExpired()); - Assert.assertFalse( - AuthenticationUtils.parseSessionTokenCookie( - AuthenticationUtils.createSessionTokenCookie(t3), null) - .isHashValid()); - Assert.assertFalse( - AuthenticationUtils.parseSessionTokenCookie( - AuthenticationUtils.createSessionTokenCookie(t3), null) - .isValid()); - Assert.assertFalse( - AuthenticationUtils.parseSessionTokenCookie( - AuthenticationUtils.createSessionTokenCookie(t3), curry) - .isExpired()); - Assert.assertTrue( - AuthenticationUtils.parseSessionTokenCookie( - AuthenticationUtils.createSessionTokenCookie(t3), curry) - .isHashValid()); - Assert.assertTrue( - AuthenticationUtils.parseSessionTokenCookie( - AuthenticationUtils.createSessionTokenCookie(t3), curry) - .isValid()); - } - - @Test - public void testOneTimeToken() { - final String curry = null; - final OneTimeAuthenticationToken t1 = - new OneTimeAuthenticationToken( - new Principal("somerealm", "someuser"), - System.currentTimeMillis(), - 60000L, - "sdfh37456sd", - curry, - new String[] {""}); - System.err.println(t1.toString()); - Assert.assertFalse(t1.isExpired()); - Assert.assertTrue(t1.isHashValid()); - Assert.assertTrue(t1.isValid()); - - Assert.assertEquals( - t1.toString(), OneTimeAuthenticationToken.parse(t1.toString(), curry).toString()); - Assert.assertFalse(OneTimeAuthenticationToken.parse(t1.toString(), curry).isExpired()); - Assert.assertTrue(OneTimeAuthenticationToken.parse(t1.toString(), curry).isHashValid()); - Assert.assertTrue(OneTimeAuthenticationToken.parse(t1.toString(), curry).isValid()); - } -} diff --git a/src/test/java/caosdb/server/jobs/extension/TestAWIBoxLoan.java b/src/test/java/caosdb/server/jobs/extension/TestAWIBoxLoan.java deleted file mode 100644 index 08a0e412d8562779cb54574f94ddca932ff54777..0000000000000000000000000000000000000000 --- a/src/test/java/caosdb/server/jobs/extension/TestAWIBoxLoan.java +++ /dev/null @@ -1,277 +0,0 @@ -package caosdb.server.jobs.extension; - -import static org.junit.Assert.assertEquals; - -import caosdb.server.entity.container.TransactionContainer; -import caosdb.server.jobs.core.Mode; -import caosdb.server.transaction.Transaction; -import caosdb.server.utils.EntityStatus; -import java.util.Collection; -import java.util.List; -import java.util.concurrent.Callable; -import org.apache.shiro.authc.AuthenticationException; -import org.apache.shiro.authc.AuthenticationToken; -import org.apache.shiro.authz.AuthorizationException; -import org.apache.shiro.authz.Permission; -import org.apache.shiro.session.Session; -import org.apache.shiro.subject.ExecutionException; -import org.apache.shiro.subject.PrincipalCollection; -import org.apache.shiro.subject.Subject; -import org.junit.Test; - -public class TestAWIBoxLoan { - - @Test - public void testNonAnonymousUser() { - TransactionContainer container = new TransactionContainer(); - AWIBoxLoan j = - new AWIBoxLoan() { - - @Override - protected Subject getUser() { - return new Subject() { - - @Override - public void runAs(PrincipalCollection principals) - throws NullPointerException, IllegalStateException {} - - @Override - public PrincipalCollection releaseRunAs() { - return null; - } - - @Override - public void logout() {} - - @Override - public void login(AuthenticationToken token) throws AuthenticationException {} - - @Override - public boolean isRunAs() { - return false; - } - - @Override - public boolean isRemembered() { - return false; - } - - @Override - public boolean isPermittedAll(Collection<Permission> permissions) { - return false; - } - - @Override - public boolean isPermittedAll(String... permissions) { - return false; - } - - @Override - public boolean[] isPermitted(List<Permission> permissions) { - return null; - } - - @Override - public boolean[] isPermitted(String... permissions) { - return null; - } - - @Override - public boolean isPermitted(Permission permission) { - - return false; - } - - @Override - public boolean isPermitted(String permission) { - - return false; - } - - @Override - public boolean isAuthenticated() { - - return false; - } - - @Override - public boolean[] hasRoles(List<String> roleIdentifiers) { - - return null; - } - - @Override - public boolean hasRole(String roleIdentifier) { - - return false; - } - - @Override - public boolean hasAllRoles(Collection<String> roleIdentifiers) { - - return false; - } - - @Override - public Session getSession(boolean create) { - return null; - } - - @Override - public Session getSession() { - return null; - } - - @Override - public PrincipalCollection getPrincipals() { - return null; - } - - @Override - public Object getPrincipal() { - return null; - } - - @Override - public PrincipalCollection getPreviousPrincipals() { - return null; - } - - @Override - public void execute(Runnable runnable) {} - - @Override - public <V> V execute(Callable<V> callable) throws ExecutionException { - return null; - } - - @Override - public void checkRoles(String... roleIdentifiers) throws AuthorizationException {} - - @Override - public void checkRoles(Collection<String> roleIdentifiers) - throws AuthorizationException {} - - @Override - public void checkRole(String roleIdentifier) throws AuthorizationException {} - - @Override - public void checkPermissions(Collection<Permission> permissions) - throws AuthorizationException {} - - @Override - public void checkPermissions(String... permissions) throws AuthorizationException {} - - @Override - public void checkPermission(Permission permission) throws AuthorizationException {} - - @Override - public void checkPermission(String permission) throws AuthorizationException {} - - @Override - public Runnable associateWith(Runnable runnable) { - return null; - } - - @Override - public <V> Callable<V> associateWith(Callable<V> callable) { - return null; - } - }; - } - }; - Transaction<TransactionContainer> t = - new Transaction<TransactionContainer>(container, null) { - - @Override - protected void transaction() throws Exception {} - - @Override - protected void preTransaction() throws InterruptedException {} - - @Override - protected void preCheck() throws InterruptedException, Exception {} - - @Override - protected void postTransaction() throws Exception {} - - @Override - protected void postCheck() {} - - @Override - public boolean logHistory() { - return false; - } - - @Override - protected void init() throws Exception {} - - @Override - protected void cleanUp() {} - }; - - j.init(Mode.MUST, null, t); - assertEquals(0, j.getContainer().getMessages().size()); - assertEquals(EntityStatus.QUALIFIED, j.getContainer().getStatus()); - - // non-anonymous user - j.run(); - assertEquals(0, j.getContainer().getMessages().size()); - assertEquals(EntityStatus.QUALIFIED, j.getContainer().getStatus()); - } - - @Test - public void testAnonymousUserUnqualified() { - TransactionContainer container = new TransactionContainer(); - AWIBoxLoan j = - new AWIBoxLoan() { - - @Override - protected Subject getUser() { - return null; - } - - @Override - boolean isAnonymous() { - return true; - } - }; - Transaction<TransactionContainer> t = - new Transaction<TransactionContainer>(container, null) { - - @Override - protected void transaction() throws Exception {} - - @Override - protected void preTransaction() throws InterruptedException {} - - @Override - protected void preCheck() throws InterruptedException, Exception {} - - @Override - protected void postTransaction() throws Exception {} - - @Override - protected void postCheck() {} - - @Override - public boolean logHistory() { - return false; - } - - @Override - protected void init() throws Exception {} - - @Override - protected void cleanUp() {} - }; - - j.init(Mode.MUST, null, t); - assertEquals(0, j.getContainer().getMessages().size()); - assertEquals(EntityStatus.QUALIFIED, j.getContainer().getStatus()); - - j.run(); - assertEquals(2, j.getContainer().getMessages().size()); - assertEquals(EntityStatus.UNQUALIFIED, j.getContainer().getStatus()); - } -} diff --git a/src/test/java/caosdb/server/permissions/EntityACLTest.java b/src/test/java/caosdb/server/permissions/EntityACLTest.java deleted file mode 100644 index 13ebb6279546606c8e796672db09a7e99ffea588..0000000000000000000000000000000000000000 --- a/src/test/java/caosdb/server/permissions/EntityACLTest.java +++ /dev/null @@ -1,345 +0,0 @@ -/* - * ** header v3.0 - * This file is a part of the CaosDB Project. - * - * Copyright (C) 2018 Research Group Biomedical Physics, - * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * - * 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 <https://www.gnu.org/licenses/>. - * - * ** end header - */ -package caosdb.server.permissions; - -import static org.junit.Assert.assertNotNull; - -import caosdb.server.CaosDBServer; -import caosdb.server.resource.AbstractCaosDBServerResource; -import caosdb.server.resource.AbstractCaosDBServerResource.XMLParser; -import caosdb.server.utils.Utils; -import java.io.IOException; -import java.util.BitSet; -import java.util.LinkedList; -import org.jdom2.Element; -import org.jdom2.JDOMException; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -public class EntityACLTest { - - public static long convert(final BitSet bits) { - long value = 0L; - for (int i = 0; i < bits.length(); ++i) { - value += bits.get(i) ? (1L << i) : 0L; - } - return value; - } - - @BeforeClass - public static void init() throws IOException { - CaosDBServer.initServerProperties(); - assertNotNull(EntityACL.GLOBAL_PERMISSIONS); - } - - @Test - public void testConvert() { - long l = Integer.MAX_VALUE; - System.out.println(EntityACL.convert(l)); - l = Integer.MIN_VALUE; - System.out.println(EntityACL.convert(l)); - l = Long.MAX_VALUE; - System.out.println(EntityACL.convert(l)); - l = Long.MIN_VALUE; - System.out.println(EntityACL.convert(l)); - final BitSet bitSet = new BitSet(64); - Assert.assertEquals(0, convert(bitSet)); - - bitSet.set(0); - Assert.assertEquals(1, convert(bitSet)); - - bitSet.clear(); - bitSet.set(63); - Assert.assertEquals(Long.MIN_VALUE, convert(bitSet)); - - bitSet.clear(); - bitSet.set(0, 63, true); - Assert.assertEquals(Long.MAX_VALUE, convert(bitSet)); - - bitSet.clear(); - bitSet.set(62); - Assert.assertEquals(EntityACL.MIN_PRIORITY_BITSET, convert(bitSet)); - - bitSet.set(63); - Assert.assertEquals(-EntityACL.MIN_PRIORITY_BITSET, convert(bitSet)); - - bitSet.clear(); - bitSet.set(0, 64, true); - Assert.assertEquals(-1L, convert(bitSet)); - - Assert.assertTrue(EntityACL.convert(-12523).get(63)); - Assert.assertFalse(EntityACL.convert(12523).get(63)); - - bitSet.clear(); - bitSet.set(0, 63, true); - Assert.assertEquals(Long.MAX_VALUE + 1L, Long.MIN_VALUE); - Assert.assertEquals(Long.MAX_VALUE, convert(bitSet)); - } - - @Test - public void testIsDenial() { - final BitSet bitSet = new BitSet(64); - bitSet.set(63); - - Assert.assertTrue(EntityACL.isDenial(convert(bitSet))); - Assert.assertTrue(EntityACL.isDenial(-12523)); - Assert.assertFalse(EntityACL.isDenial(0)); - Assert.assertFalse(EntityACL.isDenial(246345)); - Assert.assertTrue(EntityACL.isDenial(-EntityACL.MIN_PRIORITY_BITSET)); - } - - @Test - public void testIsAllowance() { - final BitSet bitSet = new BitSet(32); - bitSet.set(27); - - Assert.assertTrue(EntityACL.isAllowance(convert(bitSet))); - Assert.assertTrue(EntityACL.isAllowance(12523)); - Assert.assertTrue(EntityACL.isAllowance(0)); - Assert.assertFalse(EntityACL.isAllowance(-246345)); - Assert.assertTrue(EntityACL.isAllowance(EntityACL.MIN_PRIORITY_BITSET)); - } - - @Test - public void testGetResultingACL() { - final LinkedList<Long> acl = new LinkedList<Long>(); - acl.add(1L); // +P1 - Assert.assertEquals(1L, EntityACL.getResultingACL(acl)); // P1 - - acl.add(2L); // +P2 - Assert.assertEquals(3L, EntityACL.getResultingACL(acl)); // P1,P2 - - acl.add(4L); // +P3 - Assert.assertEquals(7L, EntityACL.getResultingACL(acl)); // P1,P2,P3 - - acl.add(Long.MIN_VALUE + 1); // -P1 - Assert.assertEquals(6L, EntityACL.getResultingACL(acl)); // P2,P3 - - acl.add(Long.MIN_VALUE + 1); // -P1Allow - Assert.assertEquals(6L, EntityACL.getResultingACL(acl)); // P2,P3 - - acl.add(Long.MIN_VALUE + 8); // -P4 - Assert.assertEquals(6L, EntityACL.getResultingACL(acl)); // P2,P3 - - acl.add(8L); // +P4 - Assert.assertEquals(6L, EntityACL.getResultingACL(acl)); // P2,P3 - - acl.add(EntityACL.MIN_PRIORITY_BITSET + 1); // ++P1 - Assert.assertEquals(7L, EntityACL.getResultingACL(acl)); // P1,P2,P3 - - acl.add(EntityACL.MIN_PRIORITY_BITSET + 2); // ++P2 - Assert.assertEquals(7L, EntityACL.getResultingACL(acl)); // P1,P2,P3 - - acl.add(Long.MIN_VALUE + 1); // -P1 - Assert.assertEquals(7l, EntityACL.getResultingACL(acl)); // P1,P2,P3 - - acl.add(Long.MIN_VALUE + 4); // -P1 - Assert.assertEquals(3l, EntityACL.getResultingACL(acl)); // P1,P2 - - acl.add(EntityACL.MIN_PRIORITY_BITSET + 8); // ++P4 - Assert.assertEquals(11L, EntityACL.getResultingACL(acl)); // P1,P2,P4 - - acl.add(Long.MIN_VALUE + EntityACL.MIN_PRIORITY_BITSET + 2); // --P2 - Assert.assertEquals(9L, EntityACL.getResultingACL(acl)); // P1,P4 - - acl.add(Long.MIN_VALUE + EntityACL.MIN_PRIORITY_BITSET + 1); // --P1Allow - Assert.assertEquals(8L, EntityACL.getResultingACL(acl)); // P4 - } - - @Test - public void testOwnerBitSet() { - Assert.assertEquals(convert(EntityACL.convert(EntityACL.OWNER_BITSET).get(1, 32)), 0); - } - - // @Test - // public void testDeserialize() { - // Assert.assertTrue(EntityACL.deserialize("{}") instanceof EntityACL); - // Assert.assertTrue(EntityACL.deserialize("{tf:134}") instanceof - // EntityACL); - // Assert.assertTrue(EntityACL.deserialize("{tf:6343;bla:884}") instanceof - // EntityACL); - // Assert.assertTrue(EntityACL.deserialize("{tf:-2835;bla:884}") instanceof - // EntityACL); - // Assert.assertTrue(EntityACL.deserialize("{?OWNER?:526;tahsdh : -235;}") - // instanceof EntityACL); - // Assert.assertTrue(EntityACL.deserialize("{asdf:2345;}") instanceof - // EntityACL); - // Assert.assertTrue(raisesIllegalArguementException("{")); - // Assert.assertTrue(raisesIllegalArguementException("}")); - // Assert.assertTrue(raisesIllegalArguementException("{tf:}")); - // Assert.assertTrue(raisesIllegalArguementException("{tf:;}")); - // Assert.assertTrue(raisesIllegalArguementException("{:234}")); - // Assert.assertTrue(raisesIllegalArguementException("{:234;}")); - // Assert.assertTrue(raisesIllegalArguementException("{tf:tf;}")); - // Assert.assertTrue(raisesIllegalArguementException("{tf: +5259;}")); - // Assert.assertTrue(raisesIllegalArguementException("{tf;}")); - // Assert.assertTrue(raisesIllegalArguementException("{tf:123223727356235782735235;}")); - // } - - public boolean raisesIllegalArguementException(final String input) { - try { - EntityACL.deserialize(input); - } catch (final IllegalArgumentException e) { - return true; - } - return false; - } - - public static AbstractCaosDBServerResource.XMLParser parser = new XMLParser(); - - public Element stringToJdom(final String s) throws JDOMException, IOException { - return parser.parse(Utils.String2InputStream(s)).getRootElement(); - } - - // @Test - // public void testParseFromElement() throws JDOMException, IOException { - // Assert.assertEquals("{}", - // EntityACL.serialize(EntityACL.parseFromElement(stringToJdom("<ACL></ACL>")))); - // Assert.assertEquals("{}", EntityACL.serialize(EntityACL - // .parseFromElement(stringToJdom("<ACL><Grant></Grant></ACL>")))); - // Assert.assertEquals("{}", EntityACL.serialize(EntityACL - // .parseFromElement(stringToJdom("<ACL><Deny></Deny></ACL>")))); - // Assert.assertEquals("{}", EntityACL.serialize(EntityACL - // .parseFromElement(stringToJdom("<ACL><Grant role='bla'></Grant></ACL>")))); - // Assert.assertEquals("{}", EntityACL.serialize(EntityACL - // .parseFromElement(stringToJdom("<ACL><Deny role='bla'></Deny></ACL>")))); - // Assert.assertEquals( - // "{bla:2;}", - // EntityACL.serialize(EntityACL - // .parseFromElement(stringToJdom("<ACL><Grant role='bla'><Permission name='DELETE' - // /></Grant></ACL>")))); - // Assert.assertEquals( - // "{bla:" + (Long.MIN_VALUE + 2) + ";}", - // EntityACL.serialize(EntityACL - // .parseFromElement(stringToJdom("<ACL><Deny role='bla'><Permission name='DELETE' - // /></Deny></ACL>")))); - // Assert.assertEquals( - // "{bla:32;}", - // EntityACL.serialize(EntityACL - // .parseFromElement(stringToJdom("<ACL><Grant role='bla'><Permission name='RETRIEVE:ACL' - // /></Grant></ACL>")))); - // } - - // @Test - // public void testFactory() { - // final EntityACLFactory f = new EntityACLFactory(); - // f.grant("user1", "UPDATE:NAME"); - // Assert.assertTrue((f.create().isPermitted("user1", - // EntityPermission.UPDATE_NAME))); - // Assert.assertFalse((f.create().isPermitted("user2", - // EntityPermission.UPDATE_NAME))); - // f.grant("user2", "DELETE"); - // Assert.assertFalse((f.create().isPermitted("user1", - // EntityPermission.DELETE))); - // Assert.assertTrue((f.create().isPermitted("user2", - // EntityPermission.DELETE))); - // f.deny("user2", 1); - // f.deny("user1", 1); - // Assert.assertFalse((f.create().isPermitted("user1", - // EntityPermission.DELETE))); - // Assert.assertFalse((f.create().isPermitted("user2", - // EntityPermission.DELETE))); - // f.grant("user1", true, 1); - // Assert.assertTrue((f.create().isPermitted("user1", - // EntityPermission.DELETE))); - // Assert.assertFalse((f.create().isPermitted("user2", - // EntityPermission.DELETE))); - // f.deny("user2", true, 1); - // Assert.assertTrue((f.create().isPermitted("user1", - // EntityPermission.DELETE))); - // Assert.assertFalse((f.create().isPermitted("user2", - // EntityPermission.DELETE))); - // f.grant("user2", true, 1); - // Assert.assertTrue((f.create().isPermitted("user1", - // EntityPermission.DELETE))); - // Assert.assertFalse((f.create().isPermitted("user2", - // EntityPermission.DELETE))); - // f.deny("user1", true, 1); - // Assert.assertFalse((f.create().isPermitted("user1", - // EntityPermission.DELETE))); - // Assert.assertFalse((f.create().isPermitted("user2", - // EntityPermission.DELETE))); - // Assert.assertTrue((f.create().isPermitted("user1", - // EntityPermission.UPDATE_NAME))); - // Assert.assertFalse((f.create().isPermitted("user2", - // EntityPermission.UPDATE_NAME))); - // } - - // @Test - // public void niceFactoryStuff() { - // final EntityACLFactory f = new EntityACLFactory(); - // f.grant("user1", "*"); - // final EntityACL acl1 = f.create(); - // Assert.assertTrue(acl1.isPermitted("user1", EntityPermission.EDIT_ACL)); - // Assert.assertTrue(acl1.isPermitted("user1", EntityPermission.DELETE)); - // Assert.assertTrue(acl1.isPermitted("user1", - // EntityPermission.RETRIEVE_ENTITY)); - // Assert.assertTrue(acl1.isPermitted("user1", - // EntityPermission.UPDATE_DATA_TYPE)); - // Assert.assertTrue(acl1.isPermitted("user1", - // EntityPermission.USE_AS_PROPERTY)); - // - // f.grant("?OWNER?", "DELETE", "EDIT:ACL", "RETRIEVE:*", "UPDATE:*", - // "USE:*"); - // f.grant("user2", "EDIT:ACL"); - // final EntityACL acl2 = f.create(); - // Assert.assertTrue(acl2.isPermitted("user2", EntityPermission.EDIT_ACL)); - // Assert.assertTrue(acl2.isPermitted("user2", EntityPermission.DELETE)); - // Assert.assertTrue(acl2.isPermitted("user2", - // EntityPermission.RETRIEVE_ENTITY)); - // Assert.assertTrue(acl2.isPermitted("user2", - // EntityPermission.UPDATE_DATA_TYPE)); - // Assert.assertTrue(acl2.isPermitted("user2", - // EntityPermission.USE_AS_PROPERTY)); - // - // } - - // @Test - // public void testDeny() { - // EntityACLFactory f = new EntityACLFactory(); - // f.deny("test", "DELETE"); - // Assert.assertFalse(f.create().isPermitted("test", - // EntityPermission.DELETE)); - // - // System.out.println(Utils.element2String(f.create().toElement())); - // - // System.out.println(Utils.element2String(EntityACL.GLOBAL_PERMISSIONS.toElement())); - // - // f.grant("test", "USE:*"); - // Assert.assertFalse(f.create().isPermitted("test", - // EntityPermission.DELETE)); - // - // System.out.println(Utils.element2String(f.create().toElement())); - // - // f = new EntityACLFactory(); - // f.grant(EntityACL.OTHER_ROLE, "RETRIEVE:*"); - // f.deny(EntityACL.OTHER_ROLE, "DELETE"); - // final EntityACL a = f.create(); - // - // System.out.println(Utils.element2String(a.toElement())); - // - // System.out.println(Utils.element2String(EntityACL.deserialize(a.serialize()).toElement())); - // } - -} diff --git a/src/test/java/caosdb/CaosDBTestClass.java b/src/test/java/org/caosdb/CaosDBTestClass.java similarity index 98% rename from src/test/java/caosdb/CaosDBTestClass.java rename to src/test/java/org/caosdb/CaosDBTestClass.java index 6b894c75b097b4aa324a432b6338f84a0527f84c..d22f9ade8ed43b5e44e505b70e7d2b1d704e211b 100644 --- a/src/test/java/caosdb/CaosDBTestClass.java +++ b/src/test/java/org/caosdb/CaosDBTestClass.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb; +package org.caosdb; import java.io.File; import java.io.IOException; diff --git a/src/test/java/caosdb/datetime/DateTimeTest.java b/src/test/java/org/caosdb/datetime/DateTimeTest.java similarity index 99% rename from src/test/java/caosdb/datetime/DateTimeTest.java rename to src/test/java/org/caosdb/datetime/DateTimeTest.java index 032ab240eaa083d63acdd033431b6f0d2cfcdfd9..81e0edf748432daf8c023b421b6119a3bf14f2d4 100644 --- a/src/test/java/caosdb/datetime/DateTimeTest.java +++ b/src/test/java/org/caosdb/datetime/DateTimeTest.java @@ -20,20 +20,20 @@ * * ** end header */ -package caosdb.datetime; +package org.caosdb.datetime; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import caosdb.server.CaosDBServer; -import caosdb.server.database.backend.implementation.MySQL.ConnectionException; import java.io.IOException; import java.sql.SQLException; import java.sql.Timestamp; import java.time.ZoneId; import java.util.GregorianCalendar; import java.util.TimeZone; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.database.backend.implementation.MySQL.ConnectionException; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; diff --git a/src/test/java/caosdb/server/Misc.java b/src/test/java/org/caosdb/server/Misc.java similarity index 93% rename from src/test/java/caosdb/server/Misc.java rename to src/test/java/org/caosdb/server/Misc.java index bcdc1729f008dbb1393fe238a3eb763c67d69e0f..f6d1364644d803abf194532471f9e1775fa990de 100644 --- a/src/test/java/caosdb/server/Misc.java +++ b/src/test/java/org/caosdb/server/Misc.java @@ -20,16 +20,13 @@ * * ** end header */ -package caosdb.server; +package org.caosdb.server; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import caosdb.server.database.misc.TransactionBenchmark; -import caosdb.server.jobs.core.CheckFileStorageConsistency; -import caosdb.server.utils.CronJob; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -39,11 +36,10 @@ import java.io.ObjectOutputStream; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.shiro.SecurityUtils; -import org.apache.shiro.config.Ini; -import org.apache.shiro.config.IniSecurityManagerFactory; -import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.subject.Subject; -import org.apache.shiro.util.Factory; +import org.caosdb.server.database.misc.TransactionBenchmark; +import org.caosdb.server.jobs.core.CheckFileStorageConsistency; +import org.caosdb.server.utils.CronJob; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; @@ -293,12 +289,7 @@ public class Misc { @Test public void testShiro() { - Ini config = CaosDBServer.getShiroConfig(); - final Factory<SecurityManager> factory = new IniSecurityManagerFactory(config); - - final SecurityManager securityManager = factory.getInstance(); - - SecurityUtils.setSecurityManager(securityManager); + CaosDBServer.initShiro(); final Subject subject = SecurityUtils.getSubject(); diff --git a/src/test/java/caosdb/server/accessControl/TestDefaultPamScriptCaller.java b/src/test/java/org/caosdb/server/accessControl/TestDefaultPamScriptCaller.java similarity index 98% rename from src/test/java/caosdb/server/accessControl/TestDefaultPamScriptCaller.java rename to src/test/java/org/caosdb/server/accessControl/TestDefaultPamScriptCaller.java index bb207aadcdef6ba9fdeecc2b0f32cd9f70a50512..21197f4fa430283898c87741df4c765b28152f33 100644 --- a/src/test/java/caosdb/server/accessControl/TestDefaultPamScriptCaller.java +++ b/src/test/java/org/caosdb/server/accessControl/TestDefaultPamScriptCaller.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.accessControl; +package org.caosdb.server.accessControl; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; diff --git a/src/test/java/org/caosdb/server/authentication/AuthTokenTest.java b/src/test/java/org/caosdb/server/authentication/AuthTokenTest.java new file mode 100644 index 0000000000000000000000000000000000000000..ca19603230bf6aa989c495fbadabd0989c2a9790 --- /dev/null +++ b/src/test/java/org/caosdb/server/authentication/AuthTokenTest.java @@ -0,0 +1,451 @@ +/* + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2018 Research Group Biomedical Physics, + * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * + * 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 <https://www.gnu.org/licenses/>. + * + * ** end header + */ +package org.caosdb.server.authentication; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectReader; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import org.apache.commons.io.input.CharSequenceInputStream; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.subject.Subject; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.ServerProperties; +import org.caosdb.server.accessControl.AnonymousAuthenticationToken; +import org.caosdb.server.accessControl.AuthenticationUtils; +import org.caosdb.server.accessControl.Config; +import org.caosdb.server.accessControl.OneTimeAuthenticationToken; +import org.caosdb.server.accessControl.Principal; +import org.caosdb.server.accessControl.SelfValidatingAuthenticationToken; +import org.caosdb.server.accessControl.SessionToken; +import org.caosdb.server.accessControl.SessionTokenRealm; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.backend.interfaces.RetrievePasswordValidatorImpl; +import org.caosdb.server.database.backend.interfaces.RetrievePermissionRulesImpl; +import org.caosdb.server.database.backend.interfaces.RetrieveRoleImpl; +import org.caosdb.server.database.backend.interfaces.RetrieveUserImpl; +import org.caosdb.server.resource.TestScriptingResource.RetrievePasswordValidator; +import org.caosdb.server.resource.TestScriptingResource.RetrievePermissionRules; +import org.caosdb.server.resource.TestScriptingResource.RetrieveRole; +import org.caosdb.server.resource.TestScriptingResource.RetrieveUser; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +public class AuthTokenTest { + + @BeforeClass + public static void initServerProperties() throws IOException { + CaosDBServer.initServerProperties(); + } + + @BeforeClass + public static void setupShiro() throws IOException { + BackendTransaction.setImpl(RetrieveRoleImpl.class, RetrieveRole.class); + BackendTransaction.setImpl(RetrievePermissionRulesImpl.class, RetrievePermissionRules.class); + BackendTransaction.setImpl(RetrieveUserImpl.class, RetrieveUser.class); + BackendTransaction.setImpl( + RetrievePasswordValidatorImpl.class, RetrievePasswordValidator.class); + + CaosDBServer.initServerProperties(); + CaosDBServer.initShiro(); + } + + @Before + public void reset() { + OneTimeAuthenticationToken.resetConfig(); + } + + @Test + public void testSessionToken() throws InterruptedException { + // Token 1 - wrong checksum, not expired + final SessionToken t1 = + new SessionToken( + new Principal("somerealm", "someuser1"), + System.currentTimeMillis(), + 60000, + "345sdf56sdf", + "wrong checksum", + null, + null); + Assert.assertFalse(t1.isExpired()); + Assert.assertFalse(t1.isHashValid()); + Assert.assertFalse(t1.isValid()); + + // Token 3 - correct checksum, not expired + final SessionToken t3 = + new SessionToken(new Principal("somerealm", "someuser2"), 60000, null, null); + Assert.assertFalse(t3.isExpired()); + Assert.assertTrue(t3.isHashValid()); + Assert.assertTrue(t3.isValid()); + + // Token 5 - correct checksum, soon to be expired + final SessionToken t5 = + new SessionToken(new Principal("somerealm", "someuser3"), 2000, null, null); + Assert.assertFalse(t5.isExpired()); + Assert.assertTrue(t5.isHashValid()); + Assert.assertTrue(t5.isValid()); + // wait until expired + Thread.sleep(2001); + Assert.assertTrue(t5.isExpired()); + Assert.assertTrue(t5.isHashValid()); + Assert.assertFalse(t5.isValid()); + + // Token 6 - correct checksum, immediately expired + final SessionToken t6 = + new SessionToken(new Principal("somerealm", "someuser3"), 0, null, null); + Assert.assertTrue(t6.isExpired()); + Assert.assertTrue(t6.isHashValid()); + Assert.assertFalse(t6.isValid()); + + // All tokens can be successfully parsed back. + final SelfValidatingAuthenticationToken t1p = SessionToken.parse(t1.toString()); + final SelfValidatingAuthenticationToken t3p = SessionToken.parse(t3.toString()); + final SelfValidatingAuthenticationToken t5p = SessionToken.parse(t5.toString()); + final SelfValidatingAuthenticationToken t6p = SessionToken.parse(t6.toString()); + Assert.assertEquals(t1.toString(), t1p.toString()); + Assert.assertEquals(t3.toString(), t3p.toString()); + Assert.assertEquals(t5.toString(), t5p.toString()); + Assert.assertEquals(t6.toString(), t6p.toString()); + + // ... and parsed tokens have the correct hash validation + Assert.assertFalse(t1p.isHashValid()); + Assert.assertTrue(t3p.isHashValid()); + Assert.assertTrue(t5p.isHashValid()); + Assert.assertTrue(t6p.isHashValid()); + + Assert.assertFalse( + AuthenticationUtils.parseSessionTokenCookie( + AuthenticationUtils.createSessionTokenCookie(t3)) + .isExpired()); + Assert.assertTrue( + AuthenticationUtils.parseSessionTokenCookie( + AuthenticationUtils.createSessionTokenCookie(t3)) + .isHashValid()); + Assert.assertTrue( + AuthenticationUtils.parseSessionTokenCookie( + AuthenticationUtils.createSessionTokenCookie(t3)) + .isValid()); + + // TODO parse invalid tokens + } + + @Test + public void testOneTimeTokenSerialization() { + final OneTimeAuthenticationToken t1 = + new OneTimeAuthenticationToken( + new Principal("somerealm", "someuser"), + 60000, + new String[] {"permissions"}, + new String[] {"roles"}, + 1L, + 3000L); + Assert.assertEquals(1L, t1.getMaxReplays()); + Assert.assertFalse(t1.isExpired()); + Assert.assertTrue(t1.isHashValid()); + Assert.assertTrue(t1.isValid()); + + String serialized = t1.toString(); + OneTimeAuthenticationToken parsed = + (OneTimeAuthenticationToken) OneTimeAuthenticationToken.parse(serialized); + + Assert.assertEquals(t1, parsed); + Assert.assertEquals(serialized, parsed.toString()); + + Assert.assertEquals(1L, parsed.getMaxReplays()); + Assert.assertFalse(parsed.isExpired()); + Assert.assertTrue(parsed.isHashValid()); + Assert.assertTrue(parsed.isValid()); + } + + @Test(expected = AuthenticationException.class) + public void testOneTimeTokenConsume() { + final OneTimeAuthenticationToken t1 = + new OneTimeAuthenticationToken( + new Principal("somerealm", "someuser"), + 60000, + new String[] {"permissions"}, + new String[] {"roles"}, + 3L, + 3000L); + Assert.assertFalse(t1.isExpired()); + Assert.assertTrue(t1.isHashValid()); + Assert.assertTrue(t1.isValid()); + try { + t1.consume(); + t1.consume(); + t1.consume(); + } catch (AuthenticationException e) { + Assert.fail(e.getMessage()); + } + + // throws + t1.consume(); + Assert.fail("4th time consume() should throw"); + } + + @Test(expected = AuthenticationException.class) + public void testOneTimeTokenConsumeByParsing() { + final OneTimeAuthenticationToken t1 = + new OneTimeAuthenticationToken( + new Principal("somerealm", "someuser"), + 60000, + new String[] {"permissions"}, + new String[] {"roles"}, + 3L, + 3000L); + Assert.assertFalse(t1.isExpired()); + Assert.assertTrue(t1.isHashValid()); + Assert.assertTrue(t1.isValid()); + + String serialized = t1.toString(); + try { + SelfValidatingAuthenticationToken parsed1 = OneTimeAuthenticationToken.parse(serialized); + Assert.assertTrue(parsed1.isValid()); + SelfValidatingAuthenticationToken parsed2 = OneTimeAuthenticationToken.parse(serialized); + Assert.assertTrue(parsed2.isValid()); + SelfValidatingAuthenticationToken parsed3 = OneTimeAuthenticationToken.parse(serialized); + Assert.assertTrue(parsed3.isValid()); + } catch (AuthenticationException e) { + Assert.fail(e.getMessage()); + } + + // throws + OneTimeAuthenticationToken.parse(serialized); + Assert.fail("4th parsing should throw"); + } + + @Test + public void testOneTimeTokenConfigEmpty() throws Exception { + StringBuilder testYaml = new StringBuilder(); + testYaml.append("[]"); + + List<Config> configs = + OneTimeAuthenticationToken.loadConfig(new CharSequenceInputStream(testYaml, "utf-8")); + + Assert.assertTrue("empty config", configs.isEmpty()); + } + + @Test + public void testOneTimeTokenConfigDefaults() throws Exception { + StringBuilder testYaml = new StringBuilder(); + testYaml.append("roles: []\n"); + + List<Config> configs = + OneTimeAuthenticationToken.loadConfig(new CharSequenceInputStream(testYaml, "utf-8")); + + Assert.assertEquals(1, configs.size()); + Assert.assertTrue("parsing to Config object", configs.get(0) instanceof Config); + + Config config = configs.get(0); + + Assert.assertEquals( + Integer.parseInt( + CaosDBServer.getServerProperty(ServerProperties.KEY_ONE_TIME_TOKEN_EXPIRES_MS)), + config.getExpiresAfter()); + Assert.assertEquals(1, config.getMaxReplays()); + Assert.assertNull("no purpose", config.getPurpose()); + + Assert.assertArrayEquals("no permissions", new String[] {}, config.getPermissions()); + Assert.assertArrayEquals("no roles", new String[] {}, config.getRoles()); + Assert.assertNull("no output", config.getOutput()); + } + + @Test + public void testOneTimeTokenConfigBasic() throws Exception { + StringBuilder testYaml = new StringBuilder(); + testYaml.append("purpose: test purpose 1\n"); + testYaml.append("roles: [ role1, \"role2\"]\n"); + testYaml.append("expiresAfterSeconds: 10\n"); + testYaml.append("maxReplays: 3\n"); + testYaml.append("permissions:\n"); + testYaml.append(" - permission1\n"); + testYaml.append(" - 'permission2'\n"); + testYaml.append(" - \"permission3\"\n"); + testYaml.append(" - \"permission with white space\"\n"); + + OneTimeAuthenticationToken.initConfig(new CharSequenceInputStream(testYaml, "utf-8")); + Map<String, Config> map = OneTimeAuthenticationToken.getPurposeMap(); + Assert.assertNotNull("test purpose there", map.get("test purpose 1")); + Assert.assertTrue("parsing to Config object", map.get("test purpose 1") instanceof Config); + Config config = map.get("test purpose 1"); + Assert.assertEquals(10000, config.getExpiresAfter()); + Assert.assertEquals(3, config.getMaxReplays()); + + Assert.assertArrayEquals( + "permissions parsed", + new String[] {"permission1", "permission2", "permission3", "permission with white space"}, + config.getPermissions()); + Assert.assertArrayEquals("roles parsed", new String[] {"role1", "role2"}, config.getRoles()); + } + + @Test + public void testOneTimeTokenConfigNoRoles() throws Exception { + StringBuilder testYaml = new StringBuilder(); + testYaml.append("purpose: no roles test\n"); + testYaml.append("permissions:\n"); + testYaml.append(" - permission1\n"); + testYaml.append(" - 'permission2'\n"); + testYaml.append(" - \"permission3\"\n"); + testYaml.append(" - \"permission with white space\"\n"); + + OneTimeAuthenticationToken.initConfig(new CharSequenceInputStream(testYaml, "utf-8")); + Map<String, Config> map = OneTimeAuthenticationToken.getPurposeMap(); + Config config = map.get("no roles test"); + + Assert.assertArrayEquals("empty roles array parsed", new String[] {}, config.getRoles()); + } + + @Test + public void testOneTimeTokenConfigNoPurpose() throws Exception { + StringBuilder testYaml = new StringBuilder(); + testYaml.append("permissions:\n"); + testYaml.append(" - permission1\n"); + testYaml.append(" - 'permission2'\n"); + testYaml.append(" - \"permission3\"\n"); + testYaml.append(" - \"permission with white space\"\n"); + + OneTimeAuthenticationToken.initConfig(new CharSequenceInputStream(testYaml, "utf-8")); + Map<String, Config> map = OneTimeAuthenticationToken.getPurposeMap(); + Assert.assertEquals(map.size(), 0); + } + + @Test + public void testOneTimeTokenConfigMulti() throws Exception { + StringBuilder testYaml = new StringBuilder(); + testYaml.append("- purpose: purpose 1\n"); + testYaml.append("- purpose: purpose 2\n"); + testYaml.append("- purpose: purpose 3\n"); + testYaml.append("- purpose: purpose 4\n"); + + OneTimeAuthenticationToken.initConfig(new CharSequenceInputStream(testYaml, "utf-8")); + Map<String, Config> map = OneTimeAuthenticationToken.getPurposeMap(); + Assert.assertEquals("four items", 4, map.size()); + Assert.assertTrue(map.get("purpose 2") instanceof Config); + } + + @Test + public void testOneTimeTokenConfigOutputFile() throws Exception { + File tempFile = File.createTempFile("authtoken", "json"); + tempFile.deleteOnExit(); + + StringBuilder testYaml = new StringBuilder(); + testYaml.append("- output:\n"); + testYaml.append(" file: " + tempFile.getAbsolutePath() + "\n"); + testYaml.append(" permissions: [ permission1 ]\n"); + + // write the token + OneTimeAuthenticationToken.initConfig(new CharSequenceInputStream(testYaml, "utf-8")); + Assert.assertTrue(tempFile.exists()); + try (BufferedReader reader = new BufferedReader(new FileReader(tempFile))) { + OneTimeAuthenticationToken token = + (OneTimeAuthenticationToken) SelfValidatingAuthenticationToken.parse(reader.readLine()); + assertEquals("Token has anonymous username", "anonymous", token.getPrincipal().getUsername()); + assertEquals( + "Token has anonymous realm", + OneTimeAuthenticationToken.REALM_NAME, + token.getPrincipal().getRealm()); + assertArrayEquals( + "Permissions array has been written and read", + new String[] {"permission1"}, + token.getPermissions().toArray()); + } + } + + @Test + public void testOneTimeTokenForAnonymous() throws Exception { + StringBuilder testYaml = new StringBuilder(); + testYaml.append("purpose: for anonymous\n"); + testYaml.append("roles: [ role1 ]\n"); + testYaml.append("permissions:\n"); + testYaml.append(" - permission1\n"); + + OneTimeAuthenticationToken.initConfig(new CharSequenceInputStream(testYaml, "utf-8")); + + Subject anonymous = SecurityUtils.getSubject(); + anonymous.login(AnonymousAuthenticationToken.getInstance()); + + OneTimeAuthenticationToken token = + OneTimeAuthenticationToken.generateForPurpose("for anonymous", anonymous); + assertEquals("anonymous", token.getPrincipal().getUsername()); + } + + @Test + public void testSessionTokenRealm() { + Config config = new Config(); + OneTimeAuthenticationToken token = OneTimeAuthenticationToken.generate(config); + + String serialized = token.toString(); + SelfValidatingAuthenticationToken parsed = SelfValidatingAuthenticationToken.parse(serialized); + + SessionTokenRealm sessionTokenRealm = new SessionTokenRealm(); + Assert.assertTrue(sessionTokenRealm.supports(token)); + Assert.assertTrue(sessionTokenRealm.supports(parsed)); + + Assert.assertNotNull(sessionTokenRealm.getAuthenticationInfo(token)); + Assert.assertNotNull(sessionTokenRealm.getAuthenticationInfo(parsed)); + + Subject anonymous = SecurityUtils.getSubject(); + anonymous.login(token); + } + + @Test + public void testIntInConfigYaml() throws IOException { + StringBuilder testYaml = new StringBuilder(); + testYaml.append("- expiresAfterSeconds: 1000\n"); + testYaml.append(" replayTimeout: 1000\n"); + + ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + ObjectReader reader = mapper.readerFor(Config.class); + Config config = + (Config) reader.readValues(new CharSequenceInputStream(testYaml, "utf-8")).next(); + + assertEquals(1000000, config.getExpiresAfter()); + assertEquals(1000, config.getReplayTimeout()); + } + + @Test + public void testLongInConfigYaml() throws IOException { + StringBuilder testYaml = new StringBuilder(); + testYaml.append("- expiresAfter: 9223372036854775000\n"); + testYaml.append(" replayTimeoutSeconds: 922337203685477\n"); + + ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + ObjectReader reader = mapper.readerFor(Config.class); + Config config = + (Config) reader.readValues(new CharSequenceInputStream(testYaml, "utf-8")).next(); + + assertEquals(9223372036854775000L, config.getExpiresAfter()); + assertEquals(922337203685477000L, config.getReplayTimeout()); + } +} diff --git a/src/test/java/caosdb/server/caching/TestCaching.java b/src/test/java/org/caosdb/server/caching/TestCaching.java similarity index 89% rename from src/test/java/caosdb/server/caching/TestCaching.java rename to src/test/java/org/caosdb/server/caching/TestCaching.java index 56d8e750ab75663e29808a0f97962df88006d080..40387790b369a711ff95668821cbe4e64d813150 100644 --- a/src/test/java/caosdb/server/caching/TestCaching.java +++ b/src/test/java/org/caosdb/server/caching/TestCaching.java @@ -1,14 +1,14 @@ -package caosdb.server.caching; +package org.caosdb.server.caching; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; -import caosdb.server.CaosDBServer; -import caosdb.server.accessControl.Pam; -import caosdb.server.database.backend.transaction.RetrieveProperties; import java.io.IOException; import org.apache.commons.jcs.JCS; import org.apache.commons.jcs.access.CacheAccess; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.accessControl.Pam; +import org.caosdb.server.database.backend.transaction.RetrieveProperties; import org.junit.BeforeClass; import org.junit.Test; diff --git a/src/test/java/caosdb/server/caching/TestNoCaching.java b/src/test/java/org/caosdb/server/caching/TestNoCaching.java similarity index 78% rename from src/test/java/caosdb/server/caching/TestNoCaching.java rename to src/test/java/org/caosdb/server/caching/TestNoCaching.java index dfab9de67b8c79871b6d2fd70fc6e25a1c231230..bcd2f08f128fe58de760ec9e1abca2b0837e7136 100644 --- a/src/test/java/caosdb/server/caching/TestNoCaching.java +++ b/src/test/java/org/caosdb/server/caching/TestNoCaching.java @@ -1,13 +1,13 @@ -package caosdb.server.caching; +package org.caosdb.server.caching; import static org.junit.Assert.assertEquals; -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; -import caosdb.server.database.backend.transaction.RetrieveProperties; import java.io.IOException; import org.apache.commons.jcs.JCS; import org.apache.commons.jcs.access.CacheAccess; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.ServerProperties; +import org.caosdb.server.database.backend.transaction.RetrieveProperties; import org.junit.BeforeClass; import org.junit.Test; diff --git a/src/test/java/caosdb/server/database/DatabaseMonitorTest.java b/src/test/java/org/caosdb/server/database/DatabaseMonitorTest.java similarity index 99% rename from src/test/java/caosdb/server/database/DatabaseMonitorTest.java rename to src/test/java/org/caosdb/server/database/DatabaseMonitorTest.java index 20f2cdf64ca6d17ab1ea9ec40d6e20a942595ce5..554baec079ed17d332dff47f0afb57405913dc33 100644 --- a/src/test/java/caosdb/server/database/DatabaseMonitorTest.java +++ b/src/test/java/org/caosdb/server/database/DatabaseMonitorTest.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.database; +package org.caosdb.server.database; import org.junit.Assert; import org.junit.Test; diff --git a/src/test/java/caosdb/server/database/InsertTest.java b/src/test/java/org/caosdb/server/database/InsertTest.java similarity index 96% rename from src/test/java/caosdb/server/database/InsertTest.java rename to src/test/java/org/caosdb/server/database/InsertTest.java index 70fef365c6c88699b5c566ea48c0de2a1c631fa5..7b00cacfe7c3454539cb6823d62bc3af9b4d7ce7 100644 --- a/src/test/java/caosdb/server/database/InsertTest.java +++ b/src/test/java/org/caosdb/server/database/InsertTest.java @@ -20,23 +20,23 @@ * * ** end header */ -package caosdb.server.database; +package org.caosdb.server.database; -import static caosdb.server.database.DatabaseUtils.deriveStage1Inserts; -import static caosdb.server.database.DatabaseUtils.deriveStage2Inserts; +import static org.caosdb.server.database.DatabaseUtils.deriveStage1Inserts; +import static org.caosdb.server.database.DatabaseUtils.deriveStage2Inserts; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import caosdb.server.datatype.CollectionValue; -import caosdb.server.datatype.GenericValue; -import caosdb.server.datatype.SingleValue; -import caosdb.server.entity.Entity; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.Role; -import caosdb.server.entity.StatementStatus; -import caosdb.server.entity.wrapper.Property; import java.util.LinkedList; +import org.caosdb.server.datatype.CollectionValue; +import org.caosdb.server.datatype.GenericValue; +import org.caosdb.server.datatype.SingleValue; +import org.caosdb.server.entity.Entity; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Role; +import org.caosdb.server.entity.StatementStatus; +import org.caosdb.server.entity.wrapper.Property; import org.junit.Test; public class InsertTest { diff --git a/src/test/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTest.java b/src/test/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTest.java new file mode 100644 index 0000000000000000000000000000000000000000..52b4c951d939f097258ec40ed16b6fd99784f9bd --- /dev/null +++ b/src/test/java/org/caosdb/server/database/backend/transaction/RetrieveFullEntityTest.java @@ -0,0 +1,79 @@ +/* + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> + * + * 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 <https://www.gnu.org/licenses/>. + * + * ** end header + */ +package org.caosdb.server.database.backend.transaction; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import java.util.ArrayList; +import java.util.List; +import org.caosdb.server.datatype.ReferenceValue; +import org.caosdb.server.entity.Entity; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.wrapper.Property; +import org.caosdb.server.entity.xml.PropertyToElementStrategyTest; +import org.caosdb.server.query.Query.Selection; +import org.junit.Test; + +public class RetrieveFullEntityTest { + + @Test + public void testRetrieveSubEntities() { + RetrieveFullEntity r = + new RetrieveFullEntity(0) { + + /** Mock-up */ + @Override + public void retrieveFullEntity(EntityInterface e, List<Selection> selections) { + // The id of the referenced window + assertEquals(1234, (int) e.getId()); + + // The level of selectors has been reduced by 1 + assertEquals("description", selections.get(0).getSelector()); + + e.setDescription("A heart-shaped window."); + }; + }; + + Property window = new Property(2345); + window.setName("Window"); + window.setDatatype("Window"); + window.setValue(new ReferenceValue(1234)); + + Entity house = new Entity(); + house.addProperty(window); + ReferenceValue value = (ReferenceValue) house.getProperties().getEntityById(2345).getValue(); + assertEquals(1234, (int) value.getId()); + assertNull(value.getEntity()); + + List<Selection> selections = new ArrayList<>(); + selections.add(PropertyToElementStrategyTest.parse("window.description")); + + r.retrieveSubEntities(house, selections); + + assertEquals(1234, (int) value.getId()); + assertNotNull(value.getEntity()); + assertEquals("A heart-shaped window.", value.getEntity().getDescription()); + } +} diff --git a/src/test/java/caosdb/server/database/backend/transactions/TestGetAllNames.java b/src/test/java/org/caosdb/server/database/backend/transactions/TestGetAllNames.java similarity index 73% rename from src/test/java/caosdb/server/database/backend/transactions/TestGetAllNames.java rename to src/test/java/org/caosdb/server/database/backend/transactions/TestGetAllNames.java index 1c67d5cba56cd3bfb1516788a0187f9bc673f5e6..73d434218dcd0962d31a798af510277708cf1a32 100644 --- a/src/test/java/caosdb/server/database/backend/transactions/TestGetAllNames.java +++ b/src/test/java/org/caosdb/server/database/backend/transactions/TestGetAllNames.java @@ -1,18 +1,18 @@ -package caosdb.server.database.backend.transactions; +package org.caosdb.server.database.backend.transactions; import static org.junit.Assert.assertEquals; -import caosdb.server.CaosDBServer; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.GetAllNamesImpl; -import caosdb.server.database.backend.transaction.GetAllNames; -import caosdb.server.database.misc.TransactionBenchmark; -import caosdb.server.database.proto.SparseEntity; -import caosdb.server.entity.EntityInterface; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.GetAllNamesImpl; +import org.caosdb.server.database.backend.transaction.GetAllNames; +import org.caosdb.server.database.misc.TransactionBenchmark; +import org.caosdb.server.database.proto.SparseEntity; +import org.caosdb.server.entity.EntityInterface; import org.junit.BeforeClass; import org.junit.Test; diff --git a/src/test/java/caosdb/server/datatype/testBoolean.java b/src/test/java/org/caosdb/server/datatype/testBoolean.java similarity index 95% rename from src/test/java/caosdb/server/datatype/testBoolean.java rename to src/test/java/org/caosdb/server/datatype/testBoolean.java index 3e20830e9261c70fa3ead33e34d12ed1e9fc2f25..acf0578a332bb4ef21e1ff9eecce4037fc78540c 100644 --- a/src/test/java/caosdb/server/datatype/testBoolean.java +++ b/src/test/java/org/caosdb/server/datatype/testBoolean.java @@ -20,16 +20,16 @@ * * ** end header */ -package caosdb.server.datatype; +package org.caosdb.server.datatype; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import caosdb.server.datatype.AbstractDatatype.Table; -import caosdb.server.entity.Message; -import caosdb.server.utils.ServerMessages; +import org.caosdb.server.datatype.AbstractDatatype.Table; +import org.caosdb.server.entity.Message; +import org.caosdb.server.utils.ServerMessages; import org.junit.Test; public class testBoolean { diff --git a/src/test/java/caosdb/server/entity/SelectionTest.java b/src/test/java/org/caosdb/server/entity/SelectionTest.java similarity index 78% rename from src/test/java/caosdb/server/entity/SelectionTest.java rename to src/test/java/org/caosdb/server/entity/SelectionTest.java index cc961b9a5cfa47c022cfdf63201ea53613758a32..0ede3a970be6504ef0a89868aed40e4cadb141d0 100644 --- a/src/test/java/caosdb/server/entity/SelectionTest.java +++ b/src/test/java/org/caosdb/server/entity/SelectionTest.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -20,15 +22,28 @@ * * ** end header */ -package caosdb.server.entity; +package org.caosdb.server.entity; -import caosdb.server.entity.xml.SetFieldStrategy; -import caosdb.server.query.Query.Selection; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.entity.xml.SetFieldStrategy; +import org.caosdb.server.query.Query; +import org.caosdb.server.query.Query.Selection; import org.junit.Assert; +import org.junit.BeforeClass; import org.junit.Test; public class SelectionTest { + @BeforeClass + public static void initServerProperties() throws IOException { + CaosDBServer.initServerProperties(); + } + @Test public void testEmpty1() { final SetFieldStrategy setFieldStrategy = new SetFieldStrategy(); @@ -59,7 +74,7 @@ public class SelectionTest { final Selection selection = new Selection("id"); final SetFieldStrategy setFieldStrategy = (new SetFieldStrategy()).addSelection(selection); - Assert.assertFalse(setFieldStrategy.isToBeSet("name")); + Assert.assertTrue(setFieldStrategy.isToBeSet("name")); } @Test @@ -262,16 +277,50 @@ public class SelectionTest { .addSelection(new Selection("blabla").setSubSelection(new Selection("value"))) .addSelection(new Selection("blabla").setSubSelection(new Selection("description"))); - Assert.assertTrue(setFieldStrategy.isToBeSet("blabla")); - Assert.assertTrue(setFieldStrategy.isToBeSet("id")); - Assert.assertTrue(setFieldStrategy.isToBeSet("name")); - Assert.assertFalse(setFieldStrategy.isToBeSet("bleb")); + assertTrue(setFieldStrategy.isToBeSet("blabla")); + assertTrue(setFieldStrategy.isToBeSet("id")); + assertTrue(setFieldStrategy.isToBeSet("name")); + assertFalse(setFieldStrategy.isToBeSet("bleb")); final SetFieldStrategy forProperty = setFieldStrategy.forProperty("blabla"); - Assert.assertTrue(forProperty.isToBeSet("id")); - Assert.assertTrue(forProperty.isToBeSet("name")); - Assert.assertTrue(forProperty.isToBeSet("description")); - Assert.assertTrue(forProperty.isToBeSet("value")); - Assert.assertFalse(forProperty.isToBeSet("blub")); + assertTrue(forProperty.isToBeSet("id")); + assertTrue(forProperty.isToBeSet("name")); + assertTrue(forProperty.isToBeSet("description")); + assertTrue(forProperty.isToBeSet("value")); + assertFalse(forProperty.isToBeSet("blub")); + } + + @Test + public void testSubSubSelection() { + String query_str = "SELECT property.subproperty.subsubproperty FROM ENTITY"; + Query query = new Query(query_str); + query.parse(); + assertEquals(query.getSelections().size(), 1); + + Selection s = query.getSelections().get(0); + assertEquals(s.toString(), "property.subproperty.subsubproperty"); + assertEquals(s.getSubselection().toString(), "subproperty.subsubproperty"); + assertEquals(s.getSubselection().getSubselection().toString(), "subsubproperty"); + } + + @Test + public void testSubSubProperty() { + Selection s = + new Selection("property") + .setSubSelection( + new Selection("subproperty").setSubSelection(new Selection("subsubproperty"))); + + assertEquals(s.toString(), "property.subproperty.subsubproperty"); + + SetFieldStrategy setFieldStrategy = new SetFieldStrategy().addSelection(s); + assertTrue(setFieldStrategy.isToBeSet("property")); + assertFalse(setFieldStrategy.forProperty("property").isToBeSet("sadf")); + // assertFalse(setFieldStrategy.forProperty("property").isToBeSet("name")); + assertTrue(setFieldStrategy.forProperty("property").isToBeSet("subproperty")); + assertTrue( + setFieldStrategy + .forProperty("property") + .forProperty("subproperty") + .isToBeSet("subsubproperty")); } } diff --git a/src/test/java/org/caosdb/server/entity/container/PropertyContainerTest.java b/src/test/java/org/caosdb/server/entity/container/PropertyContainerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..0428af146f7b4a191fa6be679e01af45aff315f2 --- /dev/null +++ b/src/test/java/org/caosdb/server/entity/container/PropertyContainerTest.java @@ -0,0 +1,80 @@ +/* + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> + * + * 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 <https://www.gnu.org/licenses/>. + * + * ** end header + */ +package org.caosdb.server.entity.container; + +import static org.junit.Assert.assertEquals; + +import org.caosdb.server.datatype.GenericValue; +import org.caosdb.server.datatype.ReferenceValue; +import org.caosdb.server.entity.Entity; +import org.caosdb.server.entity.Role; +import org.caosdb.server.entity.wrapper.Property; +import org.caosdb.server.entity.xml.PropertyToElementStrategyTest; +import org.caosdb.server.entity.xml.SetFieldStrategy; +import org.jdom2.Element; +import org.junit.BeforeClass; +import org.junit.Test; + +public class PropertyContainerTest { + + public static Entity house = null; + public static Property houseHeight = null; + public static Entity window = null; + public static Property windowHeight = null; + public static Entity houseOwner = null; + public static Property windowProperty = null; + + @BeforeClass + public static void setup() { + window = new Entity(1234); + windowHeight = new Property(new Entity("window.height", Role.Property)); + window.addProperty(windowHeight); + windowHeight.setValue(new GenericValue("windowHeight")); + + houseOwner = new Entity("The Queen", Role.Record); + + house = new Entity("Buckingham Palace", Role.Record); + houseHeight = new Property(new Entity("height", Role.Property)); + houseHeight.setValue(new GenericValue("houseHeight")); + house.addProperty(houseHeight); + windowProperty = new Property(2345); + windowProperty.setName("window"); + windowProperty.setValue(new ReferenceValue(window.getId())); + house.addProperty(windowProperty); + + house.addProperty(new Property()); + house.addProperty(new Property(houseHeight)); + } + + @Test + public void test() { + PropertyContainer container = new PropertyContainer(new Entity()); + Element element = new Element("Record"); + SetFieldStrategy setFieldStrategy = + new SetFieldStrategy().addSelection(PropertyToElementStrategyTest.parse("window.height")); + + container.addToElement(windowProperty, element, setFieldStrategy); + + assertEquals(1, element.getChildren().size()); + } +} diff --git a/src/test/java/org/caosdb/server/entity/xml/PropertyToElementStrategyTest.java b/src/test/java/org/caosdb/server/entity/xml/PropertyToElementStrategyTest.java new file mode 100644 index 0000000000000000000000000000000000000000..99cf2706937dce10b8db3a1305053356587e139a --- /dev/null +++ b/src/test/java/org/caosdb/server/entity/xml/PropertyToElementStrategyTest.java @@ -0,0 +1,105 @@ +/* + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> + * + * 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 <https://www.gnu.org/licenses/>. + * + * ** end header + */ +package org.caosdb.server.entity.xml; + +import static org.junit.Assert.assertEquals; + +import org.caosdb.server.datatype.GenericValue; +import org.caosdb.server.datatype.ReferenceValue; +import org.caosdb.server.entity.Entity; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.Role; +import org.caosdb.server.entity.wrapper.Property; +import org.caosdb.server.query.Query.Selection; +import org.jdom2.Element; +import org.junit.Before; +import org.junit.Test; + +public class PropertyToElementStrategyTest { + + public static Entity house = null; + public static Property houseHeight = null; + public static Entity window = null; + public static Property windowHeight = null; + public static Entity houseOwner = null; + public static Property windowProperty = null; + + /** + * Create a nested selection out of the dot-separated parts of <code>select</code>. + * + * <p>The returned Selection has nested subselections, so that each subselection corresponds to + * the next part and the remainder of the initial <code>select</code> String. + */ + public static Selection parse(String select) { + String[] split = select.split("\\."); + Selection result = new Selection(split[0]); + Selection next = result; + + for (int i = 1; i < split.length; i++) { + next.setSubSelection(new Selection(split[i])); + next = next.getSubselection(); + } + return result; + } + + @Before + public void setup() { + window = new Entity(1234, Role.Record); + windowHeight = new Property(new Entity("height", Role.Property)); + window.addProperty(windowHeight); + windowHeight.setValue(new GenericValue("windowHeight")); + + houseOwner = new Entity("The Queen", Role.Record); + + house = new Entity("Buckingham Palace", Role.Record); + houseHeight = new Property(new Entity("height", Role.Property)); + houseHeight.setValue(new GenericValue("houseHeight")); + house.addProperty(houseHeight); + windowProperty = new Property(2345); + windowProperty.setName("window"); + windowProperty.setValue(new ReferenceValue(window.getId())); + house.addProperty(windowProperty); + + house.addProperty(new Property()); + house.addProperty(new Property(houseHeight)); + } + + @Test + public void test() { + PropertyToElementStrategy strategy = new PropertyToElementStrategy(); + SetFieldStrategy setFieldStrategy = new SetFieldStrategy().addSelection(parse("height")); + EntityInterface property = windowProperty; + ((ReferenceValue) property.getValue()).setEntity(window, true); + Element element = strategy.toElement(property, setFieldStrategy); + assertEquals("Property", element.getName()); + assertEquals("2345", element.getAttributeValue("id")); + assertEquals("window", element.getAttributeValue("name")); + assertEquals(1, element.getChildren().size()); + assertEquals("Record", element.getChildren().get(0).getName()); + + Element recordElement = element.getChild("Record"); + assertEquals("1234", recordElement.getAttributeValue("id")); + assertEquals(1, recordElement.getChildren().size()); + assertEquals("windowHeight", recordElement.getChild("Property").getText()); + } +} diff --git a/src/test/java/caosdb/server/jobs/ScheduleTest.java b/src/test/java/org/caosdb/server/jobs/ScheduleTest.java similarity index 97% rename from src/test/java/caosdb/server/jobs/ScheduleTest.java rename to src/test/java/org/caosdb/server/jobs/ScheduleTest.java index 73c27d95af64b70d63ec8d1bed7fab0c0d41ffaa..7ad1d6112e8b7bd3a29042d5f6ca82709ae4100a 100644 --- a/src/test/java/caosdb/server/jobs/ScheduleTest.java +++ b/src/test/java/org/caosdb/server/jobs/ScheduleTest.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.jobs; +package org.caosdb.server.jobs; import static org.junit.Assert.fail; diff --git a/src/test/java/caosdb/server/jobs/core/TestInsertFilesInDir.java b/src/test/java/org/caosdb/server/jobs/core/TestInsertFilesInDir.java similarity index 92% rename from src/test/java/caosdb/server/jobs/core/TestInsertFilesInDir.java rename to src/test/java/org/caosdb/server/jobs/core/TestInsertFilesInDir.java index 37cad0eca28a50b006985a73edb07e45b60fdf9e..ae5df853ba5d29e681cd0fb0e5ec8eee6ec3462c 100644 --- a/src/test/java/caosdb/server/jobs/core/TestInsertFilesInDir.java +++ b/src/test/java/org/caosdb/server/jobs/core/TestInsertFilesInDir.java @@ -1,4 +1,4 @@ -package caosdb.server.jobs.core; +package org.caosdb.server.jobs.core; import static org.junit.Assert.assertTrue; diff --git a/src/test/java/caosdb/server/logging/TestLogging.java b/src/test/java/org/caosdb/server/logging/TestLogging.java similarity index 91% rename from src/test/java/caosdb/server/logging/TestLogging.java rename to src/test/java/org/caosdb/server/logging/TestLogging.java index 6e35d96585683d99c81a0fc2c669d4dc977bc09a..f1a130ad09c0eca378560b500fc38344df279f17 100644 --- a/src/test/java/caosdb/server/logging/TestLogging.java +++ b/src/test/java/org/caosdb/server/logging/TestLogging.java @@ -1,9 +1,9 @@ -package caosdb.server.logging; +package org.caosdb.server.logging; -import caosdb.server.CaosDBServer; import java.io.File; import java.io.IOException; import org.apache.commons.io.FileUtils; +import org.caosdb.server.CaosDBServer; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; @@ -32,7 +32,7 @@ public class TestLogging { logger.info("info"); logger.debug("debug"); logger.trace("trace"); - Assert.assertEquals(logger.getName(), "caosdb.server.logging.TestLogging"); + Assert.assertEquals(logger.getName(), "org.caosdb.server.logging.TestLogging"); Assert.assertTrue(logger.isErrorEnabled()); Assert.assertTrue(logger.isWarnEnabled()); Assert.assertTrue(logger.isInfoEnabled()); diff --git a/src/test/java/org/caosdb/server/permissions/EntityACLTest.java b/src/test/java/org/caosdb/server/permissions/EntityACLTest.java new file mode 100644 index 0000000000000000000000000000000000000000..0e0e3ee121b09332b6cbb7d86a22458bb5fbf17f --- /dev/null +++ b/src/test/java/org/caosdb/server/permissions/EntityACLTest.java @@ -0,0 +1,408 @@ +/* + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2018 Research Group Biomedical Physics, + * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * + * 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 <https://www.gnu.org/licenses/>. + * + * ** end header + */ +package org.caosdb.server.permissions; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.BitSet; +import java.util.HashSet; +import java.util.LinkedList; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.subject.Subject; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.accessControl.AnonymousAuthenticationToken; +import org.caosdb.server.accessControl.AuthenticationUtils; +import org.caosdb.server.accessControl.Config; +import org.caosdb.server.accessControl.OneTimeAuthenticationToken; +import org.caosdb.server.accessControl.Role; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.RetrievePermissionRulesImpl; +import org.caosdb.server.database.backend.interfaces.RetrieveRoleImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.misc.TransactionBenchmark; +import org.caosdb.server.resource.AbstractCaosDBServerResource; +import org.caosdb.server.resource.AbstractCaosDBServerResource.XMLParser; +import org.caosdb.server.utils.Utils; +import org.jdom2.Element; +import org.jdom2.JDOMException; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +public class EntityACLTest { + + public static long convert(final BitSet bits) { + long value = 0L; + for (int i = 0; i < bits.length(); ++i) { + value += bits.get(i) ? (1L << i) : 0L; + } + return value; + } + + /** a no-op mock-up which resolved all rules to an empty set of permissions. */ + public static class RetrievePermissionRulesMockup implements RetrievePermissionRulesImpl { + + public RetrievePermissionRulesMockup(Access a) {} + + @Override + public void setTransactionBenchmark(TransactionBenchmark b) {} + + @Override + public TransactionBenchmark getBenchmark() { + return null; + } + + @Override + public HashSet<PermissionRule> retrievePermissionRule(String role) throws TransactionException { + return new HashSet<>(); + } + } + + /** a mock-up which returns null */ + public static class RetrieveRoleMockup implements RetrieveRoleImpl { + + public RetrieveRoleMockup(Access a) {} + + @Override + public void setTransactionBenchmark(TransactionBenchmark b) {} + + @Override + public TransactionBenchmark getBenchmark() { + return null; + } + + @Override + public Role retrieve(String role) throws TransactionException { + return null; + } + } + + @BeforeClass + public static void init() throws IOException { + CaosDBServer.initServerProperties(); + CaosDBServer.initShiro(); + assertNotNull(EntityACL.GLOBAL_PERMISSIONS); + + BackendTransaction.setImpl( + RetrievePermissionRulesImpl.class, RetrievePermissionRulesMockup.class); + BackendTransaction.setImpl(RetrieveRoleImpl.class, RetrieveRoleMockup.class); + } + + @Test + public void testConvert() { + long l = Integer.MAX_VALUE; + System.out.println(EntityACL.convert(l)); + l = Integer.MIN_VALUE; + System.out.println(EntityACL.convert(l)); + l = Long.MAX_VALUE; + System.out.println(EntityACL.convert(l)); + l = Long.MIN_VALUE; + System.out.println(EntityACL.convert(l)); + final BitSet bitSet = new BitSet(64); + Assert.assertEquals(0, convert(bitSet)); + + bitSet.set(0); + Assert.assertEquals(1, convert(bitSet)); + + bitSet.clear(); + bitSet.set(63); + Assert.assertEquals(Long.MIN_VALUE, convert(bitSet)); + + bitSet.clear(); + bitSet.set(0, 63, true); + Assert.assertEquals(Long.MAX_VALUE, convert(bitSet)); + + bitSet.clear(); + bitSet.set(62); + Assert.assertEquals(EntityACL.MIN_PRIORITY_BITSET, convert(bitSet)); + + bitSet.set(63); + Assert.assertEquals(-EntityACL.MIN_PRIORITY_BITSET, convert(bitSet)); + + bitSet.clear(); + bitSet.set(0, 64, true); + Assert.assertEquals(-1L, convert(bitSet)); + + Assert.assertTrue(EntityACL.convert(-12523).get(63)); + Assert.assertFalse(EntityACL.convert(12523).get(63)); + + bitSet.clear(); + bitSet.set(0, 63, true); + Assert.assertEquals(Long.MAX_VALUE + 1L, Long.MIN_VALUE); + Assert.assertEquals(Long.MAX_VALUE, convert(bitSet)); + } + + @Test + public void testIsDenial() { + final BitSet bitSet = new BitSet(64); + bitSet.set(63); + + Assert.assertTrue(EntityACL.isDenial(convert(bitSet))); + Assert.assertTrue(EntityACL.isDenial(-12523)); + Assert.assertFalse(EntityACL.isDenial(0)); + Assert.assertFalse(EntityACL.isDenial(246345)); + Assert.assertTrue(EntityACL.isDenial(-EntityACL.MIN_PRIORITY_BITSET)); + } + + @Test + public void testIsAllowance() { + final BitSet bitSet = new BitSet(32); + bitSet.set(27); + + Assert.assertTrue(EntityACL.isAllowance(convert(bitSet))); + Assert.assertTrue(EntityACL.isAllowance(12523)); + Assert.assertTrue(EntityACL.isAllowance(0)); + Assert.assertFalse(EntityACL.isAllowance(-246345)); + Assert.assertTrue(EntityACL.isAllowance(EntityACL.MIN_PRIORITY_BITSET)); + } + + @Test + public void testGetResultingACL() { + final LinkedList<Long> acl = new LinkedList<Long>(); + acl.add(1L); // +P1 + Assert.assertEquals(1L, EntityACL.getResultingACL(acl)); // P1 + + acl.add(2L); // +P2 + Assert.assertEquals(3L, EntityACL.getResultingACL(acl)); // P1,P2 + + acl.add(4L); // +P3 + Assert.assertEquals(7L, EntityACL.getResultingACL(acl)); // P1,P2,P3 + + acl.add(Long.MIN_VALUE + 1); // -P1 + Assert.assertEquals(6L, EntityACL.getResultingACL(acl)); // P2,P3 + + acl.add(Long.MIN_VALUE + 1); // -P1Allow + Assert.assertEquals(6L, EntityACL.getResultingACL(acl)); // P2,P3 + + acl.add(Long.MIN_VALUE + 8); // -P4 + Assert.assertEquals(6L, EntityACL.getResultingACL(acl)); // P2,P3 + + acl.add(8L); // +P4 + Assert.assertEquals(6L, EntityACL.getResultingACL(acl)); // P2,P3 + + acl.add(EntityACL.MIN_PRIORITY_BITSET + 1); // ++P1 + Assert.assertEquals(7L, EntityACL.getResultingACL(acl)); // P1,P2,P3 + + acl.add(EntityACL.MIN_PRIORITY_BITSET + 2); // ++P2 + Assert.assertEquals(7L, EntityACL.getResultingACL(acl)); // P1,P2,P3 + + acl.add(Long.MIN_VALUE + 1); // -P1 + Assert.assertEquals(7l, EntityACL.getResultingACL(acl)); // P1,P2,P3 + + acl.add(Long.MIN_VALUE + 4); // -P1 + Assert.assertEquals(3l, EntityACL.getResultingACL(acl)); // P1,P2 + + acl.add(EntityACL.MIN_PRIORITY_BITSET + 8); // ++P4 + Assert.assertEquals(11L, EntityACL.getResultingACL(acl)); // P1,P2,P4 + + acl.add(Long.MIN_VALUE + EntityACL.MIN_PRIORITY_BITSET + 2); // --P2 + Assert.assertEquals(9L, EntityACL.getResultingACL(acl)); // P1,P4 + + acl.add(Long.MIN_VALUE + EntityACL.MIN_PRIORITY_BITSET + 1); // --P1Allow + Assert.assertEquals(8L, EntityACL.getResultingACL(acl)); // P4 + } + + @Test + public void testOwnerBitSet() { + Assert.assertEquals(convert(EntityACL.convert(EntityACL.OWNER_BITSET).get(1, 32)), 0); + } + + @Test + public void testDeserialize() { + Assert.assertTrue(EntityACL.deserialize("{}") instanceof EntityACL); + Assert.assertTrue(EntityACL.deserialize("{\"tf\":134}") instanceof EntityACL); + Assert.assertTrue(EntityACL.deserialize("{\"tf\":6343,\"bla\":884}") instanceof EntityACL); + Assert.assertTrue(EntityACL.deserialize("{\"tf\":-2835,\"bla\":884}") instanceof EntityACL); + Assert.assertTrue( + EntityACL.deserialize("{\"?OWNER?\":526,\"tahsdh \": -235}") instanceof EntityACL); + Assert.assertTrue(EntityACL.deserialize("{\"asdf\":2345}") instanceof EntityACL); + Assert.assertTrue(raisesIllegalStateException("{")); + Assert.assertTrue(raisesIllegalStateException("}")); + Assert.assertTrue(raisesIllegalStateException("{tf:}")); + Assert.assertTrue(raisesIllegalStateException("{tf:;}")); + Assert.assertTrue(raisesIllegalStateException("{:234}")); + Assert.assertTrue(raisesIllegalStateException("{:234;}")); + Assert.assertTrue(raisesIllegalStateException("{tf:tf;}")); + Assert.assertTrue(raisesIllegalStateException("{tf: +5259;}")); + Assert.assertTrue(raisesIllegalStateException("{tf;}")); + Assert.assertTrue(raisesIllegalStateException("{tf:123223727356235782735235;}")); + } + + public boolean raisesIllegalStateException(final String input) { + try { + EntityACL.deserialize(input); + } catch (final IllegalStateException e) { + return true; + } + return false; + } + + public static AbstractCaosDBServerResource.XMLParser parser = new XMLParser(); + + public Element stringToJdom(final String s) throws JDOMException, IOException { + return parser.parse(Utils.String2InputStream(s)).getRootElement(); + } + + @Test + public void testEntityACLForAnonymous() { + Subject anonymous = SecurityUtils.getSubject(); + anonymous.login(AnonymousAuthenticationToken.getInstance()); + assertTrue(AuthenticationUtils.isAnonymous(anonymous)); + EntityACL acl = EntityACL.getOwnerACLFor(anonymous); + assertNotNull(acl); + assertTrue(acl.getOwners().isEmpty()); + } + + // @Test + // public void testParseFromElement() throws JDOMException, IOException { + // Assert.assertEquals("[]", + // EntityACL.serialize(EntityACL.parseFromElement(stringToJdom("<ACL></ACL>")))); + // Assert.assertEquals("[]", EntityACL.serialize(EntityACL + // .parseFromElement(stringToJdom("<ACL><Grant></Grant></ACL>")))); + // Assert.assertEquals("[]", EntityACL.serialize(EntityACL + // .parseFromElement(stringToJdom("<ACL><Deny></Deny></ACL>")))); + // Assert.assertEquals("[]", EntityACL.serialize(EntityACL + // .parseFromElement(stringToJdom("<ACL><Grant role='bla'></Grant></ACL>")))); + // Assert.assertEquals("[]", EntityACL.serialize(EntityACL + // .parseFromElement(stringToJdom("<ACL><Deny role='bla'></Deny></ACL>")))); + // Assert.assertEquals( + // "{bla:2;}", + // EntityACL.serialize(EntityACL + // .parseFromElement(stringToJdom("<ACL><Grant role='bla'><Permission + // name='DELETE'/></Grant></ACL>")))); + // Assert.assertEquals( + // "{bla:" + (Long.MIN_VALUE + 2) + ";}", + // EntityACL.serialize(EntityACL + // .parseFromElement(stringToJdom("<ACL><Deny role='bla'><Permission name='DELETE' + // /></Deny></ACL>")))); + // Assert.assertEquals( + // "{bla:32;}", + // EntityACL.serialize(EntityACL + // .parseFromElement(stringToJdom("<ACL><Grant role='bla'><Permission name='RETRIEVE:ACL' + // /></Grant></ACL>")))); + // } + + @Test + public void testFactory() { + final EntityACLFactory f = new EntityACLFactory(); + + org.caosdb.server.permissions.Role role1 = org.caosdb.server.permissions.Role.create("role1"); + Config config1 = new Config(); + config1.setRoles(new String[] {role1.toString()}); + OneTimeAuthenticationToken token1 = OneTimeAuthenticationToken.generate(config1); + Subject user1 = SecurityUtils.getSecurityManager().createSubject(null); + user1.login(token1); + + org.caosdb.server.permissions.Role role2 = org.caosdb.server.permissions.Role.create("role2"); + Config config2 = new Config(); + config2.setRoles(new String[] {role2.toString()}); + OneTimeAuthenticationToken token2 = OneTimeAuthenticationToken.generate(config2); + Subject user2 = SecurityUtils.getSecurityManager().createSubject(null); + user2.login(token2); + + f.grant(role1, "UPDATE:NAME"); + Assert.assertTrue((f.create().isPermitted(user1, EntityPermission.UPDATE_NAME))); + Assert.assertFalse((f.create().isPermitted(user2, EntityPermission.UPDATE_NAME))); + f.grant(role2, "DELETE"); + Assert.assertFalse((f.create().isPermitted(user1, EntityPermission.DELETE))); + Assert.assertTrue((f.create().isPermitted(user2, EntityPermission.DELETE))); + f.deny(role2, 1); + f.deny(role1, 1); + Assert.assertFalse((f.create().isPermitted(user1, EntityPermission.DELETE))); + Assert.assertFalse((f.create().isPermitted(user2, EntityPermission.DELETE))); + f.grant(role1, true, 1); + Assert.assertTrue((f.create().isPermitted(user1, EntityPermission.DELETE))); + Assert.assertFalse((f.create().isPermitted(user2, EntityPermission.DELETE))); + f.deny(role2, true, 1); + Assert.assertTrue((f.create().isPermitted(user1, EntityPermission.DELETE))); + Assert.assertFalse((f.create().isPermitted(user2, EntityPermission.DELETE))); + f.grant(role2, true, 1); + Assert.assertTrue((f.create().isPermitted(user1, EntityPermission.DELETE))); + Assert.assertFalse((f.create().isPermitted(user2, EntityPermission.DELETE))); + f.deny(role1, true, 1); + Assert.assertFalse((f.create().isPermitted(user1, EntityPermission.DELETE))); + Assert.assertFalse((f.create().isPermitted(user2, EntityPermission.DELETE))); + Assert.assertTrue((f.create().isPermitted(user1, EntityPermission.UPDATE_NAME))); + Assert.assertFalse((f.create().isPermitted(user2, EntityPermission.UPDATE_NAME))); + } + + // @Test + // public void niceFactoryStuff() { + // final EntityACLFactory f = new EntityACLFactory(); + // f.grant("user1", "*"); + // final EntityACL acl1 = f.create(); + // Assert.assertTrue(acl1.isPermitted("user1", EntityPermission.EDIT_ACL)); + // Assert.assertTrue(acl1.isPermitted("user1", EntityPermission.DELETE)); + // Assert.assertTrue(acl1.isPermitted("user1", + // EntityPermission.RETRIEVE_ENTITY)); + // Assert.assertTrue(acl1.isPermitted("user1", + // EntityPermission.UPDATE_DATA_TYPE)); + // Assert.assertTrue(acl1.isPermitted("user1", + // EntityPermission.USE_AS_PROPERTY)); + // + // f.grant("?OWNER?", "DELETE", "EDIT:ACL", "RETRIEVE:*", "UPDATE:*", + // "USE:*"); + // f.grant("user2", "EDIT:ACL"); + // final EntityACL acl2 = f.create(); + // Assert.assertTrue(acl2.isPermitted("user2", EntityPermission.EDIT_ACL)); + // Assert.assertTrue(acl2.isPermitted("user2", EntityPermission.DELETE)); + // Assert.assertTrue(acl2.isPermitted("user2", + // EntityPermission.RETRIEVE_ENTITY)); + // Assert.assertTrue(acl2.isPermitted("user2", + // EntityPermission.UPDATE_DATA_TYPE)); + // Assert.assertTrue(acl2.isPermitted("user2", + // EntityPermission.USE_AS_PROPERTY)); + // + // } + // + // @Test + // public void testDeny() { + // EntityACLFactory f = new EntityACLFactory(); + // f.deny("test", "DELETE"); + // Assert.assertFalse(f.create().isPermitted("test", + // EntityPermission.DELETE)); + // + // System.out.println(Utils.element2String(f.create().toElement())); + // + // System.out.println(Utils.element2String(EntityACL.GLOBAL_PERMISSIONS.toElement())); + // + // f.grant("test", "USE:*"); + // Assert.assertFalse(f.create().isPermitted("test", + // EntityPermission.DELETE)); + // + // System.out.println(Utils.element2String(f.create().toElement())); + // + // f = new EntityACLFactory(); + // f.grant(EntityACL.OTHER_ROLE, "RETRIEVE:*"); + // f.deny(EntityACL.OTHER_ROLE, "DELETE"); + // final EntityACL a = f.create(); + // + // System.out.println(Utils.element2String(a.toElement())); + // + // System.out.println(Utils.element2String(EntityACL.deserialize(a.serialize()).toElement())); + // } + +} diff --git a/src/test/java/caosdb/server/query/TestCQL.java b/src/test/java/org/caosdb/server/query/TestCQL.java similarity index 97% rename from src/test/java/caosdb/server/query/TestCQL.java rename to src/test/java/org/caosdb/server/query/TestCQL.java index 6006297dac0cd029ee451c0349f2b11e7ac2f86e..2f6651cc81a2614b63f1314f35052fe2096758b0 100644 --- a/src/test/java/caosdb/server/query/TestCQL.java +++ b/src/test/java/org/caosdb/server/query/TestCQL.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.query; +package org.caosdb.server.query; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -29,14 +29,6 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import caosdb.server.CaosDBServer; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.implementation.MySQL.ConnectionException; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.query.CQLParser.CqContext; -import caosdb.server.query.Query.Pattern; -import caosdb.server.query.Query.QueryException; -import caosdb.server.utils.Initialization; import java.io.IOException; import java.sql.SQLException; import java.util.LinkedList; @@ -45,6 +37,14 @@ import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.tree.ParseTree; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.implementation.MySQL.ConnectionException; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.query.CQLParser.CqContext; +import org.caosdb.server.query.Query.Pattern; +import org.caosdb.server.query.Query.QueryException; +import org.caosdb.server.utils.Initialization; import org.junit.BeforeClass; import org.junit.Test; @@ -167,8 +167,11 @@ public class TestCQL { String ticket187 = "FIND Entity WITH pname=-1"; String ticket207 = "FIND RECORD WHICH REFERENCES 10594"; String query33 = "FIND ename WITH a date IN 2015"; + String query33a = "FIND ename WITH a date IN \"2015\""; String query34 = "FIND ename WITH a date NOT IN 2015"; + String query34a = "FIND ename WITH a date NOT IN \"2015\""; String query35 = "FIND ename WITH a date IN 2015-01-01"; + String query35a = "FIND ename WITH a date IN \"2015-01-01\""; String query36 = "FIND ename.pname LIKE \"wil*card\""; String query37 = "FIND ename.pname LIKE wil*card"; String query38 = "FIND ename WHICH HAS A pname LIKE \"wil*\""; @@ -238,6 +241,9 @@ public class TestCQL { String referenceByLikePattern = "FIND ENTITY WHICH IS REFERENCED BY *name*"; String emptyTextValue = "FIND ENTITY WITH prop=''"; + String queryMR56 = "FIND ENTITY WITH ((p0 = v0 OR p1=v1) AND p2=v2)"; + + String versionedQuery1 = "FIND ANY VERSION OF ENTITY e1"; @Test public void testQuery1() @@ -4671,6 +4677,45 @@ public class TestCQL { assertEquals("2015", pov.getValue()); } + /** String query33a = "FIND ename WITH a date IN \"2015\""; */ + @Test + public void testQuery33a() { + CQLLexer lexer; + lexer = new CQLLexer(CharStreams.fromString(this.query33a)); + final CommonTokenStream tokens = new CommonTokenStream(lexer); + + final CQLParser parser = new CQLParser(tokens); + final CqContext sfq = parser.cq(); + + System.out.println(sfq.toStringTree(parser)); + + // 4 children: FIND, role, WHICHCLAUSE, EOF + assertEquals(4, sfq.getChildCount()); + assertEquals("FIND", sfq.getChild(0).getText()); + assertEquals("ename", sfq.getChild(1).getText()); + assertEquals("WITHadateIN\"2015\"", sfq.getChild(2).getText()); + assertEquals("ename", sfq.e.toString()); + assertNull(sfq.r); + assertEquals("POV", sfq.filter.getClass().getSimpleName()); + + final ParseTree whichclause = sfq.getChild(2); + // 2 children; WHICH, transaction + assertEquals(2, whichclause.getChildCount()); + assertEquals("WITHa", whichclause.getChild(0).getText()); + assertEquals("dateIN\"2015\"", whichclause.getChild(1).getText()); + + final ParseTree transactionFilter = whichclause.getChild(1).getChild(0); + assertEquals(3, transactionFilter.getChildCount()); + assertEquals("date", transactionFilter.getChild(0).getText()); + assertEquals("IN", transactionFilter.getChild(1).getText()); + assertEquals("\"2015\"", transactionFilter.getChild(2).getText()); + + assertTrue(sfq.filter instanceof POV); + final POV pov = (POV) sfq.filter; + assertEquals("(", pov.getOperator()); + assertEquals("2015", pov.getValue()); + } + /** String query34 = "FIND ename WITH a date NOT IN 2015"; */ @Test public void testQuery34() { @@ -4711,6 +4756,46 @@ public class TestCQL { assertEquals("2015", pov.getValue()); } + /** String query34a = "FIND ename WITH a date NOT IN \"2015\""; */ + @Test + public void testQuery34a() { + CQLLexer lexer; + lexer = new CQLLexer(CharStreams.fromString(this.query34a)); + final CommonTokenStream tokens = new CommonTokenStream(lexer); + + final CQLParser parser = new CQLParser(tokens); + final CqContext sfq = parser.cq(); + + System.out.println(sfq.toStringTree(parser)); + + // 4 children: FIND, role, WHICHCLAUSE, EOF + assertEquals(4, sfq.getChildCount()); + assertEquals("FIND", sfq.getChild(0).getText()); + assertEquals("ename", sfq.getChild(1).getText()); + assertEquals("WITHadateNOTIN\"2015\"", sfq.getChild(2).getText()); + assertEquals("ename", sfq.e.toString()); + assertNull(sfq.r); + assertEquals("POV", sfq.filter.getClass().getSimpleName()); + + final ParseTree whichclause = sfq.getChild(2); + // 2 children: WHICH, POV + assertEquals(2, whichclause.getChildCount()); + assertEquals("WITHa", whichclause.getChild(0).getText()); + assertEquals("dateNOTIN\"2015\"", whichclause.getChild(1).getText()); + + final ParseTree transactionFilter = whichclause.getChild(1).getChild(0); + assertEquals(4, transactionFilter.getChildCount()); + assertEquals("date", transactionFilter.getChild(0).getText()); + assertEquals("NOT", transactionFilter.getChild(1).getText()); + assertEquals("IN", transactionFilter.getChild(2).getText()); + assertEquals("\"2015\"", transactionFilter.getChild(3).getText()); + + assertTrue(sfq.filter instanceof POV); + final POV pov = (POV) sfq.filter; + assertEquals("!(", pov.getOperator()); + assertEquals("2015", pov.getValue()); + } + /** String query35 = "FIND ename WITH a date IN 2015-01-01"; */ @Test public void testQuery35() { @@ -4750,6 +4835,45 @@ public class TestCQL { assertEquals("2015-01-01", pov.getValue()); } + /** String query35a = "FIND ename WITH a date IN \"2015-01-01\""; */ + @Test + public void testQuery35a() { + CQLLexer lexer; + lexer = new CQLLexer(CharStreams.fromString(this.query35a)); + final CommonTokenStream tokens = new CommonTokenStream(lexer); + + final CQLParser parser = new CQLParser(tokens); + final CqContext sfq = parser.cq(); + + System.out.println(sfq.toStringTree(parser)); + + // 4 children: FIND, role, WHICHCLAUSE, EOF + assertEquals(4, sfq.getChildCount()); + assertEquals("FIND", sfq.getChild(0).getText()); + assertEquals("ename", sfq.getChild(1).getText()); + assertEquals("WITHadateIN\"2015-01-01\"", sfq.getChild(2).getText()); + assertEquals("ename", sfq.e.toString()); + assertNull(sfq.r); + assertEquals("POV", sfq.filter.getClass().getSimpleName()); + + final ParseTree whichclause = sfq.getChild(2); + // 2 children: WHICH, POV + assertEquals(2, whichclause.getChildCount()); + assertEquals("WITHa", whichclause.getChild(0).getText()); + assertEquals("dateIN\"2015-01-01\"", whichclause.getChild(1).getText()); + + final ParseTree transactionFilter = whichclause.getChild(1).getChild(0); + assertEquals(3, transactionFilter.getChildCount()); + assertEquals("date", transactionFilter.getChild(0).getText()); + assertEquals("IN", transactionFilter.getChild(1).getText()); + assertEquals("\"2015-01-01\"", transactionFilter.getChild(2).getText()); + + assertTrue(sfq.filter instanceof POV); + final POV pov = (POV) sfq.filter; + assertEquals("(", pov.getOperator()); + assertEquals("2015-01-01", pov.getValue()); + } + /** String query36 = "FIND ename.pname LIKE \"wil*card\""; */ @Test public void testQuery36() { @@ -6296,4 +6420,55 @@ public class TestCQL { final StoredAt storedAt = (StoredAt) sfq.filter; assertEquals("SAT(/data/in0.foo)", storedAt.toString()); } + + /** + * Testing a conjunction which begins with a nested disjunction. The bug was a parsing error which + * was caused by a missing option for a disjunction/conjunction, wrapped into parenthesis as first + * element of a conjunction/disjunction + * + * <p>String queryMR56 = "FIND ENTITY WITH ((p0 = v0 OR p1=v1) AND p2=v2)"; + */ + @Test + public void testMR56() { + CQLLexer lexer; + lexer = new CQLLexer(CharStreams.fromString(this.queryMR56)); + final CommonTokenStream tokens = new CommonTokenStream(lexer); + + final CQLParser parser = new CQLParser(tokens); + final CqContext sfq = parser.cq(); + + System.out.println(sfq.toStringTree(parser)); + + // 4 children: FIND, role, WHICHCLAUSE, EOF + assertEquals(4, sfq.getChildCount()); + assertEquals("WITH((p0=v0ORp1=v1)ANDp2=v2)", sfq.getChild(2).getText()); + assertEquals("ENTITY", sfq.r.toString()); + assertEquals("Conjunction", sfq.filter.getClass().getSimpleName()); + final ParseTree whichclause = sfq.getChild(2); + final ParseTree conjunction = whichclause.getChild(2); + assertEquals("(p0=v0ORp1=v1)ANDp2=v2", conjunction.getText()); + final ParseTree disjunction = conjunction.getChild(1); + assertEquals("p0=v0ORp1=v1", disjunction.getText()); + final ParseTree pov = conjunction.getChild(4); + assertEquals("p2=v2", pov.getText()); + } + + /** String versionedQuery1 = "FIND ANY VERSION OF ENTITY e1"; */ + @Test + public void testVersionedQuery1() { + CQLLexer lexer; + lexer = new CQLLexer(CharStreams.fromString(this.versionedQuery1)); + final CommonTokenStream tokens = new CommonTokenStream(lexer); + + final CQLParser parser = new CQLParser(tokens); + final CqContext sfq = parser.cq(); + + System.out.println(sfq.toStringTree(parser)); + + // 4 children: FIND, version, role, entity, EOF + assertEquals(5, sfq.getChildCount()); + assertEquals(VersionFilter.ANY_VERSION, sfq.v); + assertEquals(Query.Role.ENTITY, sfq.r); + assertEquals("e1", sfq.e.toString()); + } } diff --git a/src/test/java/caosdb/server/resource/FileSystemResourceTest.java b/src/test/java/org/caosdb/server/resource/FileSystemResourceTest.java similarity index 97% rename from src/test/java/caosdb/server/resource/FileSystemResourceTest.java rename to src/test/java/org/caosdb/server/resource/FileSystemResourceTest.java index 31d6c6a6c4c7caf4d388a6df1404430e93a01d0f..ed89c68ae554c0f7718ccabcb6fb2b48c0d59e61 100644 --- a/src/test/java/caosdb/server/resource/FileSystemResourceTest.java +++ b/src/test/java/org/caosdb/server/resource/FileSystemResourceTest.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.resource; +package org.caosdb.server.resource; import java.io.File; import org.junit.Test; diff --git a/src/test/java/caosdb/server/resource/TestAbstractCaosDBServerResource.java b/src/test/java/org/caosdb/server/resource/TestAbstractCaosDBServerResource.java similarity index 62% rename from src/test/java/caosdb/server/resource/TestAbstractCaosDBServerResource.java rename to src/test/java/org/caosdb/server/resource/TestAbstractCaosDBServerResource.java index 81baabd4797842f1cbbc61f990d6ea580553de85..1dcf71d8f330ab6807e65bd23022138e941fca1c 100644 --- a/src/test/java/caosdb/server/resource/TestAbstractCaosDBServerResource.java +++ b/src/test/java/org/caosdb/server/resource/TestAbstractCaosDBServerResource.java @@ -1,22 +1,31 @@ -package caosdb.server.resource; +package org.caosdb.server.resource; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import caosdb.server.CaosDBException; -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; -import caosdb.server.accessControl.AnonymousAuthenticationToken; -import caosdb.server.accessControl.AnonymousRealm; -import caosdb.server.database.backend.implementation.MySQL.ConnectionException; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.security.NoSuchAlgorithmException; import java.sql.SQLException; +import java.util.HashSet; import org.apache.shiro.mgt.DefaultSecurityManager; import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.support.DelegatingSubject; +import org.caosdb.server.CaosDBException; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.ServerProperties; +import org.caosdb.server.accessControl.AnonymousAuthenticationToken; +import org.caosdb.server.accessControl.AnonymousRealm; +import org.caosdb.server.accessControl.Role; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.implementation.MySQL.ConnectionException; +import org.caosdb.server.database.backend.interfaces.RetrievePermissionRulesImpl; +import org.caosdb.server.database.backend.interfaces.RetrieveRoleImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.misc.TransactionBenchmark; +import org.caosdb.server.permissions.PermissionRule; import org.jdom2.Element; import org.junit.BeforeClass; import org.junit.Rule; @@ -29,9 +38,51 @@ public class TestAbstractCaosDBServerResource { @Rule public TemporaryFolder tempFolder = new TemporaryFolder(); + /** a no-op mock-up which resolved all rules to an empty set of permissions. */ + public static class RetrievePermissionRulesMockup implements RetrievePermissionRulesImpl { + + public RetrievePermissionRulesMockup(Access a) {} + + @Override + public void setTransactionBenchmark(TransactionBenchmark b) {} + + @Override + public TransactionBenchmark getBenchmark() { + return null; + } + + @Override + public HashSet<PermissionRule> retrievePermissionRule(String role) throws TransactionException { + return new HashSet<>(); + } + } + + /** a no-op mock-up which returns null */ + public static class RetrieveRoleMockup implements RetrieveRoleImpl { + + public RetrieveRoleMockup(Access a) {} + + @Override + public void setTransactionBenchmark(TransactionBenchmark b) {} + + @Override + public TransactionBenchmark getBenchmark() { + return null; + } + + @Override + public Role retrieve(String role) throws TransactionException { + return null; + } + } + @BeforeClass public static void initServerProperties() throws IOException { CaosDBServer.initServerProperties(); + + BackendTransaction.setImpl( + RetrievePermissionRulesImpl.class, RetrievePermissionRulesMockup.class); + BackendTransaction.setImpl(RetrieveRoleImpl.class, RetrieveRoleMockup.class); } @Test @@ -94,7 +145,7 @@ public class TestAbstractCaosDBServerResource { + "defaultRealm = PAM\n" + "\n" + "[PAM]\n" - + "class = caosdb.server.accessControl.Pam\n" + + "class = org.caosdb.server.accessControl.Pam\n" + "default_status = ACTIVE\n" + "include.user = admin\n" + ";include.group = [uncomment and put your groups here]\n" diff --git a/src/test/java/caosdb/server/resource/TestScriptingResource.java b/src/test/java/org/caosdb/server/resource/TestScriptingResource.java similarity index 66% rename from src/test/java/caosdb/server/resource/TestScriptingResource.java rename to src/test/java/org/caosdb/server/resource/TestScriptingResource.java index 2edfb82b53b56324996293a469fadf807264d86c..845f589a9700a9d3d25eb8da2878c13ee114cd7d 100644 --- a/src/test/java/caosdb/server/resource/TestScriptingResource.java +++ b/src/test/java/org/caosdb/server/resource/TestScriptingResource.java @@ -20,38 +20,37 @@ * * ** end header */ -package caosdb.server.resource; +package org.caosdb.server.resource; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import caosdb.server.CaosDBServer; -import caosdb.server.accessControl.AuthenticationUtils; -import caosdb.server.accessControl.CredentialsValidator; -import caosdb.server.accessControl.Principal; -import caosdb.server.accessControl.Role; -import caosdb.server.accessControl.SessionToken; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.interfaces.RetrievePasswordValidatorImpl; -import caosdb.server.database.backend.interfaces.RetrievePermissionRulesImpl; -import caosdb.server.database.backend.interfaces.RetrieveRoleImpl; -import caosdb.server.database.backend.interfaces.RetrieveUserImpl; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.database.misc.TransactionBenchmark; -import caosdb.server.database.proto.ProtoUser; -import caosdb.server.entity.Message; -import caosdb.server.permissions.PermissionRule; + import java.io.IOException; import java.util.Date; import java.util.HashSet; import java.util.List; import org.apache.shiro.SecurityUtils; -import org.apache.shiro.config.Ini; -import org.apache.shiro.config.IniSecurityManagerFactory; -import org.apache.shiro.mgt.SecurityManager; +import org.apache.shiro.authz.permission.WildcardPermission; import org.apache.shiro.subject.Subject; -import org.apache.shiro.util.Factory; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.accessControl.AnonymousAuthenticationToken; +import org.caosdb.server.accessControl.CredentialsValidator; +import org.caosdb.server.accessControl.Principal; +import org.caosdb.server.accessControl.Role; +import org.caosdb.server.accessControl.UserSources; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.interfaces.RetrievePasswordValidatorImpl; +import org.caosdb.server.database.backend.interfaces.RetrievePermissionRulesImpl; +import org.caosdb.server.database.backend.interfaces.RetrieveRoleImpl; +import org.caosdb.server.database.backend.interfaces.RetrieveUserImpl; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.database.misc.TransactionBenchmark; +import org.caosdb.server.database.proto.ProtoUser; +import org.caosdb.server.entity.Message; +import org.caosdb.server.permissions.PermissionRule; +import org.caosdb.server.scripting.ScriptingPermissions; +import org.caosdb.server.scripting.ServerSideScriptingCaller; +import org.jdom2.Element; import org.junit.BeforeClass; import org.junit.Test; import org.restlet.Request; @@ -93,7 +92,13 @@ public class TestScriptingResource { @Override public HashSet<PermissionRule> retrievePermissionRule(String role) throws TransactionException { - return new HashSet<>(); + HashSet<PermissionRule> result = new HashSet<>(); + result.add( + new PermissionRule( + true, + false, + new WildcardPermission(ScriptingPermissions.PERMISSION_EXECUTION("anonymous_ok")))); + return result; } @Override @@ -149,19 +154,16 @@ public class TestScriptingResource { @BeforeClass public static void setupShiro() throws IOException { + CaosDBServer.initServerProperties(); + CaosDBServer.initShiro(); + BackendTransaction.setImpl(RetrieveRoleImpl.class, RetrieveRole.class); BackendTransaction.setImpl(RetrievePermissionRulesImpl.class, RetrievePermissionRules.class); BackendTransaction.setImpl(RetrieveUserImpl.class, RetrieveUser.class); BackendTransaction.setImpl( RetrievePasswordValidatorImpl.class, RetrievePasswordValidator.class); - CaosDBServer.initServerProperties(); - Ini config = CaosDBServer.getShiroConfig(); - final Factory<SecurityManager> factory = new IniSecurityManagerFactory(config); - - final SecurityManager securityManager = factory.getInstance(); - - SecurityUtils.setSecurityManager(securityManager); + UserSources.getDefaultRealm(); } ScriptingResource resource = @@ -170,26 +172,28 @@ public class TestScriptingResource { public int callScript( java.util.List<String> invokation, Integer timeout_ms, - java.util.List<caosdb.server.entity.FileProperties> files, + java.util.List<org.caosdb.server.entity.FileProperties> files, Object authToken) throws Message { + if (invokation.get(0).equals("anonymous_ok")) { + return 0; + } return -1; }; @Override - public Object generateAuthToken() { + public Element generateRootElement(ServerSideScriptingCaller caller) { + return new Element("OK"); + }; + + @Override + public Object generateAuthToken(String purpose) { return ""; } }; @Test public void testUnsupportedMediaType() { - Subject user = SecurityUtils.getSubject(); - if (user.isAuthenticated()) { - user.logout(); - } - SessionToken t = SessionToken.generate(new Principal("CaosDB", "user"), null); - user.login(t); Representation entity = new StringRepresentation("asdf"); entity.setMediaType(MediaType.TEXT_ALL); Request request = new Request(Method.POST, "../test", entity); @@ -201,12 +205,11 @@ public class TestScriptingResource { } @Test - public void testAnonymous() { + public void testAnonymousWithOutPermission() { Subject user = SecurityUtils.getSubject(); - user.login(AuthenticationUtils.ANONYMOUS_USER); - assertTrue(resource.isAnonymous()); - Representation entity = new StringRepresentation("asdf"); - entity.setMediaType(MediaType.TEXT_ALL); + user.login(AnonymousAuthenticationToken.getInstance()); + Form form = new Form("call=anonymous_no_permission"); + Representation entity = form.getWebRepresentation(); Request request = new Request(Method.POST, "../test", entity); request.setRootRef(new Reference("bla")); request.getAttributes().put("SRID", "asdf1234"); @@ -218,6 +221,23 @@ public class TestScriptingResource { assertEquals(Status.CLIENT_ERROR_FORBIDDEN, resource.getResponse().getStatus()); } + @Test + public void testAnonymousWithPermission() { + Subject user = SecurityUtils.getSubject(); + user.login(AnonymousAuthenticationToken.getInstance()); + Form form = new Form("call=anonymous_ok"); + Representation entity = form.getWebRepresentation(); + Request request = new Request(Method.POST, "../test", entity); + request.setRootRef(new Reference("bla")); + request.getAttributes().put("SRID", "asdf1234"); + request.setDate(new Date()); + request.setHostRef("bla"); + resource.init(null, request, new Response(null)); + + resource.handle(); + assertEquals(Status.SUCCESS_OK, resource.getResponse().getStatus()); + } + @Test public void testForm2invocation() throws Message { Form form = @@ -235,8 +255,9 @@ public class TestScriptingResource { @Test public void testHandleForm() throws Message, IOException { - Form form = - new Form("-Ooption=OPTION&call=CALL&-Ooption2=OPTION2&-p=POS1&-p4=POS3&-p2=POS2&IGNORED"); - assertEquals(-1, resource.handleForm(form)); + Subject user = SecurityUtils.getSubject(); + user.login(AnonymousAuthenticationToken.getInstance()); + Form form = new Form("call=anonymous_ok"); + assertEquals(0, resource.handleForm(form)); } } diff --git a/src/test/java/caosdb/server/resource/TestSharedFileResource.java b/src/test/java/org/caosdb/server/resource/TestSharedFileResource.java similarity index 95% rename from src/test/java/caosdb/server/resource/TestSharedFileResource.java rename to src/test/java/org/caosdb/server/resource/TestSharedFileResource.java index 41e134d28aed98c0fb01bee256bce513bb43f13e..8dbbd5b1ec25843c3a5b28d46a2fa784f169330d 100644 --- a/src/test/java/caosdb/server/resource/TestSharedFileResource.java +++ b/src/test/java/org/caosdb/server/resource/TestSharedFileResource.java @@ -20,7 +20,7 @@ * ** end header */ -package caosdb.server.resource; +package org.caosdb.server.resource; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -28,11 +28,6 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import caosdb.server.CaosDBServer; -import caosdb.server.FileSystem; -import caosdb.server.ServerProperties; -import caosdb.server.accessControl.AnonymousAuthenticationToken; -import caosdb.server.accessControl.AnonymousRealm; import java.io.File; import java.io.IOException; import java.nio.file.Files; @@ -42,6 +37,11 @@ import net.jcip.annotations.NotThreadSafe; import org.apache.shiro.mgt.DefaultSecurityManager; import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.support.DelegatingSubject; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.FileSystem; +import org.caosdb.server.ServerProperties; +import org.caosdb.server.accessControl.AnonymousAuthenticationToken; +import org.caosdb.server.accessControl.AnonymousRealm; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Rule; @@ -198,7 +198,7 @@ public class TestSharedFileResource { + "defaultRealm = PAM\n" + "\n" + "[PAM]\n" - + "class = caosdb.server.accessControl.Pam\n" + + "class = org.caosdb.server.accessControl.Pam\n" + "default_status = ACTIVE\n" + "include.user = admin\n" + ";include.group = [uncomment and put your groups here]\n" diff --git a/src/test/java/caosdb/server/scripting/TestServerSideScriptingCaller.java b/src/test/java/org/caosdb/server/scripting/TestServerSideScriptingCaller.java similarity index 93% rename from src/test/java/caosdb/server/scripting/TestServerSideScriptingCaller.java rename to src/test/java/org/caosdb/server/scripting/TestServerSideScriptingCaller.java index f752c29c2f99b33d30a75ff3e09c7043c92fc464..61be0c5c3a06319dbeb826a79ddf1c6e43a0d672 100644 --- a/src/test/java/caosdb/server/scripting/TestServerSideScriptingCaller.java +++ b/src/test/java/org/caosdb/server/scripting/TestServerSideScriptingCaller.java @@ -20,19 +20,12 @@ * * ** end header */ -package caosdb.server.scripting; +package org.caosdb.server.scripting; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import caosdb.CaosDBTestClass; -import caosdb.server.CaosDBException; -import caosdb.server.CaosDBServer; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.entity.FileProperties; -import caosdb.server.entity.Message; -import caosdb.server.utils.ServerMessages; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -43,6 +36,14 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.apache.commons.io.FileUtils; +import org.caosdb.CaosDBTestClass; +import org.caosdb.server.CaosDBException; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.ServerProperties; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.entity.FileProperties; +import org.caosdb.server.entity.Message; +import org.caosdb.server.utils.ServerMessages; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; import org.junit.After; @@ -68,6 +69,10 @@ public class TestServerSideScriptingCaller extends CaosDBTestClass { @BeforeClass public static void setupTestFolder() throws IOException { + CaosDBServer.getServerProperties() + .setProperty( + ServerProperties.KEY_SERVER_SIDE_SCRIPTING_BIN_DIRS, testFolder.getAbsolutePath()); + FileUtils.forceDeleteOnExit(testFolder); FileUtils.forceDeleteOnExit(testFile); FileUtils.forceDeleteOnExit(testExecutable); @@ -305,7 +310,7 @@ public class TestServerSideScriptingCaller extends CaosDBTestClass { testExeExit(1); - assertEquals(1, caller.callScript()); + assertEquals(1, caller.callScript(cmd[0], cmd, null, emptyEnv)); } @Test @@ -319,7 +324,7 @@ public class TestServerSideScriptingCaller extends CaosDBTestClass { testExeExit(0); - assertEquals(0, caller.callScript()); + assertEquals(0, caller.callScript(cmd[0], cmd, null, emptyEnv)); } @Test @@ -387,7 +392,7 @@ public class TestServerSideScriptingCaller extends CaosDBTestClass { testSleep(10); this.exception.expect(TimeoutException.class); - caller.callScript(); + caller.callScript(cmd[0], cmd, null, emptyEnv); } @Test @@ -418,7 +423,8 @@ public class TestServerSideScriptingCaller extends CaosDBTestClass { throws FileNotFoundException, CaosDBException {} @Override - public int callScript() { + public int callScript( + String cmd, String[] cmdLine, Object authToken, Map<String, String> env) { return 0; } @@ -456,7 +462,8 @@ public class TestServerSideScriptingCaller extends CaosDBTestClass { } @Override - public int callScript() { + public int callScript( + String cmd, String[] cmdLine, Object authToken, Map<String, String> env) { return 0; } @@ -496,7 +503,9 @@ public class TestServerSideScriptingCaller extends CaosDBTestClass { public void createTmpHomeDir() throws Exception {} @Override - public int callScript() throws IOException { + public int callScript( + String cmd, String[] cmdLine, Object authToken, Map<String, String> env) + throws IOException { throw new IOException(); } @@ -532,7 +541,8 @@ public class TestServerSideScriptingCaller extends CaosDBTestClass { throws FileNotFoundException, CaosDBException {} @Override - public int callScript() { + public int callScript( + String cmd, String[] cmdLine, Object authToken, Map<String, String> env) { return 0; } @@ -562,7 +572,7 @@ public class TestServerSideScriptingCaller extends CaosDBTestClass { testPrintArgsToStdErr(); - caller.callScript(); + caller.callScript(cmd[0], cmd, "authToken", emptyEnv); assertEquals( "--auth-token=authToken opt1 opt2\n", FileUtils.readFileToString(caller.getStdErrFile())); @@ -579,7 +589,7 @@ public class TestServerSideScriptingCaller extends CaosDBTestClass { testPrintArgsToStdOut(); - caller.callScript(); + caller.callScript(cmd[0], cmd, "authToken", emptyEnv); assertEquals( "--auth-token=authToken opt1 opt2\n", FileUtils.readFileToString(caller.getStdOutFile())); @@ -599,7 +609,7 @@ public class TestServerSideScriptingCaller extends CaosDBTestClass { preparePrintEnv("TEST"); - caller.callScript(); + caller.callScript(cmd[0], cmd, null, env); assertEquals("-testcontent-\n", caller.getStdOut()); caller.cleanup(); diff --git a/src/test/java/caosdb/server/transaction/UpdateTest.java b/src/test/java/org/caosdb/server/transaction/UpdateTest.java similarity index 92% rename from src/test/java/caosdb/server/transaction/UpdateTest.java rename to src/test/java/org/caosdb/server/transaction/UpdateTest.java index d90724744164b23ecdd7a27b90cddac1e048f86f..6b0e7b3f988f18142c6ebdb535212cd7454233f0 100644 --- a/src/test/java/caosdb/server/transaction/UpdateTest.java +++ b/src/test/java/org/caosdb/server/transaction/UpdateTest.java @@ -20,21 +20,21 @@ * * ** end header */ -package caosdb.server.transaction; +package org.caosdb.server.transaction; -import static caosdb.server.utils.EntityStatus.QUALIFIED; -import static caosdb.server.utils.EntityStatus.VALID; +import static org.caosdb.server.utils.EntityStatus.QUALIFIED; +import static org.caosdb.server.utils.EntityStatus.VALID; import static org.junit.Assert.assertEquals; -import caosdb.server.CaosDBException; -import caosdb.server.datatype.GenericValue; -import caosdb.server.entity.Entity; -import caosdb.server.entity.EntityInterface; -import caosdb.server.entity.StatementStatus; -import caosdb.server.entity.wrapper.Property; -import caosdb.server.utils.EntityStatus; import java.io.IOException; import java.security.NoSuchAlgorithmException; +import org.caosdb.server.CaosDBException; +import org.caosdb.server.datatype.GenericValue; +import org.caosdb.server.entity.Entity; +import org.caosdb.server.entity.EntityInterface; +import org.caosdb.server.entity.StatementStatus; +import org.caosdb.server.entity.wrapper.Property; +import org.caosdb.server.utils.EntityStatus; import org.junit.Test; public class UpdateTest { diff --git a/src/test/java/caosdb/server/utils/FileUtilsTest.java b/src/test/java/org/caosdb/server/utils/FileUtilsTest.java similarity index 96% rename from src/test/java/caosdb/server/utils/FileUtilsTest.java rename to src/test/java/org/caosdb/server/utils/FileUtilsTest.java index e4b2411dc0e77ce0225c0637422c84bbab2cc4aa..7e0664f3df401f916ed48c6830271334083a5ac4 100644 --- a/src/test/java/caosdb/server/utils/FileUtilsTest.java +++ b/src/test/java/org/caosdb/server/utils/FileUtilsTest.java @@ -20,25 +20,13 @@ * * ** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import caosdb.server.CaosDBException; -import caosdb.server.CaosDBServer; -import caosdb.server.FileSystem; -import caosdb.server.ServerProperties; -import caosdb.server.database.BackendTransaction; -import caosdb.server.database.access.Access; -import caosdb.server.database.backend.implementation.UnixFileSystem.UnixFileSystemGetFileIterator.FileNameIterator; -import caosdb.server.database.backend.implementation.UnixFileSystem.UnixFileSystemHelper; -import caosdb.server.database.backend.transaction.FileConsistencyCheck; -import caosdb.server.database.backend.transaction.GetFileIterator; -import caosdb.server.database.exceptions.TransactionException; -import caosdb.server.entity.Message; import java.io.File; import java.io.IOException; import java.io.PrintStream; @@ -47,6 +35,18 @@ import java.security.NoSuchAlgorithmException; import java.util.Iterator; import java.util.regex.Pattern; import net.jcip.annotations.NotThreadSafe; +import org.caosdb.server.CaosDBException; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.FileSystem; +import org.caosdb.server.ServerProperties; +import org.caosdb.server.database.BackendTransaction; +import org.caosdb.server.database.access.Access; +import org.caosdb.server.database.backend.implementation.UnixFileSystem.UnixFileSystemGetFileIterator.FileNameIterator; +import org.caosdb.server.database.backend.implementation.UnixFileSystem.UnixFileSystemHelper; +import org.caosdb.server.database.backend.transaction.FileConsistencyCheck; +import org.caosdb.server.database.backend.transaction.GetFileIterator; +import org.caosdb.server.database.exceptions.TransactionException; +import org.caosdb.server.entity.Message; import org.eclipse.jetty.io.RuntimeIOException; import org.junit.After; import org.junit.AfterClass; diff --git a/src/test/java/caosdb/server/utils/UtilsTest.java b/src/test/java/org/caosdb/server/utils/UtilsTest.java similarity index 98% rename from src/test/java/caosdb/server/utils/UtilsTest.java rename to src/test/java/org/caosdb/server/utils/UtilsTest.java index c75d5a3ad861ac5b4c5ff9dfc905767479fb1a4f..3b92a11d69b465c33ddc9629d89c6d91e6f456e0 100644 --- a/src/test/java/caosdb/server/utils/UtilsTest.java +++ b/src/test/java/org/caosdb/server/utils/UtilsTest.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils; +package org.caosdb.server.utils; import static org.junit.Assert.assertEquals; diff --git a/src/test/java/caosdb/server/utils/WebinterfaceUtilsTest.java b/src/test/java/org/caosdb/server/utils/WebinterfaceUtilsTest.java similarity index 73% rename from src/test/java/caosdb/server/utils/WebinterfaceUtilsTest.java rename to src/test/java/org/caosdb/server/utils/WebinterfaceUtilsTest.java index 4ff5d7185d43704e4bc97ef435a5c853e58e3eb8..9231dd77a6724b5a8c5f7f4f244bd92c6f4a5e91 100644 --- a/src/test/java/caosdb/server/utils/WebinterfaceUtilsTest.java +++ b/src/test/java/org/caosdb/server/utils/WebinterfaceUtilsTest.java @@ -1,11 +1,12 @@ -package caosdb.server.utils; +package org.caosdb.server.utils; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import caosdb.server.CaosDBServer; import java.io.IOException; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.ServerProperties; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; @@ -26,7 +27,13 @@ public class WebinterfaceUtilsTest { WebinterfaceUtils utils = new WebinterfaceUtils(new Reference("https://host:2345/some_path")); String buildNumber = utils.getBuildNumber(); String ref = utils.getWebinterfaceURI("sub"); - assertEquals("https://host:2345/webinterface/" + buildNumber + "/sub", ref); + String contextRoot = CaosDBServer.getServerProperty(ServerProperties.KEY_CONTEXT_ROOT); + contextRoot = + contextRoot != null && contextRoot.length() > 0 + ? "/" + contextRoot.replaceFirst("^/", "").replaceFirst("/$", "") + : ""; + + assertEquals("https://host:2345" + contextRoot + "/webinterface/" + buildNumber + "/sub", ref); } @Test diff --git a/src/test/java/caosdb/server/utils/fsm/TestFiniteStateMachine.java b/src/test/java/org/caosdb/server/utils/fsm/TestFiniteStateMachine.java similarity index 98% rename from src/test/java/caosdb/server/utils/fsm/TestFiniteStateMachine.java rename to src/test/java/org/caosdb/server/utils/fsm/TestFiniteStateMachine.java index 3849df7dc66f8f812c36b0a4b49dcb2774d034b3..2a7b726b84464f3a7d287434b2767a34baaf4b50 100644 --- a/src/test/java/caosdb/server/utils/fsm/TestFiniteStateMachine.java +++ b/src/test/java/org/caosdb/server/utils/fsm/TestFiniteStateMachine.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils.fsm; +package org.caosdb.server.utils.fsm; import static org.junit.Assert.assertEquals; diff --git a/src/test/java/caosdb/server/utils/fsm/TestStrategyFiniteStateMachine.java b/src/test/java/org/caosdb/server/utils/fsm/TestStrategyFiniteStateMachine.java similarity index 97% rename from src/test/java/caosdb/server/utils/fsm/TestStrategyFiniteStateMachine.java rename to src/test/java/org/caosdb/server/utils/fsm/TestStrategyFiniteStateMachine.java index 8d383383dd4a896f0befa1b3c2b1854129377353..ebf719b1eaa4b56f3b64bdd9371f121231b4ed68 100644 --- a/src/test/java/caosdb/server/utils/fsm/TestStrategyFiniteStateMachine.java +++ b/src/test/java/org/caosdb/server/utils/fsm/TestStrategyFiniteStateMachine.java @@ -20,7 +20,7 @@ * * ** end header */ -package caosdb.server.utils.fsm; +package org.caosdb.server.utils.fsm; import java.util.HashMap; import java.util.Map; diff --git a/src/test/java/caosdb/server/utils/mail/TestMail.java b/src/test/java/org/caosdb/server/utils/mail/TestMail.java similarity index 90% rename from src/test/java/caosdb/server/utils/mail/TestMail.java rename to src/test/java/org/caosdb/server/utils/mail/TestMail.java index 2bdc90de64e58a81bafbbd7c484677b5bf54eb7a..5d7ba41089ee71d6ca4eff529bf6ce1ca0828b92 100644 --- a/src/test/java/caosdb/server/utils/mail/TestMail.java +++ b/src/test/java/org/caosdb/server/utils/mail/TestMail.java @@ -20,12 +20,12 @@ * * ** end header */ -package caosdb.server.utils.mail; +package org.caosdb.server.utils.mail; -import caosdb.CaosDBTestClass; -import caosdb.server.CaosDBServer; -import caosdb.server.ServerProperties; import java.io.IOException; +import org.caosdb.CaosDBTestClass; +import org.caosdb.server.CaosDBServer; +import org.caosdb.server.ServerProperties; import org.junit.BeforeClass; import org.junit.Test;