diff --git a/.circleci/config.yml b/.circleci/config.yml
new file mode 100644
index 0000000000..14da7f057c
--- /dev/null
+++ b/.circleci/config.yml
@@ -0,0 +1,817 @@
+version: 2.1
+
+parameters:
+ compute_size_small:
+ type: string
+ default: "small"
+ compute_size_large:
+ type: string
+ default: "large"
+ compute_size_mac_medium:
+ type: string
+ default: "macos.m1.medium.gen1"
+ compute_size_windows_medium:
+ type: string
+ default: "windows.medium"
+ maven_version:
+ type: string
+ default: "3.9.9"
+ maven_dependency_plugin_version:
+ type: string
+ default: "3.8.1"
+ maven_dependency_check_plugin_version:
+ type: string
+ default: "12.1.1"
+ java_tool_options:
+ type: string
+ default: "-DtrimStackTrace=false -Djava.awt.headless=true -XX:+UseNUMA -XX:+UseG1GC -XX:+UseStringDeduplication"
+ # NOTE(AR) -XX:+UseZGC seems to exhibit a need for more memory and somehow causes the limits of the CI to be exhausted in Docker contains even though -XX:MaxRAMPercentage=75.0 is set below
+ # default: "-DtrimStackTrace=false -Djava.awt.headless=true -XX:+UseNUMA -XX:+UseZGC"
+ extra_java_tool_options_docker:
+ type: string
+ default: "-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0"
+
+
+executors:
+ linux-docker-jdk21:
+ docker:
+ - image: "cimg/openjdk:21.0"
+ environment:
+ MAVEN_BIN: /opt/apache-maven/bin/mvn
+ macos-vm-xcode16:
+ macos:
+ xcode: 16.4.0
+ environment:
+ MAVEN_BIN: /tmp/maven/bin/mvn
+ JAVA_HOME: /Library/Java/JavaVirtualMachines/liberica-jdk-21.jdk/Contents/Home
+ windows-vm:
+ machine:
+ image: "windows-server-2022-gui:current"
+ shell: bash.exe
+ environment:
+ JAVA_HOME: /c/progra~1/BellSoft/LibericaJDK-21
+ MAVEN_BIN: /tmp/maven/bin/mvn
+
+
+commands:
+ install_jdk:
+ parameters:
+ jdk_major_version:
+ description: "The major version of the JDK to install"
+ type: string
+ default: "21"
+ compute_size:
+ type: string
+ default: << pipeline.parameters.compute_size_small >>
+ steps:
+ - when:
+ condition:
+ and:
+ - matches: { pattern: "^macos.+$", value: << parameters.compute_size >> }
+ steps:
+ - run:
+ name: "Brew - Add BellSoft Libercia JDK Tap"
+ command: "brew tap bell-sw/liberica"
+ - run:
+ name: "Brew - Install BellSoft Libercia JDK"
+ command: "brew install --cask liberica-jdk<< parameters.jdk_major_version >>"
+ - when:
+ condition:
+ and:
+ - matches: { pattern: "^windows.+$", value: << parameters.compute_size >> }
+ steps:
+ - run:
+ name: "Choco - Install BellSoft Libercia JDK"
+ command: "choco install liberica<< parameters.jdk_major_version >>jdk"
+ shell: cmd.exe
+ - run:
+ name: "Java - Show Version"
+ command: |
+ echo JAVA_HOME="${JAVA_HOME}"
+ $JAVA_HOME/bin/java -version
+
+ install_maven:
+ parameters:
+ maven_version:
+ description: "The version of Maven to install"
+ type: string
+ default: << pipeline.parameters.maven_version >>
+ directory:
+ description: "The directory in which to install Maven. Default: /tmp."
+ type: string
+ default: "/tmp"
+ symlink_target:
+ description: "The target to symlink the Maven folder to. Default: /tmp/maven."
+ type: string
+ default: "/tmp/maven"
+ compute_size:
+ type: string
+ default: << pipeline.parameters.compute_size_small >>
+ steps:
+ - when:
+ condition:
+ or:
+ - matches: { pattern: "^macos.+$", value: << parameters.compute_size >> }
+ - matches: { pattern: "^windows.+$", value: << parameters.compute_size >> }
+ steps:
+ - run:
+ name: "Install Maven"
+ environment:
+ MAVEN_VERSION: << parameters.maven_version >>
+ MAVEN_TARGET_DIR: << parameters.directory >>
+ MAVEN_SYMLINK_TARGET: << parameters.symlink_target >>
+ command: |
+ set -x
+ MAVEN_ARTIFACT=apache-maven-$MAVEN_VERSION
+ MAVEN_ARCHIVE=$MAVEN_ARTIFACT-bin.tar.gz
+ TMP_DOWNLOAD=/tmp/$MAVEN_ARCHIVE
+ if [ -z "$MAVEN_TARGET_DIR" ]; then
+ MAVEN_TARGET_DIR=$HOME
+ fi
+ if [ -z "$MAVEN_SYMLINK_TARGET" ]; then
+ MAVEN_SYMLINK_TARGET=$HOME/maven
+ fi
+ curl --fail --output $TMP_DOWNLOAD --location https://archive.apache.org/dist/maven/maven-3/$MAVEN_VERSION/binaries/$MAVEN_ARCHIVE
+ tar zxvf $TMP_DOWNLOAD -C $MAVEN_TARGET_DIR
+ ln -s $MAVEN_TARGET_DIR/$MAVEN_ARTIFACT $MAVEN_SYMLINK_TARGET
+ rm $TMP_DOWNLOAD
+ set +x
+ - run:
+ name: "Maven - Show Version"
+ command: |
+ echo MAVEN_BIN="${MAVEN_BIN}"
+ $MAVEN_BIN --version
+
+ maven_with_cache:
+ # NOTE(AR) based on https://circleci.com/developer/orbs/orb/circleci/maven
+ parameters:
+ app_src_directory:
+ description: "The directory containing the pom.xml file for the project."
+ type: string
+ default: ''
+ cache_name_prefix:
+ description: "The cache's name prefix to allow for multiple caches and/or cache invalidation."
+ type: string
+ dependency_plugin_version:
+ description: "Specify the Maven Dependency Plugin"
+ type: string
+ default: << pipeline.parameters.maven_dependency_plugin_version >>
+ verify_dependencies:
+ description: "Verify dependencies are valid and available from public sources"
+ type: boolean
+ default: true
+ steps:
+ description: "The steps to execute with the cache"
+ type: steps
+ compute_size:
+ type: string
+ default: << pipeline.parameters.compute_size_small >>
+ steps:
+ - when:
+ condition:
+ and:
+ - not:
+ and:
+ - matches: { pattern: "^windows.+$", value: << parameters.compute_size >> }
+ steps:
+ - run:
+ name: Generate Cache Checksum (Linux/macOS)
+ working_directory: << parameters.app_src_directory >>
+ command: "/usr/bin/find . -name 'pom.xml' | /usr/bin/sort | xargs cat > /tmp/maven_cache_seed"
+ - restore_cache:
+ keys:
+ - << parameters.cache_name_prefix >>-{{ checksum "/tmp/maven_cache_seed" }}
+ - when:
+ condition:
+ and:
+ - matches: { pattern: "^windows.+$", value: << parameters.compute_size >> }
+ steps:
+ - run:
+ name: Generate Cache Checksum (Windows)
+ working_directory: << parameters.app_src_directory >>
+ command: "/usr/bin/find . -name 'pom.xml' | /usr/bin/sort | xargs cat > /c/Users/circleci/AppData/Local/Temp/maven_cache_seed"
+ - restore_cache:
+ keys:
+ - << parameters.cache_name_prefix >>-{{ checksum "C:\\Users\\circleci\\AppData\\Local\\Temp\\maven_cache_seed" }}
+ - when:
+ condition: << parameters.verify_dependencies >>
+ steps:
+ - run:
+ name: Maven - Collect and Verify Dependencies
+ environment:
+ PARAM_DEP_PLUGIN_VER: << parameters.dependency_plugin_version >>
+ working_directory: << parameters.app_src_directory >>
+ command: "$MAVEN_BIN -V -T2C org.apache.maven.plugins:maven-dependency-plugin:$PARAM_DEP_PLUGIN_VER:go-offline"
+ - steps: << parameters.steps >>
+
+ - when:
+ condition:
+ and:
+ - not:
+ and:
+ - matches: { pattern: "^windows.+$", value: << parameters.compute_size >> }
+ steps:
+ - save_cache:
+ key: << parameters.cache_name_prefix >>-{{ checksum "/tmp/maven_cache_seed" }}
+ paths:
+ - ~/.m2/repository
+ - when:
+ condition:
+ and:
+ - matches: { pattern: "^windows.+$", value: << parameters.compute_size >> }
+ steps:
+ - save_cache:
+ key: << parameters.cache_name_prefix >>-{{ checksum "C:\\Users\\circleci\\AppData\\Local\\Temp\\maven_cache_seed" }}
+ paths:
+ - C:\Users\circleci\.m2\repository
+
+ install_artifacts:
+ parameters:
+ compute_size:
+ type: string
+ default: << pipeline.parameters.compute_size_small >>
+ steps:
+ - run:
+ name: "Maven - Install Artifacts"
+ environment:
+ COMPUTE_SIZE: << parameters.compute_size >>
+ command: |
+ if [[ $COMPUTE_SIZE == "small" ]] || [[ $COMPUTE_SIZE == "large" ]]; then
+ export JAVA_TOOL_OPTIONS="<< pipeline.parameters.java_tool_options >> << pipeline.parameters.extra_java_tool_options_docker >>"
+ else
+ export JAVA_TOOL_OPTIONS="<< pipeline.parameters.java_tool_options >>"
+ fi
+ $MAVEN_BIN -V -T2C install -DskipTests -Ddependency-check.skip=true -Dmdep.analyze.skip=true -Dlicense.skip=true --projects '!exist-distribution,!exist-installer' --also-make
+
+ persist_project:
+ parameters:
+ compute_size:
+ type: string
+ default: << pipeline.parameters.compute_size_small >>
+ steps:
+ - when:
+ condition:
+ or:
+ - equal: [ small, << parameters.compute_size >> ]
+ - equal: [ large, << parameters.compute_size >> ]
+ steps:
+ - persist_to_workspace:
+ root: /home/circleci/project
+ paths:
+ - "**"
+ - when:
+ condition:
+ and:
+ - matches: { pattern: "^macos.+$", value: << parameters.compute_size >> }
+ steps:
+ - persist_to_workspace:
+ root: /Users/distiller/project
+ paths:
+ - "**"
+ - when:
+ condition:
+ and:
+ - matches: { pattern: "^windows.+$", value: << parameters.compute_size >> }
+ steps:
+ - persist_to_workspace:
+ root: C:\Users\circleci\project
+ paths:
+ - "**"
+
+ attach_project:
+ parameters:
+ compute_size:
+ type: string
+ default: << pipeline.parameters.compute_size_small >>
+ steps:
+ - when:
+ condition:
+ or:
+ - equal: [ small, << parameters.compute_size >> ]
+ - equal: [ large, << parameters.compute_size >> ]
+ steps:
+ - attach_workspace:
+ at: /home/circleci/project
+ - when:
+ condition:
+ and:
+ - matches: { pattern: "^macos.+$", value: << parameters.compute_size >> }
+ steps:
+ - attach_workspace:
+ at: /Users/distiller/project
+ - when:
+ condition:
+ and:
+ - matches: { pattern: "^windows.+$", value: << parameters.compute_size >> }
+ steps:
+ - attach_workspace:
+ at: C:\Users\circleci\project
+
+ create_maven_settings:
+ steps:
+ - run:
+ name: Create Maven settings.xml
+ command: |
+ mkdir -p ~/.m2
+ cat > ~/.m2/settings.xml \<< EOF
+
+
+
+ ossindex
+ ${OSSINDEX_USERNAME}
+ ${OSSINDEX_TOKEN}
+
+
+
+ EOF
+
+jobs:
+ license-check:
+ parameters:
+ os:
+ type: executor
+ compute_size:
+ type: string
+ default: << pipeline.parameters.compute_size_small >>
+ maven_cache_name_prefix:
+ type: string
+ executor: << parameters.os >>
+ resource_class: << parameters.compute_size >>
+ steps:
+ - checkout
+ - install_jdk:
+ compute_size: << parameters.compute_size >>
+ - install_maven:
+ compute_size: << parameters.compute_size >>
+ - maven_with_cache:
+ compute_size: << parameters.compute_size >>
+ cache_name_prefix: << parameters.maven_cache_name_prefix >>
+ verify_dependencies: false
+ steps:
+ - steps:
+ - run:
+ name: "Maven - License Check"
+ command: "$MAVEN_BIN -V -T2C license:check"
+
+
+ build:
+ parameters:
+ os:
+ type: executor
+ compute_size:
+ type: string
+ default: << pipeline.parameters.compute_size_small >>
+ maven_cache_name_prefix:
+ type: string
+ executor: << parameters.os >>
+ resource_class: << parameters.compute_size >>
+ environment:
+ COMPUTE_SIZE: << parameters.compute_size >>
+ steps:
+ - checkout
+ - install_jdk:
+ compute_size: << parameters.compute_size >>
+ - install_maven:
+ compute_size: << parameters.compute_size >>
+ - maven_with_cache:
+ compute_size: << parameters.compute_size >>
+ cache_name_prefix: << parameters.maven_cache_name_prefix >>
+ verify_dependencies: true
+ steps:
+ - steps:
+ - run:
+ name: "Maven - Build Package"
+ command: |
+ if [[ $COMPUTE_SIZE == "small" ]] || [[ $COMPUTE_SIZE == "large" ]]; then
+ export JAVA_TOOL_OPTIONS="<< pipeline.parameters.java_tool_options >> << pipeline.parameters.extra_java_tool_options_docker >>"
+ else
+ export JAVA_TOOL_OPTIONS="<< pipeline.parameters.java_tool_options >>"
+ fi
+ $MAVEN_BIN -V -T2C package -DskipTests -Dappbundler.skip=true -Ddocker=false -P !mac-dmg-on-mac,!codesign-mac-app,!codesign-mac-dmg,!mac-dmg-on-unix,!installer,!concurrency-stress-tests,!micro-benchmarks,skip-build-dist-archives
+ - persist_project:
+ compute_size: << parameters.compute_size >>
+
+ dependency-analyze:
+ parameters:
+ os:
+ type: executor
+ compute_size:
+ type: string
+ default: << pipeline.parameters.compute_size_small >>
+ maven_cache_name_prefix:
+ type: string
+ executor: << parameters.os >>
+ resource_class: << parameters.compute_size >>
+ environment:
+ COMPUTE_SIZE: << parameters.compute_size >>
+ steps:
+ - attach_project:
+ compute_size: << parameters.compute_size >>
+ - install_jdk:
+ compute_size: << parameters.compute_size >>
+ - install_maven:
+ compute_size: << parameters.compute_size >>
+ - maven_with_cache:
+ compute_size: << parameters.compute_size >>
+ cache_name_prefix: << parameters.maven_cache_name_prefix >>
+ verify_dependencies: false
+ steps:
+ - steps:
+ - run:
+ name: "Maven - Run Dependency Analysis"
+ command: |
+ if [[ $COMPUTE_SIZE == "small" ]] || [[ $COMPUTE_SIZE == "large" ]]; then
+ export JAVA_TOOL_OPTIONS="<< pipeline.parameters.java_tool_options >> << pipeline.parameters.extra_java_tool_options_docker >>"
+ else
+ export JAVA_TOOL_OPTIONS="<< pipeline.parameters.java_tool_options >>"
+ fi
+ $MAVEN_BIN -V -T2C dependency:analyze
+
+ owasp-dependency-check:
+ parameters:
+ os:
+ type: executor
+ compute_size:
+ type: string
+ default: << pipeline.parameters.compute_size_small >>
+ maven_cache_name_prefix:
+ type: string
+ executor: << parameters.os >>
+ resource_class: << parameters.compute_size >>
+ environment:
+ COMPUTE_SIZE: << parameters.compute_size >>
+ steps:
+ - attach_project:
+ compute_size: << parameters.compute_size >>
+ - install_jdk:
+ compute_size: << parameters.compute_size >>
+ - install_maven:
+ compute_size: << parameters.compute_size >>
+ - create_maven_settings
+ - restore_cache:
+ keys:
+ - << parameters.maven_cache_name_prefix >>-dependency-check-data-{{ checksum "/tmp/dependency-check-data/odc.mv.db" }}
+ - maven_with_cache:
+ compute_size: << parameters.compute_size >>
+ cache_name_prefix: << parameters.maven_cache_name_prefix >>
+ verify_dependencies: false
+ steps:
+ - steps:
+ - install_artifacts:
+ compute_size: << parameters.compute_size >>
+ - run:
+ name: "Maven - Run Dependency Check"
+ no_output_timeout: 30m
+ command: |
+ if [[ $COMPUTE_SIZE == "small" ]] || [[ $COMPUTE_SIZE == "large" ]]; then
+ export JAVA_TOOL_OPTIONS="<< pipeline.parameters.java_tool_options >> << pipeline.parameters.extra_java_tool_options_docker >>"
+ else
+ export JAVA_TOOL_OPTIONS="<< pipeline.parameters.java_tool_options >>"
+ fi
+ $MAVEN_BIN -V -T2C -DdataDirectory=/tmp/dependency-check-data dependency-check:<< pipeline.parameters.maven_dependency_check_plugin_version >>:check
+ - save_cache:
+ key: << parameters.maven_cache_name_prefix >>-dependency-check-data-{{ checksum "/tmp/dependency-check-data/odc.mv.db" }}
+ paths:
+ - /tmp/dependency-check-data
+
+ javadoc:
+ parameters:
+ os:
+ type: executor
+ compute_size:
+ type: string
+ default: << pipeline.parameters.compute_size_small >>
+ maven_cache_name_prefix:
+ type: string
+ executor: << parameters.os >>
+ resource_class: << parameters.compute_size >>
+ environment:
+ COMPUTE_SIZE: << parameters.compute_size >>
+ steps:
+ - attach_project:
+ compute_size: << parameters.compute_size >>
+ - install_jdk:
+ compute_size: << parameters.compute_size >>
+ - install_maven:
+ compute_size: << parameters.compute_size >>
+ - maven_with_cache:
+ compute_size: << parameters.compute_size >>
+ cache_name_prefix: << parameters.maven_cache_name_prefix >>
+ verify_dependencies: false
+ steps:
+ - steps:
+ - install_artifacts:
+ compute_size: << parameters.compute_size >>
+ - run:
+ name: "Maven - Generate Javadoc"
+ command: |
+ if [[ $COMPUTE_SIZE == "small" ]] || [[ $COMPUTE_SIZE == "large" ]]; then
+ export JAVA_TOOL_OPTIONS="<< pipeline.parameters.java_tool_options >> << pipeline.parameters.extra_java_tool_options_docker >>"
+ else
+ export JAVA_TOOL_OPTIONS="<< pipeline.parameters.java_tool_options >>"
+ fi
+ $MAVEN_BIN -V -T2C -q javadoc:javadoc --projects '!exist-distribution,!exist-installer' --also-make
+
+ test:
+ parameters:
+ os:
+ type: executor
+ compute_size:
+ type: string
+ default: << pipeline.parameters.compute_size_large >>
+ maven_cache_name_prefix:
+ type: string
+ executor: << parameters.os >>
+ resource_class: << parameters.compute_size >>
+ environment:
+ COMPUTE_SIZE: << parameters.compute_size >>
+ steps:
+ - attach_project:
+ compute_size: << parameters.compute_size >>
+ - install_jdk:
+ compute_size: << parameters.compute_size >>
+ - install_maven:
+ compute_size: << parameters.compute_size >>
+ - maven_with_cache:
+ compute_size: << parameters.compute_size >>
+ cache_name_prefix: << parameters.maven_cache_name_prefix >>
+ verify_dependencies: false
+ steps:
+ - steps:
+ - run:
+ name: "Maven - Run Tests"
+ command: |
+ if [[ $COMPUTE_SIZE == "small" ]] || [[ $COMPUTE_SIZE == "large" ]]; then
+ export JAVA_TOOL_OPTIONS="<< pipeline.parameters.java_tool_options >> << pipeline.parameters.extra_java_tool_options_docker >>"
+ else
+ export JAVA_TOOL_OPTIONS="<< pipeline.parameters.java_tool_options >>"
+ fi
+ $MAVEN_BIN test integration-test -Dappbundler.skip=true -Ddocker=false -P !mac-dmg-on-mac,!codesign-mac-app,!codesign-mac-dmg,!mac-dmg-on-unix,!installer,!concurrency-stress-tests,!micro-benchmarks,skip-build-dist-archives
+ - run:
+ name: Save test results
+ command: |
+ mkdir -p ~/test-results/junit/
+ /usr/bin/find . -type f -regex ".*/target/surefire-reports/.*xml" -exec cp {} ~/test-results/junit/ \;
+ /usr/bin/find . -type f -regex ".*/target/failsafe-reports/.*xml" -exec cp {} ~/test-results/junit/ \;
+ when: always
+ - store_test_results:
+ path: ~/test-results
+ - when:
+ # NOTE(AR) only persist the workspace when we are on the `main` branch, and it has a `large` compute, as we then reuse it for the `code-coverage` and `sonar-analysis` jobs
+ condition:
+ and:
+ - equal: [ large, << parameters.compute_size >> ]
+ - equal: [ main, << pipeline.git.branch >> ]
+ steps:
+ - persist_project:
+ compute_size: << parameters.compute_size >>
+
+ code-coverage:
+ parameters:
+ os:
+ type: executor
+ compute_size:
+ type: string
+ default: << pipeline.parameters.compute_size_small >>
+ maven_cache_name_prefix:
+ type: string
+ executor: << parameters.os >>
+ resource_class: << parameters.compute_size >>
+ environment:
+ COMPUTE_SIZE: << parameters.compute_size >>
+ steps:
+ - attach_project:
+ compute_size: << parameters.compute_size >>
+ - install_jdk:
+ compute_size: << parameters.compute_size >>
+ - install_maven:
+ compute_size: << parameters.compute_size >>
+ - maven_with_cache:
+ compute_size: << parameters.compute_size >>
+ cache_name_prefix: << parameters.maven_cache_name_prefix >>
+ verify_dependencies: false
+ steps:
+ - steps:
+ - run:
+ name: "Maven - Produce Coverage and Coveralls Reports"
+ command: |
+ if [[ $COMPUTE_SIZE == "small" ]] || [[ $COMPUTE_SIZE == "large" ]]; then
+ export JAVA_TOOL_OPTIONS="<< pipeline.parameters.java_tool_options >> << pipeline.parameters.extra_java_tool_options_docker >>"
+ else
+ export JAVA_TOOL_OPTIONS="<< pipeline.parameters.java_tool_options >>"
+ fi
+ $MAVEN_BIN -V -T1C jacoco:report coveralls:report
+
+ sonar-analysis:
+ parameters:
+ os:
+ type: executor
+ compute_size:
+ type: string
+ default: << pipeline.parameters.compute_size_small >>
+ maven_cache_name_prefix:
+ type: string
+ executor: << parameters.os >>
+ resource_class: << parameters.compute_size >>
+ environment:
+ COMPUTE_SIZE: << parameters.compute_size >>
+ steps:
+ - attach_project:
+ compute_size: << parameters.compute_size >>
+ - install_jdk:
+ compute_size: << parameters.compute_size >>
+ - install_maven:
+ compute_size: << parameters.compute_size >>
+ - maven_with_cache:
+ compute_size: << parameters.compute_size >>
+ cache_name_prefix: << parameters.maven_cache_name_prefix >>
+ verify_dependencies: false
+ steps:
+ - steps:
+ - run:
+ name: "Maven - Analyze on SonarQube Cloud"
+ no_output_timeout: 30m
+ command: |
+ if [[ $COMPUTE_SIZE == "small" ]] || [[ $COMPUTE_SIZE == "large" ]]; then
+ export JAVA_TOOL_OPTIONS="<< pipeline.parameters.java_tool_options >> << pipeline.parameters.extra_java_tool_options_docker >>"
+ else
+ export JAVA_TOOL_OPTIONS="<< pipeline.parameters.java_tool_options >>"
+ fi
+ $MAVEN_BIN -V -T2C -P !installer,!concurrency-stress-tests,!micro-benchmarks sonar:sonar -Dsonar.projectKey=evolvedbinary_elemental
+
+ build-elemental-w3c-xqts-runner:
+ parameters:
+ os:
+ type: executor
+ compute_size:
+ type: string
+ default: << pipeline.parameters.compute_size_small >>
+ maven_cache_name_prefix:
+ type: string
+ executor: << parameters.os >>
+ resource_class: << parameters.compute_size >>
+ steps:
+ - checkout
+ - maven_with_cache:
+ compute_size: << parameters.compute_size >>
+ cache_name_prefix: << parameters.maven_cache_name_prefix >>
+ verify_dependencies: true
+ steps:
+ - steps:
+ - run:
+ name: "Maven - Build Elemental's XQTS Runner"
+ command: "$MAVEN_BIN -V -T2C clean package -Dmdep.analyze.skip=true -DskipTests -Ddependency-check.skip=true -Dlicense.skip=true --projects exist-xqts --also-make"
+ - persist_project:
+ compute_size: << parameters.compute_size >>
+
+ run-elemental-w3c-xqts-runner:
+ parameters:
+ os:
+ type: executor
+ compute_size:
+ type: string
+ default: << pipeline.parameters.compute_size_small >>
+ maven_cache_name_prefix:
+ type: string
+ executor: << parameters.os >>
+ resource_class: << parameters.compute_size >>
+ environment:
+ JAVA_OPTS: "<< pipeline.parameters.java_tool_options >> << pipeline.parameters.extra_java_tool_options_docker >> -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp -XX:+ExitOnOutOfMemoryError"
+ steps:
+ - attach_project:
+ compute_size: << parameters.compute_size >>
+ - run:
+ name: "Run Elemental's W3C XQTS Runner"
+ command: |
+ #!/usr/bin/env bash
+ DIR="$(find exist-xqts/target -type d -name exist-xqts-*)"
+ $DIR/bin/exist-xqts-runner.sh --xqts-version HEAD --output-dir /tmp/xqts-output --exclude-test-case RangeExpr-411d,RangeExpr-409d,RangeExpr-408d,RangeExpr-409c,RangeExpr-408c,GenCompEq-21
+ - run:
+ name: "Compress (any) Heap Dump files"
+ command: |
+ #!/usr/bin/env bash
+ if [ -f /tmp/*.hprof ]; then
+ tar cvf /tmp/heap-dumps.tar -C /tmp *.hprof
+ zstd --rm -9 --progress -T0 /tmp/heap-dumps.tar
+ fi
+ when: on_fail
+ - store_artifacts:
+ name: "Store (any) Heap Dump files"
+ path: /tmp/heap-dumps.tar.zst
+ destination: heap-dumps
+ - store_artifacts:
+ name: "Archive XQTS Logs"
+ path: /tmp/xqts-output
+ destination: xqts-logs
+
+
+workflows:
+ license-check:
+ jobs:
+ - license-check:
+ os: linux-docker-jdk21
+ maven_cache_name_prefix: linux-docker-jdk21
+
+ build-and-test:
+ jobs:
+ - build:
+ name: build-<< matrix.os >>
+ matrix:
+ parameters:
+ os: [linux-docker-jdk21, macos-vm-xcode16, windows-vm]
+ compute_size: [<< pipeline.parameters.compute_size_small >>, << pipeline.parameters.compute_size_mac_medium >>, << pipeline.parameters.compute_size_windows_medium >>]
+ maven_cache_name_prefix: [ << matrix.os >> ]
+ exclude:
+ - os: linux-docker-jdk21
+ compute_size: << pipeline.parameters.compute_size_mac_medium >>
+ maven_cache_name_prefix: << matrix.os >>
+ - os: linux-docker-jdk21
+ compute_size: << pipeline.parameters.compute_size_windows_medium >>
+ maven_cache_name_prefix: << matrix.os >>
+ - os: macos-vm-xcode16
+ compute_size: << pipeline.parameters.compute_size_small >>
+ maven_cache_name_prefix: << matrix.os >>
+ - os: macos-vm-xcode16
+ compute_size: << pipeline.parameters.compute_size_windows_medium >>
+ maven_cache_name_prefix: << matrix.os >>
+ - os: windows-vm
+ compute_size: << pipeline.parameters.compute_size_small >>
+ maven_cache_name_prefix: << matrix.os >>
+ - os: windows-vm
+ compute_size: << pipeline.parameters.compute_size_mac_medium >>
+ maven_cache_name_prefix: << matrix.os >>
+
+ - dependency-analyze:
+ os: linux-docker-jdk21
+ maven_cache_name_prefix: linux-docker-jdk21
+ requires:
+ - build-linux-docker-jdk21
+ - owasp-dependency-check:
+ os: linux-docker-jdk21
+ maven_cache_name_prefix: linux-docker-jdk21
+ requires:
+ - build-linux-docker-jdk21
+ - javadoc:
+ os: linux-docker-jdk21
+ maven_cache_name_prefix: linux-docker-jdk21
+ requires:
+ - build-linux-docker-jdk21
+ - test:
+ name: test-<< matrix.os >>
+ matrix:
+ parameters:
+ os: [linux-docker-jdk21, macos-vm-xcode16, windows-vm]
+ compute_size: [<< pipeline.parameters.compute_size_large >>, << pipeline.parameters.compute_size_mac_medium >>, << pipeline.parameters.compute_size_windows_medium >>]
+ maven_cache_name_prefix: [<< matrix.os >>]
+ exclude:
+ - os: linux-docker-jdk21
+ compute_size: << pipeline.parameters.compute_size_mac_medium >>
+ maven_cache_name_prefix: << matrix.os >>
+ - os: linux-docker-jdk21
+ compute_size: << pipeline.parameters.compute_size_windows_medium >>
+ maven_cache_name_prefix: << matrix.os >>
+ - os: macos-vm-xcode16
+ compute_size: << pipeline.parameters.compute_size_large >>
+ maven_cache_name_prefix: << matrix.os >>
+ - os: macos-vm-xcode16
+ compute_size: << pipeline.parameters.compute_size_windows_medium >>
+ maven_cache_name_prefix: << matrix.os >>
+ - os: windows-vm
+ compute_size: << pipeline.parameters.compute_size_large >>
+ maven_cache_name_prefix: << matrix.os >>
+ - os: windows-vm
+ compute_size: << pipeline.parameters.compute_size_mac_medium >>
+ maven_cache_name_prefix: << matrix.os >>
+ requires:
+ - build-<< matrix.os >>
+ - code-coverage:
+ os: linux-docker-jdk21
+ maven_cache_name_prefix: linux-docker-jdk21
+ requires:
+ - test-linux-docker-jdk21
+ filters:
+ branches:
+ only:
+ - main
+ - sonar-analysis:
+ os: linux-docker-jdk21
+ compute_size: << pipeline.parameters.compute_size_large >>
+ maven_cache_name_prefix: linux-docker-jdk21
+ requires:
+ - test-linux-docker-jdk21
+ filters:
+ branches:
+ only:
+ - main
+
+ w3c-xqts:
+ jobs:
+ - build-elemental-w3c-xqts-runner:
+ os: linux-docker-jdk21
+ maven_cache_name_prefix: linux-docker-jdk21
+ - run-elemental-w3c-xqts-runner:
+ os: linux-docker-jdk21
+ compute_size: << pipeline.parameters.compute_size_large >>
+ maven_cache_name_prefix: linux-docker-jdk21
+ requires:
+ - build-elemental-w3c-xqts-runner
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
deleted file mode 100644
index a065fd8db1..0000000000
--- a/.github/FUNDING.yml
+++ /dev/null
@@ -1 +0,0 @@
-open_collective: existdb
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index b987330cfc..92752f787c 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -5,21 +5,20 @@ To be able to better understand you problem or suggestion, please add as much in
Please fill in the following sections:
### What is the problem
-> Describe exactly what you see (e.g. an output of an XQuery)
+> Describe exactly what you see (e.g. the output of an XQuery)
### What did you expect
-> Describe what you expected to happen. Add for example a reference to a [specification](https://www.w3.org/TR/xquery-3/).
+> Describe what you expected to happen. Add for example a reference to a [specification](https://www.w3.org/TR/xquery-31/).
### Describe how to reproduce or add a test
-> Describe how we can can reproduce the problem.
+> Describe how we can reproduce the problem.
-> The *best* way is to provide an [SSCCE (Short, Self Contained, Correct (Compilable), Example)](http://sscce.org/). One type of SSCCE could be a small test which reproduces the issue and can be run without dependencies. The [XQSuite - Annotation-based Test Framework for XQuery](http://exist-db.org/exist/apps/doc/xqsuite.xml) makes it very easy for you to create tests. These tests can be executed from the [eXide editor](http://exist-db.org/exist/apps/eXide/index.html) (XQuery - Run as Test)
+> The *best* way is to provide an [SSCCE (Short, Self Contained, Correct (Compilable), Example)](http://sscce.org/). One type of SSCCE could be a small test which reproduces the issue and can be run without dependencies. The [XQSuite - Annotation-based Test Framework for XQuery](http://exist-db.org/exist/apps/doc/xqsuite.xml) makes it easy for you to create tests. These tests can be executed from the [eXide editor](http://exist-db.org/exist/apps/eXide/index.html) via `XQuery` > `Run as Test`.
### Context information
-Please always add the following information
-- eXist-db version + Git Revision hash e.g. eXist-db 3.0 / acd0c14
-- Java version (e.g. Java8u121)
-- Operating system (Windows 7, Linux, MacOs)
-- 32 or 64 bit
-- How is eXist-db installed? (JAR installer, DMG, .tar.gz/.zip distribution, clone from GitHub)
-- Any custom changes in e.g. conf.xml
+Please always add the following information:
+- Elemental version + Git Revision hash e.g. Elemental 6.3.1 / 31fc2c1
+- Java version (e.g. Java 8u121)
+- Operating system (Windows 11, Linux, macOS)
+- How is Elemental installed? (JAR installer, DMG, .tar.gz/.zip distribution, clone from GitHub)
+- Any custom config changes in e.g. conf.xml
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index 1af912a732..934e3dc888 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -1,13 +1,13 @@
---
name: Bug report
-about: Thank you for reporting your issue and helping us to improve!
+about: Thank you for helping us to improve Elemental by reporting a bug.
title: "[BUG]"
labels: ''
assignees: ''
---
-> To be able to better understand you problem, please add as much information as possible to this ticket. Always test your bugs against the latest stable release of exist. We cannot provide support for older versions here on GitHub. If the version of eXist that is experiencing the issue is more than 1 major version behind the most recent release, please consider posting a question on our mailing list.
+> To be able to better understand you problem, please add as much information as possible to this ticket. Please also test your bugs against the latest stable release of Elemental to check whether it has already been fixed.
**Describe the bug**
@@ -17,29 +17,30 @@ A clear and concise description of what the bug is.
A clear and concise description of what you expected to happen.
**To Reproduce**
-> The *best* way is to provide an [SSCCE (Short, Self Contained, Correct (Compilable), Example)](http://sscce.org/). One type of SSCCE could be a small test which reproduces the issue and can be run without dependencies. The [XQSuite - Annotation-based Test Framework for XQuery](http://exist-db.org/exist/apps/doc/xqsuite.xml) makes it very easy for you to create tests. These tests can be executed from the [eXide editor](http://exist-db.org/exist/apps/eXide/index.html) (XQuery - Run as Test)
+> The *best* way is to provide an [SSCCE (Short, Self Contained, Correct (Compilable), Example)](http://sscce.org/). One type of SSCCE could be a small test which reproduces the issue and can be run without dependencies. The [XQSuite - Annotation-based Test Framework for XQuery](http://exist-db.org/exist/apps/doc/xqsuite.xml) makes it very easy for you to create tests. These tests can be executed from the [eXide editor](http://exist-db.org/exist/apps/eXide/index.html) `XQuery` > `Run as Test`.
-```Xquery
+```xquery
xquery version "3.1";
module namespace t="http://exist-db.org/xquery/test";
declare namespace test="http://exist-db.org/xquery/xqsuite";
-
+(: Replace root with your data :)
declare variable $t:XML := document {
-
+
};
-
-declare variable $t:xconf :=
+(: Replace index config if needed :)
+declare variable $t:xconf := document {
-
-
-
-;
+
+
+
+
+};
-
+(: Collections and Indexes can be configured here :)
declare
%test:setUp
function t:setup() {
@@ -60,33 +61,33 @@ function t:tearDown() {
xmldb:remove("/db/system/config/db/test")
};
-<-- Adjust to your reported issue -->
+(: Adjust to your reported issue :)
declare
- %test:assertTrue
-function t:test() {
+ %test:assertEquals(1)
+function t:test-1() {
let $test-data := collection('/db/test')
for $result in $test-data//root
return
- count($result) eq 1
+ count($result)
};
```
-If the above isn't working, please tell us the exact steps you took when you encountered the problem:
-1. Go to '...'
-2. Click on '....'
-3. Scroll down to '....'
-4. See error
+If the above isn't working, please tell us the exact steps you took when you encountered the problem, e.g.
+1. Go to ...
+2. Click on ...
+3. Scroll down to ...
+4. Results in the error ...
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Context (please always complete the following information)**
-One option is to use [xst](https://www.npmjs.com/package/@existdb/xst), and copy and paste the output produced by running `xst info` here:**
- - Build: [eXist-6.1.0]
- - Java: [1.8.0_352]
- - OS: [Mac OS X 12.6.2]
+* Version: [Elemental 6.3.1]
+* Java: [1.8.0_352]
+* OS: [macOS X 12.6.2]
**Additional context**
-- How is eXist-db installed? [e.g. JAR installer, DMG, … ]
-- Any custom changes in e.g. `conf.xml`?
+
+* How is Elemental installed? [e.g. JAR installer, DMG, … ]
+* Any custom changes in e.g. `conf.xml`?
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 0b55e198c6..f44f6da08b 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,14 +1,14 @@
-Thank you for your contribution to eXist-db!
+Thank you for contributing to Elemental!
-To help the community judge your pull request (PR), please include the following:
+To help the community judge your PR (Pull Request), please include the following:
-- A (short) description of the content of changes.
-- A context reference to a [Github Issue](https://github.com/eXist-db/exist/issues), a message in the [eXist-open mailinglist](http://exist-open.markmail.org), or a [specification](https://www.w3.org/TR/xquery-31/).
-- Tests. The [XQSuite - Annotation-based Test Framework for XQuery](http://exist-db.org/exist/apps/doc/xqsuite.xml) makes it very easy for you to create tests. These tests can be executed from the [eXide editor](http://exist-db.org/exist/apps/eXide/index.html) via XQuery > Run as Test.
+- A (short) description of the content of your changes.
+- A context reference to a [Github Issue](https://github.com/evolvedbinary/elemental/issues), a message in the [Elemental users mailing list](https://groups.google.com/u/1/a/elemental.xyz/g/users), or a [specification](https://www.w3.org/TR/xquery-31/).
+- Tests. The [XQSuite - Annotation-based Test Framework for XQuery](http://exist-db.org/exist/apps/doc/xqsuite.xml) makes it easy for you to create tests. These tests can be executed from the [eXide editor](http://exist-db.org/exist/apps/eXide/index.html) via `XQuery` > `Run as Test`.
-Your PR will be tested using [GitHub Actions](https://github.com/eXist-db/exist/actions) against a number of operating systems and environments. The build status is visible in the PR.
+Your PR will be tested using [CircleCI](https://github.com/evolvedbinary/elemental/actions) against a number of operating systems and environments. The build status is visible in the PR.
-To detect errors in your PR before submitting it, please run eXist's full test suite on your own system via `mvn -V clean verify`.
+To detect errors in your PR before submitting it, please run Elemental's full test suite on your own system via `mvn -V clean site`.
------
@@ -16,4 +16,4 @@ To detect errors in your PR before submitting it, please run eXist's full test s
### Reference:
-### Type of tests:
+### Tests:
diff --git a/.github/actions/install-mvnd/action.yml b/.github/actions/install-mvnd/action.yml
deleted file mode 100644
index a0dc3bdf1f..0000000000
--- a/.github/actions/install-mvnd/action.yml
+++ /dev/null
@@ -1,89 +0,0 @@
-name: 'install-mvnd'
-description: 'Install the Maven Daemon'
-inputs:
- version:
- description: 'The version of the Maven Daemon to install'
- required: true
- default: '0.9.0'
- file-version-suffix:
- description: 'A suffix to append to the version of the download file of Maven Daemon to install'
- required: false
- default: ''
- install-path:
- description: 'The folder in which Maven Daemon will be installed as a sub-folder'
- required: true
- default: '/tmp'
- cache:
- description: 'Set to true to cache Maven Daemon artifacts per-platform-architecture'
- required: true
- default: 'true'
- mvnd-connect-timeout:
- description: 'The timeout (as a duration, e.g. `90 seconds`) for connecting to the Maven Daemon'
- required: true
- default: '90 seconds'
-outputs:
- mvnd-dir:
- description: "The directory where the command mvnd is located"
- value: ${{ steps.mvnd-location.outputs.mvnd-dir }}
-runs:
- using: "composite"
- steps:
- - name: Determine mvnd platform and architecture
- shell: bash
- run: |
- if [ "$RUNNER_OS" == "Linux" ]; then
- MVND_PLATFORM="linux"
- elif [ "$RUNNER_OS" == "macOS" ]; then
- MVND_PLATFORM="darwin"
- elif [ "$RUNNER_OS" == "Windows" ]; then
- MVND_PLATFORM="windows"
- else
- "echo Unknown platform: $RUNNER_OS"
- exit 1
- fi
- MVND_ARCHITECTURE="amd64"
- echo "MVND_PLATFORM=${MVND_PLATFORM}" >> $GITHUB_ENV
- echo "MVND_ARCHITECTURE=${MVND_ARCHITECTURE}" >> $GITHUB_ENV
- echo "MVND_NAME=maven-mvnd-${{ inputs.version }}${{ inputs.file-version-suffix }}-${MVND_PLATFORM}-${MVND_ARCHITECTURE}" >> $GITHUB_ENV
- - name: Cache mvnd
- if: inputs.cache == 'true'
- id: cache-mvnd
- uses: actions/cache@v4
- with:
- path: |
- ${{ inputs.install-path }}/${{ env.MVND_NAME }}.zip
- ${{ inputs.install-path }}/${{ env.MVND_NAME }}.zip.sha256
- ${{ inputs.install-path }}/${{ env.MVND_NAME }}
- key: setup-${{ env.MVND_NAME }}
- - name: Download mvnd
- if: steps.cache-mvnd.outputs.cache-hit != 'true'
- shell: bash
- run: |
- curl -fsSL -o ${{ inputs.install-path }}/${{ env.MVND_NAME }}.zip https://archive.apache.org/dist/maven/mvnd/${{ inputs.version }}/${{ env.MVND_NAME }}.zip
- curl -fsSL -o ${{ inputs.install-path }}/${{ env.MVND_NAME }}.zip.sha256 https://archive.apache.org/dist/maven/mvnd/${{ inputs.version }}/${{ env.MVND_NAME }}.zip.sha256
- - name: Install sha256sum (macOS)
- if: ${{ runner.os == 'macOS' }}
- shell: bash
- run: brew install coreutils
- - name: Verify mvnd sha256 checksum
- shell: bash
- run: echo "$(cat ${{ inputs.install-path }}/${{ env.MVND_NAME }}.zip.sha256) ${{ inputs.install-path }}/${{ env.MVND_NAME }}.zip" | sha256sum --check
- - name: Unzip mvnd
- if: steps.cache-mvnd.outputs.cache-hit != 'true'
- shell: bash
- run: unzip ${{ inputs.install-path }}/${{ env.MVND_NAME }}.zip -d ${{ inputs.install-path }}/
- - name: Show Maven Daemon version
- shell: bash
- run: |
- ${{ inputs.install-path }}/${{ env.MVND_NAME }}/bin/mvnd -D'mvnd.connectTimeout=${{ inputs.mvnd-connect-timeout }}' --version
- ${{ inputs.install-path }}/${{ env.MVND_NAME }}/bin/mvnd -D'mvnd.connectTimeout=${{ inputs.mvnd-connect-timeout }}' --status
- - name: Set mvnd-dir
- id: mvnd-location
- shell: bash
- run: |
- MVND_BIN_DIR="${{ inputs.install-path }}/${{ env.MVND_NAME }}/bin"
- if [ "$RUNNER_OS" == "Windows" ]; then
- MVND_BIN_DIR="$(cygpath --absolute --long-name --windows $MVND_BIN_DIR)"
- fi
- echo "MVND_BIN_DIR=${MVND_BIN_DIR}" >> $GITHUB_ENV
- echo "mvnd-dir=${MVND_BIN_DIR}" >> $GITHUB_OUTPUT
diff --git a/.github/move.yml b/.github/move.yml
deleted file mode 100644
index e52b287683..0000000000
--- a/.github/move.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-# Configuration for move-issues - https://github.com/dessant/move-issues
-
-# Delete the command comment. Ignored when the comment also contains other content
-deleteCommand: true
-# Close the source issue after moving
-closeSourceIssue: true
-# Lock the source issue after moving
-lockSourceIssue: false
-# Set custom aliases for targets
-# aliases:
-# r: repo
-# or: owner/repo
diff --git a/.github/opencollective.yml b/.github/opencollective.yml
deleted file mode 100644
index f455e87a92..0000000000
--- a/.github/opencollective.yml
+++ /dev/null
@@ -1,17 +0,0 @@
-collective: eXist-db
-tiers:
- - tiers: '*'
- labels: ['backer']
- message: 'Hey '
- - tiers: ['Sponsor']
- labels: ['sponsor']
- message: 'Hey sponsor '
-invitation: |
- Hey :wave:,
-
- Thank you for opening an issue. We will get back to you as soon as we can.
-
- Also, check out our [Open Collective](https://opencollective.com/existdb) and consider backing us - every little helps!
-
- :gift_heart: We also offer bounties for some issues, please tell us if you want to boost this issue with one!
-
diff --git a/.github/workflows/ci-deploy.yml b/.github/workflows/ci-deploy.yml
deleted file mode 100644
index 94b1ee46c4..0000000000
--- a/.github/workflows/ci-deploy.yml
+++ /dev/null
@@ -1,71 +0,0 @@
-name: Deploy
-on: [push, pull_request]
-jobs:
- build:
- name: Build and Test Images
- runs-on: ubuntu-latest
- # NOTE (DP): Publish on develop and master, test on PRs against these
- if: github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/master' || github.base_ref == 'develop' || github.base_ref == 'master'
- steps:
- - uses: actions/checkout@v4
- with:
- fetch-depth: 1
- - name: Set up JDK 17
- uses: actions/setup-java@v4
- with:
- distribution: liberica
- java-version: '17'
- - name: Make buildkit default
- uses: docker/setup-buildx-action@v3
- id: buildx
- with:
- install: true
- - name: Cache Maven packages
- uses: actions/cache@v4
- with:
- path: ~/.m2
- key: deploy-${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
- restore-keys: deploy-${{ runner.os }}-maven
- - name: Install bats
- run: sudo apt-get install bats
- - name: Build images
- run: mvn -V -B -q -Pdocker -DskipTests -Ddependency-check.skip=true -P !mac-dmg-on-unix,!installer,!concurrency-stress-tests,!micro-benchmarks,skip-build-dist-archives clean package
- - name: Check local images
- run: docker image ls
- - name: Check license headers
- run: mvn license:check
- working-directory: exist-docker
- - name: Start exist-ci container
- run: |
- docker run -dit -p 8080:8080 --name exist-ci --rm existdb/existdb:latest
- sleep 35s
- - name: Run tests
- run: bats --tap exist-docker/src/test/bats/*.bats
- # NOTE (DP): When on master push release, when on develop push latest: Version is included automatically
- # TODO (DP): Confirm that releases triggered from maven publish images with the non SNAPSHOT version
- - name: Publish latest images
- if: github.ref == 'refs/heads/develop'
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
- DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
- run: mvn -q -Ddocker.tag=latest -Ddocker.username=$DOCKER_USERNAME -Ddocker.password=$DOCKER_PASSWORD docker:build docker:push
- working-directory: ./exist-docker
- - name: Publish release images
- if: github.ref == 'refs/heads/master'
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
- DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
- run: mvn -q -Ddocker.tag=release -Ddocker.username=$DOCKER_USERNAME -Ddocker.password=$DOCKER_PASSWORD docker:build docker:push
- working-directory: ./exist-docker
- # NOTE (DP): This is for debugging, publishes an experimental image from inside PRs against develop
- # - name: Publish experimental images
- # if: github.base_ref == 'develop'
- # env:
- # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- # DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
- # DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
- # run: mvn -q -Ddocker.tag=experimental -Ddocker.username=$DOCKER_USERNAME -Ddocker.password=$DOCKER_PASSWORD docker:build docker:push
- # working-directory: ./exist-docker
-
diff --git a/.github/workflows/ci-test.yml b/.github/workflows/ci-test.yml
deleted file mode 100644
index 66a053a326..0000000000
--- a/.github/workflows/ci-test.yml
+++ /dev/null
@@ -1,86 +0,0 @@
-name: Test & documentation
-on: [push, pull_request]
-permissions:
- contents: read
-env:
- MAVEN_OPTS: -DtrimStackTrace=false -D'maven.resolver.transport=wagon'
- DEV_JDK: '17'
-jobs:
- license:
- name: License check
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-java@v4
- with:
- distribution: liberica
- java-version: ${{ env.DEV_JDK }}
- cache: 'maven'
- - run: mvn -V -B license:check
- timeout-minutes: 60
- dependencies:
- name: Dependency checks
- if: ${{ github.event_name != 'pull_request' && github.ref == 'refs/heads/develop' }}
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-java@v4
- with:
- distribution: liberica
- java-version: ${{ env.DEV_JDK }}
- cache: 'maven'
- - name: OWASP dependency check
- env:
- NVD_API_KEY: ${{ secrets.NVD_API_KEY }}
- run: mvn -V -B dependency-check:check
- timeout-minutes: 60
- test:
- name: ${{ matrix.os }} Test
- strategy:
- fail-fast: false
- matrix:
- os: [ubuntu-latest, windows-latest, macOS-latest]
- jvm: ['17', '21']
- runs-on: ${{ matrix.os }}
- steps:
- - uses: actions/checkout@v4
- - name: Set up JDK
- uses: actions/setup-java@v4
- with:
- distribution: liberica
- java-version: ${{ matrix.jvm }}
- cache: 'maven'
- - name: Install Maven Daemon
- id: install-mvnd
- uses: ./.github/actions/install-mvnd
- with:
- version: '1.0.2'
- file-version-suffix: ''
- cache: 'true'
- - name: Maven Build
- timeout-minutes: 10
- run: ${{ steps.install-mvnd.outputs.mvnd-dir }}/mvnd -V -B -T 1C compile test-compile -DtrimStackTrace=false -D'dependency-check.skip' -D'license.skip'
- - name: Maven Test
- timeout-minutes: 60
- run: ${{ steps.install-mvnd.outputs.mvnd-dir }}/mvnd -V -B verify -DtrimStackTrace=false -D'dependency-check.skip' -D'license.skip' -D'mvnd.maxLostKeepAlive=6000'
- - name: Javadoc (Linux only)
- if: ${{ matrix.os == 'ubuntu-latest' }}
- run: ${{ steps.install-mvnd.outputs.mvnd-dir }}/mvnd -V -B -q -T 1C install javadoc:javadoc -DskipTests -D'dependency-check.skip' -D'license.skip' --projects '!exist-distribution,!exist-installer' --also-make
- - name: Maven Code Coverage (Develop branch on Linux only)
- if: ${{ github.event_name != 'pull_request' && github.ref == 'refs/heads/develop' && matrix.os == 'ubuntu-latest' }}
- env:
- CI_NAME: github
- BRANCH_NAME_OR_REF: ${{ github.head_ref || github.ref }}
- CI_BUILD_NUMBER: ${{ github.run_id }}
- CI_BUILD_URL: https://github.com/${{ github.repository }}/commit/${{ github.event.after }}/checks
- COVERALLS_TOKEN: ${{ secrets.COVERALLS_TOKEN }}
- run: ${{ steps.install-mvnd.outputs.mvnd-dir }}/mvnd -V -B jacoco:report coveralls:report
- - name: Archive build logs
- if: always()
- uses: actions/upload-artifact@v4
- with:
- name: ${{ runner.os }}-${{ matrix.jvm }}-build-logs
- retention-days: 5
- path: |
- **/hs_err_pid*.log
- **/target/surefire-reports/*
diff --git a/.github/workflows/ci-xqts.yml b/.github/workflows/ci-xqts.yml
deleted file mode 100644
index f326aec091..0000000000
--- a/.github/workflows/ci-xqts.yml
+++ /dev/null
@@ -1,65 +0,0 @@
-name: XQTS
-on: [push, pull_request]
-permissions:
- contents: read
-
-jobs:
- xqts:
- name: W3C XQuery Test Suite
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - name: Set up JDK 17
- uses: actions/setup-java@v4
- with:
- distribution: liberica
- java-version: '17'
- - name: Cache Maven packages
- uses: actions/cache@v4
- with:
- path: ~/.m2
- key: xqts-${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
- restore-keys: xqts-${{ runner.os }}-maven
- - name: Maven XQTS Build
- run: mvn -V -B clean package -DskipTests -Ddependency-check.skip=true --projects exist-xqts --also-make
- - name: Run XQTS
- timeout-minutes: 60
- env:
- JAVA_OPTS: -XX:+UseZGC -Xmx6g -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp -XX:+ExitOnOutOfMemoryError
- run: find exist-xqts/target -name exist-xqts-runner.sh -exec {} --xqts-version HEAD --output-dir /tmp/xqts-output --exclude-test-case RangeExpr-411d,RangeExpr-409d,RangeExpr-408d,RangeExpr-409c,RangeExpr-408c,GenCompEq-21 \;
- - name: Check for HeapDump
- id: check_heapdump
- uses: andstor/file-existence-action@v3
- with:
- files: "/tmp/*.hprof"
- - name: Compress HeapDump
- if: steps.check_heapdump.outputs.files_exists == 'true'
- run: zstd --rm -9 --progress -T0 /tmp/*.hprof
- - name: Attach HeapDump artifact
- if: steps.check_heapdump.outputs.files_exists == 'true'
- uses: actions/upload-artifact@v4
- with:
- name: exist-xqts-runner-hprof
- retention-days: 1
- path: /tmp/*.hprof.zst
- - name: Archive XQTS Logs
- if: always()
- uses: actions/upload-artifact@v4
- with:
- name: xqts-logs
- retention-days: 14
- path: /tmp/xqts-output
- - name: Get Previous XQTS Logs Artifacts JSON
- run: 'curl -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" https://api.github.com/repos/exist-db/exist/actions/artifacts?name=xqts-logs > /tmp/previous-xqts-logs-artifacts.json'
- - name: Extract Previous XQTS Logs Artifact JSON
- run: cat /tmp/previous-xqts-logs-artifacts.json | jq -r "[.artifacts[] | select(.workflow_run.head_branch == \"develop\")][1].archive_download_url" > /tmp/previous-xqts-logs-artifact.json
- - name: Get Previous XQTS Logs Artifact
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: 'cat /tmp/previous-xqts-logs-artifact.json | xargs curl -H "Authorization: Bearer ${GITHUB_TOKEN}" --location --output /tmp/previous-xqts-output.zip'
- - name: Extract Previous XQTS Logs Artifact
- run: mkdir /tmp/previous-xqts-output && unzip /tmp/previous-xqts-output.zip -d /tmp/previous-xqts-output
- - name: Compare Previous and Current XQTS Logs
- run: java -jar ~/.m2/repository/net/sf/saxon/Saxon-HE/9.9.1-8/Saxon-HE-9.9.1-8.jar -xsl:exist-xqts/src/main/xslt/compare-results.xslt -it:compare-results -o:/tmp/comparison-results.xml xqts.previous.junit-data-path=/tmp/previous-xqts-output/junit/data xqts.current.junit-data-path=/tmp/xqts-output/junit/data
- - name: Show Comparison Results
- run: cat /tmp/comparison-results.xml
diff --git a/.idea/runConfigurations/Java_Admin_Client.xml b/.idea/runConfigurations/Java_Admin_Client.xml
index dd116638bf..229b57992a 100644
--- a/.idea/runConfigurations/Java_Admin_Client.xml
+++ b/.idea/runConfigurations/Java_Admin_Client.xml
@@ -1,11 +1,11 @@
-
+
-
+
diff --git a/.idea/runConfigurations/Jetty_Server.xml b/.idea/runConfigurations/Jetty_Server.xml
index 51c43f6b99..6ed072ad65 100644
--- a/.idea/runConfigurations/Jetty_Server.xml
+++ b/.idea/runConfigurations/Jetty_Server.xml
@@ -1,11 +1,11 @@
-
+
-
-
+
+
diff --git a/.idea/runConfigurations/Local_Jetty_Server.xml b/.idea/runConfigurations/Local_Jetty_Server.xml
index b290ff47d6..f00e42bae5 100644
--- a/.idea/runConfigurations/Local_Jetty_Server.xml
+++ b/.idea/runConfigurations/Local_Jetty_Server.xml
@@ -1,11 +1,11 @@
-
+
-
-
+
+
diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 0000000000..2f94e61698
--- /dev/null
+++ b/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+wrapperVersion=3.3.2
+distributionType=only-script
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.10/apache-maven-3.9.10-bin.zip
diff --git a/BUILD.md b/BUILD.md
index 8e1c8374f7..11f195339d 100644
--- a/BUILD.md
+++ b/BUILD.md
@@ -1,33 +1,43 @@
-Building eXist-db from Source
---------------------------
+# Building Elemental from Source Code
-eXist-db itself is written in Java 17. The build system is [Apache Maven](http://maven.apache.org/). If you're not familiar with Git, we recommend [this excellent online interactive tutorial](http://try.github.io).
+Elemental itself is written in Java 21. The build system is [Apache Maven](http://maven.apache.org/). If you're not familiar with Git, we recommend [this excellent online interactive tutorial](http://try.github.io).
-To build eXist-db:
+To build Elemental:
-- Checkout the Git Repository
-- Execute a Maven to compile eXist-db
+1. Checkout the Git Repository
-```bash
-$ git clone https://github.com/eXist-db/exist.git
-$ cd exist
-$ git checkout master
-$ mvn -DskipTests package
-```
+ ```bash
+ $ git clone https://github.com/evolvedbinary/elemental.git
+ $ git checkout gold
+ $ cd elemental
+ ```
-From here, you now have a compiled version of eXist-db in the `exist-distribution/target` folder that you may use just as you would an installed version of eXist-db. An installer is also build and present uin `exist-installer/target` for easy installation elsewhere.
+2. Execute Maven to compile Elemental
-Useful build switches:
-- `-Ddocker=true` : builds the docker image
-- `-DskipTests` : skips running tests
-- `-Ddependency-check.skip=true` : skips validating dependencies
+ We provide a build script to try and make common build tasks easier for users.
-Further build options can be found at: [eXist-db Build Documentation](http://www.exist-db.org/exist/apps/doc/exist-building.xml "How to build eXist").
+ For macOS/Linux/Unix platforms:
+ ```bash
+ $ ./build.sh quick
+ ```
+
+ or, for Windows platforms:
+ ```cmd
+ > build.bat quick
+ ```
+
+From here, you now have a compiled version of Elemental in the `exist-distribution/target` folder that you may use just as you would an installed version of Elemental. An installer is also build and present in `exist-installer/target` for easy installation elsewhere.
+
+The `quick` build target will build distribution directory that can be found at: `exist-distribution/target/elemental-x.y.x-dir`.
+If you wish to see what other build targets are available, you can run `./build.sh --help` (or `build.bat --help` on Windows platforms).
+
+
+Further build options can be found at: [eXist-db Build Documentation](http://www.exist-db.org/exist/apps/doc/exist-building.xml "How to build eXist-db").
**NOTE:**
-In the above example, we switched the current (checked-out) branch from `develop` to `master`. We use the [GitFlow for eXist-db](#contributing-to-exist) process:
-- `develop` is the current (and stable) work-in-progress (the next release)
-- `master` is the latest release
+In the above example, we switched the current (checked-out) branch from `main` to `gold`.
+- `main` is the current (and stable) work-in-progress (the next release)
+- `gold` is the last release
The choice of which to use is up to you.
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index fd558d0107..ffda176840 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -2,76 +2,68 @@
## Our Pledge
-In the interest of fostering an open and welcoming environment, we as
-contributors and maintainers pledge to making participation in our project and
-our community a harassment-free experience for everyone, regardless of age, body
-size, disability, ethnicity, sex characteristics, gender identity and expression,
-level of experience, education, socio-economic status, nationality, personal
-appearance, race, religion, or sexual identity and orientation.
+We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
## Our Standards
-Examples of behavior that contributes to creating a positive environment
-include:
+Examples of behavior that contributes to a positive environment for our community include:
-* Using welcoming and inclusive language
-* Being respectful of differing viewpoints and experiences
-* Gracefully accepting constructive criticism
-* Focusing on what is best for the community
-* Showing empathy towards other community members
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the overall community
-Examples of unacceptable behavior by participants include:
+Examples of unacceptable behavior include:
-* The use of sexualized language or imagery and unwelcome sexual attention or
- advances
-* Trolling, insulting/derogatory comments, and personal or political attacks
+* The use of sexualized language or imagery, and sexual attention or advances of any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
-* Publishing others' private information, such as a physical or electronic
- address, without explicit permission
-* Other conduct which could reasonably be considered inappropriate in a
- professional setting
+* Publishing others’ private information, such as a physical or email address, without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a professional setting
-## Our Responsibilities
+## Enforcement Responsibilities
-Project maintainers are responsible for clarifying the standards of acceptable
-behavior and are expected to take appropriate and fair corrective action in
-response to any instances of unacceptable behavior.
+Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
-Project maintainers have the right and responsibility to remove, edit, or
-reject comments, commits, code, wiki edits, issues, and other contributions
-that are not aligned to this Code of Conduct, or to ban temporarily or
-permanently any contributor for other behaviors that they deem inappropriate,
-threatening, offensive, or harmful.
+Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
## Scope
-This Code of Conduct applies both within project spaces and in public spaces
-when an individual is representing the project or its community. Examples of
-representing a project or community include using an official project e-mail
-address, posting via an official social media account, or acting as an appointed
-representative at an online or offline event. Representation of a project may be
-further defined and clarified by project maintainers.
+This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official email address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
## Enforcement
-Instances of abusive, harassing, or otherwise unacceptable behavior may be
-reported by contacting the project team at info@exist-db.org. All
-complaints will be reviewed and investigated and will result in a response that
-is deemed necessary and appropriate to the circumstances. The project team is
-obligated to maintain confidentiality with regard to the reporter of an incident.
-Further details of specific enforcement policies may be posted separately.
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at admin@elemental.xyz. All complaints will be reviewed and investigated promptly and fairly.
-Project maintainers who do not follow or enforce the Code of Conduct in good
-faith may face temporary or permanent repercussions as determined by other
-members of the project's leadership.
+All community leaders are obligated to respect the privacy and security of the reporter of any incident.
-## Attribution
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
+
+1. Correction
+ Community Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
+ Consequence: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
-This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
-available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
+2. Warning
+ Community Impact: A violation through a single incident or series of actions.
+ Consequence: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
+
+3. Temporary Ban
+ Community Impact: A serious violation of community standards, including sustained inappropriate behavior.
+ Consequence: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
+
+4. Permanent Ban
+ Community Impact: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
+ Consequence: A permanent ban from any sort of public interaction within the community.
+
+## Attribution
-[homepage]: https://www.contributor-covenant.org
+This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/), version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.
-For answers to common questions about this code of conduct, see
-https://www.contributor-covenant.org/faq
+Community Impact Guidelines were inspired by [Mozilla’s code of conduct enforcement ladder](https://github.com/mozilla/diversity).
+For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index ae83393a5a..0c1668eb9a 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,36 +1,33 @@
-# Contributing to eXist-db
-We welcome everyone to contribute to eXist-db. We will consider each individual contribution on its own merits.
-We strongly suggest that you join the [eXist-db Slack Workspace](https://exist-db.slack.com), so that you can collaborate with the eXist-db community. It is often valuable to discuss a potential contribution before undertaking any work.
+# Contributing to Elemental
+We welcome everyone to contribute to Elemental. We will consider each individual contribution separately on its own merits.
+We strongly suggest that you join the [Elemental Slack Workspace](https://join.slack.com/t/elemental-xyz/shared_invite/zt-3290ginoh-lWocaoR3UMw7jghfrt~kFA), so that you can collaborate with the Elemental community. It is often valuable to discuss a potential contribution before undertaking any work.
-We follow a "Hub and Spoke" like development model; therefore you should fork our eXist-db repository, work on branches within your own fork, and then send pull requests for your branches to our GitHub repository.
+We follow a *Hub and Spoke* like development model; therefore you should fork our Elemental repository, work on branches within your own fork, and then send pull requests for your branches to our GitHub repository.
## Branch Naming
-eXist-db uses a [GitFlow](http://nvie.com/git-model)-like branching model for development.
+Elemental uses a simple Git branching model for development.
The names of each branch should reflect their purpose, the following branches may be of interest:
-* `develop` - the main line of development for the next version of eXist-db.
-* `master` - reflects the `tag` of the last released version of eXist-db.
+* `main` - the main line of development for the next version.
+* `gold` - reflects the `tag` of the last released version.
-There are also branches that enable us to backport hot-fixes and features to older major versions of eXist-db, so that we might release small updates occasionally.
-* `develop-4.x.x` - development of the 4.x.x version line of eXist-db, mostly now only used for hot-fixes.
-* `develop-5.x.x` - development of the 5.x.x version line of eXist-db.
-* `develop-6.x.x` - development of the 6.x.x version line of eXist-db.
+There are also branches that enable us to backport hot-fixes and features to older major versions, so that we might release small updates occasionally.
+* `develop-6.x.x` - development of the 6.x.x version line of Elemental.
-When contributing to eXist-db you should branch one of the development branches above, your branch should be named in one of two ways:
+When contributing to Elemental you should branch our `main` (or for backports the `develop-6.x.x`) branch. Your branch should be named in one of two ways:
* `feature/`
- This naming convention should be used when contributing new features to eXist-db. For example `feature/xquery31-sliding-window`
+ This naming convention should be used when contributing new features. For example `feature/xquery31-sliding-window`
* `hotfix/`
- This naming convention should be used when contributing bug fixes to eXist-db. For example `hotfix/memory-leak-xquery-context`
+ This naming convention should be used when contributing bug fixes. For example `hotfix/memory-leak-xquery-context`
-Additionally, if you are back-porting a feature or bug fix to a previous version of eXist-db, you should prefix your branch name with a `V.x.x/` where `V` is the major version number, for example: `6.x.x/feature/xquery31-sliding-window`.
+Additionally, if you are back-porting a feature or bug fix to a previous version of Elemental, you should prefix your branch name with a `V.x.x/` where `V` is the major version number, for example: `6.x.x/feature/xquery31-sliding-window`.
## Code Formatting
All new Java code is expected to be formatted inline with the [IntelliJ Default Style for Java code](https://www.jetbrains.com/help/idea/configuring-code-style.html#configure-code-style-schemes).
-
## Commit Messages
-Commits to eXist-db by developers *should* follow the Git [Commit Guidelines](https://git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-Project#_commit_guidelines). In addition the summary line of the commit message *must* be prefixed with a label from our controlled list that helps us to better understand the commit and also to generate Change Logs.
+Commits by developers *should* follow the Git [Commit Guidelines](https://git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-Project#_commit_guidelines). In addition, the summary line of the commit message *must* be prefixed with a label from our controlled list that helps us to better understand the commit and also to generate Change Logs.
### Commit Labels
Our controlled list of commit labels that should be prefixed to each commit summary is:
@@ -52,9 +49,9 @@ Our controlled list of commit labels that should be prefixed to each commit summ
* `[ci]`
This should be used when a commit solely makes changes to CI configuration.
-In addition any commit that addresses a GitHub issue, should have an additonal line in its commit after the summary and before any fuller explaination that takes this form:
+Finally, any commit that addresses a GitHub issue, should have an additional line in its commit after the summary and before any fuller explanation that takes this form:
```
-Closes https://github.com/eXist-db/exist/issues/
+Closes https://github.com/evolvedbinary/elemental/issues/
```
### Commit Message Example
@@ -63,147 +60,64 @@ For example, here is a correctly formatted commit message:
```
[bugfix] Fix relative paths in EXPath classpath.txt files.
-Closes https://github.com/eXist-db/exist/issues/4901
-We now store the path of Jar files in each EXPath Package's `.exist/classpath.txt` file relative to the package's `content/` sub-folder.
+Closes https://github.com/eevolvedbinary/elemental/issues/4901
+We now store the path of Jar files in each EXPath Package's `classpath.txt` file relative to the package's `content/` sub-folder.
```
## Pull Requests and Code Review
-Pull requests are reviewed and tested before they're merged by the eXist-db Core Development Team.
-We have a policy around how pull requests are reviewed in a timely and fair manner. That policy is available here - [Community Code Review and Merge Policy for the exist-db/exist Git Repository](PR-CODE-REVIEW-POLICY.md).
+Pull requests will be reviewed and tested before they're merged.
Worth restating, is the one "golden rule", even within the Core Team, **no developer should merge their own pull request**. This simple-but-important rule ensures that at least two people have considered the change.
-Although the following are taken from our [Developer Manifesto](http://www.exist-db.org/exist/apps/doc/devguide_manifesto.xml "eXist Project Developer Manifesto") and [Code Review Guide](http://www.exist-db.org/exist/apps/doc/devguide_codereview.xml "eXist Project Code Review Guide"), the main things that get a pull request accepted are:
-
+Some things to keep in mind when trying to craft an acceptable Pull Request are:
+- **Atomic changes.** We prefer changes that have a single purpose to be grouped into their own individual commits. Each commit should have a single purpose.
- **Only change what you need to.** If you must reformat code, keep it in a separate commit to any syntax or functionality changes.
- **Test.** If you fix something prove it, write a test that illustrates the issue and validate the test. If you add a new feature it also requires tests, so that we can understand its intent and try to avoid regressions in future as much as possible.
-- **Make sure the appropriate licence header appears at the top of your source code file.** We use [LGPL v2.1](http://opensource.org/licenses/LGPL-2.1 "The GNU Lesser General Public License, version 2.1") for eXist-db and *strongly* encourage that, but ultimately any compatible [OSI approved license](http://opensource.org/licenses "Open Source Licenses") without further restrictions may be used.
-- **Run the full eXist test suite.** We don't accept code that causes regressions. This will also be checked in CI.
+- **Run the full test suite.** We don't accept code that causes regressions. This will also be checked in CI.
## Security Issues
***If you find a security vulnerability, do NOT open an issue.***
-
-Any security issues should be submitted directly to . In order to determine whether you are dealing with a security issue, ask yourself these two questions:
-
-* Can I access something that's not mine, or something I shouldn't have access to?
-* Can I disable something for other people?
-
-If the answer to either of those two questions are "yes", then you're probably dealing with a security issue. Note that even if you answer "no" to both questions, you may still be dealing with a security issue, so if you're unsure, just email us at .
+See the [Security Policy](SECURITY.md).
## Versions and Releases
-eXist follows a Semantic Versioning scheme, this is further documented in the [eXist Versioning Scheme and Release Process](exist-versioning-release.md) document.
+Elemental follows a Semantic Versioning scheme, this is further documented in the [Versioning Scheme and Release Process](VERSIONING_AND_RELEASING.md) document.
### Porting during Release Candidate development phase
When developing one or more stable release lines and/or a release-candidate in parallel, this may require commits to be both back- and forward-ported until the release-candidate has become the next stable release.
-In these circumstances pull request(s) for the same purpose may be opened multiple times against different `develop`* branches.
+In these circumstances pull request(s) for the same purpose may be opened multiple times against different `develop-`* branches.
#### Backport
-Assuming the stable is `6.x.x` and the RC is `7.x.x`
-- create a second branch `6.x.x/feature/` based off `develop-6.x.x`
-- [`cherry-pick`](https://git-scm.com/docs/git-cherry-pick) your commits from `feature/` into `6.x.x/feature/`
-- open a second PR from `6.x.x/feature/` against `develop-6.x.x` mentioning the original PR in the commit message
+Assuming the stable is `6.x.x` and the RC is `7.x.x`:
+1. Create a second branch `6.x.x/feature/` based off of our `develop-6.x.x` branch
+2. [Cherry Pick](https://git-scm.com/docs/git-cherry-pick) your commits from `feature/` into `6.x.x/feature/`
+3. Open a second PR from `6.x.x/feature/` against `develop-6.x.x` mentioning the original PR in the commit message
### Forward-port
-Works just as backport but with `feature/` and `develop`
-
+Works just as backport but with your `feature/` branch based off of our `main` branch
## Syncing a Fork
-Your fork will eventually become out of sync with the upstream repo as others contribute to eXist. To pull upstream changes into your fork, you have two options:
+Your fork will eventually become out of sync with the upstream repo as others contribute. To pull upstream changes into your fork, you have two options:
1. [Merging](https://help.github.com/articles/syncing-a-fork).
2. Rebasing.
Rebasing leads to a cleaner revision history which is much easier to follow and is our preferred approach. However, `git rebase` is a very sharp tool and must be used with care. For those new to rebase, we would suggest having a backup of your local (and possibly remote) git repos before continuing. Read on to learn how to sync using rebase.
-
#### Rebase Example
-Lets say that you have a fork of eXist-db's GitHub repo, and you have been working in your feature branch called `feature/my-feature` for some time, you are happy with how your work is progressing, but you want to sync so that your changes are based on the latest and greatest changes from eXist-db. The way to do this using `git rebase` is as follows:
+Let's say that you have a fork of Elemental's Git repo, and you have been working in your feature branch called `feature/my-feature` for some time, you are happy with how your work is progressing, but you want to sync so that your changes are based on the latest and greatest changes from Elemental. The way to do this using `git rebase` is as follows:
1. If you have any un-committed changes you need to stash them using: `git stash save "changes before rebase"`.
-2. If you have not added eXist-db's GitHub as an upstream remote, you need to do so once by running `git remote add upstream https://github.com/exist-db/exist.git`. You can view your existing remotes, by running `git remote -v`.
+2. If you have not added Elemental's GitHub as an upstream remote, you need to do so once by running `git remote add upstream https://github.com/evolvedbinary/elemental.git`. You can view your existing remotes, by running `git remote -v`.
-3. You need to fetch the latest changes from eXist-db's GitHub: `git fetch upstream`. This will not yet change your local branches in any way.
+3. You need to fetch the latest changes from Elemental's GitHub: `git fetch upstream`. This will not yet change your local branches in any way.
-4. You should first sync your `develop` branch with eXist-db's `develop` branch. As you always work in feature branches, this should a simple fast-forward by running: `git checkout develop` and then `git rebase upstream/develop`.
- 1. If all goes well in (4) then you can push your `develop` branch to your remote server (e.g. GitHub) with `git push origin develop`.
+4. You should first sync your `main` branch with Elemental's `main` branch. As you always work in feature branches, this should a simple fast-forward by running: `git checkout main` and then `git rebase upstream/main`.
+ 1. If all goes well in (4) then you can push your `main` branch to your remote server (e.g. GitHub) with `git push origin main`.
-5. You can then replay your work in your feature branch `feature/my-feature` atop the lastest changes from the `develop` branch by running: `git checkout feature/my-feature` and then `git rebase develop`.
+5. You can then replay your work in your feature branch `feature/my-feature` atop the latest changes from the `main` branch by running: `git checkout feature/my-feature` and then `git rebase main`.
1. Should you encounter any conflicts during (5) you can resolve them using `git mergetool` and then `git rebase --continue`.
2. If all goes well in (5), and take care to check your history is correct with `git log`, then you can force push your `feature/my-feature` branch to your remote server (e.g. GitHub) with `git push -f origin feature/my-feature`. *NOTE* the reason you need to use the `-f` to force the push is because the commit ids of your revisions will have changed after the rebase.
-Note that it is worth syncing your branches that you are working on relatively frequently to prevent any large rebases which could lead to resolving many conflicting changes where your branch has diverged over a long period of time.
-
-## Tools
-Some developers may find that GitFlow tools can help them follow the above branching model. One such tool which may help is the [AVH Edition of GitFlow tools](https://github.com/petervanderdoes/gitflow).
-
-If you're not familiar with GitFlow, check out some of the good tutorials linked in ["Getting Started"](https://github.com/petervanderdoes/gitflow#getting-started) of the GitFlow AVH Edition page. There's also a very good [git-flow cheatsheet](http://danielkummer.github.io/git-flow-cheatsheet/).
-
-If you wish to contribute, the general approach using GitFlow AVH Edition is:
-
-- Fork the repo on GitHub
-- `git clone` your fork
-- Make sure you've [GitFlow AVH Edition](https://github.com/petervanderdoes/gitflow) installed
-- Run `git flow init` on the cloned repo using [these settings](#our-git-flow-init-settings).
-- Use Git Flow to *start* a hotfix or feature i.e. `git flow feature start my-feature`.
-- Do your stuff! :-)
-- Commit to your repo. We like small, atomic commits that don't mix concerns.
-- **Do NOT** finish the `hotfix` or `feature` with GitFlow.
-- Make sure your branch is based on the latest eXist develop branch before making a pull request. This will ensure that we can easily merge in your changes. See [Syncing a Fork](#syncing-a-fork).
-- Push your hotfix or feature branch to your GitHub using GitFlow: `git flow feature publish my-feature`.
-- Send us a pull request on GitHub from your branch to our develop branch.
-- Once the pull request is merged you can delete your branch, you need not finish or merge it, you will however want to sync your develop branch to bring back your changes. See [Syncing a Fork](#syncing-a-fork).
-
-### Our `git-flow init` settings
-When we started working with the eXist repo we needed to configure it for GitFlow:
-
-```bash
-$ git flow init
-
-Which branch should be used for bringing forth production releases?
- - master
-Branch name for production releases: [master]
-Branch name for "next release" development: [develop]
-
-How to name your supporting branch prefixes?
-Feature branches? [feature/]
-Release branches? [release/]
-Hotfix branches? [hotfix/]
-Support branches? [support/]
-Version tag prefix? [] eXist-
-Hooks and filters directory? [.git/hooks]
-```
-
-A new `develop` branch is created, and checked out.
-
-Verify it like this:
-
-```bash
-$ git status
-# On branch develop
-```
-
-As we have already started with GitFlow, when you run `git flow init`, you'll get slightly different prompts--but the same answers apply!
-
-You **must** use the following settings:
-
-```bash
-$ git flow init
-
-Which branch should be used for bringing forth production releases?
- - develop
-Branch name for production releases: [] master
-
-Which branch should be used for integration of the "next release"?
- - develop
-Branch name for "next release" development: [develop]
-
-How to name your supporting branch prefixes?
-Feature branches? [feature/]
-Release branches? [release/]
-Hotfix branches? [hotfix/]
-Support branches? [support/]
-Version tag prefix? [] eXist-
-Hooks and filters directory? [.git/hooks]
-```
+Note that it is worth syncing your branches that you are working on relatively frequently to prevent any large rebase processes which could lead to you having to resolve many conflicting changes where your branch has diverged over a long period of time.
diff --git a/LICENSE b/LICENSE
index 4f1852ffe8..4f1fb49bc1 100644
--- a/LICENSE
+++ b/LICENSE
@@ -55,7 +55,7 @@ modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
-
+
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
@@ -111,7 +111,7 @@ modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
-
+
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@@ -158,7 +158,7 @@ Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
-
+
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
@@ -216,7 +216,7 @@ instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
-
+
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
@@ -267,7 +267,7 @@ Library will still fall under Section 6.)
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
-
+
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
@@ -329,7 +329,7 @@ restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
-
+
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
@@ -370,7 +370,7 @@ subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
-
+
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
@@ -422,7 +422,7 @@ conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
-
+
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
diff --git a/PR-CODE-REVIEW-POLICY.md b/PR-CODE-REVIEW-POLICY.md
deleted file mode 100644
index 5ab7f51cf6..0000000000
--- a/PR-CODE-REVIEW-POLICY.md
+++ /dev/null
@@ -1,54 +0,0 @@
-# Community Code Review and Merge Policy for the [exist-db/exist](https://github.com/exist-db/exist) Git Repository
-
-**Version:** 2.0.0 (2022-08-01)
-
-**NOTE:** This policy is ONLY concerned with the [exist-db/exist](https://github.com/exist-db/exist) Git repository. Other repositories of the eXist-db project are free to adopt and/or adapt it, but there is no obligation to do so.
-
-## Policy
-
-1. As an Open Source project, there is no obligation on the part of the eXist-db project that any PR (Pull Request) will be accepted and merged into the code-base. Best efforts will be made to Review and Merge contributions inline with the policy set out within this document.
-
-2. Members of the community other than the Author or Reviewer(s) are explicitly encouraged to contribute to the review process by testing and commenting on the PR. Concerns raised in such comments must not be disregarded by the Reviewer(s) but should be answered appropriately and considered in the decision.
-
-3. An Author of a PR (Pull Request) *must* **never** Merge their own PRs.
-
-4. A PR *must* always have at least 1 review from a Reviewer who is a [Core Team](#existdb-core-team) member of the [exist-db/exist](https://github.com/exist-db/exist) repository.
- 1. Any such [Core Team](#existdb-core-team) member who volunteers to act as a Reviewer on a particular PR *must* be prepared to see it through to completion (i.e. Merged), unless they otherwise indicate within the Review Comments that they have resigned as Reviewer of a particular PR.
- 2. If there is only a single Reviewer from the [Core Team](#existdb-core-team), and they resign from the review of a particular PR, a new Reviewer from the [Core Team](#existdb-core-team) *must* be sought by the Author.
-
-5. A PR *should* have at least 2 reviewers.
- 1. If after 5 days (Mon-Fri days) there is no second review, then review from one Reviewer will suffice. This grace period allows time for any other interested party to also contribute a review and/or object to the PR.
-
-6. All PRs *must* be subjected to the same quality standards by the Reviewer.
- 1. The Reviewer *must* act in the interests of the eXist-db Open Source project and not any personal or private affiliations.
-
-7. The Review process is an iterative process entered into by the Author and Reviewer(s).
- 1. Firstly, if clarification is needed, the Author *must* enter into a discussion of the Review comments with the Reviewer(s).
- 2. Secondly, assuming agreement between the Author and Reviewer(s), the Author *must* take appropriate action to address the comments from the Review.
- 3. This process *should* be carried out publicly.
- 4. All decisions *must* be documented within the comments of the PR itself.
-
-8. Remediation process:
- 1. In case of
- 1. a disagreement between Author and Reviewer(s),
- 2. between Reviewers,
- 3. or if there has not been within 14 days a reaction
- 1. by the author to a blocking review, or
- 2. no response by a blocking core developer to a response by the author
- the PR is considered stale. A stale PR *must* be discussed in an upcoming community call where both Author(s) and blocking Reviewer(s) *must* be present.
- 2. Should there not be a solution in said call or no call where Author(s) and Reviewer(s) can both be present, a mediator *must* be chosen from a community call. This mediator is announced via Slack and the PR comments. The person chosen will collect feedback by all parties involved, try to find a solution and report back to the community call and other communication channels.
- 3. Should the remediation process fail, a vote between the [Core Team](#existdb-core-team) members of the exist-db/exist repository *should* be solicited for a majority result. Any [Core Team](#existdb-core-team) member voting against the PR *must* provide feedback for the reason to the Author; thus allowing the Author to further consider revising their PR.
-
-
-## Core Team members of the [exist-db/exist](https://github.com/exist-db/exist) Git repository
-
-These members have been chosen based on their past contributions to the [exist-db/exist](https://github.com/exist-db/exist) repository and experience. They have been identified as having the necessary skills to review code submitted for inclusion in the [exist-db/exist](https://github.com/exist-db/exist) Git repository (i.e. they are experienced Java Developers with a track record of improving eXist-db).
-
-1. [Juri Leino](https://github.com/line-o)
-2. [Wolfgang Meier](https://github.com/wolfgangmm)
-3. [Leif-Joran Olsson](https://github.com/ljo)
-4. [Patrick Reinhart](https://github.com/reinhapa)
-5. [Adam Retter](https://github.com/adamretter)
-6. [Dannes Wessels](https://github.com/dizzzz)
-
-This list should be considered current, that is to say that it is not static. Any contributor to eXist-db who demonstrated ability and longevity may apply to join the Core Team. Appointment to the Core Team is approved by a majority vote of the existing Core Team members.
diff --git a/README.md b/README.md
index 4d9c4ad1cb..06db5df4b7 100644
--- a/README.md
+++ b/README.md
@@ -1,54 +1,59 @@
-## eXist-db Native XML Database
+## Elemental - Native XML Database
-[](https://github.com/eXist-db/exist/actions/workflows/ci-build.yml)
-[](https://coveralls.io/github/eXist-db/exist?branch=develop)
-[](https://www.codacy.com/gh/eXist-db/exist/dashboard?utm_source=github.com&utm_medium=referral&utm_content=eXist-db/exist&utm_campaign=Badge_Grade)
-[](https://sonarcloud.io/summary/new_code?id=eXist-db_exist)
-[](https://adoptopenjdk.net/)
+[](https://dl.circleci.com/status-badge/redirect/gh/evolvedbinary/elemental/tree/main)
+[](https://coveralls.io/github/evolvedbinary/elemental?branch=main)
+[](https://app.codacy.com/gh/evolvedbinary/elemental/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
+[](https://sonarcloud.io/summary/new_code?id=evolvedbinary_elemental)
+[](https://adoptopenjdk.net/)
[](https://www.gnu.org/licenses/lgpl-2.1.html)
-[](https://github.com/eXist-db/exist/releases/)
-[](https://search.maven.org/search?q=g:org.exist-db)
-[](https://exist-db.slack.com)
-
-
-
+[](https://github.com/evolvedbinary/elemental/releases/)
+[](https://central.sonatype.com/search?namespace=xyz.elemental)
+[](https://formulae.brew.sh/cask/elemental)
+[](https://hub.docker.com/r/evolvedbinary/elemental)
+[](https://join.slack.com/t/elemental-xyz/shared_invite/zt-34r53san4-fzHCV0vDT9lYSMChUdn3cQ)
+[](https://www.contributor-covenant.org/version/2/1/code_of_conduct.html)
-[](https://contributor-covenant.org/version/1/4/)
+---
+**NOTE**: Elemental was seeded from a fork of eXist-db's git `develop` branch, commit: `adaa276b9cfcaaeb4ee03ee3822ab882e6779f77` (Fri Oct 25 21:27:35 2024 +0200). The Git history was then rewritten to remove many historic files that we no longer need. This resulted in our commit: [`e065a83bf4dc94abfeebcc353cbfbd496976f440`](https://github.com/evolvedbinary/elemental/commit/e065a83bf4dc94abfeebcc353cbfbd496976f440).
-eXist-db is a high-performance open source native XML database—a NoSQL document database and application platform built entirely around XML technologies. The main homepage for eXist-db can be found at [exist-db.org](https://exist-db.org "eXist Homepage"). This is the GitHub repository of eXist source code, and this page links to resources for downloading, building, and contributing to eXist-db, below.
+---
-The eXist-db community has adopted the [Contributor Covenant](https://www.contributor-covenant.org/) [Code of Conduct](https://www.contributor-covenant.org/version/1/4/code-of-conduct).
+Elemental is a high-performance open source native XML database—a NoSQL document database and application platform built entirely around XML technologies. The main homepage for Elemental can be found at [elemental.xyz](https://www.elemental.xyz "Elemental Website"). This is the GitHub repository of Elemental source code, and this page links to resources for downloading, building, and contributing to Elemental, below.
-## Open Community Calls
-We hold an open Community Call each week on Monday, from 19:30-20:30 CET. The meetings are posted to this [public Google Calendar](https://calendar.google.com/calendar/u/0?cid=OHVnNmtwcnFnNWNvNmRwZGZxc2FrY283MWtAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ).
+The Elemental community has adopted the [Contributor Covenant](https://www.contributor-covenant.org/) [Code of Conduct](https://www.contributor-covenant.org/version/2/1/code_of_conduct/).
-If you wish to participate, please join the #community channel on our Slack workspace (invitation link below). Pinned to that channel is a link to the upcoming meeting's agenda, which contains the link to the call, as well as a link to timeanddate.com to look up the time of the meeting for your local time zone.
+## Help and Support
-The notes of past Community Calls are located [here](https://drive.google.com/drive/folders/0B4NLNdpw86LPc2JsV294NDFfTjQ?resourcekey=0-NQPHfHbtiDuZULNDi06dbA&usp=sharing).
+The best place to seek help or support is in our public [Slack](https://join.slack.com/t/elemental-xyz/shared_invite/zt-3290ginoh-lWocaoR3UMw7jghfrt~kFA) channel, or on our [Mailing List](https://groups.google.com/u/1/a/elemental.xyz/g/users).
## Resources
-- **Homepage:** [https://exist-db.org](https://exist-db.org)
-- **Binaries:** [https://exist-db.org/exist/apps/homepage/index.html#download](https://exist-db.org/exist/apps/homepage/index.html#download)
-- **Documentation:** [https://exist-db.org/exist/apps/doc](https://exist-db.org/exist/apps/doc)
+- **Homepage:** [https://www.elemental.xyz](https://www.elemental.xyz)
+- **Binaries:** [https://www.elemental.xyz/downloads](https://www.elemental.xyz/downloads)
+- **Homebrew:** [https://formulae.brew.sh/cask/elemental](https://formulae.brew.sh/cask/elemental)
+- **Docker Images:** [https://hub.docker.com/r/evolvedbinary/elemental](https://hub.docker.com/r/evolvedbinary/elemental)
+- **Documentation:** [https://www.elemental.xyz/documentation](https://www.elemental.xyz/documentation)
- **Book:** [https://www.oreilly.com/library/view/exist/9781449337094/](https://www.oreilly.com/library/view/exist/9781449337094/)
- **Packages:** [https://exist-db.org/exist/apps/public-repo](https://exist-db.org/exist/apps/public-repo)
-- **Source code:** [https://github.com/eXist-db/exist](https://github.com/eXist-db/exist)
-- **Git clone URL:** `git://github.com/eXist-db/exist.git`
-- **Mailing list:** [https://lists.sourceforge.net/lists/listinfo/exist-open](https://lists.sourceforge.net/lists/listinfo/exist-open)
-- **Slack:** [https://exist-db.slack.com](https://join.slack.com/t/exist-db/shared_invite/enQtNjQ4MzUyNTE4MDY3LWNkYjZjMmZkNWQ5MDBjODQ3OTljNjMyODkwNmY1MzQwNjUwZjMzZTY1MGJkMjY5NDFhOWZjMDZiMDdhMzY4NGY)
+- **Source code:** [https://github.com/evolvedbinary/elemental](https://github.com/evolvedbinary/elemental)
+- **Git clone URL:** `git://github.com/evolvedbinary/elemental.git`
+- **Mailing list:** [https://groups.google.com/u/1/a/elemental.xyz/g/users](https://groups.google.com/u/1/a/elemental.xyz/g/users)
+- **LinkedIn:** [https://www.linkedin.com/groups/10070373/](https://www.linkedin.com/groups/10070373/)
+- **Slack:** [https://elemental-xyz.slack.com](https://join.slack.com/t/elemental-xyz/shared_invite/zt-34r53san4-fzHCV0vDT9lYSMChUdn3cQ)
-New developers may find the notes in [BUILD.md](https://github.com/eXist-db/exist/blob/develop/BUILD.md) and [CONTRIBUTING.md](https://github.com/eXist-db/exist/blob/develop/CONTRIBUTING.md) helpful to start using and sharing your work with the eXist community.
+
+
+New developers may find the notes in [BUILD.md](https://github.com/evolvedbinary/elemental/blob/main/BUILD.md) and [CONTRIBUTING.md](https://github.com/evolvedbinary/elemental/blob/main/CONTRIBUTING.md) helpful to start using and sharing your work with the Elemental community.
## Credits
-The eXist-db developers use the YourKit Java Profiler.
+The Elemental developers use the YourKit Java Profiler.
@@ -56,7 +61,3 @@ YourKit kindly supports open source projects with its full-featured Java Profile
YourKit, LLC is the creator of YourKit Java Profiler
and YourKit .NET Profiler,
innovative and intelligent tools for profiling Java and .NET applications.
-
-
-
-Cross-browser Testing Platform and Open Source <3 Provided by [Sauce Labs](https://saucelabs.com)
diff --git a/RECOVERY.md b/RECOVERY.md
index 7b214c108b..ef3734b0df 100644
--- a/RECOVERY.md
+++ b/RECOVERY.md
@@ -21,9 +21,9 @@ for available command-line options.
To recover from a corrupted index, perform the following steps:
-1. Stop the running eXist database instance
-2. Change into directory `$EXIST_HOME/data` or another directory you specified
- as data directory in the configuration (`$EXIST_HOME/etc/conf.xml`).
+1. Stop the running Elemental database instance
+2. Change into directory `$ELEMENTAL_HOME/data` or another directory you specified
+ as data directory in the configuration (`$ELEMENTAL_HOME/etc/conf.xml`).
3. Delete
the following resources:
- All ".dbx" files EXCEPT blob.dbx, collections.dbx, dom.dbx, and symbols.dbx
@@ -31,7 +31,7 @@ To recover from a corrupted index, perform the following steps:
- All ".log" transaction log files
- The "lucene" and "range" directories
4. Trigger a reindex in order to reconstruct the secondary indexes, via the
- eXist-db XQuery function `xmldb:reindex("/db")`. This can be executed directly
+ XQuery function `xmldb:reindex("/db")`. This can be executed directly
via the Java admin client, or, alternatively, on the command line via the
following command:
@@ -49,7 +49,7 @@ e.g., for supplying a username and password.
To completely wipe a database—for example, in order to restore a backup onto
a clean database—perform the following steps:
-1. Stop the running eXist database instance
+1. Stop the running Elemental database instance
2. Delete all files and directories from the "data" directory
> Note that restoring from a backup (or parts of it) does not automatically
diff --git a/SECURITY.md b/SECURITY.md
index 69b7768888..e0d0e61049 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -1,19 +1,10 @@
# Security Policy
-## Supported Versions
-
-eXist-db provides security patches for the following versions:
-
-| Version | Supported |
-| ------- | ------------------ |
-| < 4.7.0 | :white_check_mark: |
-| < 4.0 | :x: |
-
## Reporting a Vulnerability
***If you find a security vulnerability, do NOT open an issue.***
-Any security issues should be submitted directly to .
+Any security issues should be submitted directly to .
In order to determine whether you are dealing with a security issue, ask yourself these two questions:
* Can I access something that's not mine, or something I shouldn't have access to?
@@ -21,6 +12,6 @@ In order to determine whether you are dealing with a security issue, ask yoursel
If the answer to either of those two questions are "yes", then you're probably dealing with a security issue.
Note that even if you answer "no" to both questions, you may still be dealing with a security issue,
-so if you're unsure, just email us at .
+so if you're unsure, just email us at .
You can generally expect a response from the core developers within 48h.
diff --git a/VERSIONING_AND_RELEASING.md b/VERSIONING_AND_RELEASING.md
new file mode 100644
index 0000000000..767b76e57d
--- /dev/null
+++ b/VERSIONING_AND_RELEASING.md
@@ -0,0 +1,243 @@
+# Elemental Versioning Scheme and Release Process
+
+
+
+## Overview
+This document describes the Versioning Scheme and Release Process for Elemental. These two topics are tightly connected, and so both are covered in this one document.
+
+* The Versioning Scheme describes how the source code and releases are named. Version numbers unambiguously inform users and developers about the significance of the release and order relative to past and future versions.
+
+* The Release Process describes how the Release Manager (the person who orchestrates a release) should take a `snapshot (tag)` of source code, apply the Versioning Scheme, assemble it, and publish the resulting products. The goal is to have a clear procedure for altering the version number to mark transitions in phases of development leading up to each release, and to ensure that releases are consistently sourced from a specific point in the project repository's history.
+
+### Motivation
+
+This approach was chosen to try and facilitate more rapid releases, with the goal of getting new features and bug fixes out to the community without sacrificing quality or stability. Critical to the success of this effort is achieving a common understanding about version numbers and managing version changes during releases.
+The versioning scheme uses the popular Semantic Versioning scheme, in which each number here reflects major, minor, and patch versions. This single version-related property will bring clarity and semantic precision to releases. The Semantic Versioning scheme allows the team to label development versions as snapshots or release candidates, and to release these and nightly builds with clear version numbers.
+The new versioning scheme ensures the names of new versions of delivered to the community are precise and reliable. Removing versioning ambiguities and clarifying release practices facilitates a rapid cycle of development and release.
+
+## Versioning Scheme
+
+We follow a widely-used, semantically precise versioning scheme called [Semantic Versioning](http://semver.org/) (specifically [version 2.0.0](https://github.com/mojombo/semver/tree/v2.0.0)) of this scheme. For a complete introduction to Semantic Versioning, please consult the documentation. Here, we summarize how the principles of Semantic Versioning are applied.
+
+### Product Releases
+
+For product releases (also called stable or final releases), a 3-component Semantic Versioning version number is used: "`MAJOR`**.**`MINOR`**.**`PATCH`". When a new version is released, its version number is incremented according to the following criteria:
+
+1. `MAJOR` versions contain incompatible API changes, including changes to the on-disk format of the database;
+2. `MINOR` versions add functionality or deprecate API functions, without breaking backward compatibility; and
+3. `PATCH` versions contain only backwards-compatible bug fixes.
+
+(Any public or protected methods of public or protected classes are considered API)
+
+For example, the 8th major version of Elemental would have the Semantic Version number `8.0.0`. A new release following this including new features would be version `8.1.0`. A bugfix-only release following that would be version `8.1.1`.
+
+### Pre-Releases
+
+For pre-releases, such as [release candidates](https://en.wikipedia.org/wiki/Software_release_life_cycle#Release_candidate) or [snapshots](https://docs.oracle.com/middleware/1212/core/MAVEN/maven_version.htm#MAVEN401), a 4-component Semantic Versioning version number is used: "`MAJOR`**.**`MINOR`**.**`PATCH`**-**`PRERELEASE`. We follow Semantic Versioning's definitions for the `PRERELEASE` label scheme:
+
+* `PRERELEASE` is a series of dot separated identifiers, each identifier must use only the following ASCII characters `[0-9A-Za-z-]` and must not be empty.
+
+* The presence of `PRERELEASE` indicates that the version is pre-release and not yet considered stable. Product releases do not have `PRERELEASE`.
+
+* Given two versions in which `MAJOR`, `MINOR`, and `PATCH` are equal, the version with a `PRERELEASE` has lower precedence than one without it. The following rules hold true in terms of version number preference:
+
+ * `8.0.0` > `8.0.0-SNAPSHOT`
+ * `8.0.0` > `8.0.0-RC2`
+ * `8.0.0-RC2` > `8.0.0-RC1`
+ * `8.0.0-RC1` > `7.1.0`
+ * `8.0.0-SNAPSHOT` > `7.1.0`
+ * `7.6.0-SNAPSHOT` > `7.1.0`
+
+We use only two clearly defined forms of `PRERELEASE` label:
+
+* `RCx` is used for release candidates. The `x` should be replaced with the iteration of the release candidate, for example `8.0.0-RC1` for the first release candidate of version 8, and `8.0.0-RC2` for the second release candidate of version 8. While not all releases are necessarily preceded by a release candidate (which are feature complete and considered ready for release), we may opt to issue one or more release candidates in order to gather feedback from testing by early adopters.
+
+* `SNAPSHOT` is used for point-in-time builds. These products are typically not published or distributed, but used only for local testing by developers or by the nightly-build system.
+
+### Nightly Builds
+
+A nightly build is similar to a snapshot, except it is automatically built from the latest source code and released once daily. To help distinguish between one day's nightly build and the next's, a 5-component Semantic Versioning version number is used for nightly builds' filenames: "`MAJOR`**.**`MINOR`**.**`PATCH`**-**`PRERELEASE`**+**`BUILD`. We follow Semantic Versioning's definitions for the `BUILD` label scheme:
+
+* `BUILD` is a series of dot separated identifiers, each identifier must use only ASCII alphanumerics and hyphen [0-9A-Za-z-] and must be empty. Build metadata SHOULD be ignored when determining version precedence.
+
+* The presence of `BUILD` indicates that the version is pre-release and not yet considered stable. Product releases do not have `BUILD`.
+
+We add a further constraint and modify the precedence for the `BUILD` label:
+
+* The `BUILD` label is a UTC timezone timestamp, in the format `YYYYMMDDHHmmSS` (as would be given by the UNIX command `date +%Y%m%d%H%M%S`).
+
+* The precedence of the `BUILD` label, may be numerically compared by timestamp, e.g. `20240527142409 > 20240504000001`.
+
+For example, the macOS disk image for the build from the SNAPSHOT pre-release version of 8.0.0 on May 7, 2024 at 21:37:22 UTC would be named:
+
+ * elemental-8.0.0-SNAPSHOT+20240507213722.dmg
+
+It is trivial for a developer to relate a timestamp back to a Git hash (by using the command `git rev-list -1 --before="$DATE" main`), should they need to do so.
+
+### Where the version number is stored
+
+The version number is stored in the `exist-parent/pom.xml` file, in a single property, ``. The Semantic Versioning number `8.0.0-SNAPSHOT` would be stored as follows:
+```xml
+8.0.0-SNAPSHOT
+```
+
+That version number is also copied into the `META-INF/MANIFEST.MF` file of any Jar packages that are built, using the standard manifest attributes: `Specification-Version` and `Implementation-Version`.
+
+## Release Process
+
+This section details concrete steps for creating and publishing product releases. Each section here assumes you are starting with a clean Git checkout of the `main` branch from [https://github.com/evolvedbinary/elemental.git](https://github.com/evolvedbinary/elemental.git).
+
+### Preparing a Product Release
+
+Once development on a new stable version is complete, the following steps will prepare the version for release. For purposes of illustration, we will assume we are preparing the stable release of version 7.6.0.
+You will require a system with:
+* macOS
+* JDK 8
+* Maven 3.6.0+
+* Python 3 with Pip
+* Docker
+* GnuPG
+* A GPG key (for signing release artifacts)
+* A Java KeyStore with key (for signing IzPack Installer)
+* A valid Apple Developer Certificate (for signing Mac DMG)
+* A GitHub account and Personal Access Token (https://github.com/settings/tokens) with permission to publish GitHub releases to the Elemental repository.
+
+1. You will need login credentials for the Elemental organisation on:
+ 1. Sonatype Portal for Maven Central - https://central.sonatype.com/publishing/deployments
+ 2. DockerHub - https://cloud.docker.com/orgs/elemental/
+
+ Your credentials for these should be stored securely in the `` section on your machine in your local `~/.m2/settings.xml` file, e.g.:
+ ```xml
+
+
+
+
+
+
+ central-ossrh-staging
+ your-username
+ your-password
+
+
+
+
+ docker.io
+ your-username
+ your-password
+
+
+
+
+ github
+ your-github-personal-access-token
+
+
+
+ ```
+
+2. You will need your GPG Key, Java KeyStore, and Apple Notarization API credentials for signing the release artifacts in the ` section on your machine in your local `~/.m2/settings.xml` file, e.g.:
+ ```xml
+
+
+
+ elemental-release-signing
+
+ ABC1234
+ ${user.home}/.gnupg/pubring.gpg
+ ${user.home}/.gnupg/secring.gpg
+ your-password
+
+ ${user.home}/your.store
+ your-keystore-password
+ your-alias
+ your-key-password
+
+ your-apple-developer-email@your-dom.ain
+ your-apple-developer-team-id
+ your-apple-notarize-api-password
+
+ signature-of-your-apple-developer-certificate
+
+
+
+
+
+
+
+
+ elemental-release-signing
+
+
+ ```
+
+3. Merge any outstanding PRs that have been reviewed and accepted for the milestone (e.g. `elemental-7.6.0`).
+
+4. Make sure that you have the HEAD of `origin/main` (or `upstream` if you are on a fork).
+
+5. Prepare the release, if you wish you can do a dry-run first by specifying `-DdryRun=true`:
+ ```bash
+ $ mvn -Ddocker=true -Dmac-signing=true -P installer -Dizpack-signing=true -Darguments="-Ddocker=true -Dmac-signing=true -P installer -Dizpack-signing=true" release:prepare
+ ```
+
+ Maven will start the release process and prompt you for any information that it requires, for example:
+
+ ```
+ [INFO] --- maven-release-plugin:2.1:prepare (default-cli) @ elemental ---
+ [INFO] Verifying that there are no local modifications...
+ [INFO] ignoring changes on: pom.xml.next, pom.xml.releaseBackup, pom.xml.tag, pom.xml.backup, pom.xml.branch, release.properties
+ [INFO] Executing: /bin/sh -c cd /Users/aretter/code/evolvedbinary/elemental.maven && git status
+ [INFO] Working directory: /Users/aretter/code/evolvedbinary/elemental.maven
+ [INFO] Checking dependencies and plugins for snapshots ...
+ What is the release version for "Elemental"? (xyz.elemental:elemental) 7.6.0: :
+ What is SCM release tag or label for "Elemental"? (xyz.elemental:elemental) elemental-7.6.0: :
+ What is the new development version for "Elemental"? (xyz.elemental:elemental) 7.7.0-SNAPSHOT: :
+ ```
+
+6. Once the prepare process completes you can perform the release. This will upload Maven Artifacts to Maven Central (staging), Docker images to Docker Hub, and Elemental distributions and installer to GitHub releases:
+ ```bash
+ $ mvn -Ddocker=true -Dmac-signing=true -P installer -Dizpack-signing=true -Djarsigner.skip=false -Darguments="-Ddocker=true -Dmac-signing=true -P installer -Dizpack-signing=true -Djarsigner.skip=false" release:perform
+ ```
+
+7. Update the stable branch (`gold`) of Elemental to reflect the latest release:
+ ```bash
+ $ git push origin elemental-7.6.0:gold
+ ```
+
+#### Publishing/Promoting the Product Release
+1. Check that the new versions are visible on [GitHub](https://github.com/evolvedbinary/elemental/releases).
+
+2. Check that the new versions are visible on [DockerHub](https://hub.docker.com/r/evolvedbinary/elemental).
+
+3. Login to https://central.sonatype.com/publishing/deployments and release the Maven artifacts to Maven central as described [here](https://central.sonatype.org/publish/publish-portal-guide/).
+
+4. Check that the HomeBrew for Elemental delivers the latest version, see: [Releasing to Homebrew](https://github.com/evolvedbinary/elemental/blob/main/VERSIONING_AND_RELEASING.md#releasing-to-homebrew).
+
+5. Visit the GitHub releases page [https://github.com/evolvedbinary/elemental/releases](https://github.com/evolvedbinary/elemental/releases) and create a new release, enter the tag you previously created and link the release notes from the blog.
+
+6. Send an email to the `Elemental` mailing list announcing the release with a title similar to `[ANN] Release of Elemental 7.6.0`, copy and paste the release notes from the blog into the email and reformat appropriately (see past emails).
+
+7. Tweet about it using the `elemental` Twitter account.
+
+8. Post it to the [LinkedIn Elemental group](https://www.linkedin.com/groups/10070373/)
+
+9. Post a message about the release to the Elemental #community Slack channel.
+
+10. Post a message about the release to the XML.com #general Slack channel.
+
+11. Submit a news item to XML.com - [https://www.xml.com/news/submit-news-item/](https://www.xml.com/news/submit-news-item/).
+
+12. Update the Wikipedia page with the new version details - [https://en.wikipedia.org/wiki/Elemental](https://en.wikipedia.org/wiki/Elemental).
+
+13. Go to GitHub and move all issues and PRs which are still open for the release milestone to the next release milestone. Close the release milestone.
+
+
+### Releasing to Homebrew
+[Homebrew](http://brew.sh) is a popular command-line package manager for macOS. Once Homebrew is installed, applications like Elemental can be installed via a simple command. Elemental's presence on Homebrew is found in the Caskroom project, as a "cask", at [https://github.com/Homebrew/homebrew-cask/blob/master/Casks/e/elemental.rb](https://github.com/Homebrew/homebrew-cask/blob/master/Casks/e/elemental.rb).
+
+**Terminology:** "Homebrew Cask" is the aspect of Homebrew that provides pre-built application binaries, whereas the original "Homebrew" project is reserved for applications that can be built from source. The macOS version of Elemental is released as an app bundle with GUI components, and therefore it is delivered as a Homebrew Cask.
+
+When there is a new release, Homebrew should automatically register the new release. This can be tested by running `brew install --cask elemental`.
+
+Should the new version not be available via Homebrew, full directions for this utility as well as procedures for more complex PRs can be found on [the Homebrew Cask CONTRIBUTING page](https://github.com/Homebrew/homebrew-cask/blob/master/CONTRIBUTING.md).
diff --git a/build.bat b/build.bat
new file mode 100644
index 0000000000..d050956a4d
--- /dev/null
+++ b/build.bat
@@ -0,0 +1,160 @@
+@REM
+@REM Elemental
+@REM Copyright (C) 2024, Evolved Binary Ltd
+@REM
+@REM admin@evolvedbinary.com
+@REM https://www.evolvedbinary.com | https://www.elemental.xyz
+@REM
+@REM This library is free software; you can redistribute it and/or
+@REM modify it under the terms of the GNU Lesser General Public
+@REM License as published by the Free Software Foundation; version 2.1.
+@REM
+@REM This library is distributed in the hope that it will be useful,
+@REM but WITHOUT ANY WARRANTY; without even the implied warranty of
+@REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+@REM Lesser General Public License for more details.
+@REM
+@REM You should have received a copy of the GNU Lesser General Public
+@REM License along with this library; if not, write to the Free Software
+@REM Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+@REM
+
+@REM
+@REM Simple build Script for Elemental that tries to make it easier to build a few of the usual targets
+@REM Author: Adam Retter
+@REM
+
+@echo off
+setlocal enabledelayedexpansion
+
+set "TARGET=useage"
+set "DEBUG=false"
+set "OFFLINE=false"
+set "CONCURRENCY=-T2C"
+
+:: Process arguments
+:parse_args
+if "%~1"=="" goto done_parsing
+
+if /I "%~1"=="--debug" (
+ set "DEBUG=true"
+) else if /I "%~1"=="--offline" (
+ set "OFFLINE=true"
+) else if /I "%~1"=="--help" (
+ set "TARGET=useage"
+) else if /I "%~1"=="-h" (
+ set "TARGET=useage"
+) else if /I "%~1"=="clean" (
+ set "TARGET=clean"
+) else if /I "%~1"=="quick" (
+ set "TARGET=quick"
+) else if /I "%~1"=="quick-archives" (
+ set "TARGET=quick-archives"
+) else if /I "%~1"=="quick-docker" (
+ set "TARGET=quick-docker"
+) else if /I "%~1"=="quick-archives-docker" (
+ set "TARGET=quick-archives-docker"
+) else if /I "%~1"=="quick-install" (
+ set "TARGET=quick-install"
+) else if /I "%~1"=="test" (
+ set "TARGET=test"
+) else if /I "%~1"=="site" (
+ set "TARGET=site"
+) else if /I "%~1"=="license-check" (
+ set "TARGET=license-check"
+) else if /I "%~1"=="license-format" (
+ set "TARGET=license-format"
+) else if /I "%~1"=="dependency-check" (
+ set "TARGET=dependency-check"
+) else if /I "%~1"=="dependency-security-check" (
+ set "TARGET=dependency-security-check"
+) else if /I "%~1"=="format-poms" (
+ set "TARGET=format-poms"
+)
+shift
+goto parse_args
+
+:done_parsing
+
+if "%DEBUG%"=="true" (
+ set "BASE_CMD=%BASE_CMD% --debug"
+)
+
+if "%OFFLINE%"=="true" (
+ set "BASE_CMD=%BASE_CMD% --offline"
+)
+
+if "%TARGET%"=="useage" (
+ goto show_useage
+)
+
+:: Determine script directory
+set "SCRIPT_DIR=%~dp0"
+set "BASE_CMD=%SCRIPT_DIR%\mvnw.cmd -V"
+
+:: Set CMD based on TARGET
+if "%TARGET%"=="clean" (
+ set "CMD=%BASE_CMD% %CONCURRENCY% clean -Pinstaller,docker,concurrency-stress-tests,micro-benchmarks"
+) else if "%TARGET%"=="quick" (
+ set "CMD=%BASE_CMD% %CONCURRENCY% clean package -DskipTests -Ddependency-check.skip=true -Dappbundler.skip=true -Ddocker=false -P !mac-dmg-on-mac,!codesign-mac-app,!codesign-mac-dmg,!mac-dmg-on-unix,!installer,!concurrency-stress-tests,!micro-benchmarks,skip-build-dist-archives"
+) else if "%TARGET%"=="quick-archives" (
+ set "CMD=%BASE_CMD% %CONCURRENCY% clean package -DskipTests -Ddependency-check.skip=true -Ddocker=false -P installer,!concurrency-stress-tests,!micro-benchmarks"
+) else if "%TARGET%"=="quick-docker" (
+ set "CMD=%BASE_CMD% %CONCURRENCY% clean package -DskipTests -Ddependency-check.skip=true -Dappbundler.skip=true -Ddocker=true -P docker,!mac-dmg-on-mac,!codesign-mac-app,!codesign-mac-dmg,!mac-dmg-on-unix,!installer,!concurrency-stress-tests,!micro-benchmarks,skip-build-dist-archives"
+) else if "%TARGET%"=="quick-archives-docker" (
+ set "CMD=%BASE_CMD% %CONCURRENCY% clean package -DskipTests -Ddependency-check.skip=true -Ddocker=true -P installer,-P docker,!concurrency-stress-tests,!micro-benchmarks"
+) else if "%TARGET%"=="quick-install" (
+ set "CMD=%BASE_CMD% %CONCURRENCY% clean install package -DskipTests -Ddependency-check.skip=true -Dappbundler.skip=true -Ddocker=false -P !mac-dmg-on-mac,!codesign-mac-app,!codesign-mac-dmg,!mac-dmg-on-unix,!installer,!concurrency-stress-tests,!micro-benchmarks,skip-build-dist-archives"
+) else if "%TARGET%"=="test" (
+ set "CMD=%BASE_CMD% clean test -Ddependency-check.skip=true"
+) else if "%TARGET%"=="site" (
+ set "CMD=%BASE_CMD% clean verify site -Ddependency-check.skip=true"
+) else if "%TARGET%"=="license-check" (
+ set "CMD=%BASE_CMD% license:check"
+) else if "%TARGET%"=="license-format" (
+ set "CMD=%BASE_CMD% license:format"
+) else if "%TARGET%"=="dependency-check" (
+ set "CMD=%BASE_CMD% dependency:analyze"
+) else if "%TARGET%"=="dependency-security-check" (
+ set "CMD=%BASE_CMD% dependency-check:check"
+) else if "%TARGET%"=="format-poms" (
+ set "SAXON=%USERPROFILE%\.m2\repository\net\sf\saxon\Saxon-HE\9.9.1-8\Saxon-HE-9.9.1-8.jar"
+ for /r %%POM in (pom.xml) do (
+ echo | set /p dummyName="Formatting %%POM ..."
+ java -jar "%SAXON%" -s:%%POM -xsl:format-pom.xslt -o:%%POM
+ echo OK
+
+ echo | set /p dummyName="Checking for duplicate license entries in %%POM ... "
+ java -cp "%SAXON%" net.sf.saxon.Query -q:check-pom-license-uniqueness.xq pom-file-uri=file:%%POM
+ echo OK
+ )
+ goto end
+) else (
+ echo Invalid target: %TARGET%
+ goto show_useage
+)
+
+:: Execute the command
+call %CMD%
+goto end
+
+:show_useage
+echo.
+echo Usage: build.bat [--debug] [--offline] ^ ^| --help
+echo.
+echo Available build targets:
+echo clean - Remove all built artifacts
+echo quick - Build distribution directory
+echo quick-archives - Build and archive distribution
+echo quick-docker - Build distribution + Docker image
+echo quick-archives-docker - All of the above
+echo quick-install - Installs Maven artifacts locally
+echo test - Run test suite
+echo site - Run tests and generate Maven site
+echo license-check - Check license headers
+echo license-format - Add missing license headers
+echo dependency-check - Analyze dependencies
+echo dependency-security-check - Check for known CVEs
+
+:end
+endlocal
diff --git a/build.sh b/build.sh
new file mode 100755
index 0000000000..37673a114d
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,194 @@
+#!/usr/bin/env bash
+#
+# Elemental
+# Copyright (C) 2024, Evolved Binary Ltd
+#
+# admin@evolvedbinary.com
+# https://www.evolvedbinary.com | https://www.elemental.xyz
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; version 2.1.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+##
+# Simple build Script for Elemental that tries to make it easier to build a few of the usual targets
+# Author: Adam Retter
+##
+
+set -e
+
+TARGET="useage"
+DEBUG=false
+OFFLINE=false
+CONCURRENCY="-T2C"
+
+POSITIONAL=()
+while [[ $# -gt 0 ]]
+do
+key="$1"
+
+case $key in
+ clean|quick|quick-archives|quick-docker|quick-archives-docker|quick-install|test|site|license-check|license-format|dependency-check|dependency-security-check|format-poms)
+ TARGET="$1"
+ shift
+ ;;
+ --debug)
+ DEBUG=true
+ shift
+ ;;
+ --offline)
+ OFFLINE=true
+ shift
+ ;;
+ -h|--help)
+ TARGET="useage"
+ shift
+ ;;
+ *)
+ POSITIONAL+=("$1") # save it in an array for later
+ shift
+ ;;
+esac
+done
+
+function print-useage() {
+ echo -e "\n./build.sh [--debug] [--offline] | --help"
+ echo -e "\nAvailable build targets are:"
+ echo -e "\tquick - A distribution directory that can be found in exist-distribution/target/elemental-x.y.x-dir"
+ echo -e "\tquick-archives - A distribution directory, and distribution archives that can be found in exist-distribution/target/"
+ echo -e "\tquick-docker - A distribution directory and Docker Image"
+ echo -e "\tquick-archives-docker - A distribution directory, distribution archives, and Docker Image"
+ echo -e "\tquick-install - A distribution directory, and installs Maven Artifacts to your local Maven repository"
+ echo -e "\ttest - Runs the test suite"
+ echo -e "\tsite - Runs the test suite and produces a Maven Site in target/site/ that details the results"
+ echo -e "\tlicence-check - Checks that all source files have the correct license header"
+ echo -e "\tlicence-format - Adds the correct license header to any source files that are missing it"
+ echo -e "\tdependency-check - Checks that all modules have correctly declared their dependencies"
+ echo -e "\tdependency-security-check - Checks that all dependencies have no unexpected CVE security issues"
+ echo -e "\tformat-poms - Format the pom.xml files"
+ echo -e "\tclean - Remove all built artifacts"
+ echo -e "\n--offline - attempts to run the Maven build in offline mode"
+}
+
+set -- "${POSITIONAL[@]}" # restore positional parameters
+
+if [ "${TARGET}" == "useage" ]; then
+ print-useage
+ exit 0;
+fi
+
+
+SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
+BASE_CMD="${SCRIPT_DIR}/mvnw -V"
+
+if [ "${DEBUG}" == "true" ]; then
+ BASE_CMD="${BASE_CMD} --debug"
+fi
+
+if [ "${OFFLINE}" == "true" ]; then
+ BASE_CMD="${BASE_CMD} --offline"
+fi
+
+if [ "${TARGET}" == "clean" ]; then
+ CMD="${BASE_CMD} ${CONCURRENCY} clean -Pinstaller,docker,concurrency-stress-tests,micro-benchmarks"
+ $CMD
+ exit 0;
+fi
+
+if [ "${TARGET}" == "quick" ]; then
+ CMD="${BASE_CMD} ${CONCURRENCY} clean package -DskipTests -Ddependency-check.skip=true -Dappbundler.skip=true -Ddocker=false -P !mac-dmg-on-mac,!codesign-mac-app,!codesign-mac-dmg,!mac-dmg-on-unix,!installer,!concurrency-stress-tests,!micro-benchmarks,skip-build-dist-archives"
+ $CMD
+ exit 0;
+fi
+
+if [ "${TARGET}" == "quick-archives" ]; then
+ CMD="${BASE_CMD} ${CONCURRENCY} clean package -DskipTests -Ddependency-check.skip=true -Ddocker=false -P installer,!concurrency-stress-tests,!micro-benchmarks"
+ $CMD
+ exit 0;
+fi
+
+if [ "${TARGET}" == "quick-docker" ]; then
+ CMD="${BASE_CMD} ${CONCURRENCY} clean package -DskipTests -Ddependency-check.skip=true -Dappbundler.skip=true -Ddocker=true -P docker,!mac-dmg-on-mac,!codesign-mac-app,!codesign-mac-dmg,!mac-dmg-on-unix,!installer,!concurrency-stress-tests,!micro-benchmarks,skip-build-dist-archives"
+ $CMD
+ exit 0;
+fi
+
+if [ "${TARGET}" == "quick-archives-docker" ]; then
+ CMD="${BASE_CMD} ${CONCURRENCY} clean package -DskipTests -Ddependency-check.skip=true -Ddocker=true -P installer,-P docker,!concurrency-stress-tests,!micro-benchmarks"
+ $CMD
+ exit 0;
+fi
+
+if [ "${TARGET}" == "quick-install" ]; then
+ CMD="${BASE_CMD} ${CONCURRENCY} clean install package -DskipTests -Ddependency-check.skip=true -Dappbundler.skip=true -Ddocker=false -P !mac-dmg-on-mac,!codesign-mac-app,!codesign-mac-dmg,!mac-dmg-on-unix,!installer,!concurrency-stress-tests,!micro-benchmarks,skip-build-dist-archives"
+ $CMD
+ exit 0;
+fi
+
+if [ "${TARGET}" == "test" ]; then
+ CMD="${BASE_CMD} clean test -Ddependency-check.skip=true"
+ $CMD
+ exit 0;
+fi
+
+if [ "${TARGET}" == "site" ]; then
+ CMD="${BASE_CMD} clean verify site -Ddependency-check.skip=true"
+ $CMD
+ exit 0;
+fi
+
+if [ "${TARGET}" == "license-check" ]; then
+ CMD="${BASE_CMD} license:check"
+ $CMD
+ exit 0;
+fi
+
+if [ "${TARGET}" == "license-format" ]; then
+ CMD="${BASE_CMD} license:format"
+ $CMD
+ exit 0;
+fi
+
+if [ "${TARGET}" == "dependency-check" ]; then
+ CMD="${BASE_CMD} dependency:analyze"
+ $CMD
+ exit 0;
+fi
+
+if [ "${TARGET}" == "dependency-security-check" ]; then
+ CMD="${BASE_CMD} dependency-check:check"
+ $CMD
+ exit 0;
+fi
+
+if [ "${TARGET}" == "format-poms" ]; then
+ SAXON="${HOME}/.m2/repository/net/sf/saxon/Saxon-HE/9.9.1-8/Saxon-HE-9.9.1-8.jar"
+ POMS="$(find . -name pom.xml)"
+ for pom in $POMS; do
+
+ echo -n "Formatting ${pom} ... "
+ CMD="java -jar ${SAXON} -s:${pom} -xsl:format-pom.xslt -o:${pom}"
+ $CMD
+ echo "OK"
+
+ echo -n "Checking for duplicate license entries in ${pom} ... "
+ CMD="java -cp ${SAXON} net.sf.saxon.Query -q:check-pom-license-uniqueness.xq pom-file-uri=file:${pom}"
+ $CMD
+ echo "OK"
+
+ done
+ exit 0;
+fi
+
+print-useage
+exit 0;
diff --git a/check-pom-license-uniqueness.xq b/check-pom-license-uniqueness.xq
new file mode 100644
index 0000000000..6407294d9d
--- /dev/null
+++ b/check-pom-license-uniqueness.xq
@@ -0,0 +1,79 @@
+(:
+ : Elemental
+ : Copyright (C) 2024, Evolved Binary Ltd
+ :
+ : admin@evolvedbinary.com
+ : https://www.evolvedbinary.com | https://www.elemental.xyz
+ :
+ : This library is free software; you can redistribute it and/or
+ : modify it under the terms of the GNU Lesser General Public
+ : License as published by the Free Software Foundation; version 2.1.
+ :
+ : This library is distributed in the hope that it will be useful,
+ : but WITHOUT ANY WARRANTY; without even the implied warranty of
+ : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ : Lesser General Public License for more details.
+ :
+ : You should have received a copy of the GNU Lesser General Public
+ : License along with this library; if not, write to the Free Software
+ : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ :)
+ xquery version "3.1";
+
+(:~
+ : Checks within the and of each with a pom.xml
+ : file to make sure there are no duplicate entries.
+ :)
+
+declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
+declare namespace pom = "http://maven.apache.org/POM/4.0.0";
+
+declare option output:omit-xml-declaration "yes";
+
+
+(: Must be set externally with the URI to the pom.xml file :)
+declare variable $pom-file-uri as xs:string external;
+
+let $pom := doc($pom-file-uri)
+return
+(
+
+ let $includes-elements := $pom//pom:includes
+ for $includes-element in $includes-elements
+ let $total-includes := count($includes-element/pom:include/string(.))
+ let $distinct-includes := count(distinct-values($includes-element/pom:include/string(.)))
+ return
+ if ($total-includes ne $distinct-includes)
+ then
+ let $duplicates :=
+ distinct-values(
+ for $include in $includes-element/pom:include/string(.)
+ where count($includes-element/pom:include[. eq $include]) gt 1
+ return $include
+ )
+ return
+ error(xs:QName("duplicate-include"), "There are duplicate 'include' license entries within a 'licenseSet' in: " || $pom-file-uri || " at: " || path($includes-element) || " duplicates: " || string-join($duplicates, ", "))
+ else
+ ()
+
+,
+
+ let $excludes-elements := $pom//pom:excludes[parent::pom:licenseSet]
+ for $excludes-element in $excludes-elements
+ let $total-excludes := count($excludes-element/pom:exclude/string(.))
+ let $distinct-excludes := count(distinct-values($excludes-element/pom:exclude/string(.)))
+ return
+ if ($total-excludes ne $distinct-excludes)
+ then
+ let $duplicates :=
+ distinct-values(
+ for $exclude in $excludes-element/pom:exclude/string(.)
+ where count($excludes-element/pom:exclude[. eq $exclude]) gt 1
+ return $exclude
+ )
+ return
+ error(xs:QName("duplicate-exclude"), "There are duplicate 'exclude' license entries within a 'licenseSet' in: " || $pom-file-uri || " at: " || path($excludes-element) || " duplicates: " || string-join($duplicates, ", "))
+ else
+ ()
+
+)
\ No newline at end of file
diff --git a/elemental-media-type/elemental-media-type-api/pom.xml b/elemental-media-type/elemental-media-type-api/pom.xml
new file mode 100644
index 0000000000..f7406bb9bb
--- /dev/null
+++ b/elemental-media-type/elemental-media-type-api/pom.xml
@@ -0,0 +1,85 @@
+
+
+
+ 4.0.0
+
+
+ xyz.elemental
+ elemental-media-type
+ 7.6.0-SNAPSHOT
+ ..
+
+
+ elemental-media-type-api
+
+ Elemental Internet Media Type Resolver API
+ Internet Media Type Resolver API for Elemental
+
+
+ scm:git:https://github.com/evolvedbinary/elemental.git
+ scm:git:https://github.com/evolvedbinary/elemental.git
+ scm:git:https://github.com/evolvedbinary/elemental.git
+ HEAD
+
+
+
+
+ com.google.code.findbugs
+ jsr305
+
+
+
+
+
+
+ com.mycila
+ license-maven-plugin
+
+
+
+ ${project.parent.relativePath}/../elemental-parent/FDB-backport-to-EDB-LGPL-21-ONLY-license.template.txt
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/elemental-media-type/elemental-media-type-api/src/main/java/xyz/elemental/mediatype/MediaType.java b/elemental-media-type/elemental-media-type-api/src/main/java/xyz/elemental/mediatype/MediaType.java
new file mode 100644
index 0000000000..ee5c1f792d
--- /dev/null
+++ b/elemental-media-type/elemental-media-type-api/src/main/java/xyz/elemental/mediatype/MediaType.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2014, Evolved Binary Ltd
+ *
+ * This file was originally ported from FusionDB to Elemental by
+ * Evolved Binary, for the benefit of the Elemental Open Source community.
+ * Only the ported code as it appears in this file, at the time that
+ * it was contributed to Elemental, was re-licensed under The GNU
+ * Lesser General Public License v2.1 only for use in Elemental.
+ *
+ * This license grant applies only to a snapshot of the code as it
+ * appeared when ported, it does not offer or infer any rights to either
+ * updates of this source code or access to the original source code.
+ *
+ * The GNU Lesser General Public License v2.1 only license follows.
+ *
+ * =====================================================================
+ *
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package xyz.elemental.mediatype;
+
+import javax.annotation.Nullable;
+
+/**
+ * Information about a Media Type (aka MIME Type)
+ * and how resources of that type should be stored into
+ * the database.
+ *
+ * @author Adam Retter
+ */
+public interface MediaType {
+
+ /**
+ * Get the identifier of the Media Type.
+ *
+ * For example {@code application/xml}.
+ *
+ * @return the identifier of the Media Type
+ */
+ String getIdentifier();
+
+ /**
+ * Get the file extensions that are known
+ * to be associated with the Media Type.
+ *
+ * @return the known file extensions associated with the Media Type, or null if there are none
+ */
+ @Nullable String[] getKnownFileExtensions();
+
+ /**
+ * Get the database storage type that should
+ * be used for resources of this Media Type.
+ *
+ * @return the database storage type of the Media Type
+ */
+ StorageType getStorageType();
+
+ //
+ String APPLICATION_ATOM = "application/atom+xml";
+ String APPLICATION_BZIP2 = "application/x-bzip2";
+ String APPLICATION_DITA = "application/dita+xml";
+ String APPLICATION_ELEMENTAL_DOCUMENT = "application/vnd.elemental.document";
+ String APPLICATION_ELEMENTAL_DOCUMENT_BINARY = "application/vnd.elemental.document+binary";
+ String APPLICATION_ELEMENTAL_DOCUMENT_XML = "application/vnd.elemental.document+xml";
+ String APPLICATION_ELEMENTAL_COLLECTION = "application/vnd.elemental.collection";
+ String APPLICATION_EXPATH_PACKAGE_ZIP = "application/prs.expath.package+zip";
+ String APPLICATION_GML = "application/gml+xml";
+ String APPLICATION_GZIP = "application/gzip";
+ String APPLICATION_INVISIBLE_XML_GRAMMAR = "application/prs.invisible-xml.grammar";
+ String APPLICATION_INVISIBLE_XML_GRAMMAR_XML = "application/prs.invisible-xml.grammar+xml";
+ String APPLICATION_JAVA_ARCHIVE = "application/java-archive";
+ String APPLICATION_JSON = "application/json";
+ String APPLICATION_MADS = "application/mads+xml";
+ String APPLICATION_MARC = "application/marcxml+xml";
+ String APPLICATION_METS = "application/mets+xml";
+ String APPLICATION_MODS = "application/mods+xml";
+ String APPLICATION_NCX = "application/x-dtbncx+xml";
+ String APPLICATION_OCTET_STREAM = "application/octet-stream";
+ String APPLICATION_OEBPS_PACKAGE = "application/oebps-package+xml";
+ String APPLICATION_OPENDOCUMENT_PRESENTATION = "application/vnd.oasis.opendocument.presentation";
+ String APPLICATION_OPENDOCUMENT_TEXT = "application/vnd.oasis.opendocument.text";
+ String APPLICATION_OPENDOCUMENT_SPREADSHEET = "application/vnd.oasis.opendocument.spreadsheet";
+ String APPLICATION_OPENXML_PRESENTATION = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
+ String APPLICATION_OPENXML_SPREADSHEET = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
+ String APPLICATION_OPENXML_WORDPROCESSING = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
+ String APPLICATION_PACK200 = "application/x-java-pack200";
+ String APPLICATION_PDF = "application/pdf";
+ String APPLICATION_RDF_XML = "application/rdf+xml";
+ String APPLICATION_RELAXNG_COMPACT = "application/relax-ng-compact-syntax";
+ String APPLICATION_RSS = "application/rss+xml";
+ String APPLICATION_SCHEMATRON = "application/schematron+xml";
+ String APPLICATION_SRU = "application/sru+xml";
+ String APPLICATION_TAR = "application/x-tar";
+ String APPLICATION_TEI = "application/tei+xml";
+ String APPLICATION_WSDL = "application/wsdl+xml";
+ String APPLICATION_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded";
+ String APPLICATION_XMI = "application/vnd.xmi+xml";
+ String APPLICATION_XML = "application/xml";
+ String APPLICATION_XML_DTD = "application/xml-dtd";
+ String APPLICATION_XHTML = "application/xhtml+xml";
+ String APPLICATION_XPROC = "application/xproc+xml";
+ String APPLICATION_XSLT = "application/xslt+xml";
+ String APPLICATION_XQUERY = "application/xquery";
+ String APPLICATION_XQUERY_XML = "application/xquery+xml";
+ String APPLICATION_XZ = "application/x-xz";
+ String APPLICATION_ZIP = "application/zip";
+ String APPLICATION_ZSTD = "application/zstd";
+
+ String IMAGE_GIF = "image/gif";
+ String IMAGE_JPEG = "image/jpeg";
+ String IMAGE_PNG = "image/png";
+ String IMAGE_SVG = "image/svg+xml";
+ String IMAGE_SVG_GZIP = "image/svg+xml";
+ // See: https://github.com/w3c/svgwg/issues/701
+// String IMAGE_SVG_GZIP = "image/x.svg+gzip";
+
+ String MULTIPART_ALTERNATIVE = "multipart/alternative";
+ String MULTIPART_MIXED = "multipart/mixed";
+
+ String TEXT_CSS = "text/css";
+ String TEXT_CSV = "text/csv";
+ String TEXT_CSV_SCHEMA = "text/csv-schema";
+ String TEXT_HTML = "text/html";
+ String TEXT_JAVASCRIPT = "text/javascript";
+ String TEXT_MARKDOWN = "text/markdown";
+ String TEXT_N3 = "text/n3";
+ String TEXT_PLAIN = "text/plain";
+ String TEXT_TURTLE = "text/turtle";
+ String TEXT_URI_LIST = "text/uri-list";
+
+ /**
+ * Expect for use within the type attribute of an XML Processing Instruction
+ * this is probably not what you need, and you should likely use {@link #APPLICATION_XML} instead.
+ */
+ @Deprecated
+ String TEXT_XSL = "text/xsl";
+ //
+
+ //
+ String APPLICATION_EXISTDB_COLLECTION_CONFIG_XML = "application/prs.existdb.collection-config+xml";
+
+ /**
+ * Use {@link #APPLICATION_ELEMENTAL_DOCUMENT} instead.
+ */
+ @Deprecated
+ String APPLICATION_EXISTDB_DOCUMENT = "application/vnd.existdb.document";
+
+ /**
+ * Use {@link #APPLICATION_ELEMENTAL_DOCUMENT_BINARY} instead.
+ */
+ @Deprecated
+ String APPLICATION_EXISTDB_DOCUMENT_BINARY = "application/vnd.existdb.document+binary";
+
+ /**
+ * Use {@link #APPLICATION_ELEMENTAL_DOCUMENT_XML} instead.
+ */
+ @Deprecated
+ String APPLICATION_EXISTDB_DOCUMENT_XML = "application/vnd.existdb.document+xml";
+
+ /**
+ * Use {@link #APPLICATION_ELEMENTAL_COLLECTION} instead.
+ */
+ @Deprecated
+ String APPLICATION_EXISTDB_COLLECTION = "application/vnd.existdb.collection";
+ //
+}
diff --git a/elemental-media-type/elemental-media-type-api/src/main/java/xyz/elemental/mediatype/MediaTypeResolver.java b/elemental-media-type/elemental-media-type-api/src/main/java/xyz/elemental/mediatype/MediaTypeResolver.java
new file mode 100644
index 0000000000..575a43806d
--- /dev/null
+++ b/elemental-media-type/elemental-media-type-api/src/main/java/xyz/elemental/mediatype/MediaTypeResolver.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2014, Evolved Binary Ltd
+ *
+ * This file was originally ported from FusionDB to Elemental by
+ * Evolved Binary, for the benefit of the Elemental Open Source community.
+ * Only the ported code as it appears in this file, at the time that
+ * it was contributed to Elemental, was re-licensed under The GNU
+ * Lesser General Public License v2.1 only for use in Elemental.
+ *
+ * This license grant applies only to a snapshot of the code as it
+ * appeared when ported, it does not offer or infer any rights to either
+ * updates of this source code or access to the original source code.
+ *
+ * The GNU Lesser General Public License v2.1 only license follows.
+ *
+ * =====================================================================
+ *
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package xyz.elemental.mediatype;
+
+import javax.annotation.Nullable;
+import java.nio.file.Path;
+
+/**
+ * Finds Media Types for resources.
+ *
+ * @author Adam Retter
+ */
+public interface MediaTypeResolver {
+
+ /**
+ * Resolve the Media Type for the filename.
+ *
+ * @param path the Path containing the filename.
+ *
+ * @return The MediaType for the filename, or null if there is no known or configured media type
+ */
+ @Nullable MediaType fromFileName(@Nullable final Path path);
+
+ /**
+ * Resolve the MediaType for the filename.
+ *
+ * @param path the file path containing the filename.
+ *
+ * @return The MediaType for the filename, or null if there is no known or configured media type.
+ */
+ @Nullable MediaType fromFileName(@Nullable final String path);
+
+ /**
+ * Resolve the MediaType from the name/identifier
+ * of the media type.
+ *
+ * @param mediaType the name/identifier of the media type.
+ *
+ * @return The MediaType for the name/identifier, or null if the media type is unknown.
+ */
+ @Nullable MediaType fromString(@Nullable final String mediaType);
+
+ /**
+ * Returns the MediaType to be used for
+ * unknown types of resources.
+ *
+ * This is typically used as a catch-all.
+ *
+ * @return the MediaType to use for unknown
+ * types of resources.
+ */
+ MediaType forUnknown();
+
+ /**
+ * The Instantiation Exception is thrown
+ * if an error occurs when the factory
+ * tries to instantiate a new Media Type Resolver.
+ */
+ class InstantiationException extends Exception {
+ public InstantiationException(final String message) {
+ super(message);
+ }
+
+ public InstantiationException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+
+ public InstantiationException(final Throwable cause) {
+ super(cause);
+ }
+ }
+}
diff --git a/elemental-media-type/elemental-media-type-api/src/main/java/xyz/elemental/mediatype/MediaTypeResolverFactory.java b/elemental-media-type/elemental-media-type-api/src/main/java/xyz/elemental/mediatype/MediaTypeResolverFactory.java
new file mode 100644
index 0000000000..a622df185e
--- /dev/null
+++ b/elemental-media-type/elemental-media-type-api/src/main/java/xyz/elemental/mediatype/MediaTypeResolverFactory.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2014, Evolved Binary Ltd
+ *
+ * This file was originally ported from FusionDB to Elemental by
+ * Evolved Binary, for the benefit of the Elemental Open Source community.
+ * Only the ported code as it appears in this file, at the time that
+ * it was contributed to Elemental, was re-licensed under The GNU
+ * Lesser General Public License v2.1 only for use in Elemental.
+ *
+ * This license grant applies only to a snapshot of the code as it
+ * appeared when ported, it does not offer or infer any rights to either
+ * updates of this source code or access to the original source code.
+ *
+ * The GNU Lesser General Public License v2.1 only license follows.
+ *
+ * =====================================================================
+ *
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package xyz.elemental.mediatype;
+
+import javax.annotation.Nullable;
+import java.nio.file.Path;
+import xyz.elemental.mediatype.MediaTypeResolver.InstantiationException;
+
+/**
+ * Factory for instantiating Media Type Resolvers.
+ *
+ * @author Adam Retter
+ */
+public interface MediaTypeResolverFactory {
+
+ /**
+ * Instantiate a new Media Type Resolver.
+ *
+ * @return a new Media Type Resolver.
+ *
+ * @throws InstantiationException if an error occurs
+ * whilst instantiating the MediaTypeResolver.
+ */
+ MediaTypeResolver newMediaTypeResolver()
+ throws InstantiationException;
+
+ /**
+ * Instantiate a new Media Type Resolver.
+ *
+ * @param configDirs paths to directories which contain configuration
+ * files for the media type resolver.
+ *
+ * @return a new Media Type Resolver.
+ *
+ * @throws InstantiationException if an error occurs
+ * whilst instantiating the MediaTypeResolver.
+ */
+ MediaTypeResolver newMediaTypeResolver(@Nullable final Path... configDirs)
+ throws InstantiationException;
+
+}
diff --git a/elemental-media-type/elemental-media-type-api/src/main/java/xyz/elemental/mediatype/StorageType.java b/elemental-media-type/elemental-media-type-api/src/main/java/xyz/elemental/mediatype/StorageType.java
new file mode 100644
index 0000000000..01282650c0
--- /dev/null
+++ b/elemental-media-type/elemental-media-type-api/src/main/java/xyz/elemental/mediatype/StorageType.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2014, Evolved Binary Ltd
+ *
+ * This file was originally ported from FusionDB to Elemental by
+ * Evolved Binary, for the benefit of the Elemental Open Source community.
+ * Only the ported code as it appears in this file, at the time that
+ * it was contributed to Elemental, was re-licensed under The GNU
+ * Lesser General Public License v2.1 only for use in Elemental.
+ *
+ * This license grant applies only to a snapshot of the code as it
+ * appeared when ported, it does not offer or infer any rights to either
+ * updates of this source code or access to the original source code.
+ *
+ * The GNU Lesser General Public License v2.1 only license follows.
+ *
+ * =====================================================================
+ *
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package xyz.elemental.mediatype;
+
+import javax.annotation.Nullable;
+
+/**
+ * Types of database storage to use for resources of various Media Type.
+ *
+ * @author Adam Retter
+ */
+public enum StorageType {
+ /**
+ * Native XML document storage within the database.
+ */
+ XML,
+
+ /**
+ * Binary document storage within the database.
+ */
+ BINARY;
+
+ /**
+ * Get a StorageType by its name.
+ * Similar to {@link #valueOf(String)} but ignores
+ * cases sensitivity.
+ *
+ * @param name the name of the StorageType
+ * @return the StorageType
+ *
+ * @throws IllegalArgumentException if the name is unknown
+ */
+ public static StorageType fromName(final String name) {
+ final StorageType storageType = lookup(name);
+ if (storageType != null) {
+ return storageType;
+ }
+ throw new IllegalArgumentException();
+ }
+
+ /**
+ * Get a StorageType by its name.
+ * Similar to {@link #fromName(String)} but
+ * if no Storage Type matches the {@code name}
+ * then the Storage Type for Unknown resources
+ * is returned.
+ *
+ * @param name the name of the StorageType
+ * @return the StorageType for the name, or the Storage
+ * Type for Unknown resources as returned by {@link #forUnknown()}.
+ */
+ public static StorageType fromNameOrDefault(final String name) {
+ final StorageType storageType = lookup(name);
+ if (storageType != null) {
+ return storageType;
+ }
+ return forUnknown();
+ }
+
+ /**
+ * Get a StorageType by its name.
+ * Similar to {@link #valueOf(String)} but ignores
+ * cases sensitivity.
+ *
+ * @param name the name of the StorageType
+ * @return the StorageType or null if there is
+ * no StorageType for the provided name.
+ */
+ private static @Nullable StorageType lookup(String name) {
+ name = name.toUpperCase();
+ for (final StorageType storageType : StorageType.values()) {
+ if (storageType.name().equals(name)) {
+ return storageType;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the StorageType to be used for
+ * unknown types of resources.
+ *
+ * This is typically used as a catch-all.
+ *
+ * @return the StorageType to use for unknown
+ * types of resources.
+ */
+ public static StorageType forUnknown() {
+ return BINARY;
+ }
+}
diff --git a/elemental-media-type/elemental-media-type-impl/pom.xml b/elemental-media-type/elemental-media-type-impl/pom.xml
new file mode 100644
index 0000000000..ad44d77527
--- /dev/null
+++ b/elemental-media-type/elemental-media-type-impl/pom.xml
@@ -0,0 +1,209 @@
+
+
+
+ 4.0.0
+
+
+ xyz.elemental
+ elemental-media-type
+ 7.6.0-SNAPSHOT
+ ..
+
+
+ elemental-media-type-impl
+
+ Elemental Internet Media Type Resolver Implementation
+ Internet Media Type Implementation for Elemental
+
+
+ scm:git:https://github.com/evolvedbinary/elemental.git
+ scm:git:https://github.com/evolvedbinary/elemental.git
+ scm:git:https://github.com/evolvedbinary/elemental.git
+ HEAD
+
+
+
+ 2.4.65+1.0.1
+
+
+
+
+ xyz.elemental
+ elemental-media-type-api
+ ${project.version}
+
+
+
+ com.google.code.findbugs
+ jsr305
+
+
+
+ net.jcip
+ jcip-annotations
+
+
+
+ org.slf4j
+ slf4j-api
+
+
+
+ org.slf4j
+ slf4j-simple
+ ${slf4j.version}
+ test
+
+
+
+ io.lacuna
+ bifurcan
+
+
+
+ jakarta.xml.bind
+ jakarta.xml.bind-api
+
+
+
+ org.glassfish.jaxb
+ jaxb-runtime
+ runtime
+
+
+
+ jakarta.activation
+ jakarta.activation-api
+
+
+
+ org.eclipse.angus
+ angus-activation
+
+
+
+ com.evolvedbinary.thirdparty.org.apache.httpd
+ apache-httpd-mime-types
+ ${httpd.mime-types.version}
+ runtime
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ test
+
+
+
+
+
+
+
+ com.mycila
+ license-maven-plugin
+
+
+ SCRIPT_STYLE
+
+
+
+ ${project.parent.relativePath}/../elemental-parent/FDB-backport-to-EDB-LGPL-21-ONLY-license.template.txt
+
+
+
+
+
+
+ org.jvnet.jaxb
+ jaxb-maven-plugin
+
+ src/main/xjb
+ src/main/xsd
+
+
+
+ generate-jaxb-objects
+
+ generate
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+
+
+ analyze
+
+ analyze-only
+
+
+ true
+
+
+ org.glassfish.jaxb:jaxb-runtime:jar:${jaxb.impl.version}
+
+ com.evolvedbinary.thirdparty.org.apache.httpd:apache-httpd-mime-types:jar:${httpd.mime-types.version}
+
+
+
+ net.sf.xmldb-org:xmldb-api:jar
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+
+
+
+ ${project.build.directory}/generated-sources/xjc/**
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/elemental-media-type/elemental-media-type-impl/src/main/java/xyz/elemental/mediatype/impl/ApplicationMimetypesFileTypeMap.java b/elemental-media-type/elemental-media-type-impl/src/main/java/xyz/elemental/mediatype/impl/ApplicationMimetypesFileTypeMap.java
new file mode 100644
index 0000000000..0a75879a47
--- /dev/null
+++ b/elemental-media-type/elemental-media-type-impl/src/main/java/xyz/elemental/mediatype/impl/ApplicationMimetypesFileTypeMap.java
@@ -0,0 +1,365 @@
+/*
+ * Copyright (C) 2014, Evolved Binary Ltd
+ *
+ * This file was originally ported from FusionDB to Elemental by
+ * Evolved Binary, for the benefit of the Elemental Open Source community.
+ * Only the ported code as it appears in this file, at the time that
+ * it was contributed to Elemental, was re-licensed under The GNU
+ * Lesser General Public License v2.1 only for use in Elemental.
+ *
+ * This license grant applies only to a snapshot of the code as it
+ * appeared when ported, it does not offer or infer any rights to either
+ * updates of this source code or access to the original source code.
+ *
+ * The GNU Lesser General Public License v2.1 only license follows.
+ *
+ * =====================================================================
+ *
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package xyz.elemental.mediatype.impl;
+
+import io.lacuna.bifurcan.IList;
+import io.lacuna.bifurcan.LinearList;
+import jakarta.activation.MimeTypeEntry;
+import jakarta.activation.MimeTypeRegistry;
+import jakarta.activation.MimetypesFileTypeMap;
+import org.eclipse.angus.activation.MimeTypeFile;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.Nullable;
+import java.io.File;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.*;
+
+/**
+ * An implementation of {@link jakarta.activation.FileTypeMap} which
+ * extends {@link jakarta.activation.MimetypesFileTypeMap} to also
+ * read from an application specific file.
+ *
+ *
MIME types file search order
+ * The ApplicationMimetypesFileTypeMap looks in various places in the user's
+ * system for MIME types file entries. When requests are made
+ * to search for MIME types in the ApplicationMimetypesFileTypeMap, it searches
+ * MIME types files in the following order:
+ *
+ *
Programmatically added entries to the ApplicationMimetypesFileTypeMap instance.
+ *
The file .jakarta.mime.types in the user's home directory.
+ *
The file .mime.types in the user's home directory.
+ *
The file jakarta.mime.types from within the user's home directory:
+ *
+ *
Linux/Unix: $XDG_DATA_HOME/jakarta.mime.types If $XDG_DATA_HOME is not set then, ~/.local/share/jakarta.mime.types
+ *
macOS: $XDG_DATA_HOME/jakarta.mime.types. If $XDG_DATA_HOME is not set then, ~/Library/Application Support/jakarta.mime.types
+ *
Windows: %APPDATA%/jakarta.mime.types. If %APPDATA% is not set then, %USERPROFILE%/AppData/Local/jakarta.mime.types
+ *
+ *
+ *
One or more files named jakarta.mime.types in the application's config directory(s).
+ *
One or more files named mime.types in the application's config directory(s).
+ *
The file jakarta.mime.types on the classpath in the package xyz.elemental.mediatype.
+ *
The file mime.types on the classpath in the package xyz.elemental.mediatype.
+ *
The file jakarta.mime.types in the Java runtime.
+ *
The file mime.types in the Java runtime.
+ *
The file or resources named META-INF/jakarta.mime.types.
+ *
The file or resources named META-INF/mime.types.
+ *
The file or resource named META-INF/jakarta.mimetypes.default (usually found only in the activation.jar file).
+ *
The file or resource named META-INF/mimetypes.default (usually found only in the activation.jar file).
+ *
+ *
+ *
(The current implementation looks for the jakarta.mime.types and mime.types files
+ * in the Java runtime in the directory java.home/conf
+ * if it exists, and otherwise in the directory
+ * java.home/lib, where java.home is the value
+ * of the "java.home" System property. Note that the "conf" directory was
+ * introduced in JDK 9.)
+ *
+ * See {@link MimetypesFileTypeMap} for further information.
+ *
+ * @author Adam Retter
+ */
+public class ApplicationMimetypesFileTypeMap extends MimetypesFileTypeMap {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ApplicationMimetypesFileTypeMap.class);
+
+ private static final String JAKARTA_MIME_TYPES_FILENAME = "jakarta.mime.types";
+ private static final String LEGACY_MIME_TYPES_FILENAME = "mime.types";
+
+ public ApplicationMimetypesFileTypeMap(@Nullable final Path... configDirs) {
+ final Vector dbv = new Vector<>(6); // usually 6 or fewer databases
+ @Nullable MimeTypeRegistry mf;
+ dbv.add(null); // place holder for PROG entry
+
+ @Nullable final Method loadFileMethod = getLoadFileMethod();
+ if (loadFileMethod != null) {
+
+ LOG.trace("MimetypesFileTypeMap: load HOME");
+ try {
+ final String user_home = System.getProperty("user.home");
+
+ if (user_home != null) {
+ String path = user_home + File.separator + "." + JAKARTA_MIME_TYPES_FILENAME;
+ mf = loadFileRefl(loadFileMethod, path);
+ if (mf != null) {
+ dbv.add(mf);
+ }
+
+ path = user_home + File.separator + "." + LEGACY_MIME_TYPES_FILENAME;
+ mf = loadFileRefl(loadFileMethod, path);
+ if (mf != null) {
+ dbv.add(mf);
+ }
+ }
+ } catch (final SecurityException ex) {
+ // no-op
+ }
+
+ LOG.trace("MimetypesFileTypeMap: load HOME DATA");
+ try {
+ @Nullable final Path userDataFolder = PathUtil.getUserDataFolder();
+
+ if (userDataFolder != null) {
+ String path = userDataFolder.resolve("." + JAKARTA_MIME_TYPES_FILENAME).toAbsolutePath().toString();
+ mf = loadFileRefl(loadFileMethod, path);
+ if (mf != null) {
+ dbv.add(mf);
+ }
+
+ path = userDataFolder.resolve("." + LEGACY_MIME_TYPES_FILENAME).toAbsolutePath().toString();
+ mf = loadFileRefl(loadFileMethod, path);
+ if (mf != null) {
+ dbv.add(mf);
+ }
+ }
+ } catch (final SecurityException ex) {
+ // no-op
+ }
+
+ LOG.trace("ApplicationMimetypesFileTypeMap: load application");
+ if (configDirs != null) {
+ for (final Path configDir : configDirs) {
+ boolean found = false;
+ final String[] filenames = new String[]{JAKARTA_MIME_TYPES_FILENAME, LEGACY_MIME_TYPES_FILENAME};
+ for (final String filename : filenames) {
+
+ final Path mimeTypesPath = configDir.resolve(filename);
+ if (!Files.exists(mimeTypesPath)) {
+ LOG.trace("No custom {} found at: {}, skipping...", filename, mimeTypesPath.toAbsolutePath());
+ }
+
+ mf = loadFileRefl(loadFileMethod, mimeTypesPath.toAbsolutePath().toString());
+ if (mf != null) {
+ dbv.add(mf);
+ found = true;
+ }
+ }
+ if (!found) {
+ LOG.warn("Could not find Media Types file named {} or {} in: {}, skipping...", JAKARTA_MIME_TYPES_FILENAME, LEGACY_MIME_TYPES_FILENAME, configDir.toAbsolutePath());
+ }
+ }
+ }
+ }
+
+ LOG.trace("ApplicationMimetypesFileTypeMap: load classpath from xyz.elemental.mediatype");
+ @Nullable final Method loadAllResourcesMethod = getLoadAllResourcesMethod();
+ if (loadAllResourcesMethod != null) {
+ loadAllResourcesRefl(loadAllResourcesMethod, dbv, new String[] {
+ "xyz/elemental/mediatype/" + JAKARTA_MIME_TYPES_FILENAME,
+ "xyz/elemental/mediatype/" + LEGACY_MIME_TYPES_FILENAME
+ });
+ }
+
+ if (loadFileMethod != null) {
+ LOG.trace("MimetypesFileTypeMap: load SYS");
+ try {
+ // check system's home
+ final String confDir = confDirRefl();
+ if (confDir != null) {
+ mf = loadFileRefl(loadFileMethod, confDir + JAKARTA_MIME_TYPES_FILENAME);
+ if (mf != null) {
+ dbv.add(mf);
+ }
+
+ mf = loadFileRefl(loadFileMethod, confDir + LEGACY_MIME_TYPES_FILENAME);
+ if (mf != null) {
+ dbv.add(mf);
+ }
+ }
+ } catch (final SecurityException ex) {
+ // no-op
+ }
+ }
+
+ if (loadAllResourcesMethod != null) {
+ LOG.trace("MimetypesFileTypeMap: load JAR");
+ // load from the app's jar file
+ loadAllResourcesRefl(loadAllResourcesMethod, dbv, new String[] {
+ "META-INF/" + JAKARTA_MIME_TYPES_FILENAME,
+ "META-INF/" + LEGACY_MIME_TYPES_FILENAME
+ });
+ }
+
+ @Nullable final Method loadResourceMethod = getLoadResourceMethod();
+ if (loadResourceMethod != null) {
+ LOG.trace("MimetypesFileTypeMap: load DEF");
+ mf = loadResourceRefl(loadResourceMethod, new String[] {
+ "/META-INF/jakarta.mimetypes.default",
+ "/META-INF/mimetypes.default"
+ });
+ if (mf != null) {
+ dbv.add(mf);
+ }
+ }
+
+ final MimeTypeFile[] DB = new MimeTypeFile[dbv.size()];
+ dbv.copyInto(DB);
+ setDBRefl(DB);
+ }
+
+ private static @Nullable Method getLoadFileMethod() {
+ try {
+ final Method loadFileMethod = MimetypesFileTypeMap.class.getDeclaredMethod("loadFile", String.class);
+ loadFileMethod.setAccessible(true);
+ return loadFileMethod;
+ } catch (final NoSuchMethodException e) {
+ LOG.error(e.getMessage(), e);
+ return null;
+ }
+ }
+
+ private @Nullable MimeTypeRegistry loadFileRefl(final Method loadFileMethod, final String name) {
+ try {
+ return (MimeTypeRegistry) loadFileMethod.invoke(this, name);
+ } catch (final IllegalAccessException | InvocationTargetException e) {
+ LOG.error(e.getMessage(), e);
+ return null;
+ }
+ }
+
+ private static @Nullable String confDirRefl() {
+ try {
+ final Field confDirField = MimetypesFileTypeMap.class.getDeclaredField("confDir");
+ confDirField.setAccessible(true);
+ return (String) confDirField.get(null);
+ } catch (final NoSuchFieldException | IllegalAccessException e) {
+ LOG.error(e.getMessage(), e);
+ return null;
+ }
+ }
+
+ private static @Nullable Method getLoadAllResourcesMethod() {
+ try {
+ final Method loadAllResourcesMethod = MimetypesFileTypeMap.class.getDeclaredMethod("loadAllResources", Vector.class, String[].class);
+ loadAllResourcesMethod.setAccessible(true);
+ return loadAllResourcesMethod;
+ } catch (final NoSuchMethodException e) {
+ LOG.error(e.getMessage(), e);
+ return null;
+ }
+ }
+
+ @SuppressWarnings("RawUseOfParameterizedType")
+ private void loadAllResourcesRefl(final Method loadAllResourcesMethod, final Vector v, final String[] names) {
+ try {
+ loadAllResourcesMethod.invoke(this, v, (Object) names);
+ } catch (final IllegalAccessException | InvocationTargetException e) {
+ LOG.error(e.getMessage(), e);
+ }
+ }
+
+ private static @Nullable Method getLoadResourceMethod() {
+ try {
+ final Method loadResourceMethod = MimetypesFileTypeMap.class.getDeclaredMethod("loadResource", String[].class);
+ loadResourceMethod.setAccessible(true);
+ return loadResourceMethod;
+ } catch (final NoSuchMethodException e) {
+ LOG.error(e.getMessage(), e);
+ return null;
+ }
+ }
+
+ private @Nullable MimeTypeRegistry loadResourceRefl(final Method loadResourceMethod, final String[] names) {
+ try {
+ return (MimeTypeFile) loadResourceMethod.invoke(this, (Object) names);
+ } catch (final IllegalAccessException | InvocationTargetException e) {
+ LOG.error(e.getMessage(), e);
+ return null;
+ }
+ }
+
+ private void setDBRefl(final MimeTypeRegistry[] DB) {
+ try {
+ final Field dbField = MimetypesFileTypeMap.class.getDeclaredField("DB");
+ dbField.setAccessible(true);
+ dbField.set(this, DB);
+ } catch (final NoSuchFieldException | IllegalAccessException e) {
+ LOG.error(e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Get all the entries from the MimetypesFileTypeMap.
+ *
+ * @return the entries from the MimetypesFileTypeMap.
+ */
+ @SuppressWarnings("unchecked")
+ IList>> getAllEntries() {
+ final MimeTypeRegistry[] mimeTypeRegistries;
+ try {
+ final Field dbField = MimetypesFileTypeMap.class.getDeclaredField("DB");
+ dbField.setAccessible(true);
+ mimeTypeRegistries = (MimeTypeRegistry[]) dbField.get(this);
+ } catch (final NoSuchFieldException | IllegalAccessException e) {
+ LOG.error(e.getMessage(), e);
+ return null;
+ }
+
+ if (mimeTypeRegistries == null) {
+ return null;
+ }
+
+ final LinearList>> entries = new LinearList<>();
+ final Field typeHashField;
+ try {
+ typeHashField = MimeTypeFile.class.getDeclaredField("type_hash");
+ } catch (final NoSuchFieldException e) {
+ LOG.error(e.getMessage(), e);
+ return null;
+ }
+ typeHashField.setAccessible(true);
+
+ try {
+ for (final MimeTypeRegistry mimeTypeRegistry : mimeTypeRegistries) {
+ if (mimeTypeRegistry != null) {
+ final Hashtable typeHash = (Hashtable) typeHashField.get(mimeTypeRegistry);
+ entries.addLast(typeHash.entrySet());
+ }
+ }
+ } catch (final IllegalAccessException e) {
+ LOG.error("Unable to access type_hash from MimeTypeFile", e);
+ return null;
+ }
+
+ return entries.forked();
+ }
+}
diff --git a/elemental-media-type/elemental-media-type-impl/src/main/java/xyz/elemental/mediatype/impl/MediaTypeImpl.java b/elemental-media-type/elemental-media-type-impl/src/main/java/xyz/elemental/mediatype/impl/MediaTypeImpl.java
new file mode 100644
index 0000000000..21ac682c9d
--- /dev/null
+++ b/elemental-media-type/elemental-media-type-impl/src/main/java/xyz/elemental/mediatype/impl/MediaTypeImpl.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2014, Evolved Binary Ltd
+ *
+ * This file was originally ported from FusionDB to Elemental by
+ * Evolved Binary, for the benefit of the Elemental Open Source community.
+ * Only the ported code as it appears in this file, at the time that
+ * it was contributed to Elemental, was re-licensed under The GNU
+ * Lesser General Public License v2.1 only for use in Elemental.
+ *
+ * This license grant applies only to a snapshot of the code as it
+ * appeared when ported, it does not offer or infer any rights to either
+ * updates of this source code or access to the original source code.
+ *
+ * The GNU Lesser General Public License v2.1 only license follows.
+ *
+ * =====================================================================
+ *
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package xyz.elemental.mediatype.impl;
+
+import io.lacuna.bifurcan.LinearSet;
+import net.jcip.annotations.NotThreadSafe;
+import net.jcip.annotations.ThreadSafe;
+import xyz.elemental.mediatype.MediaType;
+import xyz.elemental.mediatype.StorageType;
+
+import javax.annotation.Nullable;
+
+/**
+ * Immutable implementation of a Media Type.
+ *
+ * @author Adam Retter
+ */
+@ThreadSafe
+public class MediaTypeImpl implements MediaType {
+
+ private final String identifier;
+ @Nullable private final String[] knownFileExtensions;
+ private final StorageType storageType;
+
+ /**
+ * MediaTypeImpl is 100% immutable.
+ *
+ * Instead of calling the constructor you can incrementally
+ * build one via {@link Builder}.
+ */
+ private MediaTypeImpl(final String identifier, @Nullable final String[] knownFileExtensions, final StorageType storageType) {
+ this.identifier = identifier;
+ this.knownFileExtensions = knownFileExtensions;
+ this.storageType = storageType;
+ }
+
+ @Override
+ public String getIdentifier() {
+ return identifier;
+ }
+
+ @Override
+ public @Nullable String[] getKnownFileExtensions() {
+ return knownFileExtensions;
+ }
+
+ @Override
+ public StorageType getStorageType() {
+ return storageType;
+ }
+
+ /**
+ * Construct a new Media Type.
+ *
+ * @param identifier the Media Type identifier
+ * @param storageType the database storage that should be used for resources of this Media Type
+ *
+ * @return a media type builder.
+ */
+ public static MediaTypeImpl.Builder builder(final String identifier, final StorageType storageType) {
+ return Builder.forMediaType(identifier, storageType);
+ }
+
+ /**
+ * Builder pattern which allows us to
+ * ultimately construct an Immutable MediaTypeImpl.
+ */
+ @NotThreadSafe
+ public static class Builder {
+ private final String identifier;
+ private final StorageType storageType;
+ private final LinearSet knownFileExtensions = new LinearSet<>();
+
+ private Builder(final String identifier, final StorageType storageType) {
+ this.identifier = identifier;
+ this.storageType = storageType;
+ }
+
+ /**
+ * Initiate the build of a MediaTypeImpl.
+ *
+ * @param identifier the Media Type identifier
+ * @param storageType the database storage that should be used for resources of this Media Type
+ */
+ static Builder forMediaType(final String identifier, final StorageType storageType) {
+ return new Builder(identifier, storageType);
+ }
+
+ /**
+ * Add a file extension for the Media Type.
+ *
+ * @param fileExtension a file extension
+ * @return this
+ */
+ public Builder addFileExtension(final String fileExtension) {
+ knownFileExtensions.add(fileExtension);
+ return this;
+ }
+
+ /**
+ * Build the Immutable MediaType.
+ *
+ * @return an immutable MediaType.
+ */
+ public MediaType build() {
+ final String[] aryKnownFileExtensions = knownFileExtensions.size() > 0 ? knownFileExtensions.toArray(size -> new String[size]) : null;
+ return new MediaTypeImpl(identifier, aryKnownFileExtensions, storageType);
+ }
+ }
+}
diff --git a/elemental-media-type/elemental-media-type-impl/src/main/java/xyz/elemental/mediatype/impl/MediaTypeMapper.java b/elemental-media-type/elemental-media-type-impl/src/main/java/xyz/elemental/mediatype/impl/MediaTypeMapper.java
new file mode 100644
index 0000000000..cc1786a2b3
--- /dev/null
+++ b/elemental-media-type/elemental-media-type-impl/src/main/java/xyz/elemental/mediatype/impl/MediaTypeMapper.java
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2014, Evolved Binary Ltd
+ *
+ * This file was originally ported from FusionDB to Elemental by
+ * Evolved Binary, for the benefit of the Elemental Open Source community.
+ * Only the ported code as it appears in this file, at the time that
+ * it was contributed to Elemental, was re-licensed under The GNU
+ * Lesser General Public License v2.1 only for use in Elemental.
+ *
+ * This license grant applies only to a snapshot of the code as it
+ * appeared when ported, it does not offer or infer any rights to either
+ * updates of this source code or access to the original source code.
+ *
+ * The GNU Lesser General Public License v2.1 only license follows.
+ *
+ * =====================================================================
+ *
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package xyz.elemental.mediatype.impl;
+
+import io.lacuna.bifurcan.IList;
+import io.lacuna.bifurcan.LinearList;
+import net.jcip.annotations.NotThreadSafe;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import xyz.elemental.mediatype.StorageType;
+import xyz.elemental.mediatype.impl.configuration.MediaType;
+import xyz.elemental.mediatype.impl.configuration.MediaTypeMappings;
+import xyz.elemental.mediatype.impl.configuration.Storage;
+
+import javax.annotation.Nullable;
+import jakarta.xml.bind.JAXBContext;
+import jakarta.xml.bind.JAXBException;
+import jakarta.xml.bind.Unmarshaller;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.function.Function;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Maps Media Types to database Storage Types.
+ *
Mappings file search order.
+ * The MediaTypeMapper looks in various places in the user's
+ * system for media type mappings files. When requests are made
+ * to resolve media types to storage types, it searches
+ * mappings types files in the following order:
+ *
+ *
The file media-type-mappings.xml from within the user's home directory:
+ *
+ *
Linux/Unix: $XDG_CONFIG_HOME/elemental/media-type-mappings.xml. If $XDG_CONFIG_HOME is not set then, ~/.config/elemental/media-type-mappings.xml
+ *
macOS: $XDG_CONFIG_HOME/elemental/media-type-mappings.xml. If $XDG_CONFIG_HOME is not set then, ~/Library/Preferences/xyz.elemental/media-type-mappings.xml
+ *
Windows: %APPDATA%/Elemental/media-type-mappings.xml. If %APPDATA% is not set then, %USERPROFILE%/AppData/Local/Elemental/media-type-mappings.xml
+ *
+ *
+ *
One or more files named media-type-mappings.xml in the Application's config directory(s).
+ *
The file media-type-mappings.xml on the classpath in the package xyz.elemental.mediatype.
+ *
+ *
+ * @author Adam Retter
+ */
+@NotThreadSafe
+public class MediaTypeMapper {
+
+ private static final Logger LOG = LoggerFactory.getLogger(MediaTypeMapper.class);
+
+ private static final String MEDIA_TYPE_MAPPINGS_FILENAME = "media-type-mappings.xml";
+
+ private final Function[] matchers;
+
+ public MediaTypeMapper(@Nullable final Path... configDirs) {
+ final IList mappingsFileSources = getMappingsFileSources(configDirs);
+ this.matchers = loadMatchers(mappingsFileSources);
+ }
+
+ private static IList getMappingsFileSources(final Path... configDirs) {
+ final LinearList mappingsFileSources = new LinearList<>();
+
+ LOG.trace("MediaTypeMapper: load HOME");
+ @Nullable final Path userConfigFolder = PathUtil.getUserConfigFolder();
+ if (userConfigFolder != null) {
+ final Path mappingsFile = userConfigFolder.resolve(MEDIA_TYPE_MAPPINGS_FILENAME);
+ if (!Files.exists(mappingsFile)) {
+ LOG.trace("No media-type-mappings.xml found at: {}, skipping...", mappingsFile.toAbsolutePath());
+ } else {
+ mappingsFileSources.addLast(new MappingsFileSource(mappingsFile));
+ }
+ }
+
+ LOG.trace("MediaTypeMapper: load application");
+ if (configDirs != null) {
+ for (final Path configDir : configDirs) {
+ final Path mappingsFile = configDir.resolve(MEDIA_TYPE_MAPPINGS_FILENAME);
+ if (!Files.exists(mappingsFile)) {
+ LOG.warn("No custom media-type-mappings.xml found at: {}, skipping...", mappingsFile.toAbsolutePath());
+ } else {
+ mappingsFileSources.addLast(new MappingsFileSource(mappingsFile));
+ }
+ }
+ }
+
+ LOG.trace("ApplicationMimetypesFileTypeMap: load classpath from xyz.elemental.mediatype");
+ final String classPathLocationStr = "xyz/elemental/mediatype/" + MEDIA_TYPE_MAPPINGS_FILENAME;
+ @Nullable final URL url = MediaTypeMapper.class.getClassLoader().getResource(classPathLocationStr);
+ if (url == null) {
+ LOG.trace("No media-type-mappings.xml found on classpath from xyz.elemental.mediatype, skipping...");
+ } else {
+ final InputStream is = MediaTypeMapper.class.getClassLoader().getResourceAsStream(classPathLocationStr);
+ mappingsFileSources.addLast(new MappingsFileSource(url.toString(), is));
+ }
+
+ return mappingsFileSources.forked();
+ }
+
+ @SuppressWarnings("unchecked")
+ private static Function[] loadMatchers(final IList mappingsFileSources) {
+ try {
+ assert (!mappingsFileSources.isLinear());
+
+ final JAXBContext context;
+ final Unmarshaller unmarshaller;
+ try {
+ context = JAXBContext.newInstance(MediaTypeMappings.class);
+ unmarshaller = context.createUnmarshaller();
+ } catch (final JAXBException e) {
+ LOG.error("Unable to instantiate JAXB Unmarshaller: {}", e.getMessage(), e);
+ return new Function[0];
+ }
+
+ final LinearList> matchersList = new LinearList<>();
+ for (final MappingsFileSource mappingsFileSource : mappingsFileSources) {
+ if (mappingsFileSource.path != null && !Files.exists(mappingsFileSource.path)) {
+ LOG.warn("Mappings path {} does not exist, skipping...", mappingsFileSource.path);
+ continue;
+ }
+
+ try {
+ final MediaTypeMappings mappings;
+ if (mappingsFileSource.path != null) {
+ mappings = (MediaTypeMappings) unmarshaller.unmarshal(mappingsFileSource.path.toUri().toURL());
+ } else {
+ mappings = (MediaTypeMappings) unmarshaller.unmarshal(mappingsFileSource.is);
+ }
+ if (mappings == null || mappings.getStorage() == null || mappings.getStorage().isEmpty()) {
+ LOG.error("No mappings found in {} skipping...", mappingsFileSource.location);
+ continue;
+ }
+
+ for (final Storage storage : mappings.getStorage()) {
+ for (final MediaType mediaType : storage.getMediaType()) {
+
+ final StorageType storageType = toStorageType(storage.getType());
+ final Function matcher;
+ switch (mediaType.getMatch()) {
+ case STARTS_WITH:
+ matcher = identifier -> {
+ if (identifier.startsWith(mediaType.getValue())) {
+ return storageType;
+ } else {
+ return null;
+ }
+ };
+ break;
+
+ case FULL:
+ matcher = identifier -> {
+ if (identifier.equals(mediaType.getValue())) {
+ return storageType;
+ } else {
+ return null;
+ }
+ };
+ break;
+
+ case PATTERN:
+ final Pattern pattern = Pattern.compile(mediaType.getValue());
+ final Matcher patternMatcher = pattern.matcher("");
+ matcher = identifier -> {
+ patternMatcher.reset(identifier);
+ if (patternMatcher.matches()) {
+ return storageType;
+ } else {
+ return null;
+ }
+ };
+ break;
+
+ default:
+ throw new IllegalArgumentException();
+ }
+
+ matchersList.addLast(matcher);
+ }
+ }
+
+ } catch (final MalformedURLException | JAXBException e) {
+ @Nullable String message = e.getMessage();
+ if (message == null) {
+ @Nullable final Throwable cause = e.getCause();
+ if (cause != null) {
+ message = cause.getMessage();
+ }
+ }
+ LOG.error("Skipping {} due to error: {}", mappingsFileSource.location, message, e);
+ }
+ }
+
+ return matchersList.toArray(Function[]::new);
+
+ } finally {
+ for (final MappingsFileSource mappingsFileSource : mappingsFileSources) {
+ if (mappingsFileSource.is != null) {
+ try {
+ mappingsFileSource.is.close();
+ } catch (final IOException e) {
+ LOG.warn("Unable to close mappings file source: {} ", mappingsFileSource.location, e);
+ }
+ }
+ }
+ }
+ }
+
+ private static StorageType toStorageType(final xyz.elemental.mediatype.impl.configuration.StorageType type) {
+ switch (type) {
+ case XML:
+ return StorageType.XML;
+
+ case BINARY:
+ return StorageType.BINARY;
+
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ /**
+ * Given a Media Type identifier try and resolve its Storage Type.
+ *
+ * @param mediaTypeIdentifier the identifier of the Media Type.
+ *
+ * @return the Storage Type that should be used for the Media Type,
+ * or {@link StorageType#forUnknown()} if the storage type could not be resolved.
+ */
+ public StorageType resolveStorageType(final String mediaTypeIdentifier) {
+ return resolveStorageType(mediaTypeIdentifier, StorageType.forUnknown());
+ }
+
+ /**
+ * Given a Media Type identifier try and resolve its Storage Type.
+ *
+ * @param mediaTypeIdentifier the identifier of the Media Type.
+ * @param defaultStorageType the default Storage Type to return if a Storage Type cannot
+ * be resolved for the Media Type identifier.
+ *
+ * @return the Storage Type that should be used for the Media Type, or {@link StorageType#forUnknown()} if the storage type could not be found.
+ */
+ public @Nullable StorageType resolveStorageType(final String mediaTypeIdentifier, @Nullable final StorageType defaultStorageType) {
+ for (final Function matcher : matchers) {
+ final StorageType storageType = matcher.apply(mediaTypeIdentifier);
+ if (storageType != null) {
+ return storageType;
+ }
+ }
+
+ return defaultStorageType;
+ }
+
+ private static class MappingsFileSource {
+ private final String location;
+
+ /**
+ * Either {@link #path} or {@link #is} will be set, but never both.
+ */
+ @Nullable private final Path path;
+ @Nullable private final InputStream is;
+
+ private MappingsFileSource(final Path path) {
+ this.location = path.normalize().toAbsolutePath().toString();
+ this.path = path;
+ this.is = null;
+ }
+
+ private MappingsFileSource(final String location, final InputStream is) {
+ this.location = location;
+ this.is = is;
+ this.path = null;
+ }
+ }
+}
diff --git a/elemental-media-type/elemental-media-type-impl/src/main/java/xyz/elemental/mediatype/impl/MediaTypeResolverFactoryImpl.java b/elemental-media-type/elemental-media-type-impl/src/main/java/xyz/elemental/mediatype/impl/MediaTypeResolverFactoryImpl.java
new file mode 100644
index 0000000000..016a73f8e2
--- /dev/null
+++ b/elemental-media-type/elemental-media-type-impl/src/main/java/xyz/elemental/mediatype/impl/MediaTypeResolverFactoryImpl.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2014, Evolved Binary Ltd
+ *
+ * This file was originally ported from FusionDB to Elemental by
+ * Evolved Binary, for the benefit of the Elemental Open Source community.
+ * Only the ported code as it appears in this file, at the time that
+ * it was contributed to Elemental, was re-licensed under The GNU
+ * Lesser General Public License v2.1 only for use in Elemental.
+ *
+ * This license grant applies only to a snapshot of the code as it
+ * appeared when ported, it does not offer or infer any rights to either
+ * updates of this source code or access to the original source code.
+ *
+ * The GNU Lesser General Public License v2.1 only license follows.
+ *
+ * =====================================================================
+ *
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package xyz.elemental.mediatype.impl;
+
+import xyz.elemental.mediatype.MediaTypeResolver;
+import xyz.elemental.mediatype.MediaTypeResolverFactory;
+
+import javax.annotation.Nullable;
+import java.nio.file.Path;
+
+/**
+ * Implementation of a Media Type Resolver Factory for
+ * constructing {@link MediaTypeResolverImpl} instances.
+ *
+ * @author Adam Retter
+ */
+public class MediaTypeResolverFactoryImpl implements MediaTypeResolverFactory {
+
+ public MediaTypeResolverFactoryImpl() {
+ }
+
+ @Override
+ public MediaTypeResolver newMediaTypeResolver() {
+ return newMediaTypeResolver((Path[]) null);
+ }
+
+ @Override
+ public MediaTypeResolver newMediaTypeResolver(@Nullable final Path... configDirs) {
+ final ApplicationMimetypesFileTypeMap mimetypesFileTypeMap = new ApplicationMimetypesFileTypeMap(
+ configDirs);
+ final MediaTypeMapper mediaTypeMapper = new MediaTypeMapper(configDirs);
+ return new MediaTypeResolverImpl(mimetypesFileTypeMap, mediaTypeMapper);
+ }
+}
diff --git a/elemental-media-type/elemental-media-type-impl/src/main/java/xyz/elemental/mediatype/impl/MediaTypeResolverImpl.java b/elemental-media-type/elemental-media-type-impl/src/main/java/xyz/elemental/mediatype/impl/MediaTypeResolverImpl.java
new file mode 100644
index 0000000000..cf654f90a4
--- /dev/null
+++ b/elemental-media-type/elemental-media-type-impl/src/main/java/xyz/elemental/mediatype/impl/MediaTypeResolverImpl.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2014, Evolved Binary Ltd
+ *
+ * This file was originally ported from FusionDB to Elemental by
+ * Evolved Binary, for the benefit of the Elemental Open Source community.
+ * Only the ported code as it appears in this file, at the time that
+ * it was contributed to Elemental, was re-licensed under The GNU
+ * Lesser General Public License v2.1 only for use in Elemental.
+ *
+ * This license grant applies only to a snapshot of the code as it
+ * appeared when ported, it does not offer or infer any rights to either
+ * updates of this source code or access to the original source code.
+ *
+ * The GNU Lesser General Public License v2.1 only license follows.
+ *
+ * =====================================================================
+ *
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package xyz.elemental.mediatype.impl;
+
+import io.lacuna.bifurcan.IList;
+import io.lacuna.bifurcan.LinearMap;
+import jakarta.activation.MimeTypeEntry;
+import jakarta.activation.MimetypesFileTypeMap;
+import net.jcip.annotations.ThreadSafe;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import xyz.elemental.mediatype.MediaType;
+import xyz.elemental.mediatype.MediaTypeResolver;
+import xyz.elemental.mediatype.StorageType;
+
+import javax.annotation.Nullable;
+import java.nio.file.Path;
+import java.util.Map;
+import java.util.Set;
+
+import static xyz.elemental.mediatype.MediaType.APPLICATION_OCTET_STREAM;
+
+/**
+ * Implementation of a Media Type Resolver.
+ *
+ * Sources the mappings between Media Types and File Extensions
+ * from a {@link MimetypesFileTypeMap}, and then further
+ * maps those onto database storage using a {@link MediaTypeMapper}.
+ *
+ * @author Adam Retter
+ */
+@ThreadSafe
+public class MediaTypeResolverImpl implements MediaTypeResolver {
+
+ private static final Logger LOG = LoggerFactory.getLogger(MediaTypeResolverImpl.class);
+
+ private final io.lacuna.bifurcan.IMap extensionsIndex;
+ private final io.lacuna.bifurcan.IMap identifiersIndex;
+
+ private final MediaType defaultMediaType;
+
+ public MediaTypeResolverImpl(final ApplicationMimetypesFileTypeMap fileTypeMap, final MediaTypeMapper mediaTypeMapper) {
+ final IList>> allEntries = fileTypeMap.getAllEntries();
+ if (allEntries == null) {
+ LOG.warn("Could not load file type maps. No mime types are known to the system!");
+ this.extensionsIndex = io.lacuna.bifurcan.Map.empty();
+ this.identifiersIndex = io.lacuna.bifurcan.Map.empty();
+ this.defaultMediaType = null;
+ return;
+ }
+ assert(!allEntries.isLinear());
+
+ final LinearMap mutExtensionsIndex = new LinearMap<>();
+ final LinearMap mutIdentifiersIndex = new LinearMap<>();
+
+ for (final Set> entrySet : allEntries) {
+ for (final Map.Entry entry : entrySet) {
+ final String fileExtension = entry.getKey().toLowerCase();
+ final String identifier = entry.getValue().getMIMEType().toLowerCase();
+
+ MediaTypeImpl.Builder mediaTypeBuilder = mutExtensionsIndex.get(fileExtension, null);
+ if (mediaTypeBuilder == null) {
+ // not present in extensionsIndex
+
+ mediaTypeBuilder = mutIdentifiersIndex.get(identifier, null);
+ if (mediaTypeBuilder == null) {
+
+ // not present in identifiersIndex or extensionsIndex
+ mediaTypeBuilder = MediaTypeImpl.Builder
+ .forMediaType(identifier, mediaTypeMapper.resolveStorageType(identifier))
+ .addFileExtension(fileExtension);
+
+ mutExtensionsIndex.put(fileExtension, mediaTypeBuilder);
+ mutIdentifiersIndex.put(identifier, mediaTypeBuilder);
+
+ } else {
+
+ // present in identifiersIndex, but not extensionsIndex
+ mediaTypeBuilder.addFileExtension(fileExtension);
+ mutExtensionsIndex.put(fileExtension, mediaTypeBuilder);
+ }
+ }
+ }
+ }
+
+ this.extensionsIndex = mutExtensionsIndex.mapValues((k, v) -> v.build()).forked();
+ this.identifiersIndex = mutIdentifiersIndex.mapValues((k, v) -> v.build()).forked();
+
+ assert(!extensionsIndex.isLinear());
+ assert(!identifiersIndex.isLinear());
+
+ this.defaultMediaType = identifiersIndex.get(APPLICATION_OCTET_STREAM)
+ .orElseGet(() -> MediaTypeImpl.Builder.forMediaType(APPLICATION_OCTET_STREAM, StorageType.BINARY).build());
+ }
+
+ @Override
+ public @Nullable MediaType fromFileName(@Nullable final Path path) {
+ if (path == null) {
+ return null;
+ }
+ return fromFileNameImpl(path.getFileName().toString());
+ }
+
+ @Override
+ public @Nullable MediaType fromFileName(@Nullable String path) {
+ if (path == null) {
+ return null;
+ }
+
+ // if this is a path, just take the last segment i.e. the filename
+ int pathSepIdx = -1;
+ if ((pathSepIdx = path.lastIndexOf('/')) > -1) {
+ path = path.substring(pathSepIdx + 1);
+ } else if ((pathSepIdx = path.lastIndexOf('\\')) > -1) {
+ path = path.substring(pathSepIdx + 1);
+ }
+
+ return fromFileNameImpl(path);
+ }
+
+ private @Nullable MediaType fromFileNameImpl(final String fileName) {
+ final int idx = fileName.lastIndexOf("."); // period index
+ if (idx == -1) {
+ return null;
+ }
+
+ final String extension = fileName.substring(idx + 1);
+ if (extension.isEmpty()) {
+ return null;
+ }
+
+ return extensionsIndex.get(extension.toLowerCase(), null);
+ }
+
+ @Override
+ public @Nullable MediaType fromString(@Nullable final String mediaType) {
+ if (mediaType == null) {
+ return null;
+ }
+
+ return identifiersIndex.get(mediaType.toLowerCase(), null);
+ }
+
+ @Override
+ public MediaType forUnknown() {
+ return defaultMediaType;
+ }
+}
diff --git a/elemental-media-type/elemental-media-type-impl/src/main/java/xyz/elemental/mediatype/impl/PathUtil.java b/elemental-media-type/elemental-media-type-impl/src/main/java/xyz/elemental/mediatype/impl/PathUtil.java
new file mode 100644
index 0000000000..de54559a70
--- /dev/null
+++ b/elemental-media-type/elemental-media-type-impl/src/main/java/xyz/elemental/mediatype/impl/PathUtil.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2014, Evolved Binary Ltd
+ *
+ * This file was originally ported from FusionDB to Elemental by
+ * Evolved Binary, for the benefit of the Elemental Open Source community.
+ * Only the ported code as it appears in this file, at the time that
+ * it was contributed to Elemental, was re-licensed under The GNU
+ * Lesser General Public License v2.1 only for use in Elemental.
+ *
+ * This license grant applies only to a snapshot of the code as it
+ * appeared when ported, it does not offer or infer any rights to either
+ * updates of this source code or access to the original source code.
+ *
+ * The GNU Lesser General Public License v2.1 only license follows.
+ *
+ * =====================================================================
+ *
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package xyz.elemental.mediatype.impl;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.Nullable;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import static xyz.elemental.mediatype.impl.StringUtil.emptyStringAsNull;
+
+/**
+ * Utilities for working with Paths.
+ *
+ * @author Adam Retter
+ */
+class PathUtil {
+
+ private static final Logger LOG = LoggerFactory.getLogger(PathUtil.class);
+
+ /**
+ * Gets the config directory from the user's home folder.
+ *
+ * @return One of the following:
+ *
+ *
Linux/Unix: $XDG_CONFIG_HOME/elemental. If $XDG_CONFIG_HOME is not set then, ~/.config/elemental
+ *
macOS: $XDG_CONFIG_HOME/elemental. If $XDG_CONFIG_HOME is not set then, ~/Library/Preferences/xyz.elemental
+ *
Windows: %APPDATA%/Elemental. If %APPDATA% is not set then, %USERPROFILE%/AppData/Local/Elemental
+ *
+ * or null if the environment variables or home folder cannot be resolved.
+ */
+ static @Nullable Path getUserConfigFolder() {
+ final String osName = System.getProperty("os.name").toLowerCase();
+
+ if (osName.startsWith("windows")) {
+ // Windows
+ @Nullable String appDataPath = emptyStringAsNull(System.getenv("APPDATA"));
+
+ if (appDataPath == null) {
+ @Nullable String userProfilePath = emptyStringAsNull(System.getProperty("user.home"));
+ if (userProfilePath == null) {
+ LOG.warn("Unable to find environment variables %APPDATA% or %USERPROFILE%");
+ } else {
+ appDataPath = userProfilePath + "\\AppData\\Local";
+ }
+ }
+
+ if (appDataPath != null) {
+ return Paths.get(appDataPath, "Elemental");
+ }
+
+ } else {
+ @Nullable final String xdgConfigPath = emptyStringAsNull(System.getenv("XDG_CONFIG_HOME"));
+ if (xdgConfigPath != null) {
+ return Paths.get(xdgConfigPath, "elemental");
+ }
+
+ @Nullable final String homePath = System.getProperty("user.home");
+ if (homePath == null) {
+ LOG.warn("Unable to find environment variable %HOME%");
+ } else {
+ if (osName.startsWith("mac os x")) {
+ // macOS
+ return Paths.get(homePath, "Library", "Preferences", "xyz.elemental");
+
+ } else {
+ // Linux/Unix (or anything else)
+ return Paths.get(homePath, ".config", "elemental");
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Gets the data directory from the user's home folder.
+ *
+ * @return One of the following:
+ *
+ *
Linux/Unix: $XDG_DATA_HOME If $XDG_DATA_HOME is not set then, ~/.local/share
+ *
macOS: $XDG_DATA_HOME. If $XDG_DATA_HOME is not set then, ~/Library/Application Support
+ *
Windows: %APPDATA%. If %APPDATA% is not set then, %USERPROFILE%/AppData/Local
+ *
+ * or null if the environment variables or home folder cannot be resolved.
+ */
+ static @Nullable Path getUserDataFolder() {
+ final String osName = System.getProperty("os.name").toLowerCase();
+
+ if (osName.startsWith("windows")) {
+ // Windows
+ @Nullable String appDataPath = emptyStringAsNull(System.getenv("APPDATA"));
+
+ if (appDataPath == null) {
+ @Nullable String userProfilePath = emptyStringAsNull(System.getProperty("user.home"));
+ if (userProfilePath == null) {
+ LOG.warn("Unable to find environment variables %APPDATA% or %USERPROFILE%");
+ } else {
+ appDataPath = userProfilePath + "\\AppData\\Local";
+ }
+ }
+
+ if (appDataPath != null) {
+ return Paths.get(appDataPath);
+ }
+
+ } else {
+ @Nullable final String xdgConfigPath = emptyStringAsNull(System.getenv("XDG_DATA_HOME"));
+ if (xdgConfigPath != null) {
+ return Paths.get(xdgConfigPath);
+ }
+
+ @Nullable final String homePath = System.getProperty("user.home");
+ if (homePath == null) {
+ LOG.warn("Unable to find environment variable %HOME%");
+ } else {
+ if (osName.startsWith("mac os x")) {
+ // macOS
+ return Paths.get(homePath, "Library", "Application Support");
+
+ } else {
+ // Linux/Unix (or anything else)
+ return Paths.get(homePath, ".local", "share");
+ }
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/elemental-media-type/elemental-media-type-impl/src/main/java/xyz/elemental/mediatype/impl/StringUtil.java b/elemental-media-type/elemental-media-type-impl/src/main/java/xyz/elemental/mediatype/impl/StringUtil.java
new file mode 100644
index 0000000000..fb28ac87f2
--- /dev/null
+++ b/elemental-media-type/elemental-media-type-impl/src/main/java/xyz/elemental/mediatype/impl/StringUtil.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014, Evolved Binary Ltd
+ *
+ * This file was originally ported from FusionDB to Elemental by
+ * Evolved Binary, for the benefit of the Elemental Open Source community.
+ * Only the ported code as it appears in this file, at the time that
+ * it was contributed to Elemental, was re-licensed under The GNU
+ * Lesser General Public License v2.1 only for use in Elemental.
+ *
+ * This license grant applies only to a snapshot of the code as it
+ * appeared when ported, it does not offer or infer any rights to either
+ * updates of this source code or access to the original source code.
+ *
+ * The GNU Lesser General Public License v2.1 only license follows.
+ *
+ * =====================================================================
+ *
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package xyz.elemental.mediatype.impl;
+
+import javax.annotation.Nullable;
+
+/**
+ * Utilities for working with Strings.
+ *
+ * @author Adam Retter
+ */
+class StringUtil {
+
+ static @Nullable String emptyStringAsNull(@Nullable String str) {
+ if (str != null) {
+ str = str.trim();
+ if (str.isEmpty()) {
+ str = null;
+ }
+ }
+ return str;
+ }
+}
diff --git a/elemental-media-type/elemental-media-type-impl/src/main/resources/META-INF/services/xyz.elemental.mediatype.MediaTypeResolverFactory b/elemental-media-type/elemental-media-type-impl/src/main/resources/META-INF/services/xyz.elemental.mediatype.MediaTypeResolverFactory
new file mode 100644
index 0000000000..cf19bc412e
--- /dev/null
+++ b/elemental-media-type/elemental-media-type-impl/src/main/resources/META-INF/services/xyz.elemental.mediatype.MediaTypeResolverFactory
@@ -0,0 +1 @@
+xyz.elemental.mediatype.impl.MediaTypeResolverFactoryImpl
\ No newline at end of file
diff --git a/elemental-media-type/elemental-media-type-impl/src/main/xjb/media-type-mappings.xjb b/elemental-media-type/elemental-media-type-impl/src/main/xjb/media-type-mappings.xjb
new file mode 100644
index 0000000000..7df9688282
--- /dev/null
+++ b/elemental-media-type/elemental-media-type-impl/src/main/xjb/media-type-mappings.xjb
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/elemental-media-type/elemental-media-type-impl/src/main/xsd/media-type-mappings.xsd b/elemental-media-type/elemental-media-type-impl/src/main/xsd/media-type-mappings.xsd
new file mode 100644
index 0000000000..254bd9ed38
--- /dev/null
+++ b/elemental-media-type/elemental-media-type-impl/src/main/xsd/media-type-mappings.xsd
@@ -0,0 +1,156 @@
+
+
+
+
+
+
+ Maps files of various Media Types to the type of storage
+ that should be used for persisting those files.
+
+
+
+
+
+
+
+
+
+
+
+ Each type of storage should only appear once
+
+
+
+
+
+
+
+
+ The type of persistent storage to use for various Media Types
+
+
+
+
+
+
+
+
+
+
+
+ Matches a Media Type
+
+
+
+
+
+
+
+
+
+
+
+
+ Types of persistent storage
+
+
+
+
+ Native XML document storage within the database
+
+
+
+
+
+
+
+
+ Binary document storage within the database
+
+
+
+
+
+
+
+ Different types of Media Type matching
+
+
+
+
+ Media Type must exactly match the supplied value
+
+
+
+
+ Media Type(s) must start-with the supplied value
+
+
+
+
+ Media Type(s) must match the supplied Java Regular Expression
+
+
+
+
+
+
+
diff --git a/elemental-media-type/elemental-media-type-impl/src/test/java/xyz/elemental/mediatype/impl/MediaTypeResolverImplTest.java b/elemental-media-type/elemental-media-type-impl/src/test/java/xyz/elemental/mediatype/impl/MediaTypeResolverImplTest.java
new file mode 100644
index 0000000000..f90a90d06e
--- /dev/null
+++ b/elemental-media-type/elemental-media-type-impl/src/test/java/xyz/elemental/mediatype/impl/MediaTypeResolverImplTest.java
@@ -0,0 +1,833 @@
+/*
+ * Copyright (C) 2014, Evolved Binary Ltd
+ *
+ * This file was originally ported from FusionDB to Elemental by
+ * Evolved Binary, for the benefit of the Elemental Open Source community.
+ * Only the ported code as it appears in this file, at the time that
+ * it was contributed to Elemental, was re-licensed under The GNU
+ * Lesser General Public License v2.1 only for use in Elemental.
+ *
+ * This license grant applies only to a snapshot of the code as it
+ * appeared when ported, it does not offer or infer any rights to either
+ * updates of this source code or access to the original source code.
+ *
+ * The GNU Lesser General Public License v2.1 only license follows.
+ *
+ * =====================================================================
+ *
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package xyz.elemental.mediatype.impl;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import xyz.elemental.mediatype.MediaType;
+import xyz.elemental.mediatype.MediaTypeResolver;
+import xyz.elemental.mediatype.StorageType;
+
+import javax.annotation.Nullable;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+public class MediaTypeResolverImplTest {
+
+ // TODO(AR) if an explicit content type is provided, e.g. HTTP PUT, store the mime type with the document data??? what if its not provided, lookup and store, or lookup on retrieval?
+
+ private static MediaTypeMapper MEDIA_TYPE_MAPPER = null;
+ private static MediaTypeResolver DEFAULT_MEDIA_RESOLVER = null;
+ private static MediaTypeResolver APPLICATION_MEDIA_RESOLVER = null;
+
+ @BeforeAll
+ public static void setupMediaResolvers() throws URISyntaxException {
+ @Nullable final URL mediaTypeMappings = MediaTypeResolverImplTest.class.getResource("media-type-mappings.xml");
+ assertNotNull(mediaTypeMappings);
+ final Path configDir = Paths.get(mediaTypeMappings.toURI()).getParent();
+ MEDIA_TYPE_MAPPER = new MediaTypeMapper(configDir);
+
+ final ApplicationMimetypesFileTypeMap defaultMimetypesFileTypeMap = new ApplicationMimetypesFileTypeMap((Path[]) null);
+ DEFAULT_MEDIA_RESOLVER = new MediaTypeResolverImpl(defaultMimetypesFileTypeMap, MEDIA_TYPE_MAPPER);
+
+ APPLICATION_MEDIA_RESOLVER = new MediaTypeResolverFactoryImpl().newMediaTypeResolver(configDir);
+ }
+
+ //
+ @Test
+ public void allResolveAtomExtension() {
+ assertAllResolveFromFileName("something.atom", MediaType.APPLICATION_ATOM, new String[] {"atom"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveCsvExtension() {
+ assertAllResolveFromFileName("something.csv", MediaType.TEXT_CSV, new String[] {"csv"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void allResolveDocxExtension() {
+ assertAllResolveFromFileName("something.docx", MediaType.APPLICATION_OPENXML_WORDPROCESSING, new String[] {"docx"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveDtdExtension() {
+ assertAllResolveFromFileName("something.dtd", MediaType.APPLICATION_XML_DTD, new String[] {"dtd"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void allResolveGifExtension() {
+ assertAllResolveFromFileName("something.gif", MediaType.IMAGE_GIF, new String[] {"gif"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void allResolveGmlExtension() {
+ assertAllResolveFromFileName("something.gml", MediaType.APPLICATION_GML, new String[] {"gml"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveHtmExtension() {
+ assertAllResolveFromFileName("something.htm", MediaType.TEXT_HTML, new String[] {"htm", "html"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void allResolveHtmlExtension() {
+ assertAllResolveFromFileName("something.html", MediaType.TEXT_HTML, new String[] {"htm", "html"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void allResolveJpegExtension() {
+ assertAllResolveFromFileName("something.jpeg", MediaType.IMAGE_JPEG, new String[] {"jpe", "jpg", "jpeg"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void allResolveJpgExtension() {
+ assertAllResolveFromFileName("something.jpg", MediaType.IMAGE_JPEG, new String[] {"jpe", "jpg", "jpeg"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void allResolveJsExtension() {
+ assertAllResolveFromFileName("something.js", MediaType.TEXT_JAVASCRIPT, new String[] {"js", "mjs"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void allResolveJsonExtension() {
+ assertAllResolveFromFileName("something.json", MediaType.APPLICATION_JSON, new String[] {"json"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void allResolveMadsExtension() {
+ assertAllResolveFromFileName("something.mads", MediaType.APPLICATION_MADS, new String[] {"mads"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveMetsExtension() {
+ assertAllResolveFromFileName("something.mets", MediaType.APPLICATION_METS, new String[] {"mets"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveModsExtension() {
+ assertAllResolveFromFileName("something.mods", MediaType.APPLICATION_MODS, new String[] {"mods"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveMrcxExtension() {
+ assertAllResolveFromFileName("something.mrcx", MediaType.APPLICATION_MARC, new String[] {"mrcx"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveN3Extension() {
+ assertAllResolveFromFileName("something.n3", MediaType.TEXT_N3, new String[] {"n3"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void allResolveNcxExtension() {
+ assertAllResolveFromFileName("something.ncx", MediaType.APPLICATION_NCX, new String[] {"ncx"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveOdtExtension() {
+ assertAllResolveFromFileName("something.odt", MediaType.APPLICATION_OPENDOCUMENT_TEXT, new String[] {"odt"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveOdpExtension() {
+ assertAllResolveFromFileName("something.odp", MediaType.APPLICATION_OPENDOCUMENT_PRESENTATION, new String[] {"odp"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveOdsExtension() {
+ assertAllResolveFromFileName("something.ods", MediaType.APPLICATION_OPENDOCUMENT_SPREADSHEET, new String[] {"ods"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveOpfExtension() {
+ assertAllResolveFromFileName("something.opf", MediaType.APPLICATION_OEBPS_PACKAGE, new String[] {"opf"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolvePngExtension() {
+ assertAllResolveFromFileName("something.png", MediaType.IMAGE_PNG, new String[] {"png"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void allResolvePptxExtension() {
+ assertAllResolveFromFileName("something.pptx", MediaType.APPLICATION_OPENXML_PRESENTATION, new String[] {"pptx"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveRncExtension() {
+ assertAllResolveFromFileName("something.rnc", MediaType.APPLICATION_RELAXNG_COMPACT, new String[] {"rnc"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void allResolveRssExtension() {
+ assertAllResolveFromFileName("something.rss", MediaType.APPLICATION_RSS, new String[] {"rss"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveSruExtension() {
+ assertAllResolveFromFileName("something.sru", MediaType.APPLICATION_SRU, new String[] {"sru"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveTtlExtension() {
+ assertAllResolveFromFileName("something.ttl", MediaType.TEXT_TURTLE, new String[] {"ttl"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void allResolveTxtExtension() {
+ assertAllResolveFromFileName("something.txt", MediaType.TEXT_PLAIN, new String[] {"txt", "def", "log", "in", "conf", "text", "list"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void allResolveWsdlExtension() {
+ assertAllResolveFromFileName("something.wsdl", MediaType.APPLICATION_WSDL, new String[] {"wsdl"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveXhtExtension() {
+ assertAllResolveFromFileName("something.xht", MediaType.APPLICATION_XHTML, new String[] {"xht", "xhtml"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveXhtmlExtension() {
+ assertAllResolveFromFileName("something.xhtml", MediaType.APPLICATION_XHTML, new String[] {"xht", "xhtml"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveXlsxExtension() {
+ assertAllResolveFromFileName("something.xlsx", MediaType.APPLICATION_OPENXML_SPREADSHEET, new String[] {"xlsx"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveXplExtension() {
+ assertAllResolveFromFileName("something.xpl", MediaType.APPLICATION_XPROC, new String[] {"xpl"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveXsltExtension() {
+ assertAllResolveFromFileName("something.xslt", MediaType.APPLICATION_XSLT, new String[] {"xslt"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveAtomIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.APPLICATION_ATOM, new String[] {"atom"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveCsvIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.TEXT_CSV, new String[] {"csv"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void allResolveDocxIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.APPLICATION_OPENXML_WORDPROCESSING, new String[] {"docx"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveDtdIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.APPLICATION_XML_DTD, new String[] {"dtd"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void allResolveGifIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.IMAGE_GIF, new String[] {"gif"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void allResolveGmlIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.APPLICATION_GML, new String[] {"gml"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveHtmlIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.TEXT_HTML, new String[] {"htm", "html"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void allResolveJpegIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.IMAGE_JPEG, new String[] {"jpe", "jpg", "jpeg"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void allResolveJsIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.TEXT_JAVASCRIPT, new String[] {"js", "mjs"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void allResolveJsonIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.APPLICATION_JSON, new String[] {"json"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void allResolveMadsIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.APPLICATION_MADS, new String[] {"mads"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveMetsIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.APPLICATION_METS, new String[] {"mets"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveModsIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.APPLICATION_MODS, new String[] {"mods"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveMrcxIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.APPLICATION_MARC, new String[] {"mrcx"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveN3Identifier() {
+ assertAllResolveFromIdentifier(MediaType.TEXT_N3, new String[] {"n3"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void allResolveNcxIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.APPLICATION_NCX, new String[] {"ncx"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveOdtIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.APPLICATION_OPENDOCUMENT_TEXT, new String[] {"odt"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveOdpIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.APPLICATION_OPENDOCUMENT_PRESENTATION, new String[] {"odp"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveOdsIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.APPLICATION_OPENDOCUMENT_SPREADSHEET, new String[] {"ods"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveOpfIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.APPLICATION_OEBPS_PACKAGE, new String[] {"opf"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolvePngIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.IMAGE_PNG, new String[] {"png"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void allResolvePptxIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.APPLICATION_OPENXML_PRESENTATION, new String[] {"pptx"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveRncIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.APPLICATION_RELAXNG_COMPACT, new String[] {"rnc"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void allResolveRssIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.APPLICATION_RSS, new String[] {"rss"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveSruIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.APPLICATION_SRU, new String[] {"sru"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveTtlIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.TEXT_TURTLE, new String[] {"ttl"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void allResolveTxtIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.TEXT_PLAIN, new String[] {"txt", "def", "log", "in", "conf", "text", "list"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void allResolveWsdlIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.APPLICATION_WSDL, new String[] {"wsdl"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveXhtmlIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.APPLICATION_XHTML, new String[] {"xht", "xhtml"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveXlsxIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.APPLICATION_OPENXML_SPREADSHEET, new String[] {"xlsx"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveXplIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.APPLICATION_XPROC, new String[] {"xpl"}, StorageType.XML);
+ }
+
+ @Test
+ public void allResolveXsltIdentifier() {
+ assertAllResolveFromIdentifier(MediaType.APPLICATION_XSLT, new String[] {"xslt"}, StorageType.XML);
+ }
+ //
+
+
+ //
+ @Test
+ public void defaultResolveRdfExtension() {
+ assertDefaultResolveFromFileName("something.rdf", MediaType.APPLICATION_RDF_XML, new String[] {"rdf"}, StorageType.XML);
+ }
+
+ /**
+ * The Media Type for SVGZ is horribly broken, see: w3c/svgwg/issues/701
+ * So it is overridden in the application's own mime.types file,
+ * see {@link #applicationResolveSvgExtension()}.
+ */
+ @Test
+ public void defaultResolveSvgExtension() {
+ assertDefaultResolveFromFileName("something.svg", MediaType.IMAGE_SVG, new String[] {"svg", "svgz"}, StorageType.XML);
+ }
+
+ /**
+ * The Media Type for SVGZ is horribly broken, see: w3c/svgwg/issues/701
+ * So it is overridden in the application's own mime.types file,
+ * see {@link #applicationResolveSvgzExtension()}.
+ */
+ @Test
+ public void defaultResolveSvgzExtension() {
+ assertDefaultResolveFromFileName("something.svgz", MediaType.IMAGE_SVG, new String[] {"svg", "svgz"}, StorageType.XML);
+ }
+
+ @Test
+ public void defaultResolveTeiExtension() {
+ assertDefaultResolveFromFileName("something.tei", MediaType.APPLICATION_TEI, new String[] {"tei", "teicorpus"}, StorageType.XML);
+ }
+
+ @Test
+ public void defaultResolveTeicorpusExtension() {
+ assertDefaultResolveFromFileName("something.teicorpus", MediaType.APPLICATION_TEI, new String[] {"tei", "teicorpus"}, StorageType.XML);
+ }
+
+ @Test
+ public void defaultResolveXmlExtension() {
+ assertDefaultResolveFromFileName("something.xml", MediaType.APPLICATION_XML, new String[] {"xsl", "xml"}, StorageType.XML);
+ }
+
+ @Test
+ public void defaultResolveXslExtension() {
+ assertDefaultResolveFromFileName("something.xsl", MediaType.APPLICATION_XML, new String[] {"xsl", "xml"}, StorageType.XML);
+ }
+
+ @Test
+ public void defaultResolveRdfIdentifier() {
+ assertDefaultResolveFromIdentifier(MediaType.APPLICATION_RDF_XML, new String[] {"rdf"}, StorageType.XML);
+ }
+
+ /**
+ * The Media Type for SVGZ is horribly broken, see: w3c/svgwg/issues/701
+ * So it is overridden in the application's own mime.types file.
+ */
+ @Test
+ public void defaultResolveSvgIdentifier() {
+ assertDefaultResolveFromIdentifier(MediaType.IMAGE_SVG, new String[] {"svg", "svgz"}, StorageType.XML);
+ }
+
+ @Test
+ public void defaultResolveTeiIdentifier() {
+ assertDefaultResolveFromIdentifier(MediaType.APPLICATION_TEI, new String[] {"tei", "teicorpus"}, StorageType.XML);
+ }
+
+ @Test
+ public void defaultResolveXmlIdentifier() {
+ assertDefaultResolveFromIdentifier(MediaType.APPLICATION_XML, new String[] {"xsl", "xml"}, StorageType.XML);
+ }
+ //
+
+
+ //
+ @Test
+ public void applicationResolveDitaExtension() {
+ assertApplicationResolveFromFileName("something.dita",MediaType.APPLICATION_DITA, new String[] {"dita", "ditamap", "ditaval"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveDitamapExtension() {
+ assertApplicationResolveFromFileName("something.ditamap",MediaType.APPLICATION_DITA, new String[] {"dita", "ditamap", "ditaval"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveDitavalExtension() {
+ assertApplicationResolveFromFileName("something.ditaval",MediaType.APPLICATION_DITA, new String[] {"dita", "ditamap", "ditaval"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveFoExtension() {
+ assertApplicationResolveFromFileName("something.fo", MediaType.APPLICATION_XML, new String[] {"fo", "nvdl", "rng", "stx", "xconf", "xml", "xsd", "xsl"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveNvdlExtension() {
+ assertApplicationResolveFromFileName("something.nvdl", MediaType.APPLICATION_XML, new String[] {"fo", "nvdl", "rng", "stx", "xconf", "xml", "xsd", "xsl"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveOddExtension() {
+ assertApplicationResolveFromFileName("something.odd", MediaType.APPLICATION_TEI, new String[] {"odd", "tei", "teicorpus"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveOwlExtension() {
+ assertApplicationResolveFromFileName("something.owl", MediaType.APPLICATION_RDF_XML, new String[] {"xmp", "owl", "rdf"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveMdExtension() {
+ assertApplicationResolveFromFileName("something.md", MediaType.TEXT_MARKDOWN, new String[] {"md"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void applicationResolveRdfExtension() {
+ assertApplicationResolveFromFileName("something.rdf", MediaType.APPLICATION_RDF_XML, new String[] {"xmp", "owl", "rdf"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveRngExtension() {
+ assertApplicationResolveFromFileName("something.rng", MediaType.APPLICATION_XML, new String[] {"fo", "nvdl", "rng", "stx", "xconf", "xml", "xsd", "xsl"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveSchExtension() {
+ assertApplicationResolveFromFileName("something.sch", MediaType.APPLICATION_SCHEMATRON, new String[] {"sch"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveStxExtension() {
+ assertApplicationResolveFromFileName("something.stx", MediaType.APPLICATION_XML, new String[] {"fo", "nvdl", "rng", "stx", "xconf", "xml", "xsd", "xsl"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveSvgExtension() {
+ assertApplicationResolveFromFileName("something.svg", MediaType.IMAGE_SVG, new String[] {"svg", "svgz"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveSvgzExtension() {
+ assertApplicationResolveFromFileName("something.svgz", MediaType.IMAGE_SVG_GZIP, new String[] {"svg", "svgz"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveTeiExtension() {
+ assertApplicationResolveFromFileName("something.tei", MediaType.APPLICATION_TEI, new String[] {"odd", "tei", "teicorpus"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveTeicorpusExtension() {
+ assertApplicationResolveFromFileName("something.teicorpus", MediaType.APPLICATION_TEI, new String[] {"odd", "tei", "teicorpus"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveXarExtension() {
+ assertApplicationResolveFromFileName("something.xar", MediaType.APPLICATION_EXPATH_PACKAGE_ZIP, new String[] {"xar"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void applicationResolveXconfExtension() {
+ assertApplicationResolveFromFileName("something.xconf", MediaType.APPLICATION_XML, new String[] {"fo", "nvdl", "rng", "stx", "xconf", "xml", "xsd", "xsl"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveXmiExtension() {
+ assertApplicationResolveFromFileName("something.xmi", MediaType.APPLICATION_XMI, new String[] {"xmi"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveXmlExtension() {
+ assertApplicationResolveFromFileName("something.xml", MediaType.APPLICATION_XML, new String[] {"fo", "nvdl", "rng", "stx", "xconf", "xml", "xsd", "xsl"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveXmpExtension() {
+ assertApplicationResolveFromFileName("something.xmp", MediaType.APPLICATION_RDF_XML, new String[] {"xmp", "owl", "rdf"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveXqExtension() {
+ assertApplicationResolveFromFileName("something.xq", MediaType.APPLICATION_XQUERY, new String[] {"xq", "xql", "xqm", "xquery", "xqws", "xqy"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void applicationResolveXqlExtension() {
+ assertApplicationResolveFromFileName("something.xql", MediaType.APPLICATION_XQUERY, new String[] {"xq", "xql", "xqm", "xquery", "xqws", "xqy"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void applicationResolveXqmExtension() {
+ assertApplicationResolveFromFileName("something.xqm", MediaType.APPLICATION_XQUERY, new String[] {"xq", "xql", "xqm", "xquery", "xqws", "xqy"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void applicationResolveXqueryExtension() {
+ assertApplicationResolveFromFileName("something.xquery", MediaType.APPLICATION_XQUERY, new String[] {"xq", "xql", "xqm", "xquery", "xqws", "xqy"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void applicationResolveXqwsExtension() {
+ assertApplicationResolveFromFileName("something.xqws", MediaType.APPLICATION_XQUERY, new String[] {"xq", "xql", "xqm", "xquery", "xqws", "xqy"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void applicationResolveXqxExtension() {
+ assertApplicationResolveFromFileName("something.xqx", MediaType.APPLICATION_XQUERY_XML, new String[] {"xqx"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveXqyExtension() {
+ assertApplicationResolveFromFileName("something.xqy", MediaType.APPLICATION_XQUERY, new String[] {"xq", "xql", "xqm", "xquery", "xqws", "xqy"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void applicationResolveXsdExtension() {
+ assertApplicationResolveFromFileName("something.xsd", MediaType.APPLICATION_XML, new String[] {"fo", "nvdl", "rng", "stx", "xconf", "xml", "xsd", "xsl"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveXslExtension() {
+ assertApplicationResolveFromFileName("something.xsl", MediaType.APPLICATION_XML, new String[] {"fo", "nvdl", "rng", "stx", "xconf", "xml", "xsd", "xsl"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveDitaIdentifier() {
+ assertApplicationResolveFromIdentifier(MediaType.APPLICATION_DITA, new String[] {"dita", "ditamap", "ditaval"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveMdIdentifier() {
+ assertApplicationResolveFromIdentifier(MediaType.TEXT_MARKDOWN, new String[] {"md"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void applicationResolveRdfIdentifier() {
+ assertApplicationResolveFromIdentifier(MediaType.APPLICATION_RDF_XML, new String[] {"xmp", "owl", "rdf"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveSchIdentifier() {
+ assertApplicationResolveFromIdentifier(MediaType.APPLICATION_SCHEMATRON, new String[] {"sch"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveSvgIdentifier() {
+ assertApplicationResolveFromIdentifier(MediaType.IMAGE_SVG, new String[] {"svg", "svgz"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveSvgzIdentifier() {
+ assertApplicationResolveFromIdentifier(MediaType.IMAGE_SVG_GZIP, new String[] {"svg", "svgz"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveTeiIdentifier() {
+ assertApplicationResolveFromIdentifier(MediaType.APPLICATION_TEI, new String[] {"odd", "tei", "teicorpus"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveXmiIdentifier() {
+ assertApplicationResolveFromIdentifier(MediaType.APPLICATION_XMI, new String[] {"xmi"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveXmlIdentifier() {
+ assertApplicationResolveFromIdentifier(MediaType.APPLICATION_XML, new String[] {"fo", "nvdl", "rng", "stx", "xconf", "xml", "xsd", "xsl"}, StorageType.XML);
+ }
+
+ @Test
+ public void applicationResolveXqueryIdentifier() {
+ assertApplicationResolveFromIdentifier(MediaType.APPLICATION_XQUERY, new String[] {"xq", "xql", "xqm", "xquery", "xqws", "xqy"}, StorageType.BINARY);
+ }
+
+ @Test
+ public void applicationResolveXqueryXIdentifier() {
+ assertApplicationResolveFromIdentifier(MediaType.APPLICATION_XQUERY_XML, new String[] {"xqx"}, StorageType.XML);
+ }
+ //
+
+
+ /**
+ * Check that multiple levels of mime.types files
+ * yield correct lookups via. both
+ * ApplicationMimetypesFileTypeMap and MediaTypeResolverImpl.
+ */
+ @Test
+ public void resolveFromCorrectLevel() throws URISyntaxException {
+ @Nullable final URL defaultApplicationMimeTypes = MediaTypeResolverImplTest.class.getResource("mime.types");
+ assertNotNull(defaultApplicationMimeTypes);
+ final Path defaultApplicationTypesConfigDir = Paths.get(defaultApplicationMimeTypes.toURI()).getParent();
+ final String packageNamePath = MediaTypeResolverImplTest.class.getPackage().getName().replace('.', '/');
+
+ @Nullable final URL moreSpecificMimeTypes = MediaTypeResolverImplTest.class.getResource("/" + packageNamePath + "/test/levels/mime.types");
+ assertNotNull(moreSpecificMimeTypes);
+ final Path moreSpecificApplicationTypesConfigDir = Paths.get(moreSpecificMimeTypes.toURI()).getParent();
+
+ // NOTE(AR) moreSpecificApplicationTypesConfigDir is provided first so that it has highest priority
+ final ApplicationMimetypesFileTypeMap mimetypesFileTypeMap = new ApplicationMimetypesFileTypeMap(
+ moreSpecificApplicationTypesConfigDir,
+ defaultApplicationTypesConfigDir);
+
+ assertEquals("test/extensible-markup-language", mimetypesFileTypeMap.getContentType("something.xadam"));
+ assertEquals("test/prs.existdb.collection-config+xml", mimetypesFileTypeMap.getContentType("something.xconf"));
+ assertEquals("test/extensible-markup-language", mimetypesFileTypeMap.getContentType("something.xml"));
+ assertEquals(MediaType.APPLICATION_XML, mimetypesFileTypeMap.getContentType("something.xsd"));
+ assertEquals("test/x.xsl+xml", mimetypesFileTypeMap.getContentType("something.xsl"));
+
+ final MediaTypeResolverImpl specificMediaTypeResolver = new MediaTypeResolverImpl(mimetypesFileTypeMap, MEDIA_TYPE_MAPPER);
+
+ assertResolveFromFileName(specificMediaTypeResolver, "something.xadam", "test/extensible-markup-language", new String[] {"xml", "xadam"}, StorageType.BINARY);
+ assertResolveFromFileName(specificMediaTypeResolver, "something.xconf", "test/prs.existdb.collection-config+xml", new String[] {"xconf"}, StorageType.XML);
+ assertResolveFromFileName(specificMediaTypeResolver, "something.xml", "test/extensible-markup-language", new String[] {"xml", "xadam"}, StorageType.BINARY);
+ assertResolveFromFileName(specificMediaTypeResolver, "something.xsd", MediaType.APPLICATION_XML, new String[] {"nvdl", "stx", "xsd", "fo", "rng"}, StorageType.XML);
+ assertResolveFromFileName(specificMediaTypeResolver, "something.xsl", "test/x.xsl+xml", new String[] {"xsl"}, StorageType.XML);
+
+ assertResolveFromIdentifier(specificMediaTypeResolver, "test/extensible-markup-language", new String[] { "xml", "xadam" }, StorageType.BINARY);
+ assertResolveFromIdentifier(specificMediaTypeResolver, "test/prs.existdb.collection-config+xml", new String[] {"xconf"}, StorageType.XML);
+ assertResolveFromIdentifier(specificMediaTypeResolver, MediaType.APPLICATION_XML, new String[] {"nvdl", "stx", "xsd", "fo", "rng"}, StorageType.XML);
+ assertResolveFromIdentifier(specificMediaTypeResolver, "test/x.xsl+xml", new String[] {"xsl"}, StorageType.XML);
+ }
+
+ //
+ @Test
+ public void allResolveNonExistentExtension() {
+ final String fileName = "something.nonexistent";
+
+ final MediaTypeResolver[] allResolvers = {
+ DEFAULT_MEDIA_RESOLVER,
+ APPLICATION_MEDIA_RESOLVER
+ };
+
+ for (final MediaTypeResolver resolver : allResolvers) {
+ assertNotNull(resolver);
+
+ @Nullable MediaType mediaType = resolver.fromFileName(fileName);
+ assertNull(mediaType);
+ mediaType = resolver.fromFileName(Paths.get(fileName));
+ assertNull(mediaType);
+ }
+ }
+
+ @Test
+ public void allResolveNonExistentIdentifier() {
+ final String identifier = "non/existent";
+
+ final MediaTypeResolver[] allResolvers = {
+ DEFAULT_MEDIA_RESOLVER,
+ APPLICATION_MEDIA_RESOLVER
+ };
+
+ for (final MediaTypeResolver resolver : allResolvers) {
+ assertNotNull(resolver);
+
+ @Nullable MediaType mediaType = resolver.fromString(identifier);
+ assertNull(mediaType);
+ }
+ }
+ //
+
+ private void assertAllResolveFromFileName(final String fileName, final String expectedIdentifier, final String[] expectedExtensions, final StorageType expectedStorageType) {
+ assertDefaultResolveFromFileName(fileName, expectedIdentifier, expectedExtensions, expectedStorageType);
+ assertApplicationResolveFromFileName(fileName, expectedIdentifier, expectedExtensions, expectedStorageType);
+ }
+
+ private void assertDefaultResolveFromFileName(final String fileName, final String expectedIdentifier, final String[] expectedExtensions, final StorageType expectedStorageType) {
+ assertNotNull(DEFAULT_MEDIA_RESOLVER);
+ assertResolveFromFileName(DEFAULT_MEDIA_RESOLVER, fileName, expectedIdentifier, expectedExtensions, expectedStorageType);
+ }
+
+ private void assertApplicationResolveFromFileName(final String fileName, final String expectedIdentifier, final String[] expectedExtensions, final StorageType expectedStorageType) {
+ assertNotNull(APPLICATION_MEDIA_RESOLVER);
+ assertResolveFromFileName(APPLICATION_MEDIA_RESOLVER, fileName, expectedIdentifier, expectedExtensions, expectedStorageType);
+ }
+
+ private void assertResolveFromFileName(final MediaTypeResolver mediaTypeResolver, final String fileName, final String expectedIdentifier, final String[] expectedExtensions, final StorageType expectedStorageType) {
+ // by String
+ @Nullable MediaType mediaType = mediaTypeResolver.fromFileName(fileName);
+ assertNotNull(mediaType);
+ assertEquals(expectedIdentifier, mediaType.getIdentifier());
+ assertArrayAnyOrderEquals(expectedExtensions, mediaType.getKnownFileExtensions());
+ assertEquals(expectedStorageType, mediaType.getStorageType());
+
+ // by Path
+ mediaType = mediaTypeResolver.fromFileName(Paths.get(fileName));
+ assertNotNull(mediaType);
+ assertEquals(expectedIdentifier, mediaType.getIdentifier());
+ assertArrayAnyOrderEquals(expectedExtensions, mediaType.getKnownFileExtensions());
+ assertEquals(expectedStorageType, mediaType.getStorageType());
+ }
+
+ private void assertAllResolveFromIdentifier(final String identifier, final String[] expectedExtensions, final StorageType expectedStorageType) {
+ assertDefaultResolveFromIdentifier(identifier, expectedExtensions, expectedStorageType);
+ assertApplicationResolveFromIdentifier(identifier, expectedExtensions, expectedStorageType);
+ }
+
+ private void assertDefaultResolveFromIdentifier(final String identifier, final String[] expectedExtensions, final StorageType expectedStorageType) {
+ assertNotNull(DEFAULT_MEDIA_RESOLVER);
+ assertResolveFromIdentifier(DEFAULT_MEDIA_RESOLVER, identifier, expectedExtensions, expectedStorageType);
+ }
+
+ private void assertApplicationResolveFromIdentifier(final String identifier, final String[] expectedExtensions, final StorageType expectedStorageType) {
+ assertNotNull(APPLICATION_MEDIA_RESOLVER);
+ assertResolveFromIdentifier(APPLICATION_MEDIA_RESOLVER, identifier, expectedExtensions, expectedStorageType);
+ }
+
+ private void assertResolveFromIdentifier(final MediaTypeResolver mediaTypeResolver, final String identifier, final String[] expectedExtensions, final StorageType expectedStorageType) {
+ final @Nullable MediaType mediaType = mediaTypeResolver.fromString(identifier);
+ assertNotNull(mediaType);
+ assertArrayAnyOrderEquals(expectedExtensions, mediaType.getKnownFileExtensions());
+ assertEquals(expectedStorageType, mediaType.getStorageType());
+ }
+
+ private static void assertArrayAnyOrderEquals(final T[] expected, final T[] actual) {
+ Arrays.sort(expected);
+ Arrays.sort(actual);
+ assertArrayEquals(expected, actual);
+ }
+}
diff --git a/elemental-media-type/elemental-media-type-impl/src/test/resources/xyz/elemental/mediatype/impl/media-type-mappings.xml b/elemental-media-type/elemental-media-type-impl/src/test/resources/xyz/elemental/mediatype/impl/media-type-mappings.xml
new file mode 100644
index 0000000000..6d8e835bbf
--- /dev/null
+++ b/elemental-media-type/elemental-media-type-impl/src/test/resources/xyz/elemental/mediatype/impl/media-type-mappings.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+ application/xml
+ text/xml
+ application/vnd.oasis.opendocument.
+ application/vnd.openxmlformats-
+ [^+]+\+xml$
+
+
+
\ No newline at end of file
diff --git a/elemental-media-type/elemental-media-type-impl/src/test/resources/xyz/elemental/mediatype/impl/mime.types b/elemental-media-type/elemental-media-type-impl/src/test/resources/xyz/elemental/mediatype/impl/mime.types
new file mode 100644
index 0000000000..593bca4d7f
--- /dev/null
+++ b/elemental-media-type/elemental-media-type-impl/src/test/resources/xyz/elemental/mediatype/impl/mime.types
@@ -0,0 +1,51 @@
+#
+# Copyright (C) 2014, Evolved Binary Ltd
+#
+# This file was originally ported from FusionDB to Elemental by
+# Evolved Binary, for the benefit of the Elemental Open Source community.
+# Only the ported code as it appears in this file, at the time that
+# it was contributed to Elemental, was re-licensed under The GNU
+# Lesser General Public License v2.1 only for use in Elemental.
+#
+# This license grant applies only to a snapshot of the code as it
+# appeared when ported, it does not offer or infer any rights to either
+# updates of this source code or access to the original source code.
+#
+# The GNU Lesser General Public License v2.1 only license follows.
+#
+# =====================================================================
+#
+# Elemental
+# Copyright (C) 2024, Evolved Binary Ltd
+#
+# admin@evolvedbinary.com
+# https://www.evolvedbinary.com | https://www.elemental.xyz
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; version 2.1.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+application/dita+xml dita ditamap ditaval
+application/prs.existdb.collection-config+xml xconf
+application/prs.expath.package+zip xar
+application/rdf+xml xmp owl rdf
+application/schematron+xml sch
+application/tei+xml odd tei teicorpus
+application/vnd.xmi+xml xmi
+application/xml fo nvdl rng stx xconf xml xsd xsl
+application/xquery xq xql xqm xquery xqws xqy
+application/xquery+xml xqx
+image/svg+xml svg svgz
+# See: https://github.com/w3c/svgwg/issues/701
+# image/x.svg+gzip svgz
+text/markdown md
\ No newline at end of file
diff --git a/elemental-media-type/elemental-media-type-impl/src/test/resources/xyz/elemental/mediatype/impl/test/levels/mime.types b/elemental-media-type/elemental-media-type-impl/src/test/resources/xyz/elemental/mediatype/impl/test/levels/mime.types
new file mode 100644
index 0000000000..3c4966cf55
--- /dev/null
+++ b/elemental-media-type/elemental-media-type-impl/src/test/resources/xyz/elemental/mediatype/impl/test/levels/mime.types
@@ -0,0 +1,41 @@
+#
+# Copyright (C) 2014, Evolved Binary Ltd
+#
+# This file was originally ported from FusionDB to Elemental by
+# Evolved Binary, for the benefit of the Elemental Open Source community.
+# Only the ported code as it appears in this file, at the time that
+# it was contributed to Elemental, was re-licensed under The GNU
+# Lesser General Public License v2.1 only for use in Elemental.
+#
+# This license grant applies only to a snapshot of the code as it
+# appeared when ported, it does not offer or infer any rights to either
+# updates of this source code or access to the original source code.
+#
+# The GNU Lesser General Public License v2.1 only license follows.
+#
+# =====================================================================
+#
+# Elemental
+# Copyright (C) 2024, Evolved Binary Ltd
+#
+# admin@evolvedbinary.com
+# https://www.evolvedbinary.com | https://www.elemental.xyz
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; version 2.1.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+test/dita+xml dita
+test/prs.existdb.collection-config+xml xconf
+test/extensible-markup-language xadam xml
+test/x.xsl+xml xsl
\ No newline at end of file
diff --git a/elemental-media-type/pom.xml b/elemental-media-type/pom.xml
new file mode 100644
index 0000000000..d9c7277f6a
--- /dev/null
+++ b/elemental-media-type/pom.xml
@@ -0,0 +1,84 @@
+
+
+
+ 4.0.0
+
+
+ xyz.elemental
+ elemental-parent
+ 7.6.0-SNAPSHOT
+ ../elemental-parent
+
+
+ elemental-media-type
+ pom
+
+ Elemental Internet Media Type Resolver
+ Internet Media Type Resolver API and Implementation for Elemental
+
+
+ scm:git:https://github.com/evolvedbinary/elemental.git
+ scm:git:https://github.com/evolvedbinary/elemental.git
+ scm:git:https://github.com/evolvedbinary/elemental.git
+ HEAD
+
+
+
+ elemental-media-type-api
+ elemental-media-type-impl
+
+
+
+
+
+ com.mycila
+ license-maven-plugin
+
+
+
+ ${project.parent.relativePath}/FDB-backport-to-EDB-LGPL-21-ONLY-license.template.txt
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/exist-parent/FDB-backport-LGPL-21-ONLY-license.template.txt b/elemental-parent/FDB-backport-to-EDB-LGPL-21-ONLY-license.template.txt
similarity index 73%
rename from exist-parent/FDB-backport-LGPL-21-ONLY-license.template.txt
rename to elemental-parent/FDB-backport-to-EDB-LGPL-21-ONLY-license.template.txt
index d8360fa40c..b39453e753 100644
--- a/exist-parent/FDB-backport-LGPL-21-ONLY-license.template.txt
+++ b/elemental-parent/FDB-backport-to-EDB-LGPL-21-ONLY-license.template.txt
@@ -1,10 +1,10 @@
Copyright (C) 2014, Evolved Binary Ltd
-This file was originally ported from FusionDB to eXist-db by
-Evolved Binary, for the benefit of the eXist-db Open Source community.
+This file was originally ported from FusionDB to Elemental by
+Evolved Binary, for the benefit of the Elemental Open Source community.
Only the ported code as it appears in this file, at the time that
-it was contributed to eXist-db, was re-licensed under The GNU
-Lesser General Public License v2.1 only for use in eXist-db.
+it was contributed to Elemental, was re-licensed under The GNU
+Lesser General Public License v2.1 only for use in Elemental.
This license grant applies only to a snapshot of the code as it
appeared when ported, it does not offer or infer any rights to either
@@ -12,9 +12,13 @@ updates of this source code or access to the original source code.
The GNU Lesser General Public License v2.1 only license follows.
----------------------------------------------------------------------
+=====================================================================
-Copyright (C) 2014, Evolved Binary Ltd
+Elemental
+Copyright (C) 2024, Evolved Binary Ltd
+
+admin@evolvedbinary.com
+https://www.evolvedbinary.com | https://www.elemental.xyz
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
diff --git a/exist-parent/LGPL-21-license.template.txt b/elemental-parent/elemental-LGPL-21-ONLY-license.template.txt
similarity index 71%
rename from exist-parent/LGPL-21-license.template.txt
rename to elemental-parent/elemental-LGPL-21-ONLY-license.template.txt
index e2a5309009..b3392ee91d 100644
--- a/exist-parent/LGPL-21-license.template.txt
+++ b/elemental-parent/elemental-LGPL-21-ONLY-license.template.txt
@@ -1,13 +1,12 @@
-eXist-db Open Source Native XML Database
-Copyright (C) ${copyright.year} ${copyright.name}
+Elemental
+Copyright (C) 2024, Evolved Binary Ltd
-${email}
-${url}
+admin@evolvedbinary.com
+https://www.evolvedbinary.com | https://www.elemental.xyz
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
-License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version.
+License as published by the Free Software Foundation; version 2.1.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/elemental-parent/pom.xml b/elemental-parent/pom.xml
new file mode 100644
index 0000000000..68a31ad942
--- /dev/null
+++ b/elemental-parent/pom.xml
@@ -0,0 +1,816 @@
+
+
+
+ 4.0.0
+
+ xyz.elemental
+ elemental-parent
+ 7.6.0-SNAPSHOT
+ pom
+
+ Elemental Parent
+ Elemental NoSQL Database
+ https://www.elemental.xyz/
+ 2024
+
+
+ Evolved Binary
+ https://www.evolvedbinary.com
+
+
+
+
+ GNU Lesser General Public License, version 2.1 only
+ https://opensource.org/licenses/LGPL-2.1
+ repo
+
+
+
+
+
+ Adam Retter
+ Evolved Binary
+ https://www.evolvedbinary.com
+ adam@evolvedbinary.com
+
+
+
+
+ scm:git:https://github.com/evolvedbinary/elemental.git
+ scm:git:https://github.com/evolvedbinary/elemental.git
+ scm:git:https://github.com/evolvedbinary/elemental.git
+ HEAD
+
+
+
+
+ Elemental Users
+
+ users+subscribe@elemental.xyz
+ users+unsubscribe@elemental.xyz
+ users@elemental.xyz
+ https://groups.google.com/a/elemental.xyz/g/users
+
+
+
+
+ 21
+ 21
+ UTF-8
+
+ admin@evolvedbinary.com
+ ${project.inceptionYear}, ${project.organization.name} Ltd
+
+
+ .
+
+
+ 6.3.0
+
+
+ evolvedbinary_elemental
+ evolvedbinary
+ https://sonarcloud.io
+ ${project.groupId}:${project.artifactId}
+
+
+ 2.0.3
+ 6.0.1
+ 6.0.1
+ 3.4
+ 2.1.4
+ 4.0.4
+ 4.0.6
+ 2.0.17
+
+
+ 1C
+
+ true
+
+
+
+
+
+ com.google.code.findbugs
+ jsr305
+ 3.0.2
+
+
+
+ io.lacuna
+ bifurcan
+ 0.2.0-rc1
+
+
+
+ net.jcip
+ jcip-annotations
+ 1.0
+
+
+
+ org.slf4j
+ slf4j-api
+ ${slf4j.version}
+
+
+
+ jakarta.activation
+ jakarta.activation-api
+ ${jakarta.activation-api.version}
+
+
+
+ org.eclipse.angus
+ angus-activation
+ ${eclipse.angus-activation.version}
+
+
+
+ jakarta.xml.bind
+ jakarta.xml.bind-api
+ ${jaxb.api.version}
+
+
+
+ org.glassfish.jaxb
+ jaxb-runtime
+ ${jaxb.impl.version}
+ runtime
+
+
+
+ com.sun.activation
+ jakarta.activation
+
+
+
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit.jupiter.version}
+ test
+
+
+
+ org.junit.jupiter
+ junit-jupiter-params
+ ${junit.jupiter.version}
+ test
+
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ ${junit.jupiter.version}
+ test
+
+
+
+
+
+
+
+
+ true
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+ 3.6.2
+
+
+ org.jvnet.jaxb
+ jaxb-maven-plugin
+ 4.0.12
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.14.1
+
+ ${project.build.source}
+ ${project.build.target}
+ ${project.build.sourceEncoding}
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.5.0
+
+
+
+ true
+ true
+
+
+ ${build-tag}
+ ${build-commit}
+ ${build-commit-abbrev}
+ ${build-tstamp}
+ ${build-version}
+ ${maven.build.timestamp}
+ ${project.scm.connection}
+ ${project.description}
+ ${project.url}
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jarsigner-plugin
+ 3.1.0
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 3.4.0
+
+
+
+ true
+ true
+
+
+ ${build-tag}
+ ${build-commit}
+ ${build-commit-abbrev}
+ ${build-tstamp}
+ ${build-version}
+ ${maven.build.timestamp}
+ ${project.scm.connection}
+ ${project.description}
+ ${project.url}
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.12.0
+
+ ${project.build.source}
+
+
+ true
+ true
+
+
+ ${build-tag}
+ ${build-commit}
+ ${build-commit-abbrev}
+ ${build-tstamp}
+ ${build-version}
+ ${maven.build.timestamp}
+ ${project.scm.connection}
+ ${project.description}
+ ${project.url}
+
+
+
+ -Xmaxerrs
+ 65536
+ -Xmaxwarns
+ 65536
+
+
+
+
+ org.apache.maven.plugins
+ maven-clean-plugin
+ 3.5.0
+
+
+ com.mycila
+ license-maven-plugin
+ 5.0.0
+
+ true
+ true
+ ${project.build.sourceEncoding}
+
+ SCRIPT_STYLE
+
+ SLASHSTAR_STYLE
+ SLASHSTAR_STYLE
+ XML_STYLE
+ SCRIPT_STYLE
+ XML_STYLE
+ XML_STYLE
+ XML_STYLE
+ XQUERY_STYLE
+ XQUERY_STYLE
+ XQUERY_STYLE
+ XML_STYLE
+ XML_STYLE
+
+
+
+
+ org.owasp
+ dependency-check-maven
+ 12.1.9
+
+ NVD_API_KEY
+ nvd-api
+
+ ossindex
+
+ true
+
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+
+
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+ 3.4.0
+
+
+ com.code54.mojo
+ buildversion-plugin
+ 1.0.3
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+ 3.9.0
+
+
+ org.apache.maven.plugins
+ maven-project-info-reports-plugin
+ 3.9.0
+
+ false
+
+
+
+ org.apache.maven.plugins
+ maven-site-plugin
+ 3.21.0
+
+
+ org.apache.maven.plugins
+ maven-install-plugin
+ 3.1.4
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+ 3.1.4
+
+
+ org.apache.maven.plugins
+ maven-release-plugin
+ 3.3.1
+
+ true
+ elemental-@{project.version}
+ elemental-release
+
+
+
+ org.sonatype.central
+ central-publishing-maven-plugin
+ 0.9.0
+ true
+
+
+ org.apache.maven.plugins
+ maven-scm-plugin
+ 2.2.1
+
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+ 3.2.8
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ 0.8.14
+
+ jacocoArgLine
+
+ org/exist/xquery/parser/DeclScanner*
+ org/exist/xquery/parser/XQueryLexer*
+ org/exist/xquery/parser/XQueryParser*
+ org/exist/xquery/parser/XQueryTokenTypes*
+ org/exist/xquery/parser/XQueryTreeParser*
+ org/exist/xquery/xqdoc/parser/XQDocLexer*
+ org/exist/xquery/xqdoc/parser/XQDocParser*
+ org/exist/xquery/xqdoc/parser/XQDocParserTokenTypes*
+
+
+
+
+ org.codehaus.mojo
+ versions-maven-plugin
+ 2.20.1
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ 3.5.2
+
+
+ org.junit.platform
+ junit-platform-engine
+ ${junit.platform.version}
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ ${junit.jupiter.version}
+
+
+ org.junit.vintage
+ junit-vintage-engine
+ ${junit.jupiter.version}
+
+
+ org.glassfish.jaxb
+ jaxb-runtime
+ ${jaxb.impl.version}
+
+
+ org.eclipse.angus
+ angus-activation
+ ${eclipse.angus-activation.version}
+ runtime
+
+
+ org.objenesis
+ objenesis
+ ${objenesis.version}
+
+
+
+
+ ${surefire.forkCount}
+ ${surefire.reuseForks}
+ @{jacocoArgLine} --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.ref=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED -Dfile.encoding=${project.build.sourceEncoding}
+
+ UK
+ en
+ Europe/Berlin
+ CLDR,SPI
+ ${project.build.testOutputDirectory}/log4j2.xml
+
+
+ **/*Test.java
+ **/*Tests.java
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-report-plugin
+ 3.5.4
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+ 3.5.4
+
+
+ **/*IT.java
+
+
+
+
+ com.github.hazendaz.maven
+ coveralls-maven-plugin
+ 5.0.0
+
+ ${env.COVERALLS_TOKEN}
+
+
+
+ org.sonarsource.scanner.maven
+ sonar-maven-plugin
+ 5.5.0.6356
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+
+
+ enforce-maven-version
+
+ enforce
+
+
+
+
+ 3.9.0
+
+
+ true
+
+
+
+
+
+ com.mycila
+ license-maven-plugin
+
+
+ false
+
+
+
+
+
+ ${project.parent.relativePath}/elemental-LGPL-21-ONLY-license.template.txt
+
+ elemental-LGPL-21-ONLY-license.template.txt
+ FDB-backport-to-EDB-LGPL-21-ONLY-license.template.txt
+
+
+
+
+
+
+ check-headers
+ verify
+
+ check
+
+
+
+
+
+ org.owasp
+ dependency-check-maven
+
+
+
+ check
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+
+ ${project.build.sourceEncoding}
+ ${project.build.sourceEncoding}
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+
+
+ analyze
+
+ analyze-only
+
+
+ true
+
+
+
+
+
+ com.code54.mojo
+ buildversion-plugin
+
+
+ validate
+
+ set-properties
+
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+
+
+ default-prepare-agent
+
+ prepare-agent
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+
+
+ integration-test
+ integration-test
+
+ integration-test
+
+
+
+ verify
+ verify
+
+ verify
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-release-plugin
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-report-plugin
+
+ true
+
+
+
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+
+
+
+
+ report
+
+
+
+
+
+
+ org.codehaus.mojo
+ versions-maven-plugin
+
+
+
+ dependency-updates-report
+ plugin-updates-report
+ property-updates-report
+
+
+
+
+
+
+
+
+
+
+ elemental-release
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+
+
+ attach-sources
+ package
+
+ jar-no-fork
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+
+
+ attach-sources
+ package
+
+ jar
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+
+
+ sign-artifacts
+ verify
+
+ sign
+
+
+ ${elemental.release.key}
+ false
+ ${elemental.release.public-keyfile}
+ ${elemental.release.private-keyfile}
+ ${elemental.release.key.passphrase}
+
+
+
+
+
+ org.sonatype.central
+ central-publishing-maven-plugin
+
+ central
+ ${project.artifactId}-${project.version}
+ true
+ validated
+
+
+
+
+
+
+
+
+
+ clojars.org
+ https://clojars.org/repo
+
+
+
+
+
+ central-ossrh-staging
+ Central Portal - OSSRH Staging API
+ https://ossrh-staging-api.central.sonatype.com/service/local/staging/deploy/maven2/
+
+
+
+
diff --git a/exist-ant/pom.xml b/exist-ant/pom.xml
index ae8ecb380e..a6fe24bcf4 100644
--- a/exist-ant/pom.xml
+++ b/exist-ant/pom.xml
@@ -1,6 +1,30 @@
+ ${project.parent.relativePath}/../elemental-parent/elemental-LGPL-21-ONLY-license.template.txt
+
+ pom.xml
+ src/**
+
+
+
+
+
+
+ ${project.parent.relativePath}/../elemental-parent/elemental-LGPL-21-ONLY-license.template.txt
+
+ ${project.parent.relativePath}/../exist-parent/existdb-LGPL-21-license.template.txt
+
+
+ pom.xml
+ src/test/resources-filtered/conf.xml
+ src/test/resources/log4j2.xml
+ src/main/java/org/exist/ant/XMLDBStoreTask.java
+
+
+
+
+
+ ${project.parent.relativePath}/../exist-parent/existdb-LGPL-21-license.template.txt
+
+ **.md
+ **.txt
+ **.xar
+ **LICENSE
+ pom.xml
+ xquery-license-style.xml
+ src/test/resources-filtered/conf.xml
+ src/test/resources/log4j2.xml
+ src/main/java/org/exist/ant/XMLDBStoreTask.java
+
+
+
+
+
+
+
-
+
\ No newline at end of file
diff --git a/exist-ant/src/main/java/org/exist/ant/XMLDBStoreTask.java b/exist-ant/src/main/java/org/exist/ant/XMLDBStoreTask.java
index 14e8b0a96e..4f2ba92826 100644
--- a/exist-ant/src/main/java/org/exist/ant/XMLDBStoreTask.java
+++ b/exist-ant/src/main/java/org/exist/ant/XMLDBStoreTask.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -25,8 +49,7 @@
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.FileSet;
-import org.exist.util.MimeTable;
-import org.exist.util.MimeType;
+import org.exist.mediatype.MediaTypeUtil;
import org.exist.xmldb.EXistResource;
import org.exist.xmldb.XmldbURI;
import org.exist.xquery.Constants;
@@ -36,9 +59,14 @@
import org.xmldb.api.base.XMLDBException;
import org.xmldb.api.modules.BinaryResource;
import org.xmldb.api.modules.XMLResource;
+import xyz.elemental.mediatype.MediaType;
+import xyz.elemental.mediatype.MediaTypeResolver;
+import xyz.elemental.mediatype.StorageType;
+import xyz.elemental.mediatype.impl.MediaTypeImpl;
import java.io.File;
import java.util.ArrayList;
+import java.util.List;
/**
@@ -55,17 +83,17 @@
* @author Peter Klotz
*/
public class XMLDBStoreTask extends AbstractXMLDBTask {
- private File mimeTypesFile = null;
+ private File mediaTypesFile = null;
private File srcFile = null;
private String targetFile = null;
- private ArrayList fileSetList = null;
+ private List fileSetList = null;
private boolean createCollection = false;
private boolean createSubcollections = false;
private boolean includeEmptyDirs = true;
private String type = null;
private String defaultMimeType = null;
private String forceMimeType = null;
- private MimeTable mtable = null;
+ private MediaTypeResolver mediaTypeResolver = null;
@Override
public void execute() throws BuildException {
@@ -130,42 +158,61 @@ public void execute() throws BuildException {
if (srcFile != null) {
log("Storing " + srcFile.getName());
- final String baseMimeType;
+ MediaType mediaType = getMediaTypeResolver().fromFileName(srcFile.getName());
+ final String baseMediaType;
+
if (forceMimeType != null) {
- baseMimeType = forceMimeType;
+ baseMediaType = forceMimeType;
+
+ } else if (mediaType != null) {
+ baseMediaType = mediaType.getIdentifier();
+
} else {
- final MimeType fileMime = getMimeTable().getContentTypeFor(srcFile.getName());
- if (fileMime != null) {
- baseMimeType = fileMime.getName();
- } else {
- baseMimeType = defaultMimeType;
+ baseMediaType = defaultMimeType;
+ }
+
+ if (type != null) {
+ if ("xml".equals(type) && (mediaType == null || mediaType.getStorageType() != StorageType.XML)) {
+ if (baseMediaType != null) {
+ mediaType = MediaTypeImpl.builder(baseMediaType, StorageType.XML).build();
+ } else {
+ mediaType = mediaTypeResolver.fromString(MediaType.APPLICATION_XML);
+ }
+
+ } else if ("binary".equals(type) && (mediaType == null || mediaType.getStorageType() != StorageType.BINARY)) {
+ if (baseMediaType != null) {
+ mediaType = MediaTypeImpl.builder(baseMediaType, StorageType.BINARY).build();
+ } else {
+ mediaType = mediaTypeResolver.forUnknown();
+ }
}
}
- final MimeType mime;
- if ("xml".equals(type)) {
- mime = (baseMimeType != null) ? new MimeType(baseMimeType, MimeType.XML) : MimeType.XML_TYPE;
- } else if ("binary".equals(type)) {
- mime = (baseMimeType != null) ? new MimeType(baseMimeType, MimeType.BINARY) : MimeType.BINARY_TYPE;
- } else {
+ // single file
+ if (mediaType == null) {
final String msg = "Cannot guess mime-type kind for " + srcFile.getName() + ". Treating it as a binary.";
log(msg, Project.MSG_ERR);
- mime = (baseMimeType != null) ? new MimeType(baseMimeType, MimeType.BINARY) : MimeType.BINARY_TYPE;
+ if (baseMediaType != null) {
+ mediaType = MediaTypeImpl.builder(baseMediaType, StorageType.BINARY).build();
+ } else {
+ mediaType = mediaTypeResolver.forUnknown();
+ }
}
+ final Class extends Resource> resourceType = mediaType.getStorageType() == StorageType.XML ? XMLResource.class : BinaryResource.class;
+
if (targetFile == null) {
targetFile = srcFile.getName();
}
try {
- final Class extends Resource> resourceType = mime.isXMLType() ? XMLResource.class : BinaryResource.class;
- log("Creating resource " + targetFile + " in collection " + col.getName() + " of type " + resourceType.getName() + " with mime-type: " + mime.getName(), Project.MSG_DEBUG);
+ log("Creating resource " + targetFile + " in collection " + col.getName() + " of type " + resourceType + " with media-type: " + mediaType.getIdentifier(), Project.MSG_DEBUG);
try (Resource res = col.createResource(targetFile, resourceType)) {
if (srcFile.length() == 0) {
// note: solves bug id 2429889 when this task hits empty files
} else {
res.setContent(srcFile);
- ((EXistResource) res).setMimeType(mime.getName());
+ ((EXistResource) res).setMediaType(mediaType.getIdentifier());
col.storeResource(res);
}
@@ -266,40 +313,53 @@ public void execute() throws BuildException {
col = root;
}
- MimeType currentMime = getMimeTable().getContentTypeFor(file.getName());
- final String currentBaseMimeType;
+ MediaType currentMediaType = getMediaTypeResolver().fromFileName(file.getName());
+ final String currentBaseMediaType;
if (forceMimeType != null) {
- currentBaseMimeType = forceMimeType;
+ currentBaseMediaType = forceMimeType;
- } else if (currentMime != null) {
- currentBaseMimeType = currentMime.getName();
+ } else if (currentMediaType != null) {
+ currentBaseMediaType = currentMediaType.getIdentifier();
} else {
- currentBaseMimeType = defaultMimeType;
+ currentBaseMediaType = defaultMimeType;
}
if (type != null) {
- if ("xml".equals(type)) {
- currentMime = (currentBaseMimeType != null) ? (new MimeType(currentBaseMimeType, MimeType.XML)) : MimeType.XML_TYPE;
- } else if ("binary".equals(type)) {
- currentMime = (currentBaseMimeType != null) ? (new MimeType(currentBaseMimeType, MimeType.BINARY)) : MimeType.BINARY_TYPE;
+ if ("xml".equals(type) && (currentMediaType == null || currentMediaType.getStorageType() != StorageType.XML)) {
+ if (currentBaseMediaType != null) {
+ currentMediaType = MediaTypeImpl.builder(currentBaseMediaType, StorageType.XML).build();
+ } else {
+ currentMediaType = mediaTypeResolver.fromString(MediaType.APPLICATION_XML);
+ }
+
+ } else if ("binary".equals(type) && (currentMediaType == null || currentMediaType.getStorageType() != StorageType.BINARY)) {
+ if (currentBaseMediaType != null) {
+ currentMediaType = MediaTypeImpl.builder(currentBaseMediaType, StorageType.BINARY).build();
+ } else {
+ currentMediaType = mediaTypeResolver.forUnknown();
+ }
}
}
- if (currentMime == null) {
+ if (currentMediaType == null) {
final String msg = "Cannot find mime-type kind for " + file.getName() + ". Treating it as a binary.";
log(msg, Project.MSG_ERR);
- currentMime = (currentBaseMimeType != null) ? (new MimeType(currentBaseMimeType, MimeType.BINARY)) : MimeType.BINARY_TYPE;
+ if (currentBaseMediaType != null) {
+ currentMediaType = MediaTypeImpl.builder(currentBaseMediaType, StorageType.BINARY).build();
+ } else {
+ currentMediaType = mediaTypeResolver.forUnknown();
+ }
}
- final Class extends Resource> resourceType = currentMime.isXMLType() ? XMLResource.class : BinaryResource.class;
- log("Creating resource " + file.getName() + " in collection " + col.getName() + " of type " + resourceType.getName() + " with mime-type: " + currentMime.getName(), Project.MSG_DEBUG);
+ final Class extends Resource> resourceType = currentMediaType.getStorageType() == StorageType.XML ? XMLResource.class : BinaryResource.class;
+ log("Creating resource " + file.getName() + " in collection " + col.getName() + " of type " + resourceType + " with media-type: " + currentMediaType.getIdentifier(), Project.MSG_DEBUG);
try (Resource res = col.createResource(file.getName(), resourceType)) {
res.setContent(file);
- ((EXistResource) res).setMimeType(currentMime.getName());
+ ((EXistResource) res).setMediaType(currentMediaType.getIdentifier());
col.storeResource(res);
if (permissions != null) {
@@ -354,8 +414,12 @@ public void setIncludeEmptyDirs(final boolean create) {
this.includeEmptyDirs = create;
}
- public void setMimeTypesFile(final File file) {
- this.mimeTypesFile = file;
+ public void setMimeTypesFile(final File mediaTypesFile) {
+ setMediaTypesFile(mediaTypesFile);
+ }
+
+ public void setMediaTypesFile(final File mediaTypesFile) {
+ this.mediaTypesFile = mediaTypesFile;
}
public void setType(final String type) {
@@ -370,17 +434,19 @@ public void setForceMimeType(final String mimeType) {
this.forceMimeType = mimeType;
}
- private MimeTable getMimeTable() throws BuildException {
- if (mtable == null) {
- if (mimeTypesFile != null && mimeTypesFile.exists()) {
- log("Trying to use MIME Types file " + mimeTypesFile.getAbsolutePath(), Project.MSG_DEBUG);
- mtable = MimeTable.getInstance(mimeTypesFile.toPath());
- } else {
+ private MediaTypeResolver getMediaTypeResolver() throws BuildException {
+ if (mediaTypeResolver == null) {
+ if (mediaTypesFile != null && mediaTypesFile.exists()) {
+ log("Trying to use MIME Types file " + mediaTypesFile.getAbsolutePath(), Project.MSG_DEBUG);
+ mediaTypeResolver = MediaTypeUtil.newMediaTypeResolver(mediaTypesFile.getParentFile().toPath());
+ }
+
+ if (mediaTypeResolver == null) {
log("Using default MIME Types resources", Project.MSG_DEBUG);
- mtable = MimeTable.getInstance();
+ mediaTypeResolver = MediaTypeUtil.newMediaTypeResolver(null);
}
}
- return mtable;
+ return mediaTypeResolver;
}
}
diff --git a/exist-ant/src/test/resources-filtered/conf.xml b/exist-ant/src/test/resources-filtered/conf.xml
index 52cac5dde3..68d805ffc4 100644
--- a/exist-ant/src/test/resources-filtered/conf.xml
+++ b/exist-ant/src/test/resources-filtered/conf.xml
@@ -1,6 +1,30 @@
-
+
-
+
-
-
-
-
-
-
+
-
+
-
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
+
+
+
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
+
-
-
-
+
+
-
+
-
+
-
+
-
+
diff --git a/exist-core-build-tools/pom.xml b/exist-core-build-tools/pom.xml
new file mode 100644
index 0000000000..bae9079dbc
--- /dev/null
+++ b/exist-core-build-tools/pom.xml
@@ -0,0 +1,109 @@
+
+
+
+ 4.0.0
+
+
+ xyz.elemental
+ elemental-parent
+ 7.6.0-SNAPSHOT
+ ../elemental-parent
+
+
+ exist-core-build-tools
+ jar
+
+ eXist-db Core Build Tools
+ Tools for building exist-core
+
+
+ scm:git:https://github.com/evolvedbinary/elemental.git
+ scm:git:https://github.com/evolvedbinary/elemental.git
+ scm:git:https://github.com/evolvedbinary/elemental.git
+ HEAD
+
+
+
+
+ com.google.code.findbugs
+ jsr305
+
+
+
+ com.squareup
+ javapoet
+ 1.13.0
+
+
+
+
+
+
+ com.mycila
+ license-maven-plugin
+
+
+
+
+ ${project.parent.relativePath}/elemental-LGPL-21-ONLY-license.template.txt
+
+ src/main/java/xyz/elemental/build/tools/spoon/processors/PermissionRequiredProcessor.java
+
+
+
+
+
+
+ check-headers
+ verify
+
+ check
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ none
+
+
+
+
+
+
\ No newline at end of file
diff --git a/exist-core-build-tools/src/main/java/xyz/elemental/build/tools/spoon/processors/PermissionRequiredProcessor.java b/exist-core-build-tools/src/main/java/xyz/elemental/build/tools/spoon/processors/PermissionRequiredProcessor.java
new file mode 100644
index 0000000000..3a2f36510b
--- /dev/null
+++ b/exist-core-build-tools/src/main/java/xyz/elemental/build/tools/spoon/processors/PermissionRequiredProcessor.java
@@ -0,0 +1,357 @@
+/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package xyz.elemental.build.tools.spoon.processors;
+
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.CodeBlock;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.ParameterSpec;
+import com.squareup.javapoet.TypeSpec;
+
+import javax.annotation.Nullable;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.tools.Diagnostic;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Implementation of a Java Annotation Processor that
+ * processes org.exist.security.PermissionRequired annotations
+ * and generates secure subclasses that enforce the checks.
+ *
+ * Plugs into the Java Compiler.
+ *
+ * @author Adam Retter
+ */
+@SupportedAnnotationTypes("org.exist.security.PermissionRequired")
+@SupportedSourceVersion(SourceVersion.RELEASE_21)
+public class PermissionRequiredProcessor extends AbstractProcessor {
+
+ private static final String PERMISSION_REQUIRED_ANNOTATION_NAME = "org.exist.security.PermissionRequired";
+ private static final String PERMISSION_REQUIRED_UNDEFINED = PERMISSION_REQUIRED_ANNOTATION_NAME + ".UNDEFINED";
+ private static final String PERMISSION_REQUIRED_CHECK_CLASS_NAME = "org.exist.security.PermissionRequiredCheck";
+ private static final String PERMISSION_REQUIRED_CHECK_CLASS_METHOD_CHECK_NAME = "checkMethodPermissions";
+ private static final String PERMISSION_REQUIRED_CHECK_CLASS_METHOD_PARAMETER_CHECK_NAME = "checkMethodParameterPermissions";
+ private static final String BASE_CLASS_SUFFIX = "Internal";
+
+ public PermissionRequiredProcessor() {
+ super();
+ }
+
+ @Override
+ public boolean process(final Set extends TypeElement> annotations, final RoundEnvironment roundEnv) {
+ processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, String.format("%s processing round...", PermissionRequiredProcessor.class.getName()));
+
+ // collect the details of the annotated methods and parameters
+ final Map>> annotatedClassesMethods = collectAnnotatedMethodsAndParameters(annotations, roundEnv);
+
+ // generate subclasses from them
+ generateSubClasses(annotatedClassesMethods);
+
+ return true;
+ }
+
+ private void generateSubClasses(final Map>> annotatedClassesMethods) {
+ for (final Map.Entry>> annotatedClassMethods : annotatedClassesMethods.entrySet()) {
+ final TypeElement clazz = annotatedClassMethods.getKey();
+ final String clazzQualifiedName = clazz.getQualifiedName().toString();
+ final String subClazzQualifiedName = clazzQualifiedName.replace(BASE_CLASS_SUFFIX, "");
+
+ try {
+ generateSubClass(clazz, clazzQualifiedName, subClazzQualifiedName, annotatedClassMethods);
+ } catch (final IOException e) {
+ processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, String.format("Failed to generate subclass named: %s of class: %s. Error: %s", subClazzQualifiedName, clazzQualifiedName, e.getMessage()), clazz);
+ }
+ }
+ }
+
+ private void generateSubClass(final TypeElement clazz, final String clazzQualifiedName, final String subClazzQualifiedName, final Map.Entry>> annotatedClassMethods) throws IOException {
+ processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, String.format("\tGenerating subclass named: %s of class: %s", subClazzQualifiedName, clazzQualifiedName));
+
+ final int clazzQualifiedNameLastSep = clazzQualifiedName.lastIndexOf('.');
+ final String clazzPackageName = clazzQualifiedName.substring(0, clazzQualifiedNameLastSep);
+ final String clazzSimpleName = clazzQualifiedName.substring(clazzQualifiedNameLastSep + 1);
+
+ final int subClazzQualifiedNameLastSep = subClazzQualifiedName.lastIndexOf('.');
+ final String subClazzPackageName = subClazzQualifiedName.substring(0, subClazzQualifiedNameLastSep);
+ final String subClazzSimpleName = subClazzQualifiedName.substring(subClazzQualifiedNameLastSep + 1);
+
+ final int checkClassQualifiedNameLastSep = PERMISSION_REQUIRED_CHECK_CLASS_NAME.lastIndexOf('.');
+ final String checkClazzSimpleName = PERMISSION_REQUIRED_CHECK_CLASS_NAME.substring(checkClassQualifiedNameLastSep + 1);
+
+ final TypeSpec.Builder subClazzSpecBuilder = TypeSpec.classBuilder(subClazzSimpleName)
+ .addJavadoc("Wraps {@link $L} with {@link $L} to enforce security.\n\nTHIS CODE WAS GENERATED AT COMPILE TIME BY: $L", clazzSimpleName, checkClazzSimpleName, getClass().getName())
+ .addModifiers(Modifier.PUBLIC)
+ .superclass(ClassName.get(clazzPackageName, clazzSimpleName));
+
+ // copy constructors from class to subclass
+ for (final Element element : clazz.getEnclosedElements()) {
+ if (element instanceof ExecutableElement executableElement) {
+ if ("".equals(executableElement.getSimpleName().toString())) {
+
+ final MethodSpec constructorSpec = MethodSpec.constructorBuilder()
+ .addParameters(executableElement.getParameters().stream().map(ParameterSpec::get).toList())
+ .addModifiers(Modifier.PUBLIC)
+ .addStatement("super($L)", executableElement.getParameters())
+ .build();
+
+ subClazzSpecBuilder.addMethod(constructorSpec);
+
+ } else if ("newInstance".equals(executableElement.getSimpleName().toString())) {
+ // implement abstract newInstance method in subclass
+ final MethodSpec newInstanceSpec = MethodSpec.overriding(executableElement)
+ .addStatement("return new $L($L)", subClazzSimpleName, executableElement.getParameters())
+ .build();
+ subClazzSpecBuilder.addMethod(newInstanceSpec);
+ }
+ }
+ }
+
+ // override annotated methods in subclass
+ for (final Map.Entry> annotatedClassMethod : annotatedClassMethods.getValue().entrySet()) {
+ final ExecutableElement method = annotatedClassMethod.getKey();
+ final String methodName = method.getSimpleName().toString();
+ processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, String.format("\t\tOverriding method: %s", methodName));
+
+ final MethodSpec.Builder methodSpecBuilder = MethodSpec.overriding(annotatedClassMethod.getKey());
+ @Nullable final CodeBlock permissionRequiredCheckStatements = generatePermissionRequiredCheckStatements(method, annotatedClassMethod.getValue());
+ if (permissionRequiredCheckStatements != null) {
+ methodSpecBuilder.addCode(permissionRequiredCheckStatements);
+ }
+ methodSpecBuilder.addStatement("super.$L($L)", methodName, method.getParameters());
+
+ subClazzSpecBuilder.addMethod(methodSpecBuilder.build());
+ }
+
+ final JavaFile javaFile = JavaFile.builder(subClazzPackageName, subClazzSpecBuilder.build())
+ .build();
+
+ javaFile.writeTo(processingEnv.getFiler());
+ }
+
+ private @Nullable CodeBlock generatePermissionRequiredCheckStatements(final ExecutableElement method, final List methodParameters) {
+ @Nullable CodeBlock.Builder codeBlockBuilder = null;
+
+ // Add PermissionRequiredCheck based on Method Annotations
+ @Nullable Requires methodRequires = null;
+ final List extends AnnotationMirror> methodAnnotations = method.getAnnotationMirrors();
+ for (final AnnotationMirror methodAnnotation : methodAnnotations) {
+ final String methodAnnotationName = ((TypeElement) methodAnnotation.getAnnotationType().asElement()).getQualifiedName().toString();
+
+ if (methodAnnotationName.equals(PERMISSION_REQUIRED_ANNOTATION_NAME)) {
+ methodRequires = getRequires(methodAnnotation);
+
+ if (codeBlockBuilder == null) {
+ codeBlockBuilder = CodeBlock.builder();
+ }
+ codeBlockBuilder.add("// NOTE(AR) Enforce Method Permission Required Check\n");
+ codeBlockBuilder.addStatement("$L.$L(this, $L, $L, $L)", PERMISSION_REQUIRED_CHECK_CLASS_NAME, PERMISSION_REQUIRED_CHECK_CLASS_METHOD_CHECK_NAME, methodRequires.user, methodRequires.group, methodRequires.mode);
+
+ processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, String.format("\t\t\tAdded %s", PERMISSION_REQUIRED_CHECK_CLASS_METHOD_CHECK_NAME));
+ }
+ }
+
+ if (methodRequires == null) {
+ methodRequires = new Requires(PERMISSION_REQUIRED_UNDEFINED, PERMISSION_REQUIRED_UNDEFINED, PERMISSION_REQUIRED_UNDEFINED);
+ }
+
+ // Add PermissionRequiredCheck(s) based on Parameter Annotations
+ for (final VariableElement methodParameter : methodParameters) {
+ final String methodParameterName = methodParameter.getSimpleName().toString();
+ final List extends AnnotationMirror> methodParameterAnnotations = methodParameter.getAnnotationMirrors();
+
+ for (final AnnotationMirror methodParameterAnnotation : methodParameterAnnotations) {
+ final String methodParameterAnnotationName = ((TypeElement) methodParameterAnnotation.getAnnotationType().asElement()).getQualifiedName().toString();
+
+ if (methodParameterAnnotationName.equals(PERMISSION_REQUIRED_ANNOTATION_NAME)) {
+ final Requires methodParameterRequires = getRequires(methodParameterAnnotation);
+
+ if (codeBlockBuilder == null) {
+ codeBlockBuilder = CodeBlock.builder();
+ }
+ codeBlockBuilder.add("// NOTE(AR) Enforce Method Parameter Permission Required Check\n");
+ codeBlockBuilder.addStatement("$L.$L(this, $L, $L, $L, $L, $L, $L, $L)", PERMISSION_REQUIRED_CHECK_CLASS_NAME, PERMISSION_REQUIRED_CHECK_CLASS_METHOD_PARAMETER_CHECK_NAME, methodRequires.user, methodRequires.group, methodRequires.mode, methodParameterName, methodParameterRequires.user, methodParameterRequires.group, methodParameterRequires.mode);
+
+ processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, String.format("\t\t\tAdded %s", PERMISSION_REQUIRED_CHECK_CLASS_METHOD_PARAMETER_CHECK_NAME));
+ }
+ }
+ }
+
+ if (codeBlockBuilder != null) {
+ return codeBlockBuilder.build();
+ } else {
+ return null;
+ }
+ }
+
+ private Requires getRequires(final AnnotationMirror annotation) {
+ String user = PERMISSION_REQUIRED_UNDEFINED;
+ String group = PERMISSION_REQUIRED_UNDEFINED;
+ String mode = PERMISSION_REQUIRED_UNDEFINED;
+
+ final Map extends ExecutableElement, ? extends AnnotationValue> annotationValues = annotation.getElementValues();
+ for (final Map.Entry extends ExecutableElement, ? extends AnnotationValue> annotationValue : annotationValues.entrySet()) {
+ final String annotationName = annotationValue.getKey().getSimpleName().toString();
+ final AnnotationValue value = annotationValue.getValue();
+
+ switch (annotationName) {
+ case "user":
+ user = value.toString();
+ break;
+ case "group":
+ group = value.toString();
+ break;
+ case "mode":
+ mode = value.toString();
+ break;
+ }
+ }
+
+ return new Requires(user, group, mode);
+ }
+
+ /**
+ * Collect all the Annotated Method and Parameters
+ * and group them by Class.
+ *
+ * Returns a Map whose key is a Class (of annotated Methods/Parameters),
+ * the value is a Map of methods and a list of any annotated method parameters.
+ * @return Map>
+ */
+ private Map>> collectAnnotatedMethodsAndParameters(final Set extends TypeElement> annotations, final RoundEnvironment roundEnv) {
+ final Map>> annotatedClassesMethods = new LinkedHashMap<>();
+
+ for (final TypeElement annotation : annotations) {
+
+ // Process each element
+ final Set extends Element> annotatedElements = roundEnv.getElementsAnnotatedWith(annotation);
+ for (final Element element : annotatedElements) {
+
+ if (element instanceof final ExecutableElement method) {
+ if (!validateMethod(method)) {
+ continue;
+ }
+
+ final TypeElement clazz = (TypeElement) method.getEnclosingElement();
+ if (!validateClass(clazz)) {
+ continue;
+ }
+
+ annotatedClassesMethods
+ .computeIfAbsent(clazz, c -> new LinkedHashMap<>())
+ .computeIfAbsent(method, m -> new ArrayList<>());
+
+ } else if (element instanceof final VariableElement parameter) {
+ final ExecutableElement method = (ExecutableElement) parameter.getEnclosingElement();
+ if (!validateParameter(method, parameter)) {
+ continue;
+ }
+
+ final TypeElement clazz = (TypeElement) method.getEnclosingElement();
+ if (!validateClass(clazz)) {
+ continue;
+ }
+
+ annotatedClassesMethods
+ .computeIfAbsent(clazz, c -> new LinkedHashMap<>())
+ .computeIfAbsent(method, m -> new ArrayList<>())
+ .add(parameter);
+
+ } else {
+ processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, String.format("The %s annotation is only supported on methods and method parameters", PERMISSION_REQUIRED_ANNOTATION_NAME));
+ continue;
+ }
+ }
+ }
+
+ return annotatedClassesMethods;
+ }
+
+ private boolean validateClass(final TypeElement clazz) {
+ if (!clazz.getModifiers().contains(Modifier.ABSTRACT)) {
+ processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, String.format("The %s annotation is only supported in abstract classes, but found in class: %s", PERMISSION_REQUIRED_ANNOTATION_NAME, clazz.getQualifiedName().toString()));
+ return false;
+ }
+
+ if (!clazz.getSimpleName().toString().endsWith(BASE_CLASS_SUFFIX)) {
+ processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, String.format("The %s annotation is only supported classes whose name is suffixed with the string: '%s', but found in class: %s", PERMISSION_REQUIRED_ANNOTATION_NAME, BASE_CLASS_SUFFIX, clazz.getQualifiedName().toString()));
+ return false;
+ }
+
+ return true;
+ }
+
+ private boolean validateMethod(final ExecutableElement method) {
+ if (method.getModifiers().contains(Modifier.PRIVATE)) {
+ processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, String.format("The %s annotation is not supported on private methods, but found on method: %s.%s", PERMISSION_REQUIRED_ANNOTATION_NAME, ((TypeElement) method.getEnclosingElement()).getQualifiedName().toString(), method.getSimpleName()));
+ return false;
+ }
+
+ if (method.getModifiers().contains(Modifier.FINAL)) {
+ processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, String.format("The %s annotation is not supported on final methods, but found on method: %s.%s", PERMISSION_REQUIRED_ANNOTATION_NAME, ((TypeElement) method.getEnclosingElement()).getQualifiedName().toString(), method.getSimpleName()));
+ return false;
+ }
+
+ return true;
+ }
+
+ private boolean validateParameter(final ExecutableElement method, final VariableElement parameter) {
+ if (method.getModifiers().contains(Modifier.PRIVATE)) {
+ processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, String.format("The %s annotation is not supported on parameters of private methods, but found on parameter: %s of method: %s.%s", PERMISSION_REQUIRED_ANNOTATION_NAME, parameter.getSimpleName(), ((TypeElement) method.getEnclosingElement()).getQualifiedName().toString(), method.getSimpleName()));
+ return false;
+ }
+
+ if (method.getModifiers().contains(Modifier.FINAL)) {
+ processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, String.format("The %s annotation is not supported on parameters of final methods, but found on parameter: %s of method: %s.%s", PERMISSION_REQUIRED_ANNOTATION_NAME, parameter.getSimpleName(), ((TypeElement) method.getEnclosingElement()).getQualifiedName().toString(), method.getSimpleName()));
+ return false;
+ }
+
+ return true;
+ }
+
+ private static class Requires {
+ final String user;
+ final String group;
+ final String mode;
+
+ public Requires(final String user, final String group, final String mode) {
+ this.user = user;
+ this.group = group;
+ this.mode = mode;
+ }
+ }
+}
diff --git a/exist-core-build-tools/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/exist-core-build-tools/src/main/resources/META-INF/services/javax.annotation.processing.Processor
new file mode 100644
index 0000000000..00a8940cc6
--- /dev/null
+++ b/exist-core-build-tools/src/main/resources/META-INF/services/javax.annotation.processing.Processor
@@ -0,0 +1 @@
+xyz.elemental.build.tools.spoon.processors.PermissionRequiredProcessor
\ No newline at end of file
diff --git a/exist-core-jcstress/pom.xml b/exist-core-jcstress/pom.xml
index 887f0ff97f..7c31ae4825 100644
--- a/exist-core-jcstress/pom.xml
+++ b/exist-core-jcstress/pom.xml
@@ -1,6 +1,30 @@
+ ${project.parent.relativePath}/../elemental-parent/elemental-LGPL-21-ONLY-license.template.txt
+
+ pom.xml
+ src/**
+
+
+
+
+
+
+ ${project.parent.relativePath}/../elemental-parent/elemental-LGPL-21-ONLY-license.template.txt
+
+ ${project.parent.relativePath}/../exist-parent/existdb-LGPL-21-license.template.txt
+
+
+ pom.xml
+
+
+
+
+
+ ${project.parent.relativePath}/../exist-parent/existdb-LGPL-21-license.template.txt
+
+ pom.xml
+
+
+
+
+
+
org.apache.maven.pluginsmaven-shade-plugin
diff --git a/exist-core-jmh/pom.xml b/exist-core-jmh/pom.xml
index b67ce91578..9f83718d98 100644
--- a/exist-core-jmh/pom.xml
+++ b/exist-core-jmh/pom.xml
@@ -1,6 +1,30 @@
+ ${project.parent.relativePath}/../elemental-parent/elemental-LGPL-21-ONLY-license.template.txt
+
+ pom.xml
+ src/**
+
+
+
+
+
+
+ ${project.parent.relativePath}/../elemental-parent/elemental-LGPL-21-ONLY-license.template.txt
+
+ ${project.parent.relativePath}/../exist-parent/existdb-LGPL-21-license.template.txt
+
+
+ pom.xml
+
+
+
+
+
- ${project.parent.relativePath}/LGPL-21-license.template.txt
+ ${project.parent.relativePath}/existdb-LGPL-21-license.template.txt
+ pom.xmlsrc/main/java/org/exist/storage/lock/LockTableBenchmark.javasrc/main/java/org/exist/xquery/utils/StringJoinBenchmark.javasrc/main/java/org/exist/xquery/utils/URIUtilsBenchmark.java
@@ -87,7 +141,7 @@
- ${project.parent.relativePath}/FDB-backport-LGPL-21-ONLY-license.template.txt
+ ${project.parent.relativePath}/FDB-backport-to-existdb-LGPL-21-ONLY-license.template.txtsrc/main/java/org/exist/storage/lock/LockTableBenchmark.javasrc/main/java/org/exist/xquery/utils/StringJoinBenchmark.java
diff --git a/exist-core-jmh/src/main/java/org/exist/storage/lock/LockTableBenchmark.java b/exist-core-jmh/src/main/java/org/exist/storage/lock/LockTableBenchmark.java
index 452109bbe8..65ce8cdbfb 100644
--- a/exist-core-jmh/src/main/java/org/exist/storage/lock/LockTableBenchmark.java
+++ b/exist-core-jmh/src/main/java/org/exist/storage/lock/LockTableBenchmark.java
@@ -13,7 +13,7 @@
*
* The GNU Lesser General Public License v2.1 only license follows.
*
- * ---------------------------------------------------------------------
+ * =====================================================================
*
* Copyright (C) 2014, Evolved Binary Ltd
*
diff --git a/exist-core-jmh/src/main/java/org/exist/xquery/utils/StringJoinBenchmark.java b/exist-core-jmh/src/main/java/org/exist/xquery/utils/StringJoinBenchmark.java
index 0524b5610a..4dc48a4337 100644
--- a/exist-core-jmh/src/main/java/org/exist/xquery/utils/StringJoinBenchmark.java
+++ b/exist-core-jmh/src/main/java/org/exist/xquery/utils/StringJoinBenchmark.java
@@ -13,7 +13,7 @@
*
* The GNU Lesser General Public License v2.1 only license follows.
*
- * ---------------------------------------------------------------------
+ * =====================================================================
*
* Copyright (C) 2014, Evolved Binary Ltd
*
diff --git a/exist-core-jmh/src/main/java/org/exist/xquery/utils/URIUtilsBenchmark.java b/exist-core-jmh/src/main/java/org/exist/xquery/utils/URIUtilsBenchmark.java
index ac71bd710e..68182dd508 100644
--- a/exist-core-jmh/src/main/java/org/exist/xquery/utils/URIUtilsBenchmark.java
+++ b/exist-core-jmh/src/main/java/org/exist/xquery/utils/URIUtilsBenchmark.java
@@ -13,7 +13,7 @@
*
* The GNU Lesser General Public License v2.1 only license follows.
*
- * ---------------------------------------------------------------------
+ * =====================================================================
*
* Copyright (C) 2014, Evolved Binary Ltd
*
diff --git a/exist-core/FDB-backport-BSD-3-license.template.txt b/exist-core/FDB-backport-to-existdb-BSD-3-license.template.txt
similarity index 99%
rename from exist-core/FDB-backport-BSD-3-license.template.txt
rename to exist-core/FDB-backport-to-existdb-BSD-3-license.template.txt
index ec7501b6c9..2238e01d42 100644
--- a/exist-core/FDB-backport-BSD-3-license.template.txt
+++ b/exist-core/FDB-backport-to-existdb-BSD-3-license.template.txt
@@ -12,7 +12,7 @@ updates of this source code or access to the original source code.
The BSD 3-Clause license follows.
----------------------------------------------------------------------
+=====================================================================
Copyright (c) 2014, Evolved Binary Ltd
All rights reserved.
diff --git a/exist-core/pom.xml b/exist-core/pom.xml
index e7bd3fa158..5a8a49665f 100644
--- a/exist-core/pom.xml
+++ b/exist-core/pom.xml
@@ -1,6 +1,30 @@
+ xyz.elemental
+ exist-core-build-tools
+ ${project.version}
+ provided
+
+
net.jcipjcip-annotations
@@ -59,7 +92,14 @@
com.fasterxml.jackson.corejackson-core
- 2.13.4
+ 2.20.1
+
+
+
+ com.fasterxml
+ aalto-xml
+ 1.3.4
+ runtime
+ xercesxercesImpl
@@ -138,17 +178,18 @@
org.relaxngjing
- 20220510
+ 20241231
-
+
+
xml-apisxml-apis
-
+ net.sf.saxonsaxon
-
+ xercesxercesImpl
@@ -156,11 +197,23 @@
- org.exist-db
+ xyz.elemental.fork.org.exist-dbexist-start${project.version}
+
+ xyz.elemental
+ elemental-media-type-api
+ ${project.version}
+
+
+
+ xyz.elemental
+ elemental-media-type-impl
+ ${project.version}
+
+
org.exqueryexquery-common
@@ -169,13 +222,19 @@
org.bouncycastlebcprov-jdk18on
- 1.78.1
+ 1.83
- org.lz4
+ at.yawk.lz4lz4-java
- 1.8.0
+ ${lz4-java.version}
+
+
+
+ com.evolvedbinary.j8cu
+ j8cu
+ 3.0.0
@@ -186,7 +245,7 @@
com.fasterxml.uuidjava-uuid-generator
- 5.1.0
+ 5.2.0
@@ -221,18 +280,7 @@
org.jlinejline
- 3.27.1
-
-
-
- org.fusesource.jansi
- jansi
- ${jansi.version}
-
- runtime
+ ${jline.version}
@@ -255,21 +303,16 @@
commons-io
-
- org.apache.commons
- commons-lang3
-
-
commons-loggingcommons-logging
- 1.3.4
+ 1.3.5org.apache.commonscommons-pool2
- 2.12.0
+ 2.13.0
@@ -298,16 +341,10 @@
- org.exist-db.thirdparty.xerces
+ com.evolvedbinary.thirdparty.xercesxercesImpl
- 2.12.2
+ ${xerces.version}jdk14-xml-schema-1.1
-
-
- xml-apis
- xml-apis
-
-
@@ -316,7 +353,7 @@
${nekohtml.version}runtime
-
+ xercesxercesImpl
@@ -324,15 +361,14 @@
- org.apache.ws.commons.util
+ com.evolvedbinary.thirdparty.xml-apis
+ xml-apis
+
+
+
+ com.evolvedbinary.thirdparty.org.apache.ws.commons.utilws-commons-util
- 1.0.2
-
-
- xml-apis
- xml-apis
-
-
+ 1.1.0
+
+
xml-apisxml-apis
+
+
+ xerces
+ xercesImpl
+
@@ -363,19 +405,25 @@
dataruntime
-
+
+
xml-apisxml-apis
+
+
+ xerces
+ xercesImpl
+
- org.exist-db.thirdparty.org.eclipse.wst.xml
+ com.evolvedbinary.thirdparty.org.eclipse.wst.xmlxpath2
- 1.2.0
+ 1.2.1.1runtime
@@ -406,12 +454,6 @@
com.evolvedbinary.thirdparty.org.apache.xmlrpcxmlrpc-common
-
-
- xml-apis
- xml-apis
-
- com.evolvedbinary.thirdparty.org.apache.xmlrpc
@@ -424,12 +466,6 @@
${apache.xmlrpc.version}
-
- org.aspectj
- aspectjrt
- ${aspectj.version}
-
-
org.eclipse.jettyjetty-jaas
@@ -437,7 +473,7 @@
runtime
-
+
org.apache.servicemix.bundlesorg.apache.servicemix.bundles.antlr
@@ -472,13 +508,13 @@
com.fifesoftrsyntaxtextarea
- 3.5.1
+ 3.6.0org.quartz-schedulerquartz
- 2.3.2
+ 2.5.2
@@ -545,13 +581,13 @@
- org.exist-db
+ xyz.elemental.fork.org.exist-dbexist-jetty-config${project.version}test
- org.exist-db
+ xyz.elemental.fork.org.exist-dbexist-samples${project.version}test
@@ -590,11 +626,6 @@
xmlunit-matcherstest
-
- org.xmlunit
- xmlunit-legacy
- test
- com.googlecode.junit-toolboxjunit-toolbox
@@ -624,7 +655,7 @@
NOTE(AR) This is needed to enable loading of Servlets etc
that use Java Annotations for configuration.
This is less than ideal as it allows any extension to
- serve arbitary Web requests, and should ultimately be
+ serve arbitrary Web requests, and should ultimately be
removed. Unfortunately, at this time, it is required for
Monex's Remote Console to function.
-->
@@ -694,59 +725,1119 @@
+ ${project.parent.relativePath}/../elemental-parent/elemental-LGPL-21-ONLY-license.template.txt
+
+ project-suppression.xml
+ src/test/xquery/pi.xqm
+ src/test/xquery/securitymanager/acl.xqm
+ src/main/java/org/exist/dom/memtree/DocumentTypeImpl.java
+ src/test/resources/org/exist/dom/memtree/simple.xhtml
+ src/main/java/org/exist/dom/memtree/reference/AbstractReferenceCharacterData.java
+ src/main/java/org/exist/dom/memtree/reference/AbstractReferenceNodeImpl.java
+ src/main/java/org/exist/dom/memtree/reference/CommentReferenceImpl.java
+ src/main/java/org/exist/dom/memtree/reference/ElementReferenceImpl.java
+ src/main/java/org/exist/dom/memtree/reference/ProcessingInstructionReferenceImpl.java
+ src/main/java/org/exist/dom/memtree/reference/TextReferenceImpl.java
+ src/test/java/org/exist/http/RESTExternalVariableTest.java
+ src/test/java/org/exist/http/urlrewrite/RedirectTest.java
+ src/main/java/org/exist/security/PermissionRequiredCheck.java
+ src/main/java/org/exist/storage/io/AbstractVariableByteOutput.java
+ src/main/java/org/exist/storage/io/VariableByteArrayOutputStream.java
+ src/main/java/org/exist/storage/io/VariableByteBufferInput.java
+ src/main/java/org/exist/storage/io/VariableByteBufferOutput.java
+ src/main/java/org/exist/storage/io/VariableByteFilterInputStream.java
+ src/main/java/org/exist/storage/io/VariableByteFilterOutputStream.java
+ src/main/java/org/exist/storage/io/VariableByteOutput.java
+ src/test/java/org/exist/storage/serializers/NativeSerializerTest.java
+ src/main/java/org/exist/util/ByteOrderMark.java
+ src/main/java/org/exist/util/JREUtil.java
+ src/main/java/org/exist/util/OSUtil.java
+ src/main/java/org/exist/util/StringUtil.java
+ src/main/java/org/exist/util/io/AbstractContentFile.java
+ src/test/java/org/exist/util/serializer/SAXSerializerTest.java
+ src/test/java/org/exist/xmldb/XMLDBExternalVariableTest.java
+ src/main/java/org/exist/xmlrpc/ArrayWrapperParser.java
+ src/main/java/org/exist/xmlrpc/ArrayWrapperSerializer.java
+ src/main/java/org/exist/xmlrpc/XmlRpcExtensionConstants.java
+ src/test/resources-filtered/org/exist/xquery/import-from-pkg-test.conf.xml
+ src/test/java/org/exist/xquery/ImportFromPkgTest.java
+ src/main/java/org/exist/xquery/JavaBinding.java
+ src/test/resources-filtered/org/exist/xquery/JavaBindingTest.conf.xml
+ src/test/java/org/exist/xquery/JavaBindingTest.java
+ src/test/java/org/exist/xquery/WatchdogTest.java
+ src/test/java/org/exist/xquery/XPathUtilTest.java
+ src/main/java/org/exist/xquery/functions/fn/FunDocAvailable.java
+ src/test/java/org/exist/xquery/functions/fn/FunXmlToJsonTest.java
+ src/test/java/org/exist/xquery/functions/fn/ParsingFunctionsTest.java
+ src/test/java/org/exist/xquery/functions/fn/transform/ConvertTest.java
+ src/test/java/org/exist/xquery/functions/fn/transform/FunTransformITTest.java
+ src/test/java/org/exist/xquery/functions/securitymanager/AccountMetadataFunctionsTest.java
+ src/test/java/org/exist/xquery/functions/securitymanager/SecurityManagerTestUtil.java
+ src/main/java/org/exist/xquery/functions/system/FunctionAvailable.java
+ src/test/java/org/exist/xquery/functions/xmldb/XMLDBStoreTest.java
+ src/test/java/org/exist/xquery/functions/xquery3/SerializeTest.java
+ src/main/java/org/exist/xquery/value/ArrayWrapper.java
+ src/test/java/org/exist/xquery/value/DateTimeTypesTest.java
+
+
+
+
+
+
+ ${project.parent.relativePath}/../elemental-parent/elemental-LGPL-21-ONLY-license.template.txt
+
+ ${project.parent.relativePath}/../exist-parent/existdb-LGPL-21-license.template.txt
+
+
+ pom.xml
+ src/test/resources-filtered/conf.xml
+ src/test/resources/log4j2.xml
+ src/test/resources/standalone-webapp/WEB-INF/web.xml
+ src/main/xjb/rest-api.xjb
+ src/test/xquery/parenthesizedLocationStep.xml
+ src/test/xquery/tail-recursion.xml
+ src/test/xquery/maps/maps.xqm
+ src/test/xquery/numbers/format-numbers.xql
+ src/test/xquery/util/util.xml
+ src/test/xquery/xquery3/parse-xml.xqm
+ src/test/xquery/xquery3/serialize.xql
+ src/test/xquery/xquery3/xml-to-json.xql
+ src/main/java/org/exist/Indexer.java
+ src/test/java/org/exist/Indexer2Test.java
+ src/test/java/org/exist/Indexer3Test.java
+ src/test/java/org/exist/IndexerTest.java
+ src/main/java/org/exist/Namespaces.java
+ src/main/resources-filtered/org/exist/system.properties
+ src/test/java/org/exist/TestDataGenerator
+ src/main/java/org/exist/backup/Backup.java
+ src/main/java/org/exist/backup/CreateBackupDialog.java
+ src/test/java/org/exist/backup/DeepEmbeddedBackupRestoreTest.java
+ src/main/java/org/exist/backup/ExportGUI.java
+ src/main/java/org/exist/backup/ExportMain.java
+ src/main/java/org/exist/backup/Main.java
+ src/main/java/org/exist/backup/Restore.java
+ src/test/java/org/exist/backup/RestoreAppsTest.java
+ src/main/java/org/exist/backup/SystemExport.java
+ src/test/java/org/exist/backup/SystemExportFiltersTest.java
+ src/test/java/org/exist/backup/SystemExportImportTest.java
+ src/test/java/org/exist/backup/XMLDBRestoreTest.java
+ src/main/java/org/exist/backup/ZipWriter.java
+ src/main/java/org/exist/backup/restore/AbstractRestoreHandler.java
+ src/main/java/org/exist/backup/restore/AppRestoreUtils.java
+ src/main/java/org/exist/backup/xquery/RetrieveBackup.java
+ src/main/java/org/exist/client/ClientFrame.java
+ src/main/java/org/exist/client/CommandlineOptions.java
+ src/main/java/org/exist/client/Connection.java
+ src/main/java/org/exist/client/ConnectionDialog.java
+ src/main/java/org/exist/client/DocumentView.java
+ src/main/java/org/exist/client/IndexDialog.java
+ src/main/java/org/exist/client/InteractiveClient.java
+ src/main/java/org/exist/client/MediaTypeFileFilter.java
+ src/main/resources/org/exist/client/messages.properties
+ src/main/resources/org/exist/client/messages_es_ES.properties
+ src/main/resources/org/exist/client/messages_fr_FR.properties
+ src/main/resources/org/exist/client/messages_it_IT.properties
+ src/main/resources/org/exist/client/messages_nb_NO.properties
+ src/main/resources/org/exist/client/messages_nl_NL.properties
+ src/main/resources/org/exist/client/messages_no.properties
+ src/main/resources/org/exist/client/messages_ru_RU.properties
+ src/main/resources/org/exist/client/messages_sv_SE.properties
+ src/main/resources/org/exist/client/messages_zh_CN.properties
+ src/main/java/org/exist/client/NewResourceDialog.java
+ src/main/java/org/exist/client/QueryDialog.java
+ src/main/java/org/exist/client/TriggersDialog.java
+ src/main/java/org/exist/client/UploadDialog.java
+ src/main/java/org/exist/client/security/AccessControlEntryDialog.java
+ src/main/java/org/exist/client/security/EditPropertiesDialog.java
+ src/main/java/org/exist/client/security/UserDialog.java
+ src/main/java/org/exist/client/security/UserManagerDialog.java
+ src/main/java/org/exist/collections/Collection.java
+ src/main/java/org/exist/collections/CollectionConfiguration.java
+ src/main/java/org/exist/collections/CollectionConfigurationManager.java
+ src/test/java/org/exist/collections/CollectionOrderTest.java
+ src/test/java/org/exist/collections/CollectionRemovalTest.java
+ src/test/java/org/exist/collections/CollectionStoreTest.java
+ src/main/java/org/exist/collections/LockedCollection.java
+ src/main/java/org/exist/collections/MutableCollection.java
+ src/test/java/org/exist/collections/OpenCollectionTest
+ src/main/java/org/exist/collections/triggers/CollectionTrigger.java
+ src/main/java/org/exist/collections/triggers/CollectionTriggers.java
+ src/main/java/org/exist/collections/triggers/DocumentTrigger.java
+ src/main/java/org/exist/collections/triggers/DocumentTriggers.java
+ src/test/java/org/exist/collections/triggers/HistoryTriggerTest.java
+ src/test/java/org/exist/collections/triggers/MessagesTrigger.java
+ src/test/java/org/exist/collections/triggers/TriggerConfigTest.java
+ src/main/java/org/exist/collections/triggers/XQueryStartupTrigger.java
+ src/main/java/org/exist/collections/triggers/XQueryTrigger.java
+ src/test/java/org/exist/collections/triggers/XQueryTrigger2Test.java
+ src/test/java/org/exist/collections/triggers/XQueryTriggerChainTest.java
+ src/test/java/org/exist/collections/triggers/XQueryTriggerSetGidTest.java
+ src/test/java/org/exist/collections/triggers/XQueryTriggerSetUidTest.java
+ src/test/java/org/exist/collections/triggers/XQueryTriggerTest.java
+ src/main/java/org/exist/config/Configuration.java
+ src/main/java/org/exist/config/ConfigurationImpl.java
+ src/main/java/org/exist/config/Configurator.java
+ src/test/java/org/exist/config/TwoDatabasesTest.java
+ src/test/java/org/exist/deadlocks/GetReleaseBrokerDeadlocksTest.java
+ src/main/java/org/exist/dom/NodeListImpl.java
+ src/main/java/org/exist/dom/QName.java
+ src/main/java/org/exist/dom/memtree/AbstractCharacterData.java
+ src/main/java/org/exist/dom/memtree/AttrImpl.java
+ src/main/java/org/exist/dom/memtree/DocumentBuilderReceiver.java
+ src/main/java/org/exist/dom/memtree/DocumentImpl.java
+ src/test/java/org/exist/dom/memtree/DocumentImplTest.java
+ src/main/java/org/exist/dom/memtree/DOMIndexer.java
+ src/test/java/org/exist/dom/memtree/DOMIndexerTest.java
+ src/test/java/org/exist/dom/memtree/DOMTest.java
+ src/main/java/org/exist/dom/memtree/ElementImpl.java
+ src/main/java/org/exist/dom/memtree/MemTreeBuilder.java
+ src/test/java/org/exist/dom/memtree/MemtreeInXQueryTest.java
+ src/main/java/org/exist/dom/memtree/NamespaceNode.java
+ src/main/java/org/exist/dom/memtree/NodeImpl.java
+ src/main/java/org/exist/dom/memtree/ProcessingInstructionImpl.java
+ src/main/java/org/exist/dom/persistent/AbstractArrayNodeSet.java
+ src/main/java/org/exist/dom/persistent/AbstractCharacterData.java
+ src/main/java/org/exist/dom/persistent/AttrImpl.java
+ src/test/java/org/exist/dom/persistent/BasicNodeSetTest.java
+ src/main/java/org/exist/dom/persistent/BinaryDocument.java
+ src/test/java/org/exist/dom/persistent/CDataIntergationTest.java
+ src/main/java/org/exist/dom/persistent/CommentImpl.java
+ src/test/java/org/exist/dom/persistent/CommentTest.java
+ src/test/java/org/exist/dom/persistent/DefaultDocumentSetTest.java
+ src/test/java/org/exist/dom/persistent/DocTypeTest.java
+ src/main/java/org/exist/dom/persistent/DocumentImpl.java
+ src/main/java/org/exist/dom/persistent/DocumentMetadata.java
+ src/main/java/org/exist/dom/persistent/DocumentSet.java
+ src/main/java/org/exist/dom/persistent/DocumentTypeImpl.java
+ src/main/java/org/exist/dom/persistent/ElementImpl.java
+ src/main/java/org/exist/dom/persistent/EmptyNodeSet.java
+ src/main/java/org/exist/dom/persistent/LockToken.java
+ src/main/java/org/exist/dom/persistent/NewArrayNodeSet.java
+ src/main/java/org/exist/dom/persistent/NodeProxy.java
+ src/main/java/org/exist/dom/persistent/NodeSet.java
+ src/test/java/org/exist/dom/persistent/NodeTest.java
+ src/test/java/org/exist/dom/persistent/PersistentDomTest.java
+ src/main/java/org/exist/dom/persistent/ProcessingInstructionImpl.java
+ src/main/java/org/exist/dom/persistent/SortedNodeSet.java
+ src/main/java/org/exist/dom/persistent/StoredNode.java
+ src/main/java/org/exist/dom/persistent/SymbolTable.java
+ src/test/java/org/exist/dom/persistent/SymbolTableTest.java
+ src/main/java/org/exist/dom/persistent/TextImpl.java
+ src/main/java/org/exist/dom/persistent/VirtualNodeSet.java
+ src/main/java/org/exist/dom/persistent/XMLUtil.java
+ src/test/java/org/exist/http/AbstractHttpTest.java
+ src/main/java/org/exist/http/AuditTrailSessionListener.java
+ src/test/java/org/exist/http/AuditTrailSessionListenerTest.java
+ src/main/java/org/exist/http/Descriptor.java
+ src/main/java/org/exist/http/Response.java
+ src/main/java/org/exist/http/RESTServer.java
+ src/test/java/org/exist/http/RESTServiceTest.java
+ src/main/java/org/exist/http/servlets/AbstractExistHttpServlet.java
+ src/main/java/org/exist/http/servlets/EXistServlet.java
+ src/main/java/org/exist/http/servlets/HttpServletRequestWrapper.java
+ src/main/java/org/exist/http/servlets/RedirectorServlet.java
+ src/main/java/org/exist/http/servlets/XQueryServlet.java
+ src/main/java/org/exist/http/servlets/XSLTServlet.java
+ src/test/java/org/exist/http/urlrewrite/ControllerTest.java
+ src/main/java/org/exist/http/urlrewrite/ModuleCall.java
+ src/main/java/org/exist/http/urlrewrite/PathForward.java
+ src/main/java/org/exist/http/urlrewrite/Redirect.java
+ src/main/java/org/exist/http/urlrewrite/RewriteConfig.java
+ src/test/java/org/exist/http/urlrewrite/URLRewritingTest.java
+ src/main/java/org/exist/http/urlrewrite/XQueryURLRewrite.java
+ src/test/java/org/exist/http/urlrewrite/XQueryURLRewriteTest.java
+ src/main/java/org/exist/indexing/Index.java
+ src/main/java/org/exist/indexing/IndexController.java
+ src/main/java/org/exist/indexing/IndexManager.java
+ src/main/java/org/exist/indexing/ngram/NGramIndexWorker.java
+ src/main/java/org/exist/jetty/JettyStart.java
+ src/main/java/org/exist/jetty/ServerShutdown.java
+ src/main/java/org/exist/jetty/WebAppContext.java
+ src/main/resources/org/exist/launcher/ConfigurationDialog.form
+ src/main/java/org/exist/launcher/ConfigurationDialog.java
+ src/main/java/org/exist/launcher/ConfigurationUtility.java
+ src/main/java/org/exist/launcher/Launcher.java
+ src/main/java/org/exist/launcher/LauncherWrapper.java
+ src/main/java/org/exist/launcher/ServiceManagerFactory.java
+ src/main/java/org/exist/launcher/SplashScreen.java
+ src/main/java/org/exist/launcher/WindowsServiceManager.java
+ src/test/java/org/exist/management/JmxRemoteTest.java
+ src/main/java/org/exist/management/client/JMXClient.java
+ src/main/java/org/exist/management/client/JMXServlet.java
+ src/main/java/org/exist/management/client/JMXtoXML.java
+ src/main/java/org/exist/management/impl/CollectionCache.java
+ src/main/java/org/exist/management/impl/CollectionCacheMXBean.java
+ src/main/java/org/exist/management/impl/Database.java
+ src/main/java/org/exist/management/impl/DatabaseMXBean.java
+ src/main/java/org/exist/management/impl/ExistMBean.java
+ src/main/java/org/exist/management/impl/JMXAgent.java
+ src/main/java/org/exist/management/impl/SanityReport.java
+ src/main/java/org/exist/numbering/DLN.java
+ src/main/java/org/exist/numbering/DLNBase.java
+ src/main/java/org/exist/numbering/DLNFactory.java
+ src/test/java/org/exist/numbering/DLNStorageTest.java
+ src/main/java/org/exist/numbering/NodeId.java
+ src/main/java/org/exist/numbering/NodeIdFactory.java
+ src/main/java/org/exist/protocolhandler/eXistURLStreamHandlerFactory.java
+ src/main/java/org/exist/protocolhandler/URLStreamHandlerStartupTrigger.java
+ src/main/java/org/exist/protocolhandler/embedded/EmbeddedOutputStream.java
+ src/main/java/org/exist/protocolhandler/embedded/InMemoryOutputStream.java
+ src/main/java/org/exist/protocolhandler/protocols/xmldb/EmbeddedURLConnection.java
+ src/main/java/org/exist/protocolhandler/protocols/xmldb/Handler.java
+ src/main/java/org/exist/protocolhandler/protocols/xmldb/InMemoryURLConnection.java
+ src/main/java/org/exist/protocolhandler/xmldb/XmldbURL.java
+ src/main/java/org/exist/protocolhandler/xmlrpc/XmlrpcOutputStream.java
+ src/main/java/org/exist/protocolhandler/xmlrpc/XmlrpcUpload.java
+ src/main/java/org/exist/protocolhandler/xmlrpc/XmlrpcUploadRunnable.java
+ src/main/java/org/exist/repo/AutoDeploymentTrigger.java
+ src/main/java/org/exist/repo/ClasspathHelper.java
+ src/main/java/org/exist/repo/Deployment.java
+ src/main/java/org/exist/repo/ExistRepository.java
+ src/main/java/org/exist/scheduler/UserXQueryJob.java
+ src/main/java/org/exist/scheduler/impl/QuartzSchedulerImpl.java
+ src/main/java/org/exist/security/EffectiveSubject.java
+ src/test/java/org/exist/security/FnDocSecurityTest.java
+ src/main/java/org/exist/security/Permission.java
+ src/main/java/org/exist/security/PermissionRequired.java
+ src/test/java/org/exist/security/RestApiSecurityTest.java
+ src/main/java/org/exist/security/SecurityManager.java
+ src/main/java/org/exist/security/SimpleACLPermissionInternal.java
+ src/test/java/org/exist/security/SimpleACLPermissionTest.java
+ src/main/java/org/exist/security/UnixStylePermissionInternal.java
+ src/test/java/org/exist/security/UnixStylePermissionTest.java
+ src/test/java/org/exist/security/XqueryApiTest.java
+ src/main/java/org/exist/security/internal/AccountImpl.java
+ src/main/java/org/exist/security/internal/aider/UnixStylePermissionAider.java
+ src/main/java/org/exist/source/Source.java
+ src/main/java/org/exist/source/SourceFactory.java
+ src/main/java/org/exist/source/URLSource.java
+ src/test/java/org/exist/stax/EmbeddedXMLStreamReaderTest.java
+ src/test/java/org/exist/storage/AbstractUpdateTest.java
+ src/test/java/org/exist/storage/BFileRecoverTest.java
+ src/test/java/org/exist/storage/BinaryDocumentTest.java
+ src/main/java/org/exist/storage/BrokerFactory.java
+ src/main/java/org/exist/storage/BrokerPool.java
+ src/test/java/org/exist/storage/BrokerPoolsTest.java
+ src/test/java/org/exist/storage/BrokerPoolTest.java
+ src/test/java/org/exist/storage/CollectionTest.java
+ src/test/java/org/exist/storage/ConcurrentBrokerPoolTest.java
+ src/test/java/org/exist/storage/ConcurrentStoreTest.java
+ src/test/java/org/exist/storage/CopyCollectionRecoveryTest.java
+ src/test/java/org/exist/storage/CopyResourceRecoveryTest.java
+ src/test/java/org/exist/storage/CopyResourceTest.java
+ src/main/java/org/exist/storage/DBBroker.java
+ src/test/java/org/exist/storage/DirtyShutdownTest.java
+ src/test/java/org/exist/storage/DOMFileRecoverTest.java
+ src/main/java/org/exist/storage/Indexable.java
+ src/main/java/org/exist/storage/IndexSpec.java
+ src/test/java/org/exist/storage/LargeValuesTest.java
+ src/test/java/org/exist/storage/ModificationTimeTest.java
+ src/test/java/org/exist/storage/MoveCollectionRecoveryTest.java
+ src/test/java/org/exist/storage/MoveOverwriteCollectionTest.java
+ src/test/java/org/exist/storage/MoveOverwriteResourceTest.java
+ src/test/java/org/exist/storage/MoveResourceRecoveryTest.java
+ src/main/java/org/exist/storage/NativeBroker.java
+ src/main/java/org/exist/storage/NativeValueIndex.java
+ src/main/java/org/exist/storage/NodePath.java
+ src/test/java/org/exist/storage/NodePathTest.java
+ src/main/java/org/exist/storage/NotificationService.java
+ src/main/java/org/exist/storage/ProcessMonitor.java
+ src/test/java/org/exist/storage/RangeIndexUpdateTest.java
+ src/test/java/org/exist/storage/RecoverBinary2Test.java
+ src/test/java/org/exist/storage/Recovery2Test.java
+ src/test/java/org/exist/storage/RecoveryTest.java
+ src/test/java/org/exist/storage/ReindexRecoveryTest.java
+ src/test/java/org/exist/storage/ReindexTest.java
+ src/test/java/org/exist/storage/RemoveCollectionTest.java
+ src/test/java/org/exist/storage/RemoveRootCollectionTest.java
+ src/test/java/org/exist/storage/ResourceTest.java
+ src/test/java/org/exist/storage/ShutdownTest.java
+ src/main/java/org/exist/storage/StorageAddress.java
+ src/test/java/org/exist/storage/StoreBinaryTest.java
+ src/test/java/org/exist/storage/StoreResourceTest.java
+ src/test/java/org/exist/storage/UpdateRecoverTest.java
+ src/test/java/org/exist/storage/XIncludeSerializerTest.java
+ src/test/java/org/exist/storage/btree/BTreeTest.java
+ src/main/java/org/exist/storage/btree/TreeMetrics.java
+ src/main/java/org/exist/storage/index/BFile.java
+ src/main/java/org/exist/storage/io/AbstractVariableByteInput.java
+ src/main/java/org/exist/storage/io/VariableByteArrayInput.java
+ src/main/java/org/exist/storage/io/VariableByteInput.java
+ src/main/java/org/exist/storage/io/VariableByteInputToInputStream.java
+ src/main/java/org/exist/storage/io/VariableByteOutputToOutputStream.java
+ src/test/java/org/exist/storage/io/VariableByteStreamTest.java
+ src/test/java/org/exist/storage/lock/DeadlockTest.java
+ src/main/java/org/exist/storage/lock/FileLock.java
+ src/test/java/org/exist/storage/lock/GetXMLResourceNoLockTest.java
+ src/test/java/org/exist/storage/lock/ProtectedModeTest.java
+ src/main/java/org/exist/storage/recovery/RecoveryManager.java
+ src/main/java/org/exist/storage/serializers/EXistOutputKeys.java
+ src/main/java/org/exist/storage/serializers/Serializer.java
+ src/main/java/org/exist/storage/serializers/XIncludeFilter.java
+ src/test/resources-filtered/org/exist/storage/statistics/conf.xml
+ src/main/java/org/exist/storage/sync/SyncTask.java
+ src/test/java/org/exist/storage/util/PauseFunction.java
+ src/main/java/org/exist/test/ExistXmldbEmbeddedServer.java
+ src/main/java/org/exist/test/runner/AbstractTestRunner.java
+ src/main/java/org/exist/test/runner/ExtTestAssumptionFailedFunction.java
+ src/main/java/org/exist/test/runner/ExtTestErrorFunction.java
+ src/main/java/org/exist/test/runner/ExtTestFailureFunction.java
+ src/main/java/org/exist/test/runner/ExtTestFinishedFunction.java
+ src/main/java/org/exist/test/runner/ExtTestIgnoredFunction.java
+ src/main/java/org/exist/test/runner/ExtTestStartedFunction.java
+ src/main/java/org/exist/test/runner/JUnitIntegrationFunction.java
+ src/main/java/org/exist/test/runner/XMLTestRunner.java
+ src/main/java/org/exist/test/runner/XQueryTestRunner.java
+ src/main/java/org/exist/test/runner/XSuite.java
+ src/test/java/org/exist/util/AbstractXMLReaderSecurityTest.java
+ src/main/java/org/exist/util/Collations.java
+ src/test/java/org/exist/util/CollationsTest.java
+ src/main/java/org/exist/util/Configuration.java
+ src/test/java/org/exist/util/DOMSerializerTest.java
+ src/test/java/org/exist/util/LeasableTest.java
+ src/test/java/org/exist/util/MediaTypeResolverTest.java
+ src/main/java/org/exist/util/MimeTable.java
+ src/main/java/org/exist/util/MimeType.java
+ src/main/java/org/exist/util/ParametersExtractor.java
+ src/main/java/org/exist/util/XMLFilenameFilter.java
+ src/test/java/org/exist/util/XMLReaderExpansionTest.java
+ src/test/java/org/exist/util/XMLReaderSecurityTest.java
+ src/main/java/org/exist/util/XQueryFilenameFilter.java
+ src/main/java/org/exist/util/crypto/digest/DigestType.java
+ src/main/java/org/exist/util/io/ByteArrayContent.java
+ src/test/java/org/exist/util/io/ByteArrayContentTest.java
+ src/main/java/org/exist/util/io/ContentFile.java
+ src/main/java/org/exist/util/io/ContentFilePoolObjectFactory.java
+ src/test/java/org/exist/util/io/FilterInputStreamCacheMonitorTest.java
+ src/test/java/org/exist/util/io/OverflowToDiskStreamTest.java
+ src/main/java/org/exist/util/io/VirtualTempPath.java
+ src/test/java/org/exist/util/io/VirtualTempPathTest.java
+ src/test/java/org/exist/util/pool/NodePoolTest.java
+ src/main/java/org/exist/util/serializer/AttrList.java
+ src/main/java/org/exist/util/serializer/DOMSerializer.java
+ src/main/java/org/exist/util/serializer/DOMStreamer.java
+ src/main/java/org/exist/util/serializer/EXISerializer.java
+ src/test/java/org/exist/util/serializer/HTML5WriterTest.java
+ src/main/java/org/exist/util/serializer/SAXSerializer.java
+ src/main/java/org/exist/util/serializer/SerializerObjectFactory.java
+ src/main/java/org/exist/util/serializer/json/JSONObject.java
+ src/test/java/org/exist/util/serializer/json/JSONObjectTest.java
+ src/main/java/org/exist/util/serializer/json/JSONSerializer.java
+ src/test/java/org/exist/util/serializer/json/JSONWriterTest.java
+ src/test/java/org/exist/util/sorters/ListChecker.java
+ src/test/java/org/exist/util/sorters/LongArrayAndObjectChecker.java
+ src/test/java/org/exist/util/sorters/NodeProxyByIdChecker.java
+ src/test/java/org/exist/util/sorters/NodeProxyChecker.java
+ src/test/java/org/exist/util/sorters/ObjectAndIntArrayChecker.java
+ src/test/java/org/exist/util/sorters/PlainArrayChecker.java
+ src/test/java/org/exist/util/sorters/SortTestNodeId.java
+ src/test/resources/org/exist/validation/catalog.xml
+ src/test/java/org/exist/validation/CollectionConfigurationValidationModeTest.java
+ src/test/java/org/exist/validation/DtdEntityTest.java
+ src/main/java/org/exist/validation/XmlLibraryChecker.java
+ src/main/java/org/exist/validation/internal/DatabaseResources.java
+ src/main/resources/org/exist/validation/internal/query/find_catalogs_with_dtd.xq
+ src/main/resources/org/exist/validation/internal/query/find_schema_by_targetNamespace.xq
+ src/main/java/org/exist/validation/resolver/SearchResourceResolver.java
+ src/test/java/org/exist/w3c/tests/TestCase.java
+ src/main/java/org/exist/webstart/JnlpJarFiles.java
+ src/main/java/org/exist/webstart/JnlpWriter.java
+ src/main/java/org/exist/xmldb/AbstractEXistResource.java
+ src/main/java/org/exist/xmldb/AbstractRemoteResource.java
+ src/test/java/org/exist/xmldb/ContentAsDOMTest.java
+ src/test/java/org/exist/xmldb/CreateCollectionsTest.java
+ src/main/java/org/exist/xmldb/EXistResource.java
+ src/test/java/org/exist/xmldb/EXistXMLSerializeTest.java
+ src/test/java/org/exist/xmldb/IndexingTest.java
+ src/main/java/org/exist/xmldb/LocalBinaryResource.java
+ src/main/java/org/exist/xmldb/LocalCollection.java
+ src/main/java/org/exist/xmldb/LocalResourceSet.java
+ src/main/java/org/exist/xmldb/LocalRestoreService.java
+ src/main/java/org/exist/xmldb/LocalXMLResource.java
+ src/main/java/org/exist/xmldb/LocalXPathQueryService.java
+ src/main/java/org/exist/xmldb/RemoteBinaryResource.java
+ src/main/java/org/exist/xmldb/RemoteCollection.java
+ src/test/java/org/exist/xmldb/RemoteCollectionTest.java
+ src/test/java/org/exist/xmldb/RemoteDOMTest.java
+ src/test/java/org/exist/xmldb/RemoteQueryTest.java
+ src/main/java/org/exist/xmldb/RemoteResourceSet.java
+ src/main/java/org/exist/xmldb/RemoteRestoreService.java
+ src/main/java/org/exist/xmldb/RemoteXMLResource.java
+ src/main/java/org/exist/xmldb/RemoteXPathQueryService.java
+ src/test/java/org/exist/xmldb/ResourceTest.java
+ src/test/java/org/exist/xmldb/SerializationTest.java
+ src/test/java/org/exist/xmldb/TestEXistXMLSerialize.java
+ src/test/java/org/exist/xmldb/TreeLevelOrderTest.java
+ src/test/java/org/exist/xmldb/concurrent/AbstractConcurrentTest.java
+ src/test/java/org/exist/xmldb/concurrent/ComplexUpdateTest.java
+ src/test/java/org/exist/xmldb/concurrent/ConcurrentAttrUpdateTest.java
+ src/test/java/org/exist/xmldb/concurrent/ConcurrentQueryTest.java
+ src/test/java/org/exist/xmldb/concurrent/ConcurrentQueryUpdateTest.java
+ src/test/java/org/exist/xmldb/concurrent/ConcurrentResource2Test.java
+ src/test/java/org/exist/xmldb/concurrent/ConcurrentResourceTest.java
+ src/test/java/org/exist/xmldb/concurrent/ConcurrentXUpdateTest.java
+ src/test/java/org/exist/xmldb/concurrent/DBUtils.java
+ src/test/java/org/exist/xmldb/concurrent/FragmentsTest.java
+ src/test/java/org/exist/xmldb/concurrent/TextUpdateTest.java
+ src/test/java/org/exist/xmldb/concurrent/ValueIndexUpdateTest.java
+ src/test/java/org/exist/xmldb/concurrent/XMLGenerator.java
+ src/test/java/org/exist/xmldb/concurrent/action/MultiResourcesAction.java
+ src/main/java/org/exist/xmlrpc/ExistRpcTypeFactory.java
+ src/test/java/org/exist/xmlrpc/QuerySessionTest.java
+ src/main/java/org/exist/xmlrpc/RpcAPI.java
+ src/main/java/org/exist/xmlrpc/RpcConnection.java
+ src/test/java/org/exist/xmlrpc/XmlRpcTest.java
+ src/main/java/org/exist/xqj/Marshaller.java
+ src/test/java/org/exist/xqj/MarshallerTest.java
+ src/main/java/org/exist/xquery/AbstractInternalModule.java
+ src/test/java/org/exist/xquery/CardinalityTest.java
+ src/test/java/org/exist/xquery/CleanupTest.java
+ src/test/java/org/exist/xquery/ConstructedNodesRecoveryTest.java
+ src/main/java/org/exist/xquery/Context.java
+ src/main/java/org/exist/xquery/DecimalFormat.java
+ src/main/java/org/exist/xquery/DeferredFunctionCall.java
+ src/main/java/org/exist/xquery/DynamicCardinalityCheck.java
+ src/main/java/org/exist/xquery/DynamicTypeCheck.java
+ src/main/java/org/exist/xquery/DynamicVariable.java
+ src/test/java/org/exist/xquery/EmbeddedBinariesTest.java
+ src/test/java/org/exist/xquery/EmbeddedBinariesTest.java.java
+ src/main/java/org/exist/xquery/ErrorCodes.java
+ src/main/java/org/exist/xquery/Except.java
+ src/main/java/org/exist/xquery/ExternalModuleImpl.java
+ src/test/java/org/exist/xquery/ForwardReferenceTest.java
+ src/main/java/org/exist/xquery/Function.java
+ src/main/java/org/exist/xquery/FunctionFactory.java
+ src/main/java/org/exist/xquery/Intersect.java
+ src/test/java/org/exist/xquery/LexerTest.java
+ src/main/java/org/exist/xquery/LocationStep.java
+ src/main/java/org/exist/xquery/Module.java
+ src/main/java/org/exist/xquery/NamedFunctionReference.java
+ src/main/java/org/exist/xquery/NameTest.java
+ src/test/java/org/exist/xquery/NodeTypeTest.java
+ src/main/java/org/exist/xquery/Optimizer.java
+ src/main/java/org/exist/xquery/Option.java
+ src/main/java/org/exist/xquery/PathExpr.java
+ src/main/java/org/exist/xquery/PerformanceStatsImpl.java
+ src/test/java/org/exist/xquery/RestBinariesTest.java
+ src/test/java/org/exist/xquery/StoredModuleTest.java
+ src/test/java/org/exist/xquery/TransformTest.java
+ src/main/java/org/exist/xquery/TryCatchExpression.java
+ src/main/java/org/exist/xquery/UserDefinedFunction.java
+ src/main/java/org/exist/xquery/Variable.java
+ src/main/java/org/exist/xquery/VariableDeclaration.java
+ src/main/java/org/exist/xquery/VariableImpl.java
+ src/main/java/org/exist/xquery/VariableReference.java
+ src/test/java/org/exist/xquery/VariablesTest.java
+ src/test/java/org/exist/xquery/WindowClauseTest.java
+ src/test/java/org/exist/xquery/XmldbBinariesTest.java
+ src/test/java/org/exist/xquery/XPathOpOrSpecialCaseTest.java
+ src/test/java/org/exist/xquery/XPathQueryTest.java
+ src/main/java/org/exist/xquery/XPathUtil.java
+ src/main/java/org/exist/xquery/XQueryContext.java
+ src/test/java/org/exist/xquery/XQueryDeclareContextItemTest.java
+ src/test/java/org/exist/xquery/XQueryFunctionsTest.java
+ src/main/java/org/exist/xquery/XQueryProcessingInstruction.java
+ src/test/java/org/exist/xquery/XQueryProcessingInstructionTest.java
+ src/test/java/org/exist/xquery/XQueryTest.java
+ src/test/java/org/exist/xquery/XQueryUpdateTest.java
+ src/main/java/org/exist/xquery/functions/array/ArrayType.java
+ src/test/java/org/exist/xquery/functions/fn/DocTest.java
+ src/main/java/org/exist/xquery/functions/fn/ExtCollection.java
+ src/main/java/org/exist/xquery/functions/fn/FnDefaultLanguage.java
+ src/main/java/org/exist/xquery/functions/fn/FnFormatDates.java
+ src/main/java/org/exist/xquery/functions/fn/FnHasChildren.java
+ src/main/java/org/exist/xquery/functions/fn/FnInnerMost.java
+ src/main/java/org/exist/xquery/functions/fn/FnModule.java
+ src/main/java/org/exist/xquery/functions/fn/FnOuterMost.java
+ src/main/java/org/exist/xquery/functions/fn/FunAbs.java
+ src/main/java/org/exist/xquery/functions/fn/FunAdjustTimezone.java
+ src/main/java/org/exist/xquery/functions/fn/FunAnalyzeString.java
+ src/main/java/org/exist/xquery/functions/fn/FunAvg.java
+ src/main/java/org/exist/xquery/functions/fn/FunBaseURI.java
+ src/main/java/org/exist/xquery/functions/fn/FunBoolean.java
+ src/main/java/org/exist/xquery/functions/fn/FunCeiling.java
+ src/main/java/org/exist/xquery/functions/fn/FunCodepointEqual.java
+ src/main/java/org/exist/xquery/functions/fn/FunCodepointsToString.java
+ src/main/java/org/exist/xquery/functions/fn/FunCompare.java
+ src/main/java/org/exist/xquery/functions/fn/FunConcat.java
+ src/main/java/org/exist/xquery/functions/fn/FunContains.java
+ src/main/java/org/exist/xquery/functions/fn/FunContainsToken.java
+ src/main/java/org/exist/xquery/functions/fn/FunCount.java
+ src/main/java/org/exist/xquery/functions/fn/FunCurrentDateTime.java
+ src/main/java/org/exist/xquery/functions/fn/FunData.java
+ src/main/java/org/exist/xquery/functions/fn/FunDateTime.java
+ src/main/java/org/exist/xquery/functions/fn/FunDeepEqual.java
+ src/main/java/org/exist/xquery/functions/fn/FunDefaultCollation.java
+ src/main/java/org/exist/xquery/functions/fn/FunDistinctValues.java
+ src/main/java/org/exist/xquery/functions/fn/FunDoc.java
+ src/main/java/org/exist/xquery/functions/fn/FunElementWithId.java
+ src/main/java/org/exist/xquery/functions/fn/FunEmpty.java
+ src/main/java/org/exist/xquery/functions/fn/FunEncodeForURI.java
+ src/main/java/org/exist/xquery/functions/fn/FunEndsWith.java
+ src/main/java/org/exist/xquery/functions/fn/FunEnvironment.java
+ src/main/java/org/exist/xquery/functions/fn/FunEquals.java
+ src/main/java/org/exist/xquery/functions/fn/FunError.java
+ src/main/java/org/exist/xquery/functions/fn/FunEscapeHTMLURI.java
+ src/main/java/org/exist/xquery/functions/fn/FunEscapeURI.java
+ src/main/java/org/exist/xquery/functions/fn/FunExactlyOne.java
+ src/main/java/org/exist/xquery/functions/fn/FunExists.java
+ src/main/java/org/exist/xquery/functions/fn/FunFloor.java
+ src/main/java/org/exist/xquery/functions/fn/FunGetDateComponent.java
+ src/main/java/org/exist/xquery/functions/fn/FunGetDurationComponent.java
+ src/main/java/org/exist/xquery/functions/fn/FunHeadTail.java
+ src/main/java/org/exist/xquery/functions/fn/FunHigherOrderFun.java
+ src/main/java/org/exist/xquery/functions/fn/FunId.java
+ src/main/java/org/exist/xquery/functions/fn/FunIdRef.java
+ src/main/java/org/exist/xquery/functions/fn/FunImplicitTimezone.java
+ src/main/java/org/exist/xquery/functions/fn/FunIndexOf.java
+ src/main/java/org/exist/xquery/functions/fn/FunInScopePrefixes.java
+ src/main/java/org/exist/xquery/functions/fn/FunInsertBefore.java
+ src/main/java/org/exist/xquery/functions/fn/FunIRIToURI.java
+ src/main/java/org/exist/xquery/functions/fn/FunLang.java
+ src/test/java/org/exist/xquery/functions/fn/FunLangTest.java
+ src/main/java/org/exist/xquery/functions/fn/FunLast.java
+ src/main/java/org/exist/xquery/functions/fn/FunLocalName.java
+ src/main/java/org/exist/xquery/functions/fn/FunMax.java
+ src/main/java/org/exist/xquery/functions/fn/FunMin.java
+ src/main/java/org/exist/xquery/functions/fn/FunName.java
+ src/main/java/org/exist/xquery/functions/fn/FunNamespaceURI.java
+ src/main/java/org/exist/xquery/functions/fn/FunNamespaceURIForPrefix.java
+ src/main/java/org/exist/xquery/functions/fn/FunNodeName.java
+ src/main/java/org/exist/xquery/functions/fn/FunNormalizeSpace.java
+ src/main/java/org/exist/xquery/functions/fn/FunNormalizeUnicode.java
+ src/main/java/org/exist/xquery/functions/fn/FunNot.java
+ src/main/java/org/exist/xquery/functions/fn/FunNumber.java
+ src/main/java/org/exist/xquery/functions/fn/FunOneOrMore.java
+ src/main/java/org/exist/xquery/functions/fn/FunOnFunctions.java
+ src/main/java/org/exist/xquery/functions/fn/FunParseIetfDate.java
+ src/main/java/org/exist/xquery/functions/fn/FunPath.java
+ src/main/java/org/exist/xquery/functions/fn/FunPosition.java
+ src/main/java/org/exist/xquery/functions/fn/FunQName.java
+ src/main/java/org/exist/xquery/functions/fn/FunRemove.java
+ src/main/java/org/exist/xquery/functions/fn/FunReplace.java
+ src/main/java/org/exist/xquery/functions/fn/FunResolveQName.java
+ src/main/java/org/exist/xquery/functions/fn/FunResolveURI.java
+ src/main/java/org/exist/xquery/functions/fn/FunReverse.java
+ src/main/java/org/exist/xquery/functions/fn/FunRoot.java
+ src/main/java/org/exist/xquery/functions/fn/FunSerialize.java
+ src/main/java/org/exist/xquery/functions/fn/FunSort.java
+ src/main/java/org/exist/xquery/functions/fn/FunStartsWith.java
+ src/main/java/org/exist/xquery/functions/fn/FunString.java
+ src/main/java/org/exist/xquery/functions/fn/FunStringJoin.java
+ src/main/java/org/exist/xquery/functions/fn/FunStringToCodepoints.java
+ src/main/java/org/exist/xquery/functions/fn/FunStrLength.java
+ src/main/java/org/exist/xquery/functions/fn/FunSubSequence.java
+ src/main/java/org/exist/xquery/functions/fn/FunSubstring.java
+ src/main/java/org/exist/xquery/functions/fn/FunSubstringAfter.java
+ src/main/java/org/exist/xquery/functions/fn/FunSubstringBefore.java
+ src/main/java/org/exist/xquery/functions/fn/FunSum.java
+ src/main/java/org/exist/xquery/functions/fn/FunTokenize.java
+ src/main/java/org/exist/xquery/functions/fn/FunTrace.java
+ src/main/java/org/exist/xquery/functions/fn/FunTranslate.java
+ src/main/java/org/exist/xquery/functions/fn/FunTrueOrFalse.java
+ src/main/java/org/exist/xquery/functions/fn/FunUnordered.java
+ src/main/java/org/exist/xquery/functions/fn/FunUnparsedText.java
+ src/main/java/org/exist/xquery/functions/fn/FunUpperOrLowerCase.java
+ src/main/java/org/exist/xquery/functions/fn/FunUriCollection.java
+ src/main/java/org/exist/xquery/functions/fn/FunXmlToJson.java
+ src/main/java/org/exist/xquery/functions/fn/FunZeroOrOne.java
+ src/main/java/org/exist/xquery/functions/fn/LoadXQueryModule.java
+ src/main/java/org/exist/xquery/functions/fn/ParsingFunctions.java
+ src/main/java/org/exist/xquery/functions/fn/QNameFunctions.java
+ src/main/java/org/exist/xquery/functions/fn/transform/Convert.java
+ src/main/java/org/exist/xquery/functions/fn/transform/Delivery.java
+ src/main/java/org/exist/xquery/functions/fn/transform/Options.java
+ src/main/java/org/exist/xquery/functions/fn/transform/Transform.java
+ src/main/java/org/exist/xquery/functions/fn/transform/TreeUtils.java
+ src/test/java/org/exist/xquery/functions/inspect/InspectModuleTest.java
+ src/main/java/org/exist/xquery/functions/integer/WordPicture.java
+ src/main/java/org/exist/xquery/functions/map/MapExpr.java
+ src/main/java/org/exist/xquery/functions/request/GetData.java
+ src/test/java/org/exist/xquery/functions/request/GetData2Test.java
+ src/test/java/org/exist/xquery/functions/request/GetDataTest.java
+ src/test/java/org/exist/xquery/functions/request/GetHeaderTest.java
+ src/test/java/org/exist/xquery/functions/request/GetParameterTest.java
+ src/test/java/org/exist/xquery/functions/request/PatchTest.java
+ src/main/java/org/exist/xquery/functions/response/Stream.java
+ src/test/java/org/exist/xquery/functions/securitymanager/GetPermissionsTest.java
+ src/test/java/org/exist/xquery/functions/securitymanager/GroupManagementFunctionRemoveGroupTest.java
+ src/test/java/org/exist/xquery/functions/securitymanager/GroupMembershipFunctionRemoveGroupMemberTest.java
+ src/test/java/org/exist/xquery/functions/securitymanager/IdFunctionTest.java
+ src/test/java/org/exist/xquery/functions/securitymanager/PermissionsFunctionChmodTest.java
+ src/test/java/org/exist/xquery/functions/securitymanager/PermissionsFunctionChownTest.java
+ src/test/java/org/exist/xquery/functions/system/GetRunningXQueriesTest.java
+ src/main/java/org/exist/xquery/functions/system/GetUptime.java
+ src/main/java/org/exist/xquery/functions/system/Restore.java
+ src/main/java/org/exist/xquery/functions/system/Shutdown.java
+ src/main/java/org/exist/xquery/functions/system/SystemModule.java
+ src/main/java/org/exist/xquery/functions/system/TriggerSystemTask.java
+ src/test/resources-filtered/org/exist/xquery/functions/transform/transform-from-pkg-test.conf.xml
+ src/main/java/org/exist/xquery/functions/transform/Transform.java
+ src/test/java/org/exist/xquery/functions/transform/TransformFromPkgTest.java
+ src/test/java/org/exist/xquery/functions/transform/TransformTest.java
+ src/main/java/org/exist/xquery/functions/util/BuiltinFunctions.java
+ src/main/java/org/exist/xquery/functions/util/DescribeFunction.java
+ src/test/java/org/exist/xquery/functions/util/EvalTest.java
+ src/test/java/org/exist/xquery/functions/util/ExpandTest.java
+ src/main/java/org/exist/xquery/functions/util/FunctionFunction.java
+ src/main/java/org/exist/xquery/functions/util/LogFunction.java
+ src/main/java/org/exist/xquery/functions/util/ModuleInfo.java
+ src/test/java/org/exist/xquery/functions/validate/JaxpDtdCatalogTest.java
+ src/test/java/org/exist/xquery/functions/validate/JaxpParseTest.java
+ src/test/java/org/exist/xquery/functions/validate/JaxpXsdCatalogTest.java
+ src/test/java/org/exist/xquery/functions/validate/JaxvTest.java
+ src/test/java/org/exist/xquery/functions/validate/JingOnvdlTest.java
+ src/test/java/org/exist/xquery/functions/validate/JingRelaxNgTest.java
+ src/test/java/org/exist/xquery/functions/validate/JingSchematronTest.java
+ src/test/java/org/exist/xquery/functions/validate/JingXsdTest.java
+ src/main/java/org/exist/xquery/functions/validation/Jaxp.java
+ src/test/java/org/exist/xquery/functions/xmldb/DbStore2Test.java
+ src/main/java/org/exist/xquery/functions/xmldb/XMLDBGetMimeType.java
+ src/main/java/org/exist/xquery/functions/xmldb/XMLDBLoadFromPattern.java
+ src/main/java/org/exist/xquery/functions/xmldb/XMLDBModule.java
+ src/main/java/org/exist/xquery/functions/xmldb/XMLDBSetMimeType.java
+ src/main/java/org/exist/xquery/functions/xmldb/XMLDBStore.java
+ src/main/java/org/exist/xquery/functions/xmldb/XMLDBXUpdate.java
+ src/test/java/org/exist/xquery/functions/xquery3/TryCatchTest.java
+ src/main/antlr/org/exist/xquery/parser/XQuery.g
+ src/main/antlr/org/exist/xquery/parser/XQueryTree.g
+ src/test/java/org/exist/xquery/update/AbstractUpdateTest.java
+ src/test/java/org/exist/xquery/update/IndexIntegrationTest.java
+ src/test/java/org/exist/xquery/update/UpdateInsertTest.java
+ src/test/java/org/exist/xquery/update/UpdateInsertTriggersDefragTest.java
+ src/test/java/org/exist/xquery/update/UpdateReplaceTest.java
+ src/test/java/org/exist/xquery/update/UpdateValueTest.java
+ src/main/java/org/exist/xquery/util/ExpressionDumper.java
+ src/main/java/org/exist/xquery/util/SerializerUtils.java
+ src/main/java/org/exist/xquery/value/AbstractDateTimeValue.java
+ src/main/java/org/exist/xquery/value/AbstractTimeRelatedTest.java
+ src/main/java/org/exist/xquery/value/AnyURIValue.java
+ src/test/java/org/exist/xquery/value/Base64BinaryValueTypeTest.java
+ src/main/java/org/exist/xquery/value/BinaryValue.java
+ src/main/java/org/exist/xquery/value/BooleanValue.java
+ src/test/java/org/exist/xquery/value/DateTest.java
+ src/test/java/org/exist/xquery/value/DateTimeStampTest.java
+ src/main/java/org/exist/xquery/value/DateTimeStampValue.java
+ src/test/java/org/exist/xquery/value/DateTimeTest.java
+ src/main/java/org/exist/xquery/value/DateTimeValue.java
+ src/main/java/org/exist/xquery/value/DateValue.java
+ src/test/java/org/exist/xquery/value/DayTimeDurationTest.java
+ src/main/java/org/exist/xquery/value/DayTimeDurationValue.java
+ src/main/java/org/exist/xquery/value/DecimalValue.java
+ src/main/java/org/exist/xquery/value/DoubleValue.java
+ src/test/java/org/exist/xquery/value/DurationTest.java
+ src/main/java/org/exist/xquery/value/DurationValue.java
+ src/main/java/org/exist/xquery/value/FloatValue.java
+ src/main/java/org/exist/xquery/value/GDayValue.java
+ src/main/java/org/exist/xquery/value/GMonthDayValue.java
+ src/main/java/org/exist/xquery/value/GMonthValue.java
+ src/main/java/org/exist/xquery/value/GYearMonthValue.java
+ src/main/java/org/exist/xquery/value/GYearValue.java
+ src/main/java/org/exist/xquery/value/IntegerValue.java
+ src/main/java/org/exist/xquery/value/MemoryNodeSet.java
+ src/main/java/org/exist/xquery/value/QNameValue.java
+ src/main/java/org/exist/xquery/value/SequenceType.java
+ src/main/java/org/exist/xquery/value/StringValue.java
+ src/test/java/org/exist/xquery/value/TimeTest.java
+ src/main/java/org/exist/xquery/value/TimeUtils.java
+ src/main/java/org/exist/xquery/value/TimeValue.java
+ src/main/java/org/exist/xquery/value/Type.java
+ src/main/java/org/exist/xquery/value/ValueSequence.java
+ src/test/java/org/exist/xquery/value/YearMonthDurationTest.java
+ src/main/java/org/exist/xquery/value/YearMonthDurationValue.java
+ src/main/java/org/exist/xslt/EXistURIResolver.java
+ src/main/java/org/exist/xslt/XsltURIResolverHelper.java
+ src/main/java/org/exist/xupdate/Append.java
+ src/main/java/org/exist/xupdate/Conditional.java
+ src/main/java/org/exist/xupdate/Insert.java
+ src/main/java/org/exist/xupdate/Modification.java
+ src/main/java/org/exist/xupdate/Remove.java
+ src/test/java/org/exist/xupdate/RemoveAppendTest.java
+ src/main/java/org/exist/xupdate/Rename.java
+ src/main/java/org/exist/xupdate/Replace.java
+ src/main/java/org/exist/xupdate/Update.java
+ src/main/java/org/exist/xupdate/XUpdateProcessor.java
+ src/test/java/org/exist/xupdate/XUpdateTest.java
+
+
+
+
+
- ${project.parent.relativePath}/LGPL-21-license.template.txt
+ ${project.parent.relativePath}/existdb-LGPL-21-license.template.txt
+ **/READMEARC-BSD-3-license.template.txtBX-BSD-3-license.template.txtDBXML-10-license.template.txt
- FDB-backport-BSD-3-license.template.txt
- **/README
- src/main/resources/org/exist/client/*.tmpl
+ FDB-backport-to-existdb-BSD-3-license.template.txtsrc/test/resources/uk-towns.txt
- src/test/resources/**/*.xarsrc/test/resources/**/*.bin
+ src/test/resources/**/*.xar
+ src/main/resources/org/exist/client/*.tmplsrc/test/resources/org/exist/validation/entities/**src/test/resources/org/exist/xmldb/allowAnyUri.xml
-
+
+ pom.xml
+ project-suppression.xml
+ src/test/resources-filtered/conf.xml
+ src/test/resources/log4j2.xml
+ src/test/resources/standalone-webapp/WEB-INF/web.xml
+ src/main/xjb/rest-api.xjb
+ src/test/xquery/binary-value.xqm
+ src/test/xquery/instance-of.xqm
+ src/test/xquery/operator-mapping.xqm
+ src/test/xquery/order.xqm
+ src/test/xquery/parenthesizedLocationStep.xml
+ src/test/xquery/pi.xqm
+ src/test/xquery/tail-recursion.xml
+ src/test/xquery/type-promotion.xqm
+ src/test/xquery/maps/maps.xqm
+ src/test/xquery/numbers/format-numbers.xql
+ src/test/xquery/securitymanager/acl.xqm
+ src/test/xquery/util/util.xml
+ src/test/xquery/xqsuite/xqsuite-assertions-dynamic.xqm
+ src/test/xquery/xqsuite/xqsuite-assertions-inline.xqm
+ src/test/xquery/xqsuite/xqsuite-assertions.resources.xqm.ignore
+ src/test/xquery/xquery3/function-reference.xqm
+ src/test/xquery/xquery3/parse-xml.xqm
+ src/test/xquery/xquery3/postfix-expr.xqm
+ src/test/xquery/xquery3/serialize.xql
+ src/test/xquery/xquery3/xml-to-json.xql
+ src/main/java/org/exist/Indexer.java
+ src/test/java/org/exist/Indexer2Test.java
+ src/test/java/org/exist/Indexer3Test.java
+ src/test/java/org/exist/IndexerTest.java
+ src/main/java/org/exist/Namespaces.java
+ src/main/resources-filtered/org/exist/system.properties
+ src/test/java/org/exist/TestDataGenerator
+ src/main/java/org/exist/backup/Backup.java
+ src/main/java/org/exist/backup/CreateBackupDialog.java
+ src/test/java/org/exist/backup/DeepEmbeddedBackupRestoreTest.java
+ src/main/java/org/exist/backup/ExportGUI.java
+ src/main/java/org/exist/backup/ExportMain.java
+ src/main/java/org/exist/backup/Main.java
+ src/main/java/org/exist/backup/Restore.java
+ src/test/java/org/exist/backup/RestoreAppsTest.java
+ src/main/java/org/exist/backup/SystemExport.java
+ src/test/java/org/exist/backup/SystemExportFiltersTest.java
+ src/test/java/org/exist/backup/SystemExportImportTest.java
+ src/test/java/org/exist/backup/XMLDBRestoreTest.java
+ src/main/java/org/exist/backup/ZipWriter.java
+ src/main/java/org/exist/backup/restore/AbstractRestoreHandler.java
+ src/main/java/org/exist/backup/restore/AppRestoreUtils.java
+ src/main/java/org/exist/backup/xquery/RetrieveBackup.java
+ src/main/java/org/exist/client/ClientFrame.java
+ src/main/java/org/exist/client/CommandlineOptions.java
+ src/main/java/org/exist/client/Connection.java
+ src/main/java/org/exist/client/ConnectionDialog.java
+ src/main/java/org/exist/client/DocumentView.java
+ src/main/java/org/exist/client/IndexDialog.java
+ src/main/java/org/exist/client/InteractiveClient.java
+ src/main/java/org/exist/client/MediaTypeFileFilter.java
+ src/main/resources/org/exist/client/messages.properties
+ src/main/resources/org/exist/client/messages_es_ES.properties
+ src/main/resources/org/exist/client/messages_fr_FR.properties
+ src/main/resources/org/exist/client/messages_it_IT.properties
+ src/main/resources/org/exist/client/messages_nb_NO.properties
+ src/main/resources/org/exist/client/messages_nl_NL.properties
+ src/main/resources/org/exist/client/messages_no.properties
+ src/main/resources/org/exist/client/messages_ru_RU.properties
+ src/main/resources/org/exist/client/messages_sv_SE.properties
+ src/main/resources/org/exist/client/messages_zh_CN.properties
+ src/main/java/org/exist/client/NewResourceDialog.java
+ src/main/java/org/exist/client/QueryDialog.java
+ src/main/java/org/exist/client/TriggersDialog.java
+ src/main/java/org/exist/client/UploadDialog.java
+ src/main/java/org/exist/client/security/AccessControlEntryDialog.java
+ src/main/java/org/exist/client/security/EditPropertiesDialog.java
+ src/main/java/org/exist/client/security/UserDialog.java
+ src/main/java/org/exist/client/security/UserManagerDialog.java
+ src/main/java/org/exist/collections/Collection.java
+ src/main/java/org/exist/collections/CollectionConfiguration.java
+ src/main/java/org/exist/collections/CollectionConfigurationManager.java
+ src/test/java/org/exist/collections/CollectionOrderTest.java
+ src/test/java/org/exist/collections/CollectionRemovalTest.java
+ src/test/java/org/exist/collections/CollectionStoreTest.java
+ src/main/java/org/exist/collections/LockedCollection.java
+ src/main/java/org/exist/collections/MutableCollection.java
+ src/test/java/org/exist/collections/OpenCollectionTest
+ src/main/java/org/exist/collections/triggers/CollectionTrigger.java
+ src/main/java/org/exist/collections/triggers/CollectionTriggers.java
+ src/main/java/org/exist/collections/triggers/DocumentTrigger.java
+ src/main/java/org/exist/collections/triggers/DocumentTriggers.java
+ src/test/java/org/exist/collections/triggers/HistoryTriggerTest.java
+ src/test/java/org/exist/collections/triggers/MessagesTrigger.java
+ src/test/java/org/exist/collections/triggers/TriggerConfigTest.java
+ src/main/java/org/exist/collections/triggers/XQueryStartupTrigger.java
+ src/main/java/org/exist/collections/triggers/XQueryTrigger.java
+ src/test/java/org/exist/collections/triggers/XQueryTrigger2Test.java
+ src/test/java/org/exist/collections/triggers/XQueryTriggerChainTest.java
+ src/test/java/org/exist/collections/triggers/XQueryTriggerSetGidTest.java
+ src/test/java/org/exist/collections/triggers/XQueryTriggerSetUidTest.java
+ src/test/java/org/exist/collections/triggers/XQueryTriggerTest.java
+ src/main/java/org/exist/config/Configuration.java
+ src/main/java/org/exist/config/ConfigurationImpl.java
+ src/main/java/org/exist/config/Configurator.java
+ src/test/java/org/exist/config/TwoDatabasesTest.java
+ src/test/java/org/exist/deadlocks/GetReleaseBrokerDeadlocksTest.java
+ src/main/java/org/exist/dom/NodeListImpl.java
+ src/main/java/org/exist/dom/QName.java
+ src/main/java/org/exist/dom/memtree/AbstractCharacterData.java
+ src/main/java/org/exist/dom/memtree/AttrImpl.java
+ src/main/java/org/exist/dom/memtree/DocumentBuilderReceiver.java
+ src/main/java/org/exist/dom/memtree/DocumentImpl.java
+ src/test/java/org/exist/dom/memtree/DocumentImplTest.java
+ src/main/java/org/exist/dom/memtree/DocumentTypeImpl.java
+ src/main/java/org/exist/dom/memtree/DOMIndexer.java
+ src/test/java/org/exist/dom/memtree/DOMIndexerTest.java
+ src/test/java/org/exist/dom/memtree/DOMTest.java
+ src/main/java/org/exist/dom/memtree/ElementImpl.java
+ src/main/java/org/exist/dom/memtree/MemTreeBuilder.java
+ src/test/java/org/exist/dom/memtree/MemtreeInXQueryTest.java
+ src/main/java/org/exist/dom/memtree/NamespaceNode.java
+ src/main/java/org/exist/dom/memtree/NodeImpl.java
+ src/main/java/org/exist/dom/memtree/ProcessingInstructionImpl.java
+ src/test/resources/org/exist/dom/memtree/simple.xhtml
+ src/main/java/org/exist/dom/memtree/reference/AbstractReferenceCharacterData.java
+ src/main/java/org/exist/dom/memtree/reference/AbstractReferenceNodeImpl.java
+ src/main/java/org/exist/dom/memtree/reference/CommentReferenceImpl.java
+ src/main/java/org/exist/dom/memtree/reference/ElementReferenceImpl.java
+ src/main/java/org/exist/dom/memtree/reference/ProcessingInstructionReferenceImpl.java
+ src/main/java/org/exist/dom/memtree/reference/TextReferenceImpl.java
+ src/main/java/org/exist/dom/persistent/AbstractArrayNodeSet.java
+ src/main/java/org/exist/dom/persistent/AbstractCharacterData.java
+ src/main/java/org/exist/dom/persistent/AttrImpl.java
+ src/test/java/org/exist/dom/persistent/BasicNodeSetTest.java
+ src/main/java/org/exist/dom/persistent/BinaryDocument.java
+ src/test/java/org/exist/dom/persistent/CDataIntergationTest.java
+ src/main/java/org/exist/dom/persistent/CommentImpl.java
+ src/test/java/org/exist/dom/persistent/CommentTest.java
+ src/test/java/org/exist/dom/persistent/DefaultDocumentSetTest.java
+ src/test/java/org/exist/dom/persistent/DocTypeTest.java
+ src/main/java/org/exist/dom/persistent/DocumentImpl.java
+ src/main/java/org/exist/dom/persistent/DocumentMetadata.java
+ src/main/java/org/exist/dom/persistent/DocumentSet.java
+ src/main/java/org/exist/dom/persistent/DocumentTypeImpl.java
+ src/main/java/org/exist/dom/persistent/ElementImpl.java
+ src/main/java/org/exist/dom/persistent/EmptyNodeSet.java
+ src/main/java/org/exist/dom/persistent/LockToken.java
+ src/main/java/org/exist/dom/persistent/NewArrayNodeSet.java
+ src/main/java/org/exist/dom/persistent/NodeProxy.java
+ src/main/java/org/exist/dom/persistent/NodeSet.java
+ src/test/java/org/exist/dom/persistent/NodeTest.java
+ src/test/java/org/exist/dom/persistent/PersistentDomTest.java
+ src/main/java/org/exist/dom/persistent/ProcessingInstructionImpl.java
+ src/main/java/org/exist/dom/persistent/SortedNodeSet.java
+ src/main/java/org/exist/dom/persistent/StoredNode.java
+ src/main/java/org/exist/dom/persistent/SymbolTable.java
+ src/test/java/org/exist/dom/persistent/SymbolTableTest.java
+ src/main/java/org/exist/dom/persistent/TextImpl.java
+ src/main/java/org/exist/dom/persistent/VirtualNodeSet.javasrc/main/java/org/exist/dom/persistent/XMLDeclarationImpl.java
+ src/main/java/org/exist/dom/persistent/XMLUtil.java
+ src/test/java/org/exist/http/AbstractHttpTest.java
+ src/main/java/org/exist/http/AuditTrailSessionListener.java
+ src/test/java/org/exist/http/AuditTrailSessionListenerTest.java
+ src/main/java/org/exist/http/Descriptor.java
+ src/main/java/org/exist/http/Response.java
+ src/test/java/org/exist/http/RESTExternalVariableTest.java
+ src/main/java/org/exist/http/RESTServer.java
+ src/test/java/org/exist/http/RESTServiceTest.java
+ src/main/java/org/exist/http/servlets/AbstractExistHttpServlet.java
+ src/main/java/org/exist/http/servlets/EXistServlet.java
+ src/main/java/org/exist/http/servlets/HttpServletRequestWrapper.java
+ src/main/java/org/exist/http/servlets/RedirectorServlet.java
+ src/main/java/org/exist/http/servlets/XQueryServlet.java
+ src/main/java/org/exist/http/servlets/XSLTServlet.java
+ src/test/java/org/exist/http/urlrewrite/ControllerTest.java
+ src/main/java/org/exist/http/urlrewrite/ModuleCall.java
+ src/main/java/org/exist/http/urlrewrite/PathForward.java
+ src/main/java/org/exist/http/urlrewrite/Redirect.java
+ src/test/java/org/exist/http/urlrewrite/RedirectTest.java
+ src/main/java/org/exist/http/urlrewrite/RewriteConfig.java
+ src/test/java/org/exist/http/urlrewrite/URLRewritingTest.java
+ src/main/java/org/exist/http/urlrewrite/XQueryURLRewrite.java
+ src/test/java/org/exist/http/urlrewrite/XQueryURLRewriteTest.java
+ src/main/java/org/exist/indexing/Index.java
+ src/main/java/org/exist/indexing/IndexController.java
+ src/main/java/org/exist/indexing/IndexManager.java
+ src/main/java/org/exist/indexing/ngram/NGramIndexWorker.java
+ src/main/java/org/exist/jetty/JettyStart.java
+ src/main/java/org/exist/jetty/ServerShutdown.java
+ src/main/java/org/exist/jetty/WebAppContext.java
+ src/main/resources/org/exist/launcher/ConfigurationDialog.form
+ src/main/java/org/exist/launcher/ConfigurationDialog.java
+ src/main/java/org/exist/launcher/ConfigurationUtility.java
+ src/main/java/org/exist/launcher/Launcher.java
+ src/main/java/org/exist/launcher/LauncherWrapper.java
+ src/main/java/org/exist/launcher/ServiceManagerFactory.java
+ src/main/java/org/exist/launcher/SplashScreen.java
+ src/main/java/org/exist/launcher/WindowsServiceManager.java
+ src/test/java/org/exist/management/JmxRemoteTest.java
+ src/main/java/org/exist/management/client/JMXClient.java
+ src/main/java/org/exist/management/client/JMXServlet.java
+ src/main/java/org/exist/management/client/JMXtoXML.java
+ src/main/java/org/exist/management/impl/CollectionCache.java
+ src/main/java/org/exist/management/impl/CollectionCacheMXBean.java
+ src/main/java/org/exist/management/impl/Database.java
+ src/main/java/org/exist/management/impl/DatabaseMXBean.java
+ src/main/java/org/exist/management/impl/ExistMBean.java
+ src/main/java/org/exist/management/impl/JMXAgent.java
+ src/main/java/org/exist/management/impl/SanityReport.java
+ src/main/java/org/exist/mediatype/MediaTypeService.java
+ src/main/java/org/exist/mediatype/MediaTypeUtil.java
+ src/main/java/org/exist/numbering/DLN.java
+ src/main/java/org/exist/numbering/DLNBase.java
+ src/main/java/org/exist/numbering/DLNFactory.java
+ src/test/java/org/exist/numbering/DLNStorageTest.java
+ src/main/java/org/exist/numbering/NodeId.java
+ src/main/java/org/exist/numbering/NodeIdFactory.java
+ src/main/java/org/exist/protocolhandler/eXistURLStreamHandlerFactory.java
+ src/main/java/org/exist/protocolhandler/URLStreamHandlerStartupTrigger.java
+ src/main/java/org/exist/protocolhandler/embedded/EmbeddedOutputStream.java
+ src/main/java/org/exist/protocolhandler/embedded/InMemoryOutputStream.java
+ src/main/java/org/exist/protocolhandler/protocols/xmldb/EmbeddedURLConnection.java
+ src/main/java/org/exist/protocolhandler/protocols/xmldb/Handler.java
+ src/main/java/org/exist/protocolhandler/protocols/xmldb/InMemoryURLConnection.java
+ src/main/java/org/exist/protocolhandler/xmldb/XmldbURL.java
+ src/main/java/org/exist/protocolhandler/xmlrpc/XmlrpcOutputStream.java
+ src/main/java/org/exist/protocolhandler/xmlrpc/XmlrpcUpload.java
+ src/main/java/org/exist/protocolhandler/xmlrpc/XmlrpcUploadRunnable.java
+ src/main/java/org/exist/repo/AutoDeploymentTrigger.java
+ src/main/java/org/exist/repo/ClasspathHelper.java
+ src/main/java/org/exist/repo/Deployment.java
+ src/main/java/org/exist/repo/ExistRepository.javasrc/main/java/org/exist/resolver/ResolverFactory.javasrc/main/java/org/exist/resolver/XercesXmlResolverAdapter.java
- src/main/java/org/exist/util/UTF8.java
- src/test/java/org/exist/storage/MoveCollectionTest.java
- src/main/java/org/exist/storage/blob/**
- src/test/java/org/exist/storage/blob/**
- src/main/java/org/exist/storage/journal/JournalManager.java
+ src/main/java/org/exist/scheduler/UserXQueryJob.java
+ src/main/java/org/exist/scheduler/impl/QuartzSchedulerImpl.java
+ src/main/java/org/exist/security/EffectiveSubject.java
+ src/test/java/org/exist/security/FnDocSecurityTest.java
+ src/main/java/org/exist/security/Permission.java
+ src/main/java/org/exist/security/PermissionRequired.java
+ src/main/java/org/exist/security/PermissionRequiredCheck.java
+ src/test/java/org/exist/security/RestApiSecurityTest.java
+ src/main/java/org/exist/security/SecurityManager.java
+ src/main/java/org/exist/security/SimpleACLPermissionInternal.java
+ src/test/java/org/exist/security/SimpleACLPermissionTest.java
+ src/main/java/org/exist/security/UnixStylePermissionInternal.java
+ src/test/java/org/exist/security/UnixStylePermissionTest.java
+ src/test/java/org/exist/security/XqueryApiTest.java
+ src/main/java/org/exist/security/internal/AccountImpl.java
+ src/main/java/org/exist/security/internal/aider/UnixStylePermissionAider.java
+ src/main/java/org/exist/source/Source.java
+ src/main/java/org/exist/source/SourceFactory.java
+ src/main/java/org/exist/source/URLSource.java
+ src/test/java/org/exist/stax/EmbeddedXMLStreamReaderTest.javasrc/test/java/org/exist/storage/AbstractRecoverTest.java
- src/test/java/org/exist/storage/RecoverBinaryTest.java
- src/test/java/org/exist/storage/RecoverXmlTest.java
- src/test/java/org/exist/storage/journal/AbstractJournalTest.java
- src/test/java/org/exist/storage/journal/JournalBinaryTest.java
- src/test/java/org/exist/storage/journal/JournalXmlTest.java
- src/test/java/org/exist/storage/journal/LsnTest.java
+ src/test/java/org/exist/storage/AbstractUpdateTest.java
+ src/test/java/org/exist/storage/BFileRecoverTest.java
+ src/test/java/org/exist/storage/BinaryDocumentTest.java
+ src/main/java/org/exist/storage/BrokerFactory.java
+ src/main/java/org/exist/storage/BrokerPool.javasrc/main/java/org/exist/storage/BrokerPoolService.java
- src/test/java/org/exist/storage/BrokerPoolServiceTest.javasrc/main/java/org/exist/storage/BrokerPoolServiceException.javasrc/main/java/org/exist/storage/BrokerPoolServicesManager.javasrc/main/java/org/exist/storage/BrokerPoolServicesManagerException.java
+ src/test/java/org/exist/storage/BrokerPoolServiceTest.java
+ src/test/java/org/exist/storage/BrokerPoolsTest.java
+ src/test/java/org/exist/storage/BrokerPoolTest.java
+ src/test/java/org/exist/storage/CollectionTest.java
+ src/test/java/org/exist/storage/ConcurrentBrokerPoolTest.java
+ src/test/java/org/exist/storage/ConcurrentStoreTest.java
+ src/test/java/org/exist/storage/CopyCollectionRecoveryTest.java
+ src/test/java/org/exist/storage/CopyResourceRecoveryTest.java
+ src/test/java/org/exist/storage/CopyResourceTest.java
+ src/main/java/org/exist/storage/DBBroker.java
+ src/test/java/org/exist/storage/DirtyShutdownTest.java
+ src/test/java/org/exist/storage/DOMFileRecoverTest.javasrc/main/java/org/exist/storage/FluentBrokerAPI.java
+ src/main/java/org/exist/storage/Indexable.java
+ src/main/java/org/exist/storage/IndexSpec.java
+ src/test/java/org/exist/storage/LargeValuesTest.java
+ src/test/java/org/exist/storage/ModificationTimeTest.java
+ src/test/java/org/exist/storage/MoveCollectionRecoveryTest.java
+ src/test/java/org/exist/storage/MoveCollectionTest.java
+ src/test/java/org/exist/storage/MoveOverwriteCollectionTest.java
+ src/test/java/org/exist/storage/MoveOverwriteResourceTest.java
+ src/test/java/org/exist/storage/MoveResourceRecoveryTest.java
+ src/main/java/org/exist/storage/NativeBroker.java
+ src/main/java/org/exist/storage/NativeValueIndex.java
+ src/main/java/org/exist/storage/NodePath.java
+ src/test/java/org/exist/storage/NodePathTest.java
+ src/main/java/org/exist/storage/NotificationService.java
+ src/main/java/org/exist/storage/ProcessMonitor.java
+ src/test/java/org/exist/storage/RangeIndexUpdateTest.java
+ src/test/java/org/exist/storage/RecoverBinary2Test.java
+ src/test/java/org/exist/storage/RecoverBinaryTest.java
+ src/test/java/org/exist/storage/RecoverXmlTest.java
+ src/test/java/org/exist/storage/Recovery2Test.java
+ src/test/java/org/exist/storage/RecoveryTest.java
+ src/test/java/org/exist/storage/ReindexRecoveryTest.java
+ src/test/java/org/exist/storage/ReindexTest.java
+ src/test/java/org/exist/storage/RemoveCollectionTest.java
+ src/test/java/org/exist/storage/RemoveRootCollectionTest.java
+ src/test/java/org/exist/storage/ResourceTest.java
+ src/test/java/org/exist/storage/ShutdownTest.java
+ src/main/java/org/exist/storage/StorageAddress.java
+ src/test/java/org/exist/storage/StoreBinaryTest.java
+ src/test/java/org/exist/storage/StoreResourceTest.java
+ src/test/java/org/exist/storage/UpdateRecoverTest.java
+ src/test/java/org/exist/storage/XIncludeSerializerTest.javasrc/main/java/org/exist/storage/XQueryPool.java
+ src/main/java/org/exist/storage/blob/**
+ src/test/java/org/exist/storage/blob/**
+ src/test/java/org/exist/storage/btree/BTreeTest.java
+ src/main/java/org/exist/storage/btree/TreeMetrics.java
+ src/main/java/org/exist/storage/index/BFile.java
+ src/main/java/org/exist/storage/io/AbstractVariableByteInput.java
+ src/main/java/org/exist/storage/io/AbstractVariableByteOutput.java
+ src/main/java/org/exist/storage/io/VariableByteArrayInput.java
+ src/main/java/org/exist/storage/io/VariableByteArrayOutputStream.java
+ src/main/java/org/exist/storage/io/VariableByteBufferInput.java
+ src/main/java/org/exist/storage/io/VariableByteBufferOutput.java
+ src/main/java/org/exist/storage/io/VariableByteFilterInputStream.java
+ src/main/java/org/exist/storage/io/VariableByteFilterOutputStream.java
+ src/main/java/org/exist/storage/io/VariableByteInput.java
+ src/main/java/org/exist/storage/io/VariableByteInputToInputStream.java
+ src/main/java/org/exist/storage/io/VariableByteOutput.java
+ src/main/java/org/exist/storage/io/VariableByteOutputToOutputStream.java
+ src/test/java/org/exist/storage/io/VariableByteStreamTest.java
+ src/test/java/org/exist/storage/journal/AbstractJournalTest.java
+ src/test/java/org/exist/storage/journal/JournalBinaryTest.java
+ src/main/java/org/exist/storage/journal/JournalManager.java
+ src/main/java/org/exist/storage/journal/JournalReader.java
+ src/test/java/org/exist/storage/journal/JournalXmlTest.java
+ src/test/java/org/exist/storage/journal/LsnTest.java
+ src/test/java/org/exist/storage/lock/CollectionLocksTest.java
+ src/test/java/org/exist/storage/lock/DeadlockTest.java
+ src/test/java/org/exist/storage/lock/DocumentLocksTest.javasrc/main/java/org/exist/storage/lock/EnsureContainerLocked.javasrc/main/java/org/exist/storage/lock/EnsureContainerUnlocked.javasrc/main/java/org/exist/storage/lock/EnsureLocked.javasrc/main/java/org/exist/storage/lock/EnsureLockingAspect.javasrc/main/java/org/exist/storage/lock/EnsureUnlocked.java
+ src/main/java/org/exist/storage/lock/FileLock.javasrc/main/java/org/exist/storage/lock/FileLockService.java
+ src/test/java/org/exist/storage/lock/GetXMLResourceNoLockTest.java
+ src/main/java/org/exist/storage/lock/LockedPath.javasrc/main/java/org/exist/storage/lock/LockEventJsonListener.javasrc/main/java/org/exist/storage/lock/LockEventLogListener.javasrc/main/java/org/exist/storage/lock/LockEventXmlListener.java
- src/main/java/org/exist/storage/lock/LockedPath.javasrc/main/java/org/exist/storage/lock/LockGroup.javasrc/main/java/org/exist/storage/lock/LockManager.java
+ src/test/java/org/exist/storage/lock/LockManagerTest.javasrc/main/java/org/exist/storage/lock/LockTable.javasrc/main/java/org/exist/storage/lock/LockTableUtils.javasrc/main/java/org/exist/storage/lock/ManagedCollectionLock.java
@@ -754,58 +1845,466 @@
src/main/java/org/exist/storage/lock/ManagedLock.javasrc/main/java/org/exist/storage/lock/ManagedLockGroupDocumentLock.javasrc/main/java/org/exist/storage/lock/ManagedSingleLockDocumentLock.java
- src/test/java/org/exist/storage/lock/CollectionLocksTest.java
- src/test/java/org/exist/storage/lock/DocumentLocksTest.java
- src/test/java/org/exist/storage/lock/LockManagerTest.java
- src/main/java/org/exist/storage/txn/TransactionManager.java
+ src/test/java/org/exist/storage/lock/ProtectedModeTest.java
+ src/main/java/org/exist/storage/recovery/RecoveryManager.java
+ src/main/java/org/exist/storage/serializers/EXistOutputKeys.java
+ src/test/java/org/exist/storage/serializers/NativeSerializerTest.java
+ src/main/java/org/exist/storage/serializers/Serializer.java
+ src/main/java/org/exist/storage/serializers/XIncludeFilter.java
+ src/test/resources-filtered/org/exist/storage/statistics/conf.xml
+ src/main/java/org/exist/storage/sync/SyncTask.javasrc/test/java/org/exist/storage/txn/ConcurrentTransactionsTest.javasrc/test/java/org/exist/storage/txn/CountingTxnListener.javasrc/test/java/org/exist/storage/txn/ReusableTxnTest.java
+ src/main/java/org/exist/storage/txn/TransactionManager.javasrc/test/java/org/exist/storage/txn/TransactionManagerTestHelper.javasrc/test/java/org/exist/storage/txn/TxnTest.java
+ src/test/java/org/exist/storage/util/PauseFunction.javasrc/main/java/org/exist/test/DiffMatcher.java
+ src/main/java/org/exist/test/ExistXmldbEmbeddedServer.javasrc/test/java/org/exist/test/Util.java
+ src/main/java/org/exist/test/runner/AbstractTestRunner.java
+ src/main/java/org/exist/test/runner/ExtTestAssumptionFailedFunction.java
+ src/main/java/org/exist/test/runner/ExtTestErrorFunction.java
+ src/main/java/org/exist/test/runner/ExtTestFailureFunction.java
+ src/main/java/org/exist/test/runner/ExtTestFinishedFunction.java
+ src/main/java/org/exist/test/runner/ExtTestIgnoredFunction.java
+ src/main/java/org/exist/test/runner/ExtTestStartedFunction.java
+ src/main/java/org/exist/test/runner/JUnitIntegrationFunction.java
+ src/main/java/org/exist/test/runner/XMLTestRunner.java
+ src/main/java/org/exist/test/runner/XQueryTestRunner.java
+ src/main/java/org/exist/test/runner/XSuite.java
+ src/test/java/org/exist/util/AbstractXMLReaderSecurityTest.java
+ src/main/java/org/exist/util/ByteOrderMark.java
+ src/main/java/org/exist/util/Collations.java
+ src/test/java/org/exist/util/CollationsTest.javasrc/main/java/org/exist/util/CollectionOfArrayIterator.javasrc/test/java/org/exist/util/CollectionOfArrayIteratorTest.java
+ src/main/java/org/exist/util/Configuration.java
+ src/test/java/org/exist/util/DOMSerializerTest.javasrc/main/java/org/exist/util/IPUtil.java
+ src/main/java/org/exist/util/JREUtil.java
+ src/test/java/org/exist/util/LeasableTest.javasrc/main/java/org/exist/util/MapUtil.java
+ src/test/java/org/exist/util/MediaTypeResolverTest.java
+ src/main/java/org/exist/util/MimeTable.java
+ src/main/java/org/exist/util/MimeType.java
+ src/main/java/org/exist/util/OSUtil.java
+ src/main/java/org/exist/util/ParametersExtractor.java
+ src/main/java/org/exist/util/StringUtil.java
+ src/main/java/org/exist/util/UTF8.java
+ src/main/java/org/exist/util/XMLFilenameFilter.java
+ src/test/java/org/exist/util/XMLReaderExpansionTest.java
+ src/test/java/org/exist/util/XMLReaderSecurityTest.java
+ src/main/java/org/exist/util/XQueryFilenameFilter.java
+ src/main/java/org/exist/util/crypto/digest/DigestType.java
+ src/main/java/org/exist/util/io/AbstractContentFile.java
+ src/main/java/org/exist/util/io/ByteArrayContent.java
+ src/test/java/org/exist/util/io/ByteArrayContentTest.java
+ src/main/java/org/exist/util/io/ContentFile.java
+ src/main/java/org/exist/util/io/ContentFilePoolObjectFactory.java
+ src/test/java/org/exist/util/io/FilterInputStreamCacheMonitorTest.java
+ src/test/java/org/exist/util/io/OverflowToDiskStreamTest.java
+ src/main/java/org/exist/util/io/VirtualTempPath.java
+ src/test/java/org/exist/util/io/VirtualTempPathTest.java
+ src/test/java/org/exist/util/pool/NodePoolTest.java
+ src/main/java/org/exist/util/serializer/AttrList.java
+ src/main/java/org/exist/util/serializer/DOMSerializer.java
+ src/main/java/org/exist/util/serializer/DOMStreamer.java
+ src/main/java/org/exist/util/serializer/EXISerializer.java
+ src/test/java/org/exist/util/serializer/HTML5WriterTest.java
+ src/main/java/org/exist/util/serializer/SAXSerializer.java
+ src/test/java/org/exist/util/serializer/SAXSerializerTest.java
+ src/main/java/org/exist/util/serializer/SerializerObjectFactory.java
+ src/main/java/org/exist/util/serializer/json/JSONObject.java
+ src/test/java/org/exist/util/serializer/json/JSONObjectTest.java
+ src/main/java/org/exist/util/serializer/json/JSONSerializer.java
+ src/test/java/org/exist/util/serializer/json/JSONWriterTest.java
+ src/test/java/org/exist/util/sorters/ListChecker.java
+ src/test/java/org/exist/util/sorters/LongArrayAndObjectChecker.java
+ src/test/java/org/exist/util/sorters/NodeProxyByIdChecker.java
+ src/test/java/org/exist/util/sorters/NodeProxyChecker.java
+ src/test/java/org/exist/util/sorters/ObjectAndIntArrayChecker.java
+ src/test/java/org/exist/util/sorters/PlainArrayChecker.java
+ src/test/java/org/exist/util/sorters/SortTestNodeId.java
+ src/test/resources/org/exist/validation/catalog.xml
+ src/test/java/org/exist/validation/CollectionConfigurationValidationModeTest.java
+ src/test/java/org/exist/validation/DtdEntityTest.java
+ src/main/java/org/exist/validation/XmlLibraryChecker.java
+ src/main/java/org/exist/validation/internal/DatabaseResources.java
+ src/main/resources/org/exist/validation/internal/query/find_catalogs_with_dtd.xq
+ src/main/resources/org/exist/validation/internal/query/find_schema_by_targetNamespace.xq
+ src/main/java/org/exist/validation/resolver/SearchResourceResolver.java
+ src/test/java/org/exist/w3c/tests/TestCase.java
+ src/main/java/org/exist/webstart/JnlpJarFiles.java
+ src/main/java/org/exist/webstart/JnlpWriter.java
+ src/main/java/org/exist/xmldb/AbstractEXistResource.java
+ src/main/java/org/exist/xmldb/AbstractRemoteResource.java
+ src/test/java/org/exist/xmldb/ContentAsDOMTest.java
+ src/test/java/org/exist/xmldb/CreateCollectionsTest.java
+ src/main/java/org/exist/xmldb/EXistResource.java
+ src/test/java/org/exist/xmldb/EXistXMLSerializeTest.java
+ src/test/java/org/exist/xmldb/IndexingTest.java
+ src/main/java/org/exist/xmldb/LocalBinaryResource.java
+ src/main/java/org/exist/xmldb/LocalCollection.java
+ src/main/java/org/exist/xmldb/LocalResourceSet.java
+ src/main/java/org/exist/xmldb/LocalRestoreService.java
+ src/main/java/org/exist/xmldb/LocalXMLResource.java
+ src/main/java/org/exist/xmldb/LocalXPathQueryService.java
+ src/main/java/org/exist/xmldb/RemoteBinaryResource.java
+ src/main/java/org/exist/xmldb/RemoteCollection.java
+ src/test/java/org/exist/xmldb/RemoteCollectionTest.java
+ src/test/java/org/exist/xmldb/RemoteDOMTest.java
+ src/test/java/org/exist/xmldb/RemoteQueryTest.java
+ src/main/java/org/exist/xmldb/RemoteResourceSet.java
+ src/main/java/org/exist/xmldb/RemoteRestoreService.java
+ src/main/java/org/exist/xmldb/RemoteXMLResource.java
+ src/main/java/org/exist/xmldb/RemoteXPathQueryService.java
+ src/test/java/org/exist/xmldb/ResourceTest.java
+ src/test/java/org/exist/xmldb/SerializationTest.java
+ src/test/java/org/exist/xmldb/TestEXistXMLSerialize.java
+ src/test/java/org/exist/xmldb/TreeLevelOrderTest.java
+ src/test/java/org/exist/xmldb/XMLDBExternalVariableTest.java
+ src/test/java/org/exist/xmldb/concurrent/AbstractConcurrentTest.java
+ src/test/java/org/exist/xmldb/concurrent/ComplexUpdateTest.java
+ src/test/java/org/exist/xmldb/concurrent/ConcurrentAttrUpdateTest.java
+ src/test/java/org/exist/xmldb/concurrent/ConcurrentQueryTest.java
+ src/test/java/org/exist/xmldb/concurrent/ConcurrentQueryUpdateTest.java
+ src/test/java/org/exist/xmldb/concurrent/ConcurrentResource2Test.java
+ src/test/java/org/exist/xmldb/concurrent/ConcurrentResourceTest.java
+ src/test/java/org/exist/xmldb/concurrent/ConcurrentXUpdateTest.java
+ src/test/java/org/exist/xmldb/concurrent/DBUtils.java
+ src/test/java/org/exist/xmldb/concurrent/FragmentsTest.java
+ src/test/java/org/exist/xmldb/concurrent/TextUpdateTest.java
+ src/test/java/org/exist/xmldb/concurrent/ValueIndexUpdateTest.java
+ src/test/java/org/exist/xmldb/concurrent/XMLGenerator.java
+ src/test/java/org/exist/xmldb/concurrent/action/MultiResourcesAction.javasrc/main/java/org/exist/xmlrpc/ACEAiderParser.javasrc/main/java/org/exist/xmlrpc/ACEAiderSerializer.java
+ src/main/java/org/exist/xmlrpc/ArrayWrapperParser.java
+ src/main/java/org/exist/xmlrpc/ArrayWrapperSerializer.java
+ src/main/java/org/exist/xmlrpc/ExistRpcTypeFactory.java
+ src/test/java/org/exist/xmlrpc/QuerySessionTest.java
+ src/main/java/org/exist/xmlrpc/RpcAPI.java
+ src/main/java/org/exist/xmlrpc/RpcConnection.java
+ src/main/java/org/exist/xmlrpc/XmlRpcExtensionConstants.java
+ src/test/java/org/exist/xmlrpc/XmlRpcTest.java
+ src/main/java/org/exist/xqj/Marshaller.java
+ src/test/java/org/exist/xqj/MarshallerTest.java
+ src/main/java/org/exist/xquery/AbstractInternalModule.javasrc/main/java/org/exist/xquery/Cardinality.java
+ src/test/java/org/exist/xquery/CardinalityTest.javasrc/test/java/org/exist/xquery/CastExpressionTest.java
+ src/test/java/org/exist/xquery/CleanupTest.java
+ src/test/java/org/exist/xquery/ConstructedNodesRecoveryTest.java
+ src/main/java/org/exist/xquery/Context.java
+ src/main/java/org/exist/xquery/DecimalFormat.java
+ src/main/java/org/exist/xquery/DeferredFunctionCall.java
+ src/main/java/org/exist/xquery/DynamicCardinalityCheck.java
+ src/main/java/org/exist/xquery/DynamicTypeCheck.java
+ src/main/java/org/exist/xquery/DynamicVariable.java
+ src/test/java/org/exist/xquery/EmbeddedBinariesTest.java
+ src/test/java/org/exist/xquery/EmbeddedBinariesTest.java.java
+ src/main/java/org/exist/xquery/ErrorCodes.java
+ src/main/java/org/exist/xquery/Except.java
+ src/main/java/org/exist/xquery/ExternalModuleImpl.java
+ src/test/java/org/exist/xquery/ForwardReferenceTest.java
+ src/main/java/org/exist/xquery/Function.java
+ src/main/java/org/exist/xquery/FunctionFactory.java
+ src/test/resources-filtered/org/exist/xquery/import-from-pkg-test.conf.xml
+ src/test/java/org/exist/xquery/ImportFromPkgTest.javasrc/test/java/org/exist/xquery/ImportModuleTest.java
+ src/main/java/org/exist/xquery/Intersect.java
+ src/main/java/org/exist/xquery/JavaBinding.java
+ src/test/resources-filtered/org/exist/xquery/JavaBindingTest.conf.xml
+ src/test/java/org/exist/xquery/JavaBindingTest.java
+ src/test/java/org/exist/xquery/LexerTest.java
+ src/main/java/org/exist/xquery/LocationStep.javasrc/main/java/org/exist/xquery/Materializable.java
+ src/main/java/org/exist/xquery/Module.java
+ src/main/java/org/exist/xquery/NamedFunctionReference.java
+ src/main/java/org/exist/xquery/NameTest.java
+ src/test/java/org/exist/xquery/NodeTypeTest.java
+ src/main/java/org/exist/xquery/Optimizer.java
+ src/main/java/org/exist/xquery/Option.java
+ src/main/java/org/exist/xquery/PathExpr.java
+ src/main/java/org/exist/xquery/PerformanceStatsImpl.java
+ src/test/java/org/exist/xquery/RestBinariesTest.java
+ src/test/java/org/exist/xquery/StoredModuleTest.java
+ src/test/java/org/exist/xquery/TransformTest.java
+ src/main/java/org/exist/xquery/TryCatchExpression.java
+ src/main/java/org/exist/xquery/UserDefinedFunction.java
+ src/main/java/org/exist/xquery/Variable.java
+ src/main/java/org/exist/xquery/VariableDeclaration.java
+ src/main/java/org/exist/xquery/VariableImpl.java
+ src/main/java/org/exist/xquery/VariableReference.java
+ src/test/java/org/exist/xquery/VariablesTest.java
+ src/test/java/org/exist/xquery/WatchdogTest.java
+ src/test/java/org/exist/xquery/WindowClauseTest.java
+ src/test/java/org/exist/xquery/XmldbBinariesTest.java
+ src/test/java/org/exist/xquery/XPathOpOrSpecialCaseTest.java
+ src/test/java/org/exist/xquery/XPathQueryTest.java
+ src/main/java/org/exist/xquery/XPathUtil.java
+ src/test/java/org/exist/xquery/XPathUtilTest.java
+ src/main/java/org/exist/xquery/XQueryContext.javasrc/test/java/org/exist/xquery/XQueryContextAttributesTest.java
+ src/test/java/org/exist/xquery/XQueryDeclareContextItemTest.java
+ src/test/java/org/exist/xquery/XQueryFunctionsTest.java
+ src/main/java/org/exist/xquery/XQueryProcessingInstruction.java
+ src/test/java/org/exist/xquery/XQueryProcessingInstructionTest.java
+ src/test/java/org/exist/xquery/XQueryTest.java
+ src/test/java/org/exist/xquery/XQueryUpdateTest.java
+ src/main/java/org/exist/xquery/functions/array/ArrayType.java
+ src/test/java/org/exist/xquery/functions/fn/DocTest.java
+ src/main/java/org/exist/xquery/functions/fn/ExtCollection.java
+ src/main/java/org/exist/xquery/functions/fn/FnDefaultLanguage.java
+ src/main/java/org/exist/xquery/functions/fn/FnFormatDates.java
+ src/main/java/org/exist/xquery/functions/fn/FnHasChildren.java
+ src/main/java/org/exist/xquery/functions/fn/FnInnerMost.java
+ src/main/java/org/exist/xquery/functions/fn/FnModule.java
+ src/main/java/org/exist/xquery/functions/fn/FnOuterMost.java
+ src/main/java/org/exist/xquery/functions/fn/FunAbs.java
+ src/main/java/org/exist/xquery/functions/fn/FunAdjustTimezone.java
+ src/main/java/org/exist/xquery/functions/fn/FunAnalyzeString.java
+ src/main/java/org/exist/xquery/functions/fn/FunAvg.java
+ src/main/java/org/exist/xquery/functions/fn/FunBaseURI.java
+ src/main/java/org/exist/xquery/functions/fn/FunBoolean.java
+ src/main/java/org/exist/xquery/functions/fn/FunCeiling.java
+ src/main/java/org/exist/xquery/functions/fn/FunCodepointEqual.java
+ src/main/java/org/exist/xquery/functions/fn/FunCodepointsToString.java
+ src/main/java/org/exist/xquery/functions/fn/FunCompare.java
+ src/main/java/org/exist/xquery/functions/fn/FunConcat.java
+ src/main/java/org/exist/xquery/functions/fn/FunContains.java
+ src/main/java/org/exist/xquery/functions/fn/FunContainsToken.java
+ src/main/java/org/exist/xquery/functions/fn/FunCount.java
+ src/main/java/org/exist/xquery/functions/fn/FunCurrentDateTime.java
+ src/main/java/org/exist/xquery/functions/fn/FunData.java
+ src/main/java/org/exist/xquery/functions/fn/FunDateTime.java
+ src/main/java/org/exist/xquery/functions/fn/FunDeepEqual.java
+ src/main/java/org/exist/xquery/functions/fn/FunDefaultCollation.java
+ src/main/java/org/exist/xquery/functions/fn/FunDistinctValues.java
+ src/main/java/org/exist/xquery/functions/fn/FunDoc.java
+ src/main/java/org/exist/xquery/functions/fn/FunDocAvailable.java
+ src/main/java/org/exist/xquery/functions/fn/FunElementWithId.java
+ src/main/java/org/exist/xquery/functions/fn/FunEmpty.java
+ src/main/java/org/exist/xquery/functions/fn/FunEncodeForURI.java
+ src/main/java/org/exist/xquery/functions/fn/FunEndsWith.java
+ src/main/java/org/exist/xquery/functions/fn/FunEnvironment.java
+ src/main/java/org/exist/xquery/functions/fn/FunEquals.java
+ src/main/java/org/exist/xquery/functions/fn/FunError.java
+ src/main/java/org/exist/xquery/functions/fn/FunEscapeHTMLURI.java
+ src/main/java/org/exist/xquery/functions/fn/FunEscapeURI.java
+ src/main/java/org/exist/xquery/functions/fn/FunExactlyOne.java
+ src/main/java/org/exist/xquery/functions/fn/FunExists.java
+ src/main/java/org/exist/xquery/functions/fn/FunFloor.java
+ src/main/java/org/exist/xquery/functions/fn/FunGetDateComponent.java
+ src/main/java/org/exist/xquery/functions/fn/FunGetDurationComponent.java
+ src/main/java/org/exist/xquery/functions/fn/FunHeadTail.java
+ src/main/java/org/exist/xquery/functions/fn/FunHigherOrderFun.java
+ src/main/java/org/exist/xquery/functions/fn/FunId.java
+ src/main/java/org/exist/xquery/functions/fn/FunIdRef.java
+ src/main/java/org/exist/xquery/functions/fn/FunImplicitTimezone.java
+ src/main/java/org/exist/xquery/functions/fn/FunIndexOf.java
+ src/main/java/org/exist/xquery/functions/fn/FunInScopePrefixes.java
+ src/main/java/org/exist/xquery/functions/fn/FunInsertBefore.java
+ src/main/java/org/exist/xquery/functions/fn/FunIRIToURI.java
+ src/main/java/org/exist/xquery/functions/fn/FunLang.java
+ src/test/java/org/exist/xquery/functions/fn/FunLangTest.java
+ src/main/java/org/exist/xquery/functions/fn/FunLast.java
+ src/main/java/org/exist/xquery/functions/fn/FunLocalName.java
+ src/main/java/org/exist/xquery/functions/fn/FunMax.java
+ src/main/java/org/exist/xquery/functions/fn/FunMin.java
+ src/main/java/org/exist/xquery/functions/fn/FunName.java
+ src/main/java/org/exist/xquery/functions/fn/FunNamespaceURI.java
+ src/main/java/org/exist/xquery/functions/fn/FunNamespaceURIForPrefix.java
+ src/main/java/org/exist/xquery/functions/fn/FunNodeName.java
+ src/main/java/org/exist/xquery/functions/fn/FunNormalizeSpace.java
+ src/main/java/org/exist/xquery/functions/fn/FunNormalizeUnicode.java
+ src/main/java/org/exist/xquery/functions/fn/FunNot.java
+ src/main/java/org/exist/xquery/functions/fn/FunNumber.java
+ src/main/java/org/exist/xquery/functions/fn/FunOneOrMore.java
+ src/main/java/org/exist/xquery/functions/fn/FunOnFunctions.java
+ src/main/java/org/exist/xquery/functions/fn/FunParseIetfDate.java
+ src/main/java/org/exist/xquery/functions/fn/FunPath.java
+ src/main/java/org/exist/xquery/functions/fn/FunPosition.java
+ src/main/java/org/exist/xquery/functions/fn/FunQName.java
+ src/main/java/org/exist/xquery/functions/fn/FunRemove.java
+ src/main/java/org/exist/xquery/functions/fn/FunReplace.java
+ src/main/java/org/exist/xquery/functions/fn/FunResolveQName.java
+ src/main/java/org/exist/xquery/functions/fn/FunResolveURI.java
+ src/main/java/org/exist/xquery/functions/fn/FunReverse.java
+ src/main/java/org/exist/xquery/functions/fn/FunRoot.java
+ src/main/java/org/exist/xquery/functions/fn/FunSerialize.java
+ src/main/java/org/exist/xquery/functions/fn/FunSort.java
+ src/main/java/org/exist/xquery/functions/fn/FunStartsWith.java
+ src/main/java/org/exist/xquery/functions/fn/FunString.java
+ src/main/java/org/exist/xquery/functions/fn/FunStringJoin.java
+ src/main/java/org/exist/xquery/functions/fn/FunStringToCodepoints.java
+ src/main/java/org/exist/xquery/functions/fn/FunStrLength.java
+ src/main/java/org/exist/xquery/functions/fn/FunSubSequence.java
+ src/main/java/org/exist/xquery/functions/fn/FunSubstring.java
+ src/main/java/org/exist/xquery/functions/fn/FunSubstringAfter.java
+ src/main/java/org/exist/xquery/functions/fn/FunSubstringBefore.java
+ src/main/java/org/exist/xquery/functions/fn/FunSum.java
+ src/main/java/org/exist/xquery/functions/fn/FunTokenize.java
+ src/main/java/org/exist/xquery/functions/fn/FunTrace.java
+ src/main/java/org/exist/xquery/functions/fn/FunTranslate.java
+ src/main/java/org/exist/xquery/functions/fn/FunTrueOrFalse.java
+ src/main/java/org/exist/xquery/functions/fn/FunUnordered.java
+ src/main/java/org/exist/xquery/functions/fn/FunUnparsedText.java
+ src/main/java/org/exist/xquery/functions/fn/FunUpperOrLowerCase.java
+ src/main/java/org/exist/xquery/functions/fn/FunUriCollection.java
+ src/main/java/org/exist/xquery/functions/fn/FunXmlToJson.java
+ src/test/java/org/exist/xquery/functions/fn/FunXmlToJsonTest.java
+ src/main/java/org/exist/xquery/functions/fn/FunZeroOrOne.java
+ src/main/java/org/exist/xquery/functions/fn/LoadXQueryModule.java
+ src/main/java/org/exist/xquery/functions/fn/ParsingFunctions.java
+ src/test/java/org/exist/xquery/functions/fn/ParsingFunctionsTest.java
+ src/main/java/org/exist/xquery/functions/fn/QNameFunctions.java
+ src/main/java/org/exist/xquery/functions/fn/transform/Convert.java
+ src/test/java/org/exist/xquery/functions/fn/transform/ConvertTest.java
+ src/main/java/org/exist/xquery/functions/fn/transform/Delivery.java
+ src/test/java/org/exist/xquery/functions/fn/transform/FunTransformITTest.java
+ src/main/java/org/exist/xquery/functions/fn/transform/Options.java
+ src/main/java/org/exist/xquery/functions/fn/transform/Transform.java
+ src/main/java/org/exist/xquery/functions/fn/transform/TreeUtils.java
+ src/test/java/org/exist/xquery/functions/inspect/InspectModuleTest.java
+ src/main/java/org/exist/xquery/functions/integer/WordPicture.java
+ src/main/java/org/exist/xquery/functions/map/MapExpr.javasrc/main/java/org/exist/xquery/functions/map/MapType.java
+ src/main/java/org/exist/xquery/functions/request/GetData.java
+ src/test/java/org/exist/xquery/functions/request/GetData2Test.java
+ src/test/java/org/exist/xquery/functions/request/GetDataTest.java
+ src/test/java/org/exist/xquery/functions/request/GetHeaderTest.java
+ src/test/java/org/exist/xquery/functions/request/GetParameterTest.java
+ src/test/java/org/exist/xquery/functions/request/PatchTest.java
+ src/main/java/org/exist/xquery/functions/response/Stream.java
+ src/test/java/org/exist/xquery/functions/securitymanager/AccountMetadataFunctionsTest.java
+ src/test/java/org/exist/xquery/functions/securitymanager/GetPermissionsTest.java
+ src/test/java/org/exist/xquery/functions/securitymanager/GroupManagementFunctionRemoveGroupTest.java
+ src/test/java/org/exist/xquery/functions/securitymanager/GroupMembershipFunctionRemoveGroupMemberTest.java
+ src/test/java/org/exist/xquery/functions/securitymanager/IdFunctionTest.java
+ src/test/java/org/exist/xquery/functions/securitymanager/PermissionsFunctionChmodTest.java
+ src/test/java/org/exist/xquery/functions/securitymanager/PermissionsFunctionChownTest.java
+ src/test/java/org/exist/xquery/functions/securitymanager/SecurityManagerTestUtil.javasrc/test/java/org/exist/xquery/functions/session/AbstractSessionTest.java
- src/test/java/org/exist/xquery/functions/xmldb/AbstractXMLDBTest.javasrc/test/java/org/exist/xquery/functions/session/AttributeTest.java
- src/test/java/org/exist/xquery/functions/xmldb/XMLDBAuthenticateTest.java
+ src/main/java/org/exist/xquery/functions/system/FunctionAvailable.java
+ src/test/java/org/exist/xquery/functions/system/GetRunningXQueriesTest.java
+ src/main/java/org/exist/xquery/functions/system/GetUptime.java
+ src/main/java/org/exist/xquery/functions/system/Restore.java
+ src/main/java/org/exist/xquery/functions/system/Shutdown.java
+ src/main/java/org/exist/xquery/functions/system/SystemModule.java
+ src/main/java/org/exist/xquery/functions/system/TriggerSystemTask.java
+ src/test/resources-filtered/org/exist/xquery/functions/transform/transform-from-pkg-test.conf.xml
+ src/main/java/org/exist/xquery/functions/transform/Transform.java
+ src/test/java/org/exist/xquery/functions/transform/TransformFromPkgTest.java
+ src/test/java/org/exist/xquery/functions/transform/TransformTest.java
+ src/main/java/org/exist/xquery/functions/util/BuiltinFunctions.java
+ src/main/java/org/exist/xquery/functions/util/DescribeFunction.javasrc/main/java/org/exist/xquery/functions/util/Eval.java
+ src/test/java/org/exist/xquery/functions/util/EvalTest.java
+ src/test/java/org/exist/xquery/functions/util/ExpandTest.java
+ src/main/java/org/exist/xquery/functions/util/FunctionFunction.java
+ src/main/java/org/exist/xquery/functions/util/LogFunction.java
+ src/main/java/org/exist/xquery/functions/util/ModuleInfo.java
+ src/test/java/org/exist/xquery/functions/validate/JaxpDtdCatalogTest.java
+ src/test/java/org/exist/xquery/functions/validate/JaxpParseTest.java
+ src/test/java/org/exist/xquery/functions/validate/JaxpXsdCatalogTest.java
+ src/test/java/org/exist/xquery/functions/validate/JaxvTest.java
+ src/test/java/org/exist/xquery/functions/validate/JingOnvdlTest.java
+ src/test/java/org/exist/xquery/functions/validate/JingRelaxNgTest.java
+ src/test/java/org/exist/xquery/functions/validate/JingSchematronTest.java
+ src/test/java/org/exist/xquery/functions/validate/JingXsdTest.java
+ src/main/java/org/exist/xquery/functions/validation/Jaxp.java
+ src/test/java/org/exist/xquery/functions/xmldb/AbstractXMLDBTest.java
+ src/test/java/org/exist/xquery/functions/xmldb/DbStore2Test.java
+ src/test/java/org/exist/xquery/functions/xmldb/XMLDBAuthenticateTest.java
+ src/main/java/org/exist/xquery/functions/xmldb/XMLDBGetMimeType.java
+ src/main/java/org/exist/xquery/functions/xmldb/XMLDBLoadFromPattern.java
+ src/main/java/org/exist/xquery/functions/xmldb/XMLDBModule.java
+ src/main/java/org/exist/xquery/functions/xmldb/XMLDBSetMimeType.java
+ src/main/java/org/exist/xquery/functions/xmldb/XMLDBStore.java
+ src/test/java/org/exist/xquery/functions/xmldb/XMLDBStoreTest.java
+ src/main/java/org/exist/xquery/functions/xmldb/XMLDBXUpdate.java
+ src/test/java/org/exist/xquery/functions/xquery3/SerializeTest.java
+ src/test/java/org/exist/xquery/functions/xquery3/TryCatchTest.java
+ src/main/antlr/org/exist/xquery/parser/XQuery.g
+ src/main/antlr/org/exist/xquery/parser/XQueryTree.gsrc/main/java/org/exist/xquery/pragmas/TimePragma.java
+ src/test/java/org/exist/xquery/update/AbstractUpdateTest.java
+ src/test/java/org/exist/xquery/update/IndexIntegrationTest.java
+ src/test/java/org/exist/xquery/update/UpdateInsertTest.java
+ src/test/java/org/exist/xquery/update/UpdateInsertTriggersDefragTest.java
+ src/test/java/org/exist/xquery/update/UpdateReplaceTest.java
+ src/test/java/org/exist/xquery/update/UpdateValueTest.java
+ src/main/java/org/exist/xquery/util/ExpressionDumper.java
+ src/main/java/org/exist/xquery/util/SerializerUtils.javasrc/test/java/org/exist/xquery/util/URIUtilsTest.java
+ src/main/java/org/exist/xquery/value/AbstractDateTimeValue.java
+ src/main/java/org/exist/xquery/value/AbstractTimeRelatedTest.java
+ src/main/java/org/exist/xquery/value/AnyURIValue.javasrc/main/java/org/exist/xquery/value/ArrayListValueSequence.java
- src/test/java/org/exist/xquery/value/BifurcanMapTest.java
+ src/main/java/org/exist/xquery/value/ArrayWrapper.javasrc/main/java/org/exist/xquery/value/AtomicValueComparator.java
+ src/test/java/org/exist/xquery/value/Base64BinaryValueTypeTest.java
+ src/test/java/org/exist/xquery/value/BifurcanMapTest.java
+ src/main/java/org/exist/xquery/value/BinaryValue.java
+ src/main/java/org/exist/xquery/value/BooleanValue.java
+ src/test/java/org/exist/xquery/value/DateTest.java
+ src/test/java/org/exist/xquery/value/DateTimeStampTest.java
+ src/main/java/org/exist/xquery/value/DateTimeStampValue.java
+ src/test/java/org/exist/xquery/value/DateTimeTest.java
+ src/test/java/org/exist/xquery/value/DateTimeTypesTest.java
+ src/main/java/org/exist/xquery/value/DateTimeValue.java
+ src/main/java/org/exist/xquery/value/DateValue.java
+ src/test/java/org/exist/xquery/value/DayTimeDurationTest.java
+ src/main/java/org/exist/xquery/value/DayTimeDurationValue.java
+ src/main/java/org/exist/xquery/value/DecimalValue.java
+ src/main/java/org/exist/xquery/value/DoubleValue.java
+ src/test/java/org/exist/xquery/value/DurationTest.java
+ src/main/java/org/exist/xquery/value/DurationValue.java
+ src/main/java/org/exist/xquery/value/FloatValue.java
+ src/main/java/org/exist/xquery/value/GDayValue.java
+ src/main/java/org/exist/xquery/value/GMonthDayValue.java
+ src/main/java/org/exist/xquery/value/GMonthValue.java
+ src/main/java/org/exist/xquery/value/GYearMonthValue.java
+ src/main/java/org/exist/xquery/value/GYearValue.java
+ src/main/java/org/exist/xquery/value/IntegerValue.javasrc/main/java/org/exist/xquery/value/ItemComparator.java
+ src/main/java/org/exist/xquery/value/MemoryNodeSet.java
+ src/main/java/org/exist/xquery/value/QNameValue.javasrc/main/java/org/exist/xquery/value/SequenceComparator.java
+ src/main/java/org/exist/xquery/value/SequenceType.java
+ src/main/java/org/exist/xquery/value/StringValue.javasrc/main/java/org/exist/xquery/value/SubSequence.javasrc/test/java/org/exist/xquery/value/SubSequenceRangeTest.javasrc/test/java/org/exist/xquery/value/SubSequenceTest.java
- src/test/xquery/binary-value.xqm
- src/test/xquery/instance-of.xqm
- src/test/xquery/operator-mapping.xqm
- src/test/xquery/order.xqm
- src/test/xquery/type-promotion.xqm
- src/test/xquery/xqsuite/xqsuite-assertions-dynamic.xqm
- src/test/xquery/xqsuite/xqsuite-assertions-inline.xqm
- src/test/xquery/xqsuite/xqsuite-assertions.resources.xqm.ignore
- src/test/xquery/xquery3/function-reference.xqm
- src/test/xquery/xquery3/postfix-expr.xqm
-
-
+ src/test/java/org/exist/xquery/value/TimeTest.java
+ src/main/java/org/exist/xquery/value/TimeUtils.java
+ src/main/java/org/exist/xquery/value/TimeValue.java
+ src/main/java/org/exist/xquery/value/Type.java
+ src/main/java/org/exist/xquery/value/ValueSequence.java
+ src/test/java/org/exist/xquery/value/YearMonthDurationTest.java
+ src/main/java/org/exist/xquery/value/YearMonthDurationValue.java
+ src/main/java/org/exist/xslt/EXistURIResolver.java
+ src/main/java/org/exist/xslt/XsltURIResolverHelper.java
+ src/main/java/org/exist/xupdate/Append.java
+ src/main/java/org/exist/xupdate/Conditional.java
+ src/main/java/org/exist/xupdate/Insert.java
+ src/main/java/org/exist/xupdate/Modification.java
+ src/main/java/org/exist/xupdate/Remove.java
+ src/test/java/org/exist/xupdate/RemoveAppendTest.java
+ src/main/java/org/exist/xupdate/Rename.java
+ src/main/java/org/exist/xupdate/Replace.java
+ src/main/java/org/exist/xupdate/Update.java
+ src/main/java/org/exist/xupdate/XUpdateProcessor.java
+ src/test/java/org/exist/xupdate/XUpdateTest.java
+ src/main/resources/xyz/elemental/mediatype/media-type-mappings.xml
+ src/main/resources/xyz/elemental/mediatype/mime.types
+
+
+
src/main/java/org/exist/storage/btree/BTree.javasrc/main/java/org/exist/storage/btree/BTreeCallback.javasrc/main/java/org/exist/storage/btree/BTreeException.java
@@ -813,23 +2312,23 @@
src/main/java/org/exist/storage/btree/IndexQuery.javasrc/main/java/org/exist/storage/btree/Paged.javasrc/main/java/org/exist/storage/btree/Value.java
+
-
+
src/main/java/org/exist/util/CodePointString.javasrc/test/java/org/exist/util/CodePointStringTest.javasrc/main/java/org/exist/util/io/ByteBufferAccessor.javasrc/main/java/org/exist/util/io/ByteBufferInputStream.javasrc/main/java/org/exist/util/io/CachingFilterInputStream.java
+ src/test/java/org/exist/util/io/CachingFilterInputStreamNonMarkableByteArrayInputStreamTest.javasrc/main/java/org/exist/util/io/FileFilterInputStreamCache.javasrc/main/java/org/exist/util/io/FilterInputStreamCache.javasrc/main/java/org/exist/util/io/FilterInputStreamCacheFactory.javasrc/main/java/org/exist/util/io/MemoryFilterInputStreamCache.javasrc/main/java/org/exist/util/io/MemoryMappedFileFilterInputStreamCache.javasrc/main/java/org/exist/util/io/TemporaryFileManager.java
- src/test/java/org/exist/util/io/CachingFilterInputStreamTest_NonMarkableByteArrayInputStream.javasrc/main/java/org/exist/xquery/functions/fn/FnFormatNumbers.java
+
@@ -840,7 +2339,7 @@
- ${project.parent.relativePath}/LGPL-21-license.template.txt
+ ${project.parent.relativePath}/existdb-LGPL-21-license.template.txtDBXML-10-license.template.txt
@@ -860,60 +2359,73 @@ The original license statement is also included below.]]>
-->
ARC-BSD-3-license.template.txt
-
src/main/java/org/exist/util/io/ByteBufferAccessor.javasrc/main/java/org/exist/util/io/ByteBufferInputStream.javasrc/main/java/org/exist/util/io/CachingFilterInputStream.java
+ src/test/java/org/exist/util/io/CachingFilterInputStreamNonMarkableByteArrayInputStreamTest.javasrc/main/java/org/exist/util/io/FileFilterInputStreamCache.javasrc/main/java/org/exist/util/io/FilterInputStreamCache.javasrc/main/java/org/exist/util/io/FilterInputStreamCacheFactory.javasrc/main/java/org/exist/util/io/MemoryFilterInputStreamCache.javasrc/main/java/org/exist/util/io/MemoryMappedFileFilterInputStreamCache.javasrc/main/java/org/exist/util/io/TemporaryFileManager.java
- src/test/java/org/exist/util/io/CachingFilterInputStreamTest_NonMarkableByteArrayInputStream.java
- ${project.parent.relativePath}/FDB-backport-LGPL-21-ONLY-license.template.txt
+ ${project.parent.relativePath}/FDB-backport-to-existdb-LGPL-21-ONLY-license.template.txt
+ src/test/xquery/binary-value.xqm
+ src/test/xquery/instance-of.xqm
+ src/test/xquery/operator-mapping.xqm
+ src/test/xquery/order.xqm
+ src/test/xquery/type-promotion.xqm
+ src/test/xquery/xqsuite/xqsuite-assertions-dynamic.xqm
+ src/test/xquery/xqsuite/xqsuite-assertions-inline.xqm
+ src/test/xquery/xqsuite/xqsuite-assertions.resources.xqm.ignore
+ src/test/xquery/xquery3/function-reference.xqm
+ src/test/xquery/xquery3/postfix-expr.xqmsrc/main/java/org/exist/dom/persistent/XMLDeclarationImpl.javasrc/main/java/org/exist/resolver/ResolverFactory.javasrc/main/java/org/exist/resolver/XercesXmlResolverAdapter.java
- src/test/java/org/exist/storage/MoveCollectionTest.java
- src/main/java/org/exist/storage/blob/**
- src/test/java/org/exist/storage/blob/**
- src/main/java/org/exist/storage/journal/JournalManager.javasrc/test/java/org/exist/storage/AbstractRecoverTest.java
- src/test/java/org/exist/storage/RecoverBinaryTest.java
- src/test/java/org/exist/storage/RecoverXmlTest.java
- src/test/java/org/exist/storage/journal/AbstractJournalTest.java
- src/test/java/org/exist/storage/journal/JournalBinaryTest.java
- src/test/java/org/exist/storage/journal/JournalXmlTest.java
- src/test/java/org/exist/storage/journal/LsnTest.javasrc/main/java/org/exist/storage/BrokerPoolService.java
- src/test/java/org/exist/storage/BrokerPoolServiceTest.javasrc/main/java/org/exist/storage/BrokerPoolServiceException.javasrc/main/java/org/exist/storage/BrokerPoolServicesManager.javasrc/main/java/org/exist/storage/BrokerPoolServicesManagerException.java
+ src/test/java/org/exist/storage/BrokerPoolServiceTest.javasrc/main/java/org/exist/storage/FluentBrokerAPI.java
+ src/test/java/org/exist/storage/MoveCollectionTest.java
+ src/test/java/org/exist/storage/RecoverBinaryTest.java
+ src/test/java/org/exist/storage/RecoverXmlTest.javasrc/main/java/org/exist/storage/XQueryPool.java
+ src/main/java/org/exist/storage/blob/**
+ src/test/java/org/exist/storage/blob/**
+ src/test/java/org/exist/storage/journal/AbstractJournalTest.java
+ src/test/java/org/exist/storage/journal/JournalBinaryTest.java
+ src/main/java/org/exist/storage/journal/JournalManager.java
+ src/main/java/org/exist/storage/journal/JournalReader.java
+ src/test/java/org/exist/storage/journal/JournalXmlTest.java
+ src/test/java/org/exist/storage/journal/LsnTest.java
+ src/test/java/org/exist/storage/lock/CollectionLocksTest.java
+ src/test/java/org/exist/storage/lock/DocumentLocksTest.javasrc/main/java/org/exist/storage/lock/EnsureContainerLocked.javasrc/main/java/org/exist/storage/lock/EnsureContainerUnlocked.javasrc/main/java/org/exist/storage/lock/EnsureLocked.javasrc/main/java/org/exist/storage/lock/EnsureLockingAspect.javasrc/main/java/org/exist/storage/lock/EnsureUnlocked.javasrc/main/java/org/exist/storage/lock/FileLockService.java
+ src/main/java/org/exist/storage/lock/LockedPath.javasrc/main/java/org/exist/storage/lock/LockEventJsonListener.javasrc/main/java/org/exist/storage/lock/LockEventLogListener.javasrc/main/java/org/exist/storage/lock/LockEventXmlListener.java
- src/main/java/org/exist/storage/lock/LockedPath.javasrc/main/java/org/exist/storage/lock/LockGroup.javasrc/main/java/org/exist/storage/lock/LockManager.java
+ src/test/java/org/exist/storage/lock/LockManagerTest.javasrc/main/java/org/exist/storage/lock/LockTable.javasrc/main/java/org/exist/storage/lock/LockTableUtils.javasrc/main/java/org/exist/storage/lock/ManagedCollectionLock.java
@@ -921,13 +2433,10 @@ The original license statement is also included below.]]>
src/main/java/org/exist/storage/lock/ManagedLock.javasrc/main/java/org/exist/storage/lock/ManagedLockGroupDocumentLock.javasrc/main/java/org/exist/storage/lock/ManagedSingleLockDocumentLock.java
- src/test/java/org/exist/storage/lock/CollectionLocksTest.java
- src/test/java/org/exist/storage/lock/DocumentLocksTest.java
- src/test/java/org/exist/storage/lock/LockManagerTest.java
- src/main/java/org/exist/storage/txn/TransactionManager.javasrc/test/java/org/exist/storage/txn/ConcurrentTransactionsTest.javasrc/test/java/org/exist/storage/txn/CountingTxnListener.javasrc/test/java/org/exist/storage/txn/ReusableTxnTest.java
+ src/main/java/org/exist/storage/txn/TransactionManager.javasrc/test/java/org/exist/storage/txn/TransactionManagerTestHelper.javasrc/test/java/org/exist/storage/txn/TxnTest.javasrc/main/java/org/exist/test/DiffMatcher.java
@@ -939,45 +2448,48 @@ The original license statement is also included below.]]>
src/main/java/org/exist/xmlrpc/ACEAiderParser.javasrc/main/java/org/exist/xmlrpc/ACEAiderSerializer.javasrc/main/java/org/exist/xquery/Cardinality.java
- src/test/java/org/exist/xquery/CastExpressionTest.java
+ src/test/java/org/exist/xquery/CastExpressionTest.javasrc/test/java/org/exist/xquery/ImportModuleTest.javasrc/main/java/org/exist/xquery/Materializable.javasrc/test/java/org/exist/xquery/XQueryContextAttributesTest.javasrc/main/java/org/exist/xquery/functions/map/MapType.javasrc/test/java/org/exist/xquery/functions/session/AbstractSessionTest.java
- src/test/java/org/exist/xquery/functions/xmldb/AbstractXMLDBTest.javasrc/test/java/org/exist/xquery/functions/session/AttributeTest.java
- src/test/java/org/exist/xquery/functions/xmldb/XMLDBAuthenticateTest.javasrc/main/java/org/exist/xquery/functions/util/Eval.java
+ src/test/java/org/exist/xquery/functions/xmldb/AbstractXMLDBTest.java
+ src/test/java/org/exist/xquery/functions/xmldb/XMLDBAuthenticateTest.javasrc/main/java/org/exist/xquery/pragmas/TimePragma.javasrc/test/java/org/exist/xquery/util/URIUtilsTest.javasrc/main/java/org/exist/xquery/value/ArrayListValueSequence.java
- src/test/java/org/exist/xquery/value/BifurcanMapTest.javasrc/main/java/org/exist/xquery/value/AtomicValueComparator.java
+ src/test/java/org/exist/xquery/value/BifurcanMapTest.javasrc/main/java/org/exist/xquery/value/ItemComparator.javasrc/main/java/org/exist/xquery/value/SequenceComparator.javasrc/main/java/org/exist/xquery/value/SubSequence.javasrc/test/java/org/exist/xquery/value/SubSequenceRangeTest.javasrc/test/java/org/exist/xquery/value/SubSequenceTest.java
- src/test/xquery/binary-value.xqm
- src/test/xquery/instance-of.xqm
- src/test/xquery/operator-mapping.xqm
- src/test/xquery/order.xqm
- src/test/xquery/type-promotion.xqm
- src/test/xquery/xqsuite/xqsuite-assertions-dynamic.xqm
- src/test/xquery/xqsuite/xqsuite-assertions-inline.xqm
- src/test/xquery/xqsuite/xqsuite-assertions.resources.xqm.ignore
- src/test/xquery/xquery3/function-reference.xqm
- src/test/xquery/xquery3/postfix-expr.xqm
- FDB-backport-BSD-3-license.template.txt
+ ${project.parent.relativePath}/../elemental-parent/FDB-backport-to-EDB-LGPL-21-ONLY-license.template.txt
+
+ src/main/java/org/exist/mediatype/MediaTypeService.java
+ src/main/java/org/exist/mediatype/MediaTypeUtil.java
+ src/main/resources/xyz/elemental/mediatype/media-type-mappings.xml
+ src/main/resources/xyz/elemental/mediatype/mime.types
+
+
+
+
+
+ FDB-backport-to-existdb-BSD-3-license.template.txtsrc/main/java/org/exist/util/CodePointString.javasrc/test/java/org/exist/util/CodePointStringTest.java
@@ -987,12 +2499,12 @@ The original license statement is also included below.]]>
- FDB-backport-BSD-3-license.template.txt
+ FDB-backport-to-existdb-BSD-3-license.template.txtBX-BSD-3-license.template.txt
@@ -1033,18 +2545,19 @@ The BaseX Team. The original license statement is also included below.]]>org.apache.logging.log4j:log4j-jul:jar:${log4j.version}
org.eclipse.angus:angus-activation:jar:${eclipse.angus-activation.version}org.glassfish.jaxb:jaxb-runtime:jar:${jaxb.impl.version}
- org.fusesource.jansi:jansi:jar:${jansi.version}org.codelibs:nekohtml:jar:${nekohtml.version}xml-resolver:xml-resolver:jar:1.2org.xmlresolver:xmlresolver:jar:${xmlresolver.version}
- org.exist-db.thirdparty.org.eclipse.wst.xml:xpath2:jar:1.2.0
+ com.evolvedbinary.thirdparty.org.eclipse.wst.xml:xpath2:jar:1.2.1.1edu.princeton.cup:java-cup:jar:10korg.eclipse.jetty:jetty-jaas:jar:${jetty.version}org.eclipse.jetty:jetty-deploy:jar:${jetty.version}org.eclipse.jetty:jetty-jmx:jar:${jetty.version}org.eclipse.jetty:jetty-annotations:jar:${jetty.version}org.eclipse.jetty:jetty-security:jar:${jetty.version}
+ xyz.elemental:exist-core-build-tools:jar:${project.version}${project.groupId}:exist-jetty-config:jar:${project.version}
+ com.fasterxml:aalto-xml:jar
@@ -1058,7 +2571,6 @@ The BaseX Team. The original license statement is also included below.]]>
org.omnifacesantlr-maven-plugin
- 2.4
org/exist/xquery/parser/XQuery.g,org/exist/xquery/parser/XQueryTree.g,org/exist/xquery/parser/DeclScanner.g,org/exist/xquery/xqdoc/parser/XQDocParser.g
@@ -1094,69 +2606,33 @@ The BaseX Team. The original license statement is also included below.]]>
- maven-compiler-plugin
+ org.jvnet.jaxb
+ jaxb-maven-plugin
+
+ src/main/xjb
+ src/main/xsd
+
- default-compile
-
-
-
- org/exist/storage/lock/EnsureLockingAspect.java
- org/exist/security/PermissionRequiredAspect.java
-
-
+ generate-jaxb-objects
+
+ generate
+
- dev.aspectj
- aspectj-maven-plugin
- 1.14
-
-
- org.aspectj
- aspectjtools
- ${aspectj.version}
-
-
+ org.apache.maven.plugins
+ maven-compiler-plugin
-
- compile
-
-
-
-
-
+ default-compile
- true
- true
- ${project.build.source}
- ${project.build.source}
- ${project.build.target}
-
-
-
-
+ full
-
- **/EnsureLockingAspect.java
+
+ org/exist/storage/lock/EnsureLockingAspect.java
@@ -1167,7 +2643,7 @@ The BaseX Team. The original license statement is also included below.]]>org.apache.maven.plugins
maven-javadoc-plugin
- org.exist.xquery.parser:org.exist.xquery.xqdoc.parser
+ ${project.build.sourceDirectory}:${project.build.directory}/generated-sources/annotations:${project.build.directory}/generated-sources/antlr
@@ -1206,17 +2682,13 @@ The BaseX Team. The original license statement is also included below.]]>org.exist.collections.ConcurrencyTest
org.exist.xmldb.concurrent.FragmentsTest
-
- org.exist.xmldb.concurrent.ConcurrentResourceTest2
- org.exist.xmldb.concurrent.ConcurrentResourceTest3
-
org.exist.http.underheavyload.DatabaseUnderLoadTestorg.exist.storage.lock.DeadlockTestorg.exist.storage.RemoveCollectionTestorg.exist.xmldb.ShutdownTest
-
+
org.exist.xmlrpc.MoveResourceTest
@@ -1226,6 +2698,45 @@ The BaseX Team. The original license statement is also included below.]]>
+
+
+ limit-test-parallelism-in-ci
+
+
+ env.CI
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ ${junit.jupiter.version}
+
+
+ org.junit.vintage
+ junit-vintage-engine
+ ${junit.jupiter.version}
+
+
+ org.objenesis
+ objenesis
+ ${objenesis.version}
+
+
+
+
+ 0.5C
+
+
+
+
+
- org.exist.xmldb.concurrent.ConcurrentResourceTest2
- org.exist.xmldb.concurrent.ConcurrentResourceTest3
-
org.exist.http.underheavyload.DatabaseUnderLoadTestorg.exist.storage.lock.DeadlockTestorg.exist.storage.RemoveCollectionTestorg.exist.xmldb.ShutdownTest
-
+
org.exist.xmlrpc.MoveResourceTest
diff --git a/exist-core/project-suppression.xml b/exist-core/project-suppression.xml
index 624a75b6e7..69582fff6b 100644
--- a/exist-core/project-suppression.xml
+++ b/exist-core/project-suppression.xml
@@ -1,15 +1,14 @@
-
-
- ^org\.apache\.xmlrpc:xmlrpc-common:.*$
- CVE-2016-5002
-
\ No newline at end of file
diff --git a/exist-core/src/main/antlr/org/exist/xquery/parser/XQuery.g b/exist-core/src/main/antlr/org/exist/xquery/parser/XQuery.g
index bc59b416c8..d9c7a228fb 100644
--- a/exist-core/src/main/antlr/org/exist/xquery/parser/XQuery.g
+++ b/exist-core/src/main/antlr/org/exist/xquery/parser/XQuery.g
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -150,6 +174,8 @@ imaginaryTokenDefinitions
NAMESPACE_DECL
DEF_NAMESPACE_DECL
DEF_COLLATION_DECL
+ DECIMAL_FORMAT_DECL
+ DEFAULT_DECIMAL_FORMAT
DEF_FUNCTION_NS_DECL
CONTEXT_ITEM_DECL
ANNOT_DECL
@@ -256,7 +282,7 @@ prolog throws XPathException
(
importDecl
|
- ( "declare" ( "default" | "boundary-space" | "ordering" | "construction" | "base-uri" | "copy-namespaces" | "namespace" ) ) =>
+ ( "declare" ( "default" | "boundary-space" | "ordering" | "construction" | "base-uri" | "copy-namespaces" | "namespace" | "decimal-format" ) ) =>
s:setter
{
if(!inSetters)
@@ -295,10 +321,44 @@ versionDecl throws XPathException
{ #versionDecl = #(#[VERSION_DECL, v.getText()], enc); }
;
+dfPropertyName
+:
+ "decimal-separator"
+ | "grouping-separator"
+ | "infinity"
+ | "minus-sign"
+ | "NaN"
+ | "percent"
+ | "per-mille"
+ | "zero-digit"
+ | "digit"
+ | "pattern-separator"
+ | "exponent-separator"
+ ;
+
+decimalFormatDecl
+{ String dfName = null; }
+:
+ "declare"!
+ (
+ "default" "decimal-format"
+ ( dfPropertyName EQ! STRING_LITERAL )*
+ {
+ ## = #( #[DECIMAL_FORMAT_DECL, "DECIMAL_FORMAT_DECL"], #[DEFAULT_DECIMAL_FORMAT, "DEFAULT_DECIMAL_FORMAT"], ## );
+ }
+ |
+ "decimal-format" eqName
+ ( dfPropertyName EQ! STRING_LITERAL )*
+ {
+ ## = #( #[DECIMAL_FORMAT_DECL, "DECIMAL_FORMAT_DECL"], ## );
+ }
+ )
+;
+
setter
:
(
- ( "declare" "default" ) =>
+ ( "declare" "default" ( "collation" | "element" | "function" | "order" ) ) =>
"declare"! "default"!
(
"collation"! defc:STRING_LITERAL
@@ -330,6 +390,8 @@ setter
|
( "declare" "namespace" ) =>
namespaceDecl
+ | ( "declare" ( "default" )? "decimal-format" ) =>
+ decimalFormatDecl
)
;
diff --git a/exist-core/src/main/antlr/org/exist/xquery/parser/XQueryTree.g b/exist-core/src/main/antlr/org/exist/xquery/parser/XQueryTree.g
index 048ee8e7e8..44119f869d 100644
--- a/exist-core/src/main/antlr/org/exist/xquery/parser/XQueryTree.g
+++ b/exist-core/src/main/antlr/org/exist/xquery/parser/XQueryTree.g
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -56,8 +80,6 @@ header {
import org.exist.storage.ElementValue;
import org.exist.xquery.functions.map.MapExpr;
import org.exist.xquery.functions.array.ArrayConstructor;
-
- import static org.apache.commons.lang3.ArrayUtils.isNotEmpty;
}
/**
@@ -84,6 +106,7 @@ options {
protected Set importedModules = new HashSet<>();
protected Set importedModuleFunctions = null;
protected Set importedModuleVariables = null;
+ private boolean hasDefaultDecimalFormat = false;
public XQueryTreeParser(XQueryContext context) {
this(context, null);
@@ -489,6 +512,76 @@ throws PermissionDeniedException, EXistException, XPathException
}
)
|
+ #(
+ DECIMAL_FORMAT_DECL
+ {
+ final XQueryAST root = (XQueryAST) _t; // points to DECIMAL_FORMAT_DECL
+ // first sibling is either DEFAULT_DECIMAL_FORMAT (default) or EQNAME (named)
+ final XQueryAST dfName = (XQueryAST) root.getNextSibling();
+
+ final QName qnDfName;
+ if ("default".equals(dfName.getText())) {
+ qnDfName = XQueryContext.UNNAMED_DECIMAL_FORMAT;
+ if (hasDefaultDecimalFormat) {
+ throw new XPathException(dfName.getLine(), dfName.getColumn(), ErrorCodes.W3CErrorCode.XQST0111.getErrorCode(), "Query prolog cannot contain two default decimal format declarations.");
+ } else {
+ hasDefaultDecimalFormat = true;
+ }
+ } else {
+ try {
+ qnDfName = QName.parse(staticContext, dfName.getText(), null);
+ } catch (final IllegalQNameException iqe) {
+ throw new XPathException(dfName.getLine(), dfName.getColumn(), ErrorCodes.XPST0081, "No namespace defined for prefix " + dfName.getText());
+ }
+
+ if (staticContext.getStaticDecimalFormat(qnDfName) != null) {
+ throw new XPathException(dfName.getLine(), dfName.getColumn(), ErrorCodes.W3CErrorCode.XQST0111.getErrorCode(), "Query prolog cannot contain two decimal format declarations with the same name: " + dfName.getText());
+ }
+ }
+
+ // position current at the first property name for the decimal format
+ XQueryAST current = (XQueryAST) dfName.getNextSibling();
+ if ("default".equals(dfName.getText())) {
+ current = (XQueryAST) current.getNextSibling();
+ }
+
+ final Map dfProperties = new HashMap<>();
+
+ while (current != null) {
+ final XQueryAST pname = current;
+ final XQueryAST pval = (XQueryAST) current.getNextSibling();
+
+ if (pval == null) {
+ break;
+ }
+
+ final String pn = pname.getText();
+ String pv = pval.getText();
+ if (pv.length() >= 2 && (pv.startsWith("\"") || pv.startsWith("'"))) {
+ pv = pv.substring(1, pv.length() - 1);
+ }
+ if (dfProperties.put(pn, pv) != null) {
+ throw new XPathException(dfName.getLine(), dfName.getColumn(), ErrorCodes.W3CErrorCode.XQST0114.getErrorCode(), "Decimal format: " + dfName.getText() + " defines the property: " + pn + " more than once.");
+ }
+
+ current = (XQueryAST) pval.getNextSibling();
+ }
+
+ final DecimalFormat df;
+ try {
+ df = DecimalFormat.fromProperties(dfProperties);
+ } catch (final IllegalArgumentException ex) {
+ throw new XPathException(dfName.getLine(), dfName.getColumn(), ErrorCodes.W3CErrorCode.XQST0097.getErrorCode(), ex.getMessage() + " within the picture string of the decimal format: " + dfName.getText() + ".");
+ }
+ if (!df.checkDistinctCharacters()) {
+ throw new XPathException(dfName.getLine(), dfName.getColumn(), ErrorCodes.W3CErrorCode.XQST0098.getErrorCode(), "Characters within the picture string of the decimal format: " + dfName.getText() + " are not distinct.");
+ }
+
+ staticContext.setStaticDecimalFormat(qnDfName, df);
+ context.setStaticDecimalFormat(qnDfName, df);
+ }
+ )
+ |
#(
qname:GLOBAL_VAR
{
@@ -510,9 +603,8 @@ throws PermissionDeniedException, EXistException, XPathException
}
declaredGlobalVars.add(qn);
}
- { List annots = new ArrayList(); }
- (annotations [annots]
- )?
+ { List annots = new ArrayList(); }
+ (annotations [annots])?
(
#(
"as"
@@ -542,22 +634,11 @@ throws PermissionDeniedException, EXistException, XPathException
step=ext:expr [defaultValue]
)?
{
- // variable may be declared in static context: retrieve and set its sequence type
- Variable external = null;
- try {
- external = context.resolveVariable(qname.getText());
- if (external != null) {
- external.setSequenceType(type);
- }
- } catch (XPathException ignoredException) {
- }
-
final VariableDeclaration decl = new VariableDeclaration(context, qn, defaultValue);
decl.setSequenceType(type);
+ decl.setExternal(true);
decl.setASTNode(ext);
- if (external == null) {
- path.add(decl);
- }
+ path.add(decl);
if(myModule != null) {
myModule.declareVariable(qn, decl);
}
@@ -675,12 +756,12 @@ throws PermissionDeniedException, EXistException, XPathException
throw xpe;
}
- if (isNotEmpty(modules)) {
+ if (modules != null) {
for (final org.exist.xquery.Module module : modules) {
// check modules does not import any duplicate function definitions
final FunctionSignature[] signatures = module.listFunctions();
- if (isNotEmpty(signatures)) {
+ if (signatures != null) {
for (final FunctionSignature signature : signatures) {
final String qualifiedNameArity = signature.getName().toURIQualifiedName() + '#' + signature.getArgumentCount();
if (importedModuleFunctions != null) {
@@ -752,7 +833,7 @@ throws PermissionDeniedException, EXistException, XPathException
throw xpe;
}
// We ought to do this for now until Dannes can say it works. /ljo
- //throw new XPathException(s, ErrorCodes.XQST0009, "The eXist-db XQuery implementation does not support the Schema Import Feature quite yet.");
+ //throw new XPathException(s, ErrorCodes.XQST0009, "The XQuery implementation does not support the Schema Import Feature quite yet.");
}
)
;
@@ -2984,19 +3065,38 @@ throws PermissionDeniedException, EXistException, XPathException
rs.setAxis(Constants.DESCENDANT_AXIS);
} else if (rs.getAxis() == Constants.SELF_AXIS) {
rs.setAxis(Constants.DESCENDANT_SELF_AXIS);
- } else {
+ } else if (rs.getAxis() == Constants.CHILD_AXIS || rs.getAxis() == Constants.UNKNOWN_AXIS) {
+ // For CHILD_AXIS or UNKNOWN_AXIS, change to descendant-or-self
rs.setAxis(Constants.DESCENDANT_SELF_AXIS);
rs.setAbbreviated(true);
+ } else {
+ // For other explicit axes (following, preceding, ancestor, etc.)
+ // insert a separate descendant-or-self::node() step before this step
+ final LocationStep dsStep = new LocationStep(context, Constants.DESCENDANT_SELF_AXIS, new AnyNodeTest());
+ path.insertBeforeLast(dsStep);
}
} else {
- rightStep.setPrimaryAxis(Constants.DESCENDANT_SELF_AXIS);
- if(rightStep instanceof VariableReference) {
- rightStep = new SimpleStep(context, Constants.DESCENDANT_SELF_AXIS, rightStep);
- path.replaceLastExpression(rightStep);
- } else if (rightStep instanceof FilteredExpression)
- ((FilteredExpression)rightStep).setAbbreviated(true);
+ if (rightStep instanceof Function) {
+ // For non-LocationStep expressions (function calls, etc.)
+ // insert a separate descendant-or-self::node() step before this step
+ final LocationStep dsStep = new LocationStep(context, Constants.DESCENDANT_SELF_AXIS, new AnyNodeTest());
+ path.insertBeforeLast(dsStep);
+ } else {
+ if (rightStep.getPrimaryAxis() == Constants.ATTRIBUTE_AXIS) {
+ rightStep.setPrimaryAxis(Constants.DESCENDANT_ATTRIBUTE_AXIS);
+ } else {
+ rightStep.setPrimaryAxis(Constants.DESCENDANT_SELF_AXIS);
+ }
+ if(rightStep instanceof VariableReference) {
+ // VariableReference needs special handling
+ rightStep = new SimpleStep(context, Constants.DESCENDANT_SELF_AXIS, rightStep);
+ path.replaceLastExpression(rightStep);
+ } else if (rightStep instanceof FilteredExpression) {
+ ((FilteredExpression)rightStep).setAbbreviated(true);
+ }
+ }
}
}
)?
diff --git a/exist-core/src/main/java/org/exist/Indexer.java b/exist-core/src/main/java/org/exist/Indexer.java
index ea69cbcb2f..a7b7a1c7d0 100644
--- a/exist-core/src/main/java/org/exist/Indexer.java
+++ b/exist-core/src/main/java/org/exist/Indexer.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -600,7 +624,7 @@ public void startElement(final String namespace, final String name, final String
setPrevious(null);
node.setOwnerDocument(document);
node.setAttributes((short) attrLength);
- if (nsMappings != null && nsMappings.size() > 0) {
+ if (!nsMappings.isEmpty()) {
node.setNamespaceMappings(nsMappings);
nsMappings.clear();
}
@@ -624,7 +648,7 @@ public void startElement(final String namespace, final String name, final String
node.setOwnerDocument(document);
node.setNodeId(broker.getBrokerPool().getNodeFactory().createInstance(nodeFactoryInstanceCnt++));
node.setAttributes((short) attrLength);
- if (nsMappings != null && nsMappings.size() > 0) {
+ if (!nsMappings.isEmpty()) {
node.setNamespaceMappings(nsMappings);
nsMappings.clear();
}
diff --git a/exist-core/src/main/java/org/exist/Namespaces.java b/exist-core/src/main/java/org/exist/Namespaces.java
index 593ab89085..187f8d38cd 100644
--- a/exist-core/src/main/java/org/exist/Namespaces.java
+++ b/exist-core/src/main/java/org/exist/Namespaces.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -41,7 +65,8 @@ public interface Namespaces {
String SCHEMA_INSTANCE_NS = XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI;
// Move this here from Function.BUILTIN_FUNCTION_NS? /ljo
- String XPATH_FUNCTIONS_NS = "http://www.w3.org/2005/xpath-functions";
+ String XPATH_FUNCTIONS_NS = "http://www.w3.org/2005/xpath-functions";
+ String XPATH_FUNCTIONS_PREFIX = "fn";
String XQUERY_LOCAL_NS = "http://www.w3.org/2005/xquery-local-functions";
String XPATH_DATATYPES_NS = "http://www.w3.org/2003/05/xpath-datatypes";
diff --git a/exist-core/src/main/java/org/exist/backup/Backup.java b/exist-core/src/main/java/org/exist/backup/Backup.java
index e000fa6d93..4ab112b1d3 100644
--- a/exist-core/src/main/java/org/exist/backup/Backup.java
+++ b/exist-core/src/main/java/org/exist/backup/Backup.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -421,7 +445,7 @@ private void backup(final Set seenBlobIds, final Collection current, fin
}
attr.addAttribute(Namespaces.EXIST_NS, "filename", "filename", "CDATA", filename);
- attr.addAttribute(Namespaces.EXIST_NS, "mimetype", "mimetype", "CDATA", encode(((EXistResource) resource).getMimeType()));
+ attr.addAttribute(Namespaces.EXIST_NS, "mimetype", "mimetype", "CDATA", encode(((EXistResource) resource).getMediaType()));
if (XML_RESOURCE.equals(resourceType)) {
diff --git a/exist-core/src/main/java/org/exist/backup/CreateBackupDialog.java b/exist-core/src/main/java/org/exist/backup/CreateBackupDialog.java
index 189d06b3b9..5d2b92bef4 100644
--- a/exist-core/src/main/java/org/exist/backup/CreateBackupDialog.java
+++ b/exist-core/src/main/java/org/exist/backup/CreateBackupDialog.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -22,12 +46,14 @@
package org.exist.backup;
import org.exist.client.Messages;
-import org.exist.client.MimeTypeFileFilter;
+import org.exist.client.MediaTypeFileFilter;
import org.exist.security.PermissionDeniedException;
import org.exist.xmldb.XmldbURI;
import org.xmldb.api.DatabaseManager;
import org.xmldb.api.base.Collection;
import org.xmldb.api.base.XMLDBException;
+import xyz.elemental.mediatype.MediaType;
+import xyz.elemental.mediatype.MediaTypeResolver;
import javax.swing.*;
import java.awt.*;
@@ -49,12 +75,13 @@ public class CreateBackupDialog extends JPanel {
final String passwd;
Path backupDir;
final String defaultSelectedCollection;
+ private final MediaTypeResolver mediaTypeResolver;
- public CreateBackupDialog(final String uri, final String user, final String passwd, final Path backupDir) throws HeadlessException {
- this(uri, user, passwd, backupDir, null);
+ public CreateBackupDialog(final String uri, final String user, final String passwd, final Path backupDir, final MediaTypeResolver mediaTypeResolver) throws HeadlessException {
+ this(uri, user, passwd, backupDir, null, mediaTypeResolver);
}
- public CreateBackupDialog(final String uri, final String user, final String passwd, final Path backupDir, final String defaultSelectedCollection) throws HeadlessException {
+ public CreateBackupDialog(final String uri, final String user, final String passwd, final Path backupDir, final String defaultSelectedCollection, final MediaTypeResolver mediaTypeResolver) throws HeadlessException {
super(false);
this.uri = uri;
@@ -62,6 +89,7 @@ public CreateBackupDialog(final String uri, final String user, final String pass
this.passwd = passwd;
this.backupDir = backupDir;
this.defaultSelectedCollection = defaultSelectedCollection;
+ this.mediaTypeResolver = mediaTypeResolver;
setupComponents();
setSize(new Dimension(350, 200));
@@ -147,7 +175,8 @@ private void actionSelect() {
final JFileChooser chooser = new JFileChooser();
chooser.setMultiSelectionEnabled(false);
chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
- chooser.addChoosableFileFilter(new MimeTypeFileFilter("application/zip"));
+ final MediaType mediaType = mediaTypeResolver.fromString(MediaType.APPLICATION_ZIP);
+ chooser.addChoosableFileFilter(new MediaTypeFileFilter(mediaType));
chooser.setSelectedFile(Paths.get("eXist-backup.zip").toFile());
chooser.setCurrentDirectory(backupDir.toFile());
diff --git a/exist-core/src/main/java/org/exist/backup/ExportGUI.java b/exist-core/src/main/java/org/exist/backup/ExportGUI.java
index 2ed389b54f..d50d380164 100644
--- a/exist-core/src/main/java/org/exist/backup/ExportGUI.java
+++ b/exist-core/src/main/java/org/exist/backup/ExportGUI.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -29,14 +53,14 @@
import org.exist.storage.DBBroker;
import org.exist.storage.txn.Txn;
import org.exist.util.Configuration;
-import org.exist.util.MimeTable;
-import org.exist.util.MimeType;
import org.exist.util.OSUtil;
import org.exist.util.SystemExitCodes;
import org.exist.xquery.TerminatedException;
import se.softhouse.jargo.Argument;
import se.softhouse.jargo.ArgumentException;
import se.softhouse.jargo.CommandLineParser;
+import xyz.elemental.mediatype.MediaType;
+import xyz.elemental.mediatype.StorageType;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
@@ -413,19 +437,20 @@ private void btnConfSelectActionPerformed(final java.awt.event.ActionEvent evt)
.toFile());
chooser.setCurrentDirectory(dir.resolve("etc").toFile());
chooser.setFileFilter(new FileFilter() {
+ @Override
public boolean accept(final File f) {
if (f.isDirectory()) {
return (true);
}
- final MimeType mime = MimeTable.getInstance().getContentTypeFor(f.getName());
+ final MediaType mediaType = pool.getMediaTypeService().getMediaTypeResolver().fromFileName(f.toPath());
- if (mime == null) {
+ if (mediaType == null) {
return false;
}
- return mime.isXMLType();
+ return mediaType.getStorageType() == StorageType.XML;
}
-
+ @Override
public String getDescription() {
return ("Database XML configuration file");
}
@@ -625,7 +650,7 @@ public static void main(final String[] args) {
// parse command-line options
CommandLineParser
.withArguments(helpArg)
- .programName("export-gui" + (OSUtil.isWindows() ? ".bat" : ".sh"))
+ .programName("export-gui" + (OSUtil.IS_WINDOWS ? ".bat" : ".sh"))
.parse(args);
} catch (final StartException e) {
diff --git a/exist-core/src/main/java/org/exist/backup/ExportMain.java b/exist-core/src/main/java/org/exist/backup/ExportMain.java
index 117eaa9163..f4bcef145a 100644
--- a/exist-core/src/main/java/org/exist/backup/ExportMain.java
+++ b/exist-core/src/main/java/org/exist/backup/ExportMain.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -131,7 +155,7 @@ public static void main(final String[] args) {
.withArguments(noCheckArg, checkDocsArg, directAccessArg, exportArg, noExportArg, incrementalArg, zipArg, noZipArg)
.andArguments(configArg, outputDirArg)
.andArguments(helpArg, verboseArg)
- .programName("export" + (OSUtil.isWindows() ? ".bat" : ".sh"))
+ .programName("export" + (OSUtil.IS_WINDOWS ? ".bat" : ".sh"))
.parse(args);
process(arguments);
diff --git a/exist-core/src/main/java/org/exist/backup/Main.java b/exist-core/src/main/java/org/exist/backup/Main.java
index c5098db9bb..f63f98b6f2 100644
--- a/exist-core/src/main/java/org/exist/backup/Main.java
+++ b/exist-core/src/main/java/org/exist/backup/Main.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -22,6 +46,7 @@
package org.exist.backup;
import org.exist.client.ClientFrame;
+import org.exist.mediatype.MediaTypeUtil;
import org.exist.start.CompatibleJavaVersionCheck;
import org.exist.start.StartException;
import org.exist.util.ConfigurationHelper;
@@ -34,7 +59,9 @@
import org.xmldb.api.base.Database;
import org.xmldb.api.base.XMLDBException;
import se.softhouse.jargo.*;
+import xyz.elemental.mediatype.MediaTypeResolver;
+import javax.annotation.Nullable;
import javax.swing.*;
import java.io.File;
import java.io.IOException;
@@ -199,12 +226,17 @@ public static void process(final ParsedArguments arguments) {
return;
}
+ // load MediaTypeResolver
+ final Optional existHome = ConfigurationHelper.getExistHome();
+ @Nullable final Path applicationConfigDir = existHome.map(p -> p.resolve("etc")).filter(Files::exists).orElse(null);
+ @Nullable final MediaTypeResolver mediaTypeResolver = MediaTypeUtil.newMediaTypeResolver(applicationConfigDir);
+
// process
if (backupCollection.isPresent()) {
String collection = backupCollection.get();
if (collection.isEmpty()) {
if (guiMode) {
- final CreateBackupDialog dialog = new CreateBackupDialog(properties.getProperty(URI_PROP, DEFAULT_URI), properties.getProperty(USER_PROP, DEFAULT_USER), properties.getProperty(PASSWORD_PROP, DEFAULT_PASSWORD), Paths.get(preferences.get("directory.backup", System.getProperty("user.dir"))));
+ final CreateBackupDialog dialog = new CreateBackupDialog(properties.getProperty(URI_PROP, DEFAULT_URI), properties.getProperty(USER_PROP, DEFAULT_USER), properties.getProperty(PASSWORD_PROP, DEFAULT_PASSWORD), Paths.get(preferences.get("directory.backup", System.getProperty("user.dir"))), mediaTypeResolver);
if (JOptionPane.showOptionDialog(null, dialog, "Create Backup", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null) == JOptionPane.YES_OPTION) {
collection = dialog.getCollection();
@@ -462,7 +494,7 @@ public static void main(final String[] args) {
.andArguments(backupCollectionArg, backupOutputDirArg, backupDeduplicateBlobs)
.andArguments(restoreArg, rebuildExpathRepoArg, overwriteAppsArg)
.andArguments(helpArg, guiArg, quietArg, optionArg)
- .programName("backup" + (OSUtil.isWindows() ? ".bat" : ".sh"))
+ .programName("backup" + (OSUtil.IS_WINDOWS ? ".bat" : ".sh"))
.parse(args);
process(arguments);
diff --git a/exist-core/src/main/java/org/exist/backup/Restore.java b/exist-core/src/main/java/org/exist/backup/Restore.java
index 7b38622b11..b66debebf9 100644
--- a/exist-core/src/main/java/org/exist/backup/Restore.java
+++ b/exist-core/src/main/java/org/exist/backup/Restore.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -36,6 +60,7 @@
import org.exist.util.XMLReaderPool;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
+import xyz.elemental.mediatype.MediaTypeResolver;
import javax.annotation.Nullable;
import java.io.IOException;
@@ -57,7 +82,7 @@ public class Restore {
private static final byte[] ZIP_FILE_MAGIC_NUMBER = {0x50, 0x4B, 0x03, 0x04};
public void restore(final DBBroker broker, @Nullable final Txn transaction, final String newAdminPass, final Path f,
- final RestoreListener listener, final boolean overwriteApps) throws EXistException, IOException, SAXException, PermissionDeniedException {
+ final RestoreListener listener, final boolean overwriteApps, final MediaTypeResolver mediaTypeResolver) throws EXistException, IOException, SAXException, PermissionDeniedException {
//set the admin password
if (newAdminPass != null) {
diff --git a/exist-core/src/main/java/org/exist/backup/SystemExport.java b/exist-core/src/main/java/org/exist/backup/SystemExport.java
index 0a8b585746..d9eae3b9cb 100644
--- a/exist-core/src/main/java/org/exist/backup/SystemExport.java
+++ b/exist-core/src/main/java/org/exist/backup/SystemExport.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -69,6 +93,7 @@
import org.xml.sax.helpers.AttributesImpl;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.NamespaceSupport;
+import xyz.elemental.mediatype.MediaType;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
@@ -541,10 +566,10 @@ private void exportDocument(final BackupWriter output, final Date date, final Ba
}
attr.addAttribute(Namespaces.EXIST_NS, "filename", "filename", "CDATA", Backup.encode(URIUtils.urlDecodeUtf8(doc.getFileURI())));
- String mimeType = "application/xml";
+ String mimeType = MediaType.APPLICATION_XML;
- if (doc.getMimeType() != null) {
- mimeType = Backup.encode(doc.getMimeType());
+ if (doc.getMediaType() != null) {
+ mimeType = Backup.encode(doc.getMediaType());
}
attr.addAttribute(Namespaces.EXIST_NS, "mimetype", "mimetype", "CDATA", mimeType);
@@ -614,8 +639,9 @@ private void writeXML(final DocumentImpl doc, final Receiver receiver) {
receiver.startPrefixMapping(reader.getNamespacePrefix(ni), reader.getNamespaceURI(ni));
}
- final AttrList attribs = new AttrList();
- for (int j = 0; j < reader.getAttributeCount(); j++) {
+ final int attrCount = reader.getAttributeCount();
+ final AttrList attribs = new AttrList(attrCount);
+ for (int j = 0; j < attrCount; j++) {
final QName qn = new QName(reader.getAttributeLocalName(j), reader.getAttributeNamespace(j), reader.getAttributePrefix(j));
attribs.addAttribute(qn, reader.getAttributeValue(j));
}
diff --git a/exist-core/src/main/java/org/exist/backup/ZipWriter.java b/exist-core/src/main/java/org/exist/backup/ZipWriter.java
index 6e214f3703..dee39fa485 100644
--- a/exist-core/src/main/java/org/exist/backup/ZipWriter.java
+++ b/exist-core/src/main/java/org/exist/backup/ZipWriter.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -21,6 +45,8 @@
*/
package org.exist.backup;
+import org.apache.commons.io.output.StringBuilderWriter;
+
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
@@ -38,7 +64,7 @@ public class ZipWriter implements BackupWriter
{
private String currentPath;
private final ZipOutputStream out;
- private StringWriter contents;
+ private StringBuilderWriter contents;
private boolean dataWritten = false;
public ZipWriter(final String zipFile, final String collection) throws IOException
@@ -53,9 +79,9 @@ public ZipWriter(final Path zipFile, final String collection) throws IOException
currentPath = collection;
}
- public Writer newContents() throws IOException
+ public Writer newContents()
{
- contents = new StringWriter();
+ contents = new StringBuilderWriter();
return( contents );
}
diff --git a/exist-core/src/main/java/org/exist/backup/restore/AbstractRestoreHandler.java b/exist-core/src/main/java/org/exist/backup/restore/AbstractRestoreHandler.java
index 218efd7237..34fe394668 100644
--- a/exist-core/src/main/java/org/exist/backup/restore/AbstractRestoreHandler.java
+++ b/exist-core/src/main/java/org/exist/backup/restore/AbstractRestoreHandler.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -55,6 +79,10 @@
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
+import xyz.elemental.mediatype.MediaType;
+import xyz.elemental.mediatype.MediaTypeResolver;
+import xyz.elemental.mediatype.StorageType;
+import xyz.elemental.mediatype.impl.MediaTypeImpl;
import javax.annotation.Nullable;
import java.io.IOException;
@@ -63,6 +91,7 @@
import static com.evolvedbinary.j8fu.tuple.Tuple.Tuple;
import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.exist.util.StringUtil.isNullOrEmpty;
/**
* SAX Content Handler that can act upon
@@ -89,7 +118,6 @@ public abstract class AbstractRestoreHandler extends DefaultHandler {
@Nullable private final Txn transaction;
private final BackupDescriptor descriptor;
private final RestoreListener listener;
-
@Nullable private final Set pathsToIgnore;
//handler state
@@ -312,7 +340,7 @@ private DeferredPermission restoreResourceEntry(final Attributes attributes) thr
final boolean xmlType = Optional.ofNullable(attributes.getValue("type")).filter(s -> s.equals("XMLResource")).isPresent();
final String filename = getAttr(attributes, "filename", commonAttributes.name);
- @Nullable final String mimeTypeStr = attributes.getValue("mimetype");
+ @Nullable final String mediaTypeStr = attributes.getValue("mimetype");
@Nullable final String dateModifiedStr = attributes.getValue("modified");
@Nullable final String publicId = attributes.getValue("publicid");
@Nullable final String systemId = attributes.getValue("systemid");
@@ -343,12 +371,19 @@ private DeferredPermission restoreResourceEntry(final Attributes attributes) thr
}
}
- final MimeType mimeType;
- if (mimeTypeStr == null || mimeTypeStr.trim().isEmpty()) {
- mimeType = xmlType ? MimeType.XML_TYPE : MimeType.BINARY_TYPE;
- listener.warn("Missing mimetype attribute in the backup __contents__.xml file for: " + commonAttributes.name + ", assuming: " + mimeType);
+ final MediaTypeResolver mediaTypeResolver = broker.getBrokerPool().getMediaTypeService().getMediaTypeResolver();
+
+ MediaType mediaType;
+ if (isNullOrEmpty(mediaTypeStr)) {
+ mediaType = xmlType ? mediaTypeResolver.fromString(MediaType.APPLICATION_XML) : mediaTypeResolver.forUnknown();
+ listener.warn("Missing mimetype attribute in the backup __contents__.xml file for: " + commonAttributes.name + ", assuming: " + mediaType);
} else {
- mimeType = new MimeType(mimeTypeStr.trim(), xmlType ? MimeType.XML : MimeType.BINARY);
+ mediaType = mediaTypeResolver.fromString(mediaTypeStr.trim());
+ if (xmlType && mediaType.getStorageType() != StorageType.XML) {
+ mediaType = MediaTypeImpl.builder(mediaTypeStr.trim(), StorageType.XML).build();
+ } else if ((!xmlType) && mediaType.getStorageType() != StorageType.BINARY) {
+ mediaType = MediaTypeImpl.builder(mediaTypeStr.trim(), StorageType.BINARY).build();
+ }
}
Date dateCreated = null;
@@ -385,7 +420,7 @@ private DeferredPermission restoreResourceEntry(final Attributes attributes) thr
try (final Collection collection = broker.openCollection(currentCollectionUri, Lock.LockMode.WRITE_LOCK);
final ManagedDocumentLock docLock = broker.getBrokerPool().getLockManager().acquireDocumentWriteLock(docUri)) {
- broker.storeDocument(transaction, docName, is, mimeType, dateCreated, dateModified, null, docType, null, collection);
+ broker.storeDocument(transaction, docName, is, mediaType, dateCreated, dateModified, null, docType, null, collection);
validated = true;
notifyStartDocumentRestore(docUri, attributes);
@@ -572,6 +607,7 @@ private static String getAttr(final Attributes atts, final String name, final St
* @param descriptor the backup descriptor to start restoring from
* @param listener the listener to report restore events to
* @param pathsToIgnore database paths to ignore in the backup
+ *
* @return a new restore handler
*/
protected abstract AbstractRestoreHandler newSelf(final DBBroker broker, @Nullable final Txn transaction,
diff --git a/exist-core/src/main/java/org/exist/backup/restore/AppRestoreUtils.java b/exist-core/src/main/java/org/exist/backup/restore/AppRestoreUtils.java
index 261bbad142..c19e67d71a 100644
--- a/exist-core/src/main/java/org/exist/backup/restore/AppRestoreUtils.java
+++ b/exist-core/src/main/java/org/exist/backup/restore/AppRestoreUtils.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -21,7 +45,6 @@
*/
package org.exist.backup.restore;
-import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.exist.Namespaces;
@@ -44,6 +67,8 @@
import java.io.IOException;
import java.util.*;
+import static org.exist.util.StringUtil.isNullOrEmpty;
+
/**
* Utility to compare the applications contained in a backup with the already
* installed applications in the package repo.
@@ -141,7 +166,7 @@ public void startElement(String uri, String localName, String qName, Attributes
if (PKG_NAMESPACE.equals(uri) && "package".equals(localName)) {
final String version = attributes.getValue("version");
final String name = attributes.getValue("name");
- if (StringUtils.isEmpty(version) || StringUtils.isEmpty(name)) {
+ if (isNullOrEmpty(version) || isNullOrEmpty(name)) {
LOG.warn("Invalid package descriptor for {}", app.getSymbolicPath());
return;
}
diff --git a/exist-core/src/main/java/org/exist/backup/xquery/RetrieveBackup.java b/exist-core/src/main/java/org/exist/backup/xquery/RetrieveBackup.java
index 64a54d8746..c481831bb5 100644
--- a/exist-core/src/main/java/org/exist/backup/xquery/RetrieveBackup.java
+++ b/exist-core/src/main/java/org/exist/backup/xquery/RetrieveBackup.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -31,6 +55,7 @@
import org.exist.xquery.value.Sequence;
import org.exist.xquery.value.SequenceType;
import org.exist.xquery.value.Type;
+import xyz.elemental.mediatype.MediaType;
import java.io.IOException;
import java.io.OutputStream;
@@ -101,7 +126,7 @@ public Sequence eval(final Sequence[] args, final Sequence contextSequence ) thr
throw new XPathException(this, signature.toString() + " can only be used within the EXistServlet or XQueryServlet");
}
- response.setContentType("application/zip");
+ response.setContentType(MediaType.APPLICATION_ZIP);
response.setHeader("Content-Length", String.valueOf(FileUtils.sizeQuietly(backupFile)));
try {
try(final OutputStream os = response.getOutputStream()) {
diff --git a/exist-core/src/main/java/org/exist/client/ClientFrame.java b/exist-core/src/main/java/org/exist/client/ClientFrame.java
index 479f48ad16..52547f6fbb 100644
--- a/exist-core/src/main/java/org/exist/client/ClientFrame.java
+++ b/exist-core/src/main/java/org/exist/client/ClientFrame.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -21,6 +45,7 @@
*/
package org.exist.client;
+import org.apache.commons.io.output.StringBuilderWriter;
import org.exist.SystemProperties;
import org.exist.backup.Backup;
import org.exist.backup.CreateBackupDialog;
@@ -33,7 +58,6 @@
import org.exist.security.internal.aider.SimpleACLPermissionAider;
import org.exist.storage.serializers.EXistOutputKeys;
import org.exist.util.FileUtils;
-import org.exist.util.MimeTable;
import org.exist.util.SystemExitCodes;
import org.exist.util.crypto.digest.DigestType;
import org.exist.util.crypto.digest.MessageDigest;
@@ -48,7 +72,11 @@
import org.xmldb.api.base.Resource;
import org.xmldb.api.base.XMLDBException;
import org.xmldb.api.modules.XMLResource;
+import xyz.elemental.mediatype.MediaType;
+import xyz.elemental.mediatype.MediaTypeResolver;
+import xyz.elemental.mediatype.StorageType;
+import javax.annotation.Nullable;
import javax.swing.*;
import javax.swing.border.BevelBorder;
import javax.swing.filechooser.FileFilter;
@@ -81,11 +109,14 @@
import java.util.stream.Collectors;
import static java.nio.charset.StandardCharsets.UTF_8;
+import static javax.swing.JOptionPane.INFORMATION_MESSAGE;
import static org.exist.client.InteractiveClient.DATE_TIME_FORMATTER;
import static org.exist.util.FileUtils.humanSize;
/**
- * Main frame of the eXist GUI
+ * @author Adam Retter
+ *
+ * Main frame of the Elemental Java Admin client GUI
*/
public class ClientFrame extends JFrame implements WindowFocusListener, KeyListener, ActionListener, MouseListener {
@@ -108,7 +139,7 @@ public class ClientFrame extends JFrame implements WindowFocusListener, KeyListe
public static final String MULTIPLE_INDICATOR = "[...]";
private static final String NON_APPLICABLE = "N/A";
- private static final String COLLECTION_MIME_TYPE = "exist/collection";
+ private static final String COLLECTION_MIME_TYPE = "elemental/collection";
private int commandStart = 0;
@@ -130,7 +161,7 @@ public class ClientFrame extends JFrame implements WindowFocusListener, KeyListe
/**
* Constructor.
*
- * @param client Existdb client
+ * @param client Elemental client
* @param path Database connection URL.
* @param properties Configuration items.
* @throws java.awt.HeadlessException Environment does not support a keyboard, display, or mouse.
@@ -143,7 +174,7 @@ public ClientFrame(final InteractiveClient client, final XmldbURI path, final Pr
this.processRunnable = new ProcessRunnable();
this.processThread = client.newClientThread("process", processRunnable);
- this.setIconImage(InteractiveClient.getExistIcon(getClass()).getImage());
+ this.setIconImage(InteractiveClient.getElementalIcon(getClass()).getImage());
setupComponents();
addWindowListener(new WindowAdapter() {
@@ -179,7 +210,7 @@ private void setupComponents() {
try {
client.reloadCollection();
} catch (final XMLDBException e1) {
- //TODO report message
+ showErrorMessage(e1.getMessage(), e1);
}
});
toolbar.add(button);
@@ -270,7 +301,7 @@ private void setupComponents() {
// shell window
doc = new DefaultStyledDocument();
shell = new JTextPane(doc);
- shell.setContentType("text/plain; charset=UTF-8"); //$NON-NLS-1$
+ shell.setContentType(MediaType.TEXT_PLAIN + "; charset=UTF-8"); //$NON-NLS-1$
shell.setFont(new Font("Monospaced", Font.PLAIN, 12)); //$NON-NLS-1$
shell.setMargin(new Insets(7, 5, 7, 5));
shell.addKeyListener(this);
@@ -538,14 +569,15 @@ protected void displayPrompt() {
final String pathString = path.getCollectionPath();
try {
commandStart = doc.getLength();
- doc.insertString(commandStart, Messages.getString("ClientFrame.91"), promptAttrs); //$NON-NLS-1$
- commandStart += 6;
+ final String prompt = Messages.getString("ClientFrame.91");
+ doc.insertString(commandStart, prompt, promptAttrs); //$NON-NLS-1$
+ commandStart += prompt.length();
doc.insertString(commandStart, pathString + '>', promptAttrs);
commandStart += pathString.length() + 1;
doc.insertString(commandStart++, Messages.getString("ClientFrame.92"), defaultAttrs); //$NON-NLS-1$
shell.setCaretPosition(commandStart);
} catch (final BadLocationException e) {
- //TODO show error
+ showErrorMessage(e.getMessage(), e);
}
}
@@ -561,7 +593,7 @@ protected void display(final String message) {
shell.setCaretPosition(commandStart);
} catch (final BadLocationException e) {
- //TODO show error
+ showErrorMessage(e.getMessage(), e);
}
}
@@ -740,6 +772,13 @@ private void removeAction(final ActionEvent ev) {
}
}
+ try {
+ removeRootCollection.close();
+ client.reloadCollection();
+ } catch (final XMLDBException e) {
+ showErrorMessage(e.getMessage(), e);
+ }
+
ClientAction.call(client::getResources, e -> showErrorMessage(e.getMessage(), e));
};
client.newClientThread("remove", removeTask).start();
@@ -962,8 +1001,8 @@ private void uploadAction(final ActionEvent ev) {
final JFileChooser chooser = new JFileChooser(preferences.get("directory.last", System.getProperty("user.dir")));
chooser.setMultiSelectionEnabled(true);
chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
- chooser.addChoosableFileFilter(new BinaryFileFilter());
- chooser.addChoosableFileFilter(new XMLFileFilter());
+ chooser.addChoosableFileFilter(new BinaryFileFilter(client.getMediaTypeResolver()));
+ chooser.addChoosableFileFilter(new XMLFileFilter(client.getMediaTypeResolver()));
if (chooser.showDialog(this, Messages.getString("ClientFrame.146")) == JFileChooser.APPROVE_OPTION) { //$NON-NLS-1$
// remember directory in preferences
preferences.put("directory.last", chooser.getCurrentDirectory().getAbsolutePath());
@@ -1017,7 +1056,8 @@ private void backupAction(final ActionEvent ev) {
properties.getProperty(InteractiveClient.USER, SecurityManager.DBA_USER),
properties.getProperty(InteractiveClient.PASSWORD, null),
Paths.get(preferences.get("directory.backup", System.getProperty("user.home"))),
- defaultSelectedCollection
+ defaultSelectedCollection,
+ client.getMediaTypeResolver()
);
if (JOptionPane.showOptionDialog(this, dialog, Messages.getString("ClientFrame.157"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null) == JOptionPane.YES_OPTION) {
@@ -1284,7 +1324,7 @@ private void setPermAction(final ActionEvent ev) throws PermissionDeniedExceptio
final Resource res = collection.getResource(thisName.toString());
thisCreated = DATE_TIME_FORMATTER.format(res.getCreationTime());
thisModified = DATE_TIME_FORMATTER.format(res.getLastModificationTime());
- thisMimeType = ((EXistResource) res).getMimeType();
+ thisMimeType = ((EXistResource) res).getMediaType();
if (res instanceof EXistBinaryResource) {
final MessageDigest messageDigest = ((EXistBinaryResource) res).getContentDigest(DigestType.BLAKE_256);
thisMessageDigestType = messageDigest.getDigestType().getCommonNames()[0];
@@ -1482,7 +1522,8 @@ private void close() {
}
private void AboutAction() {
- JOptionPane.showMessageDialog(this, client.getNotice());
+ final Icon icon = InteractiveClient.getElementalIcon(getClass());
+ JOptionPane.showMessageDialog(this, client.getNotice(), "About", INFORMATION_MESSAGE, icon);
}
class TableMouseListener extends MouseAdapter {
@@ -1503,7 +1544,7 @@ public void mouseClicked(final MouseEvent e) {
try {
final Resource doc = client.retrieve(resource.getName(), properties.getProperty(OutputKeys.INDENT, "yes")); //$NON-NLS-1$
- if ("application/xquery".equals(((EXistResource) doc).getMimeType())) {
+ if (MediaType.APPLICATION_XQUERY.equals(((EXistResource) doc).getMediaType())) {
final Collection collection = client.getCollection();
final QueryDialog dialog = new QueryDialog(client, collection, doc, properties);
dialog.setVisible(true);
@@ -1686,7 +1727,7 @@ protected static Properties getLoginData(final Properties props) {
final ConnectionDialog connectionDialog = new ConnectionDialog(null, true, defaultConnectionSettings, Boolean.parseBoolean(props.getProperty(InteractiveClient.LOCAL_MODE, InteractiveClient.LOCAL_MODE_DEFAULT)), Boolean.parseBoolean(props.getProperty(InteractiveClient.NO_EMBED_MODE, InteractiveClient.NO_EMBED_MODE_DEFAULT)));
- connectionDialog.setTitle(SystemProperties.getInstance().getSystemProperty("product-name", "eXist-db") + " " + SystemProperties.getInstance().getSystemProperty("product-version", "unknown") + " Database Login");
+ connectionDialog.setTitle(SystemProperties.getInstance().getSystemProperty("product-name", "Elemental") + " " + SystemProperties.getInstance().getSystemProperty("product-version", "unknown") + " Database Login");
connectionDialog.addDialogCompleteWithResponseCallback(connection -> {
properties.setProperty(InteractiveClient.USER, connection.getUsername());
@@ -1714,16 +1755,17 @@ public static void showErrorMessage(final String message, final Throwable t) {
msgArea.setEditable(false);
msgArea.setBackground(null);
if (t != null) {
- final StringWriter out = new StringWriter();
- final PrintWriter writer = new PrintWriter(out);
- t.printStackTrace(writer);
- final JTextArea stacktrace = new JTextArea(out.toString(), 20, 50);
- stacktrace.setBackground(null);
- stacktrace.setEditable(false);
- scroll = new JScrollPane(stacktrace);
- scroll.setPreferredSize(new Dimension(250, 300));
- scroll.setBorder(BorderFactory
+ try (final StringBuilderWriter out = new StringBuilderWriter();
+ final PrintWriter writer = new PrintWriter(out)) {
+ t.printStackTrace(writer);
+ final JTextArea stacktrace = new JTextArea(out.toString(), 20, 50);
+ stacktrace.setBackground(null);
+ stacktrace.setEditable(false);
+ scroll = new JScrollPane(stacktrace);
+ scroll.setPreferredSize(new Dimension(250, 300));
+ scroll.setBorder(BorderFactory
.createTitledBorder(Messages.getString("ClientFrame.215"))); //$NON-NLS-1$
+ }
}
final JOptionPane optionPane = new JOptionPane();
optionPane.setMessage(new Object[]{msgArea, scroll});
@@ -1747,7 +1789,7 @@ public static int showErrorMessageQuery(final String message, final Throwable t)
JScrollPane scrollStacktrace = null;
if (t != null) {
- try (final StringWriter out = new StringWriter();
+ try (final StringBuilderWriter out = new StringBuilderWriter();
final PrintWriter writer = new PrintWriter(out)) {
t.printStackTrace(writer);
final JTextArea stacktrace = new JTextArea(out.toString(), 20, 50);
@@ -1759,8 +1801,6 @@ public static int showErrorMessageQuery(final String message, final Throwable t)
scrollStacktrace.setPreferredSize(new Dimension(600, 300));
scrollStacktrace.setBorder(BorderFactory
.createTitledBorder(Messages.getString("ClientFrame.218"))); //$NON-NLS-1$
- } catch (final IOException ioe) {
- ioe.printStackTrace();
}
}
@@ -1851,46 +1891,46 @@ public void mouseReleased(final MouseEvent e) {
}
static class BinaryFileFilter extends FileFilter {
+ private final MediaTypeResolver mediaTypeResolver;
+
+ public BinaryFileFilter(final MediaTypeResolver mediaTypeResolver) {
+ this.mediaTypeResolver = mediaTypeResolver;
+ }
- /* (non-Javadoc)
- * @see javax.swing.filechooser.FileFilter#getDescription()
- */
@Override
public String getDescription() {
return Messages.getString("ClientFrame.220"); //$NON-NLS-1$
}
- /* (non-Javadoc)
- * @see javax.swing.filechooser.FileFilter#accept(java.io.File)
- */
@Override
public boolean accept(final File f) {
if (f.isDirectory()) {
return true;
}
- return !MimeTable.getInstance().isXMLContent(f.getName());
+ @Nullable MediaType mediaType = mediaTypeResolver.fromFileName(f.toPath().getFileName());
+ return mediaType == null || mediaType.getStorageType() != StorageType.XML;
}
}
static class XMLFileFilter extends FileFilter {
+ private final MediaTypeResolver mediaTypeResolver;
+
+ public XMLFileFilter(final MediaTypeResolver mediaTypeResolver) {
+ this.mediaTypeResolver = mediaTypeResolver;
+ }
- /* (non-Javadoc)
- * @see javax.swing.filechooser.FileFilter#getDescription()
- */
@Override
public String getDescription() {
return Messages.getString("ClientFrame.221"); //$NON-NLS-1$
}
- /* (non-Javadoc)
- * @see javax.swing.filechooser.FileFilter#accept(java.io.File)
- */
@Override
public boolean accept(final File f) {
if (f.isDirectory()) {
return true;
}
- return MimeTable.getInstance().isXMLContent(f.getName());
+ @Nullable MediaType mediaType = mediaTypeResolver.fromFileName(f.toPath().getFileName());
+ return mediaType != null && mediaType.getStorageType() == StorageType.XML;
}
}
@@ -1945,7 +1985,7 @@ private List getFilesWin32(final Transferable transferable) throws Unsuppo
private List getFilesUnix(final Transferable transferable) throws ClassNotFoundException, UnsupportedFlavorException, IOException, URISyntaxException {
List files = null;
- final DataFlavor unixFileDataFlavour = new DataFlavor("text/uri-list;class=java.lang.String");
+ final DataFlavor unixFileDataFlavour = new DataFlavor(MediaType.TEXT_URI_LIST + ";class=java.lang.String");
final String data = (String) transferable.getTransferData(unixFileDataFlavour);
for (final StringTokenizer st = new StringTokenizer(data, "\r\n"); st.hasMoreTokens(); ) {
final String token = st.nextToken().trim();
diff --git a/exist-core/src/main/java/org/exist/client/CommandlineOptions.java b/exist-core/src/main/java/org/exist/client/CommandlineOptions.java
index 3c42d6577f..2e89c9dfe7 100644
--- a/exist-core/src/main/java/org/exist/client/CommandlineOptions.java
+++ b/exist-core/src/main/java/org/exist/client/CommandlineOptions.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -177,7 +201,7 @@ public static CommandlineOptions parse(final String[] args) throws ArgumentExcep
.andArguments(setDocArg, xupdateArg)
.andArguments(reindexArg, reindexRecurseDirsArg)
.andArguments(helpArg, quietArg, verboseArg, outputFileArg, optionArg)
- .programName("client" + (OSUtil.isWindows() ? ".bat" : ".sh"))
+ .programName("client" + (OSUtil.IS_WINDOWS ? ".bat" : ".sh"))
.parse(args);
final boolean quiet = getBool(arguments, quietArg);
diff --git a/exist-core/src/main/java/org/exist/client/Connection.java b/exist-core/src/main/java/org/exist/client/Connection.java
index 19be3d17dc..7680b031e1 100644
--- a/exist-core/src/main/java/org/exist/client/Connection.java
+++ b/exist-core/src/main/java/org/exist/client/Connection.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -18,12 +42,12 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
+ */
package org.exist.client;
/**
* Represents the Connection detail for
- * connecting to either a local or remote eXist-db instance
+ * connecting to either a local or remote Elemental instance
*
* You can have either:
* 1) Remote Connection, provide a uri and ssl flag.
diff --git a/exist-core/src/main/java/org/exist/client/ConnectionDialog.java b/exist-core/src/main/java/org/exist/client/ConnectionDialog.java
index 8fd6913950..c290d1415d 100644
--- a/exist-core/src/main/java/org/exist/client/ConnectionDialog.java
+++ b/exist-core/src/main/java/org/exist/client/ConnectionDialog.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -72,7 +96,7 @@ public ConnectionDialog(final java.awt.Frame parent, final boolean modal, final
this.defaultConnectionSettings = defaultConnectionSettings;
this.config = Paths.get(defaultConnectionSettings.getConfiguration());
this.disableEmbeddedConnectionType = disableEmbeddedConnectionType;
- this.setIconImage(InteractiveClient.getExistIcon(getClass()).getImage());
+ this.setIconImage(InteractiveClient.getElementalIcon(getClass()).getImage());
initComponents();
if (disableEmbeddedConnectionType) {
@@ -240,7 +264,7 @@ protected final void paintTabBorder(final java.awt.Graphics g, final int tabPlac
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
setTitle("Database Connection");
- lblExistLogo.setIcon(InteractiveClient.getExistIcon(getClass()));
+ lblExistLogo.setIcon(InteractiveClient.getElementalIcon(getClass()));
lblUsername.setText(getLabelText("LoginPanel.2"));
diff --git a/exist-core/src/main/java/org/exist/client/DocumentView.java b/exist-core/src/main/java/org/exist/client/DocumentView.java
index 315c686830..bd752fee5a 100644
--- a/exist-core/src/main/java/org/exist/client/DocumentView.java
+++ b/exist-core/src/main/java/org/exist/client/DocumentView.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -59,6 +83,7 @@
import javax.swing.border.BevelBorder;
import javax.xml.transform.OutputKeys;
+import org.apache.commons.io.output.StringBuilderWriter;
import org.exist.security.Account;
import org.exist.storage.ElementIndex;
import org.exist.util.ProgressIndicator;
@@ -75,6 +100,9 @@
import static org.xmldb.api.base.ResourceType.XML_RESOURCE;
+/**
+ * @author Adam Retter
+ */
class DocumentView extends JFrame {
private static final long serialVersionUID = 1L;
@@ -99,7 +127,7 @@ public DocumentView(InteractiveClient client, XmldbURI resourceName, Resource re
this.resourceName = resourceName;
this.resource = resource;
this.client = client;
- this.setIconImage(InteractiveClient.getExistIcon(getClass()).getImage());
+ this.setIconImage(InteractiveClient.getElementalIcon(getClass()).getImage());
this.collection = client.getCollection();
this.properties = properties;
getContentPane().setLayout(new BorderLayout());
@@ -159,16 +187,17 @@ private static void showErrorMessage(String message, Throwable t) {
msgArea.setEditable(false);
msgArea.setBackground(null);
if (t != null) {
- final StringWriter out = new StringWriter();
- final PrintWriter writer = new PrintWriter(out);
- t.printStackTrace(writer);
- final JTextArea stacktrace = new JTextArea(out.toString(), 20, 50);
- stacktrace.setBackground(null);
- stacktrace.setEditable(false);
- scroll = new JScrollPane(stacktrace);
- scroll.setPreferredSize(new Dimension(250, 300));
- scroll.setBorder(BorderFactory
+ try (final StringBuilderWriter out = new StringBuilderWriter();
+ final PrintWriter writer = new PrintWriter(out)) {
+ t.printStackTrace(writer);
+ final JTextArea stacktrace = new JTextArea(out.toString(), 20, 50);
+ stacktrace.setBackground(null);
+ stacktrace.setEditable(false);
+ scroll = new JScrollPane(stacktrace);
+ scroll.setPreferredSize(new Dimension(250, 300));
+ scroll.setBorder(BorderFactory
.createTitledBorder("Exception Stacktrace:")); //$NON-NLS-1$
+ }
}
final JOptionPane optionPane = new JOptionPane();
optionPane.setMessage(new Object[]{msgArea, scroll});
diff --git a/exist-core/src/main/java/org/exist/client/IndexDialog.java b/exist-core/src/main/java/org/exist/client/IndexDialog.java
index 6acf725ea0..9950cc6be0 100644
--- a/exist-core/src/main/java/org/exist/client/IndexDialog.java
+++ b/exist-core/src/main/java/org/exist/client/IndexDialog.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -41,9 +65,7 @@
/**
* Dialog for viewing and editing Indexes in the Admin Client
*
- * @author Adam Retter
- * @serial 2006-03-12
- * @version 1.0
+ * @author Adam Retter
*/
class IndexDialog extends JFrame {
@@ -75,7 +97,7 @@ public IndexDialog(String title, InteractiveClient client)
{
super(title);
this.client = client;
- this.setIconImage(InteractiveClient.getExistIcon(getClass()).getImage());
+ this.setIconImage(InteractiveClient.getElementalIcon(getClass()).getImage());
//capture the frame's close event
final WindowListener windowListener = new WindowAdapter()
{
diff --git a/exist-core/src/main/java/org/exist/client/InteractiveClient.java b/exist-core/src/main/java/org/exist/client/InteractiveClient.java
index 7511b01fe6..fbcfd5de0b 100644
--- a/exist-core/src/main/java/org/exist/client/InteractiveClient.java
+++ b/exist-core/src/main/java/org/exist/client/InteractiveClient.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -41,6 +65,7 @@
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
+import javax.annotation.Nullable;
import javax.swing.ImageIcon;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
@@ -52,6 +77,7 @@
import org.apache.tools.ant.DirectoryScanner;
import org.exist.SystemProperties;
import org.exist.dom.persistent.XMLUtil;
+import org.exist.mediatype.MediaTypeUtil;
import org.exist.security.Account;
import org.exist.security.Group;
import org.exist.security.Permission;
@@ -86,8 +112,12 @@
import org.xmldb.api.base.*;
import org.xmldb.api.base.Collection;
import org.xmldb.api.modules.BinaryResource;
+import org.xmldb.api.modules.XMLResource;
import org.xmldb.api.modules.XUpdateQueryService;
import se.softhouse.jargo.ArgumentException;
+import xyz.elemental.mediatype.MediaType;
+import xyz.elemental.mediatype.MediaTypeResolver;
+import xyz.elemental.mediatype.StorageType;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.time.ZoneOffset.UTC;
@@ -99,6 +129,7 @@
/**
* Command-line client based on the XML:DB API.
*
+ * @author Adam Retter
* @author wolf
*/
public class InteractiveClient {
@@ -201,6 +232,8 @@ public InteractiveClient(CommandlineOptions options) {
this.options = options;
}
+ private MediaTypeResolver mediaTypeResolver = null;
+
/**
* Display help on commands
*/
@@ -1040,7 +1073,7 @@ protected boolean process(final String line) {
command.append(lastLine);
}
} catch (final UserInterruptException e) {
- //TODO report error?
+ errorln("Interrupted by user: " + e.getMessage());
}
final String xupdate = ""
@@ -1157,16 +1190,18 @@ private ResourceSet find(String xpath) throws XMLDBException {
}
final String xpathCopy = xpath;
- getTraceWriter().ifPresent(writer -> {
+ final Optional maybeWriter = getTraceWriter();
+ if (maybeWriter.isPresent()) {
+ final Writer writer = maybeWriter.get();
try {
writer.write("");
writer.write(xpathCopy);
writer.write("");
writer.write(EOL);
} catch (final IOException e) {
- //TODO report error?
+ throw new XMLDBException(ErrorCodes.UNKNOWN_ERROR, e);
}
- });
+ }
String sortBy = null;
final int p = xpath.indexOf(" sort by ");
@@ -1284,21 +1319,25 @@ private void reindex() throws XMLDBException {
private void storeBinary(final String fileName) throws XMLDBException {
final Path file = Paths.get(fileName).normalize();
if (Files.isReadable(file)) {
- final MimeType mime = MimeTable.getInstance().getContentTypeFor(FileUtils.fileName(file));
+ @Nullable final MediaType mediaType = mediaTypeResolver.fromFileName(FileUtils.fileName(file));
try (final BinaryResource resource = current.createResource(FileUtils.fileName(file), BinaryResource.class)) {
resource.setContent(file);
- ((EXistResource) resource).setMimeType(mime == null ? "application/octet-stream" : mime.getName());
+ ((EXistResource) resource).setMediaType(mediaType == null ? mediaTypeResolver.forUnknown().getIdentifier() : mediaType.getIdentifier());
current.storeResource(resource);
}
}
}
+ MediaTypeResolver getMediaTypeResolver() {
+ return mediaTypeResolver;
+ }
+
private synchronized boolean findRecursive(final Collection collection, final Path dir, final XmldbURI base) throws XMLDBException {
Collection c;
EXistCollectionManagementService mgtService;
//The XmldbURIs here aren't really used...
XmldbURI next;
- MimeType mimeType;
+ @Nullable MediaType mediaType = null;
try {
final List files = FileUtils.list(dir);
@@ -1321,15 +1360,15 @@ private synchronized boolean findRecursive(final Collection collection, final Pa
findRecursive(c, file, next);
} else {
final long start1 = System.currentTimeMillis();
- mimeType = MimeTable.getInstance().getContentTypeFor(FileUtils.fileName(file));
- if (mimeType == null) {
+ mediaType = mediaTypeResolver.fromFileName(FileUtils.fileName(file));
+ if (mediaType == null) {
messageln("File " + FileUtils.fileName(file) + " has an unknown suffix. Cannot determine file type.");
- mimeType = MimeType.BINARY_TYPE;
+ mediaType = mediaTypeResolver.forUnknown();
}
- try (final Resource document = collection.createResource(FileUtils.fileName(file), mimeType.getXMLDBType())) {
+ try (final Resource document = collection.createResource(FileUtils.fileName(file), toResourceTypeClass(mediaType))) {
message("storing document " + FileUtils.fileName(file) + " (" + i + " of " + files.size() + ") " + "...");
document.setContent(file);
- ((EXistResource) document).setMimeType(mimeType.getName());
+ ((EXistResource) document).setMediaType(mediaType.getIdentifier());
collection.storeResource(document);
++filesCount;
messageln(" " + FileUtils.sizeQuietly(file) + " bytes in " + (System.currentTimeMillis() - start1) + "ms.");
@@ -1346,6 +1385,10 @@ private synchronized boolean findRecursive(final Collection collection, final Pa
}
}
+ private static Class extends Resource> toResourceTypeClass(final MediaType mediaType) {
+ return mediaType.getStorageType() == StorageType.XML ? XMLResource.class : BinaryResource.class;
+ }
+
/**
* Stores given Resource
*
@@ -1391,20 +1434,20 @@ protected synchronized boolean parse(final Path file) throws XMLDBException {
final long start0 = System.currentTimeMillis();
long bytes = 0;
- MimeType mimeType;
+ @Nullable MediaType mediaType = null;
for (int i = 0; i < files.size(); i++) {
if (Files.isDirectory(files.get(i))) {
continue;
}
final long start = System.currentTimeMillis();
- mimeType = MimeTable.getInstance().getContentTypeFor(FileUtils.fileName(files.get(i)));
- if (mimeType == null) {
- mimeType = MimeType.BINARY_TYPE;
+ mediaType = mediaTypeResolver.fromFileName(FileUtils.fileName(files.get(i)));
+ if (mediaType == null) {
+ mediaType = mediaTypeResolver.forUnknown();
}
- try (final Resource document = current.createResource(FileUtils.fileName(files.get(i)), mimeType.getXMLDBType())) {
+ try (final Resource document = current.createResource(FileUtils.fileName(files.get(i)), toResourceTypeClass(mediaType))) {
message("storing document " + FileUtils.fileName(files.get(i)) + " (" + (i + 1) + " of " + files.size() + ") ...");
document.setContent(files.get(i));
- ((EXistResource) document).setMimeType(mimeType.getName());
+ ((EXistResource) document).setMediaType(mediaType.getIdentifier());
current.storeResource(document);
messageln(DONE);
messageln("parsing " + FileUtils.sizeQuietly(files.get(i)) + " bytes took " + (System.currentTimeMillis() - start) + "ms." + EOL);
@@ -1426,7 +1469,7 @@ private synchronized boolean findGZipRecursive(final Collection collection, fina
EXistCollectionManagementService mgtService;
//The XmldbURIs here aren't really used...
XmldbURI next;
- MimeType mimeType;
+ @Nullable MediaType mediaType = null;
int i = 0;
for (final Path file : files) {
i++;
@@ -1458,15 +1501,15 @@ private synchronized boolean findGZipRecursive(final Collection collection, fina
break;
}
}
- mimeType = MimeTable.getInstance().getContentTypeFor(localName);
- if (mimeType == null) {
+ mediaType = mediaTypeResolver.fromFileName(localName);
+ if (mediaType == null) {
messageln("File " + compressedName + " has an unknown suffix. Cannot determine file type.");
- mimeType = MimeType.BINARY_TYPE;
+ mediaType = mediaTypeResolver.forUnknown();
}
- try (final Resource document = collection.createResource(compressedName, mimeType.getXMLDBType())) {
+ try (final Resource document = collection.createResource(compressedName, toResourceTypeClass(mediaType))) {
message("storing document " + compressedName + " (" + i + " of " + files.size() + ") " + "...");
document.setContent(isCompressed ? new GZIPInputSource(file) : file);
- ((EXistResource) document).setMimeType(mimeType.getName());
+ ((EXistResource) document).setMediaType(mediaType.getIdentifier());
collection.storeResource(document);
++filesCount;
messageln(" " + Files.size(file) + (isCompressed ? " compressed" : "") + " bytes in "
@@ -1533,7 +1576,7 @@ protected synchronized boolean parseGZip(String fileName) throws XMLDBException,
final long start0 = System.currentTimeMillis();
long bytes = 0;
- MimeType mimeType;
+ @Nullable MediaType mediaType = null;
int i = 0;
for (final Path p : files) {
i++;
@@ -1553,15 +1596,15 @@ protected synchronized boolean parseGZip(String fileName) throws XMLDBException,
break;
}
}
- mimeType = MimeTable.getInstance().getContentTypeFor(localName);
- if (mimeType == null) {
- mimeType = MimeType.BINARY_TYPE;
+ mediaType = mediaTypeResolver.fromFileName(localName);
+ if (mediaType == null) {
+ mediaType = mediaTypeResolver.forUnknown();
}
- try (final Resource document = current.createResource(compressedName, mimeType.getXMLDBType())) {
+ try (final Resource document = current.createResource(compressedName, toResourceTypeClass(mediaType))) {
message("storing document " + compressedName + " (" + i
+ " of " + Files.size(p) + ") ...");
document.setContent(isCompressed ? new GZIPInputSource(p) : p);
- ((EXistResource) document).setMimeType(mimeType.getName());
+ ((EXistResource) document).setMediaType(mediaType.getIdentifier());
current.storeResource(document);
messageln(DONE);
messageln("parsing " + Files.size(p) + (isCompressed ? " compressed" : "") + " bytes took "
@@ -1631,15 +1674,15 @@ protected synchronized boolean parseZip(final Path zipPath) throws XMLDBExceptio
if (!ze.isDirectory()) {
final String localName = pathSteps[pathSteps.length - 1];
final long start = System.currentTimeMillis();
- MimeType mimeType = MimeTable.getInstance().getContentTypeFor(localName);
- if (mimeType == null) {
- mimeType = MimeType.BINARY_TYPE;
+ @Nullable MediaType mediaType = mediaTypeResolver.fromFileName(localName);
+ if (mediaType == null) {
+ mediaType = mediaTypeResolver.forUnknown();
}
- try (final Resource document = base.createResource(localName, mimeType.getXMLDBType())) {
+ try (final Resource document = base.createResource(localName, toResourceTypeClass(mediaType))) {
message("storing Zip-entry document " + localName + " (" + (number)
+ " of " + zfile.size() + ") ...");
document.setContent(new ZipEntryInputSource(zfile, ze));
- ((EXistResource) document).setMimeType(mimeType.getName());
+ ((EXistResource) document).setMediaType(mediaType.getIdentifier());
base.storeResource(document);
messageln(DONE);
messageln("parsing " + ze.getSize() + " bytes took "
@@ -1756,19 +1799,17 @@ private void store(final Collection collection, final Path file, final UploadDia
final long fileSize = FileUtils.sizeQuietly(file);
upload.setCurrentSize(fileSize);
- MimeType mimeType = MimeTable.getInstance().getContentTypeFor(FileUtils.fileName(file));
+ MediaType mediaType = mediaTypeResolver.fromFileName(FileUtils.fileName(file));
// unknown mime type, here prefered is to do nothing
- if (mimeType == null) {
- upload.showMessage(file.toAbsolutePath() +
- " - unknown suffix. No matching mime-type found in : " +
- MimeTable.getInstance().getSrc());
+ if (mediaType == null) {
+ upload.showMessage(file.toAbsolutePath() + " - unknown suffix. No matching mime-type found");
// if some one prefers to store it as binary by default, but dangerous
- mimeType = MimeType.BINARY_TYPE;
+ mediaType = mediaTypeResolver.forUnknown();
}
- try (final Resource res = collection.createResource(filenameUri.toString(), mimeType.getXMLDBType())) {
- ((EXistResource) res).setMimeType(mimeType.getName());
+ try (final Resource res = collection.createResource(filenameUri.toString(), toResourceTypeClass(mediaType))) {
+ ((EXistResource) res).setMediaType(mediaType.getIdentifier());
res.setContent(file);
collection.storeResource(res);
++filesCount;
@@ -2077,11 +2118,14 @@ private void connectToDatabase() {
public boolean run() throws Exception {
this.path = options.setCol.orElse(XmldbURI.ROOT_COLLECTION_URI);
- // get eXist home
+ // get Elemental home
final Optional home = ConfigurationHelper.getExistHome();
// get default configuration filename from the driver class and set it in properties
- applyDefaultConfig(home);
+ final Optional configFile = applyDefaultConfig(home);
+
+ @Nullable final Path applicationConfigDir = configFile.map(Path::getParent).filter(Files::exists).orElse(null);
+ this.mediaTypeResolver = MediaTypeUtil.newMediaTypeResolver(applicationConfigDir);
properties.putAll(loadClientProperties());
@@ -2099,8 +2143,8 @@ public boolean run() throws Exception {
return false;
}
- historyFile = home.map(h -> h.resolve(".exist_history")).orElse(Paths.get(".exist_history"));
- queryHistoryFile = home.map(h -> h.resolve(".exist_query_history")).orElse(Paths.get(".exist_query_history"));
+ historyFile = home.map(h -> h.resolve(".elemental_jac_history")).orElse(Paths.get(".elemental_jac_history"));
+ queryHistoryFile = home.map(h -> h.resolve(".elemental_jac_query_history")).orElse(Paths.get(".elemental_jac_query_history"));
readQueryHistory();
if (interactive) {
@@ -2164,7 +2208,7 @@ private boolean checkLoginInfos(boolean interactive) {
return false;
}
- private void applyDefaultConfig(Optional home) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
+ private Optional applyDefaultConfig(Optional home) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
Optional configFile = ConfigurationHelper.getFromSystemProperty();
if (!configFile.isPresent()) {
final Class> cl = Class.forName(properties.getProperty(DRIVER));
@@ -2174,6 +2218,7 @@ private void applyDefaultConfig(Optional home) throws ClassNotFoundExcepti
}
}
configFile.ifPresent(value -> properties.setProperty(CONFIGURATION, value.toString()));
+ return configFile;
}
final boolean isInteractive() {
@@ -2382,10 +2427,10 @@ public void readlineInputLoop() {
while (cont) {
try {
if ("true".equals(properties.getProperty(COLORS))) {
- line = console.readLine(ANSI_CYAN + "exist:" + path + "> "
+ line = console.readLine(ANSI_CYAN + "elemental:" + path + "> "
+ ANSI_WHITE);
} else {
- line = console.readLine("exist:" + path + "> ");
+ line = console.readLine("elemental:" + path + "> ");
}
if (line != null) {
cont = process(line);
@@ -2456,22 +2501,16 @@ public String getNotice() {
String getNotice(BinaryOperator propertyAction) {
final StringBuilder builder = new StringBuilder();
- builder.append(propertyAction.apply("product-name", "eXist-db"));
+ builder.append(propertyAction.apply("product-name", "Elemental"));
builder.append(" version ");
builder.append(propertyAction.apply("product-version", "unknown"));
final String gitCommitId = propertyAction.apply("git-commit", "");
if (!gitCommitId.isEmpty()) {
builder.append(" (").append(gitCommitId).append(")");
}
- builder.append(", Copyright (C) 2001-");
+ builder.append(", Copyright (C) 2024-");
builder.append(Calendar.getInstance().get(Calendar.YEAR));
- builder.append(" The eXist-db Project");
- builder.append(EOL);
- builder.append("eXist-db comes with ABSOLUTELY NO WARRANTY.");
- builder.append(EOL);
- builder.append("This is free software, and you are welcome to redistribute it");
- builder.append(EOL);
- builder.append("under certain conditions; for details read the license file.");
+ builder.append(" Evolved Binary Ltd");
builder.append(EOL);
return builder.toString();
}
@@ -2628,7 +2667,7 @@ public static Properties getSystemProperties() {
return sysProperties;
}
- public static ImageIcon getExistIcon(final Class clazz) {
- return new javax.swing.ImageIcon(clazz.getResource("/org/exist/client/icons/x.png"));
+ public static ImageIcon getElementalIcon(final Class clazz) {
+ return new javax.swing.ImageIcon(clazz.getResource("/org/exist/client/icons/elemental-device.png"));
}
}
diff --git a/exist-core/src/main/java/org/exist/client/MimeTypeFileFilter.java b/exist-core/src/main/java/org/exist/client/MediaTypeFileFilter.java
similarity index 52%
rename from exist-core/src/main/java/org/exist/client/MimeTypeFileFilter.java
rename to exist-core/src/main/java/org/exist/client/MediaTypeFileFilter.java
index 611aa6e537..aacdcd9ef5 100644
--- a/exist-core/src/main/java/org/exist/client/MimeTypeFileFilter.java
+++ b/exist-core/src/main/java/org/exist/client/MediaTypeFileFilter.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -22,12 +46,10 @@
package org.exist.client;
import java.io.File;
-import java.util.Iterator;
-import java.util.List;
import javax.swing.filechooser.FileFilter;
-import org.exist.util.MimeTable;
+import xyz.elemental.mediatype.MediaType;
/**
@@ -36,18 +58,16 @@
*
* Java 6 API has a similar FileNameExtensionFilter
*/
-public class MimeTypeFileFilter extends FileFilter {
+public class MediaTypeFileFilter extends FileFilter {
- private String description = null;
- private List extensions = null;
+ private final MediaType mediaType;
- public MimeTypeFileFilter(String mimeType) {
- description = MimeTable.getInstance().getContentType(mimeType).getDescription();
- extensions = MimeTable.getInstance().getAllExtensions(mimeType);
+ public MediaTypeFileFilter(final MediaType mediaType) {
+ this.mediaType = mediaType;
}
@Override
- public boolean accept(File file) {
+ public boolean accept(final File file) {
if(file.isDirectory()){ //permit directories to be viewed
return true;
}
@@ -60,8 +80,9 @@ public boolean accept(File file) {
//check the extension is that of a file as defined in mime-types.xml
final String fileExtension = file.getName().substring(extensionOffset).toLowerCase();
- for(final String extension : extensions) {
- if(fileExtension.equals(extension)) {
+ final String[] extensions = mediaType.getKnownFileExtensions();
+ for (final String extension : extensions) {
+ if (fileExtension.equals(extension)) {
return true;
}
}
@@ -71,15 +92,16 @@ public boolean accept(File file) {
@Override
public String getDescription() {
- final StringBuilder description = new StringBuilder(this.description);
+ final StringBuilder description = new StringBuilder(mediaType.getIdentifier());
description.append(" (");
- for(final Iterator itExtensions = extensions.iterator(); itExtensions.hasNext();) {
- description.append(itExtensions.next());
- if(itExtensions.hasNext()) {
+ final String[] extensions = mediaType.getKnownFileExtensions();
+ for (int i = 0; i < extensions.length; i++) {
+ if (i > 0) {
description.append(' ');
}
+ description.append(extensions[i]);
}
description.append(")");
diff --git a/exist-core/src/main/java/org/exist/client/NewResourceDialog.java b/exist-core/src/main/java/org/exist/client/NewResourceDialog.java
index 373e9831be..fc7dc739f2 100644
--- a/exist-core/src/main/java/org/exist/client/NewResourceDialog.java
+++ b/exist-core/src/main/java/org/exist/client/NewResourceDialog.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -44,6 +68,9 @@
import org.xmldb.api.base.XMLDBException;
import org.xmldb.api.modules.BinaryResource;
import org.xmldb.api.modules.XMLResource;
+import xyz.elemental.mediatype.MediaType;
+
+import static org.exist.util.StringUtil.isNullOrEmpty;
/**
*
@@ -65,9 +92,9 @@ public NewResourceDialog(final InteractiveClient client) {
}
private enum ResourceType {
- XML_DOCUMENT("XML Document", "xml", "application/xml", "xml-resource.tmpl"),
- XQUERY_MAIN("XQuery Main Module", "xqy", "application/xquery", "xquery-resource.tmpl"),
- XQUERY_LIBRARY("XQuery Library Module", "xqm", "application/xquery", "xquery-lib-resource.tmpl");
+ XML_DOCUMENT("XML Document", "xml", MediaType.APPLICATION_XML, "xml-resource.tmpl"),
+ XQUERY_MAIN("XQuery Main Module", "xqy", MediaType.APPLICATION_XQUERY, "xquery-resource.tmpl"),
+ XQUERY_LIBRARY("XQuery Library Module", "xqm", MediaType.APPLICATION_XQUERY, "xquery-lib-resource.tmpl");
private final String label;
private final String fileExtension;
@@ -289,7 +316,7 @@ private void createResource(final ResourceType resourceType, final String filena
try (final Collection collection = client.current; final Resource resource = collection.createResource(resName, resType)) {
resource.setContent(resourceContent);
- ((EXistResource) resource).setMimeType(resourceType.getMimeType());
+ ((EXistResource) resource).setMediaType(resourceType.getMimeType());
collection.storeResource(resource);
}
client.reloadCollection();
@@ -297,8 +324,4 @@ private void createResource(final ResourceType resourceType, final String filena
ClientFrame.showErrorMessage(xmldbe.getMessage(), xmldbe);
}
}
-
- private boolean isNullOrEmpty(String str) {
- return str == null || str.isEmpty();
- }
-}
\ No newline at end of file
+}
diff --git a/exist-core/src/main/java/org/exist/client/QueryDialog.java b/exist-core/src/main/java/org/exist/client/QueryDialog.java
index d5de7aec1f..1253ac6eaf 100644
--- a/exist-core/src/main/java/org/exist/client/QueryDialog.java
+++ b/exist-core/src/main/java/org/exist/client/QueryDialog.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -62,6 +86,7 @@
import javax.swing.event.PopupMenuListener;
import javax.xml.transform.OutputKeys;
+import org.apache.commons.io.output.StringBuilderWriter;
import org.exist.security.PermissionDeniedException;
import org.exist.util.Holder;
import org.exist.xmldb.EXistXQueryService;
@@ -81,10 +106,14 @@
import org.xmldb.api.base.ResourceIterator;
import org.xmldb.api.base.ResourceSet;
import org.xmldb.api.base.XMLDBException;
+import xyz.elemental.mediatype.MediaType;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.xmldb.api.base.ResourceType.XML_RESOURCE;
+/**
+ * @author Adam Retter
+ */
public class QueryDialog extends JFrame {
private static final long serialVersionUID = 1L;
@@ -120,7 +149,7 @@ private QueryDialog(final InteractiveClient client, final Collection collection,
this.collection = collection;
this.properties = properties;
this.client = client;
- this.setIconImage(InteractiveClient.getExistIcon(getClass()).getImage());
+ this.setIconImage(InteractiveClient.getElementalIcon(getClass()).getImage());
setupComponents(loadedFromDb);
pack();
}
@@ -413,7 +442,7 @@ private void open() {
chooser.setCurrentDirectory(Paths.get(workDir).toFile());
chooser.setMultiSelectionEnabled(false);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
- chooser.addChoosableFileFilter(new MimeTypeFileFilter("application/xquery"));
+ chooser.addChoosableFileFilter(new MediaTypeFileFilter(client.getMediaTypeResolver().fromString(MediaType.APPLICATION_XQUERY)));
if (chooser.showDialog(this, Messages.getString("QueryDialog.opendialog")) == JFileChooser.APPROVE_OPTION) {
final Path selectedDir = chooser.getCurrentDirectory().toPath();
@@ -449,10 +478,10 @@ private void save(String stringToSave, String fileCategory) {
chooser.setCurrentDirectory(Paths.get(workDir).toFile());
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
if ("result".equals(fileCategory)) {
- chooser.addChoosableFileFilter(new MimeTypeFileFilter("application/xhtml+xml"));
- chooser.addChoosableFileFilter(new MimeTypeFileFilter("application/xml"));
+ chooser.addChoosableFileFilter(new MediaTypeFileFilter(client.getMediaTypeResolver().fromString(MediaType.APPLICATION_XHTML)));
+ chooser.addChoosableFileFilter(new MediaTypeFileFilter(client.getMediaTypeResolver().fromString(MediaType.APPLICATION_XML)));
} else {
- chooser.addChoosableFileFilter(new MimeTypeFileFilter("application/xquery"));
+ chooser.addChoosableFileFilter(new MediaTypeFileFilter(client.getMediaTypeResolver().fromString(MediaType.APPLICATION_XQUERY)));
}
if (chooser.showDialog(this, Messages.getString("QueryDialog.savedialogpre") + " " + fileCategory + " " + Messages.getString("QueryDialog.savedialogpost"))
== JFileChooser.APPROVE_OPTION) {
@@ -511,9 +540,10 @@ private void compileQuery() {
tCompiled = t1 - t0;
// In this way we can see the parsed structure meanwhile the query is
- final StringWriter writer = new StringWriter();
- service.dump(compiled, writer);
- exprDisplay.setText(writer.toString());
+ try (final StringBuilderWriter writer = new StringBuilderWriter()) {
+ service.dump(compiled, writer);
+ exprDisplay.setText(writer.toString());
+ }
resultTabs.setSelectedComponent(exprDisplayScrollPane);
statusMessage.setText(Messages.getString(QUERY_DIALOG_COMPILATION) + ": " + tCompiled + "ms");
@@ -583,9 +613,10 @@ public void run() {
tCompiled = t1 - t0;
// In this way we can see the parsed structure meanwhile the query is
- StringWriter writer = new StringWriter();
- service.dump(compiled, writer);
- exprDisplay.setText(writer.toString());
+ try (final StringBuilderWriter writer = new StringBuilderWriter()) {
+ service.dump(compiled, writer);
+ exprDisplay.setText(writer.toString());
+ }
result = service.execute(compiled);
tResult = System.currentTimeMillis() - t1;
@@ -596,9 +627,10 @@ public void run() {
}
// jmfg: Is this still needed? I don't think so
- writer = new StringWriter();
- service.dump(compiled, writer);
- exprDisplay.setText(writer.toString());
+ try (final StringBuilderWriter writer = new StringBuilderWriter()) {
+ service.dump(compiled, writer);
+ exprDisplay.setText(writer.toString());
+ }
statusMessage.setText(Messages.getString("QueryDialog.retrievingmessage"));
final int howmany = count.getNumber().intValue();
diff --git a/exist-core/src/main/java/org/exist/client/TriggersDialog.java b/exist-core/src/main/java/org/exist/client/TriggersDialog.java
index 832b2af858..f7a0241ed5 100644
--- a/exist-core/src/main/java/org/exist/client/TriggersDialog.java
+++ b/exist-core/src/main/java/org/exist/client/TriggersDialog.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -51,10 +75,8 @@
/**
* Dialog for viewing and editing Triggers in the Admin Client
- *
- * @author Adam Retter
- * @serial 2012-11-24
- * @version 1.1
+ *
+ * @author Adam Retter
*/
class TriggersDialog extends JFrame {
@@ -72,7 +94,7 @@ class TriggersDialog extends JFrame {
public TriggersDialog(final String title, final InteractiveClient client) {
super(title);
this.client = client;
- this.setIconImage(InteractiveClient.getExistIcon(getClass()).getImage());
+ this.setIconImage(InteractiveClient.getElementalIcon(getClass()).getImage());
//capture the frame's close event
final WindowListener windowListener = new WindowAdapter() {
@Override
diff --git a/exist-core/src/main/java/org/exist/client/UploadDialog.java b/exist-core/src/main/java/org/exist/client/UploadDialog.java
index 1246a18699..cadcc02b15 100644
--- a/exist-core/src/main/java/org/exist/client/UploadDialog.java
+++ b/exist-core/src/main/java/org/exist/client/UploadDialog.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -39,6 +63,9 @@
import org.exist.storage.ElementIndex;
import org.exist.util.ProgressIndicator;
+/**
+ * @author Adam Retter
+ */
class UploadDialog extends JFrame {
private static final long serialVersionUID = 1L;
@@ -61,7 +88,7 @@ public UploadDialog() {
c.insets = new Insets(5, 5, 5, 5);
JLabel label = new JLabel(Messages.getString("UploadDialog.1")); //$NON-NLS-1$
- this.setIconImage(InteractiveClient.getExistIcon(getClass()).getImage());
+ this.setIconImage(InteractiveClient.getElementalIcon(getClass()).getImage());
c.gridx = 0;
c.gridy = 0;
c.anchor = GridBagConstraints.WEST;
diff --git a/exist-core/src/main/java/org/exist/client/security/AccessControlEntryDialog.java b/exist-core/src/main/java/org/exist/client/security/AccessControlEntryDialog.java
index 5bf16b25f6..833b435031 100644
--- a/exist-core/src/main/java/org/exist/client/security/AccessControlEntryDialog.java
+++ b/exist-core/src/main/java/org/exist/client/security/AccessControlEntryDialog.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -38,7 +62,7 @@
/**
*
- * @author Adam Retter
+ * @author Adam Retter
*/
public class AccessControlEntryDialog extends javax.swing.JFrame implements DialogWithResponse {
@@ -53,7 +77,7 @@ public class AccessControlEntryDialog extends javax.swing.JFrame implements Dial
public AccessControlEntryDialog(final UserManagementService userManagementService, final String title) throws XMLDBException {
this.userManagementService = userManagementService;
- this.setIconImage(InteractiveClient.getExistIcon(getClass()).getImage());
+ this.setIconImage(InteractiveClient.getElementalIcon(getClass()).getImage());
allUsernames = new HashSet<>();
for(final Account account : userManagementService.getAccounts()) {
allUsernames.add(account.getName());
diff --git a/exist-core/src/main/java/org/exist/client/security/EditPropertiesDialog.java b/exist-core/src/main/java/org/exist/client/security/EditPropertiesDialog.java
index 5768b37cc1..daf85fe116 100644
--- a/exist-core/src/main/java/org/exist/client/security/EditPropertiesDialog.java
+++ b/exist-core/src/main/java/org/exist/client/security/EditPropertiesDialog.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -50,7 +74,7 @@
/**
*
- * @author Adam Retter
+ * @author Adam Retter
*/
public class EditPropertiesDialog extends javax.swing.JFrame {
private final UserManagementService userManagementService;
@@ -90,7 +114,7 @@ public EditPropertiesDialog(final UserManagementService userManagementService, f
this.mode = mode;
this.acl = acl;
this.applyTo = applyTo;
- this.setIconImage(InteractiveClient.getExistIcon(getClass()).getImage());
+ this.setIconImage(InteractiveClient.getElementalIcon(getClass()).getImage());
initComponents();
setFormProperties();
}
diff --git a/exist-core/src/main/java/org/exist/client/security/UserDialog.java b/exist-core/src/main/java/org/exist/client/security/UserDialog.java
index caeb8f904b..bee43c2b68 100644
--- a/exist-core/src/main/java/org/exist/client/security/UserDialog.java
+++ b/exist-core/src/main/java/org/exist/client/security/UserDialog.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -37,7 +61,7 @@
/**
*
- * @author Adam Retter
+ * @author Adam Retter
*/
public class UserDialog extends javax.swing.JFrame {
@@ -54,7 +78,7 @@ public class UserDialog extends javax.swing.JFrame {
public UserDialog(final UserManagementService userManagementService) {
this.userManagementService = userManagementService;
- this.setIconImage(InteractiveClient.getExistIcon(getClass()).getImage());
+ this.setIconImage(InteractiveClient.getElementalIcon(getClass()).getImage());
initComponents();
}
diff --git a/exist-core/src/main/java/org/exist/client/security/UserManagerDialog.java b/exist-core/src/main/java/org/exist/client/security/UserManagerDialog.java
index 6bfff3d75a..49b861bdb7 100644
--- a/exist-core/src/main/java/org/exist/client/security/UserManagerDialog.java
+++ b/exist-core/src/main/java/org/exist/client/security/UserManagerDialog.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -43,7 +67,7 @@
/**
*
- * @author Adam Retter
+ * @author Adam Retter
*/
public class UserManagerDialog extends javax.swing.JFrame {
@@ -60,7 +84,7 @@ public UserManagerDialog(final UserManagementService userManagementService, fina
this.userManagementService = userManagementService;
this.currentUser = currentUser;
this.client = client;
- this.setIconImage(InteractiveClient.getExistIcon(getClass()).getImage());
+ this.setIconImage(InteractiveClient.getElementalIcon(getClass()).getImage());
initComponents();
tblUsers.setDefaultRenderer(Object.class, new HighlightedTableCellRenderer());
tblGroups.setDefaultRenderer(Object.class, new HighlightedTableCellRenderer());
diff --git a/exist-core/src/main/java/org/exist/collections/Collection.java b/exist-core/src/main/java/org/exist/collections/Collection.java
index ed68afcf2c..c7bf145fad 100644
--- a/exist-core/src/main/java/org/exist/collections/Collection.java
+++ b/exist-core/src/main/java/org/exist/collections/Collection.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -30,7 +54,7 @@
import org.exist.security.SecurityManager;
import org.exist.storage.*;
import org.exist.storage.io.VariableByteInput;
-import org.exist.storage.io.VariableByteOutputStream;
+import org.exist.storage.io.VariableByteOutput;
import org.exist.storage.lock.*;
import org.exist.storage.lock.Lock.LockMode;
import org.exist.storage.txn.Txn;
@@ -42,6 +66,7 @@
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
+import xyz.elemental.mediatype.MediaType;
import javax.annotation.Nullable;
import java.io.IOException;
@@ -590,7 +615,7 @@ DocumentSet getDocuments(DBBroker broker, MutableDocumentSet docs, LockedDocumen
* @throws PermissionDeniedException if user has not sufficient rights
* @throws LockException if broker is locked
* @throws IOException in case of I/O errors
- * @throws TriggerException in case of eXist-db trigger error
+ * @throws TriggerException in case of trigger error
*/
void removeResource(Txn transaction, DBBroker broker, DocumentImpl doc)
throws PermissionDeniedException, LockException, IOException, TriggerException;
@@ -604,7 +629,7 @@ void removeResource(Txn transaction, DBBroker broker, DocumentImpl doc)
* @throws PermissionDeniedException if user has not sufficient rights
* @throws LockException if broker is locked
* @throws IOException in case of I/O errors
- * @throws TriggerException in case of eXist-db trigger error
+ * @throws TriggerException in case of trigger error
*/
void removeXMLResource(Txn transaction, DBBroker broker, XmldbURI name)
throws PermissionDeniedException, TriggerException, LockException, IOException;
@@ -617,7 +642,7 @@ void removeXMLResource(Txn transaction, DBBroker broker, XmldbURI name)
* @param name the name (without path) of the document
* @throws PermissionDeniedException if user has not sufficient rights
* @throws LockException if broker is locked
- * @throws TriggerException in case of eXist-db trigger error
+ * @throws TriggerException in case of trigger error
*/
void removeBinaryResource(Txn transaction, DBBroker broker, XmldbURI name)
throws PermissionDeniedException, LockException, TriggerException;
@@ -630,7 +655,7 @@ void removeBinaryResource(Txn transaction, DBBroker broker, XmldbURI name)
* @param doc the document to remove
* @throws PermissionDeniedException if user has not sufficient rights
* @throws LockException if broker is locked
- * @throws TriggerException in case of eXist-db trigger error
+ * @throws TriggerException in case of trigger error
*/
void removeBinaryResource(Txn transaction, DBBroker broker, DocumentImpl doc)
throws PermissionDeniedException, LockException, TriggerException;
@@ -640,7 +665,7 @@ void removeBinaryResource(Txn transaction, DBBroker broker, DocumentImpl doc)
* Since the process is dependent on the collection configuration,
* the collection acquires a write lock during the process.
*
- * NOTE: This should only be called from {@link NativeBroker#storeDocument(Txn, XmldbURI, InputSource, MimeType, Date, Date, Permission, DocumentType, XMLReader, Collection)}
+ * NOTE: This should only be called from {@link NativeBroker#storeDocument(Txn, XmldbURI, InputSource, MediaType, Date, Date, Permission, DocumentType, XMLReader, Collection)}
*
* @param transaction The database transaction
* @param broker The database broker
@@ -651,10 +676,13 @@ void removeBinaryResource(Txn transaction, DBBroker broker, DocumentImpl doc)
* @throws PermissionDeniedException if user has not sufficient rights
* @throws LockException if broker is locked
* @throws IOException in case of I/O errors
- * @throws TriggerException in case of eXist-db trigger error
- * @throws EXistException general eXist-db exception
+ * @throws TriggerException in case of trigger error
+ * @throws EXistException general exception
* @throws SAXException internal SAXException
+ *
+ * @deprecated Use {@link #storeDocument(Txn, DBBroker, XmldbURI, InputSource, MediaType)} instead.
*/
+ @Deprecated
void storeDocument(Txn transaction, DBBroker broker, XmldbURI name, InputSource source, @Nullable MimeType mimeType) throws EXistException, PermissionDeniedException, TriggerException, SAXException, LockException, IOException;
/**
@@ -662,7 +690,29 @@ void removeBinaryResource(Txn transaction, DBBroker broker, DocumentImpl doc)
* Since the process is dependent on the collection configuration,
* the collection acquires a write lock during the process.
*
- * NOTE: This should only be called from {@link NativeBroker#storeDocument(Txn, XmldbURI, InputSource, MimeType, Date, Date, Permission, DocumentType, XMLReader, Collection)}
+ * NOTE: This should only be called from {@link NativeBroker#storeDocument(Txn, XmldbURI, InputSource, MediaType, Date, Date, Permission, DocumentType, XMLReader, Collection)}
+ *
+ * @param transaction The database transaction
+ * @param broker The database broker
+ * @param name The name (without path) of the document
+ * @param source The source of the content for the new document to store
+ * @param mediaType The Internet Media Type of the document to store, or null if unknown.
+ *
+ * @throws PermissionDeniedException if user has not sufficient rights
+ * @throws LockException if broker is locked
+ * @throws IOException in case of I/O errors
+ * @throws TriggerException in case of trigger error
+ * @throws EXistException general exception
+ * @throws SAXException internal SAXException
+ */
+ void storeDocument(Txn transaction, DBBroker broker, XmldbURI name, InputSource source, @Nullable MediaType mediaType) throws EXistException, PermissionDeniedException, TriggerException, SAXException, LockException, IOException;
+
+ /**
+ * Stores a document.
+ * Since the process is dependent on the collection configuration,
+ * the collection acquires a write lock during the process.
+ *
+ * NOTE: This should only be called from {@link NativeBroker#storeDocument(Txn, XmldbURI, InputSource, MediaType, Date, Date, Permission, DocumentType, XMLReader, Collection)}
*
* @param transaction The database transaction
* @param broker The database broker
@@ -679,10 +729,13 @@ void removeBinaryResource(Txn transaction, DBBroker broker, DocumentImpl doc)
* @throws PermissionDeniedException if user has not sufficient rights
* @throws LockException if broker is locked
* @throws IOException in case of I/O errors
- * @throws TriggerException in case of eXist-db trigger error
- * @throws EXistException general eXist-db exception
+ * @throws TriggerException in case of trigger error
+ * @throws EXistException general exception
* @throws SAXException internal SAXException
+ *
+ * @deprecated Use {@link #storeDocument(Txn, DBBroker, XmldbURI, InputSource, MediaType, Date, Date, Permission, DocumentType, XMLReader)} instead.
*/
+ @Deprecated
void storeDocument(Txn transaction, DBBroker broker, XmldbURI name, InputSource source, @Nullable MimeType mimeType, @Nullable Date createdDate, @Nullable Date lastModifiedDate, @Nullable Permission permission, @Nullable DocumentType documentType, @Nullable XMLReader xmlReader) throws EXistException, PermissionDeniedException, TriggerException, SAXException, LockException, IOException;
/**
@@ -690,7 +743,35 @@ void removeBinaryResource(Txn transaction, DBBroker broker, DocumentImpl doc)
* Since the process is dependent on the collection configuration,
* the collection acquires a write lock during the process.
*
- * NOTE: This should only be called from {@link NativeBroker#storeDocument(Txn, XmldbURI, Node, MimeType, Collection)}
+ * NOTE: This should only be called from {@link NativeBroker#storeDocument(Txn, XmldbURI, InputSource, MediaType, Date, Date, Permission, DocumentType, XMLReader, Collection)}
+ *
+ * @param transaction The database transaction
+ * @param broker The database broker
+ * @param name The name (without path) of the document
+ * @param source The source of the content for the new document to store
+ * @param mediaType The Internet Media Type of the document to store, or null if unknown.
+ * If null, application/octet-stream will be used to store a binary document.
+ * @param createdDate The created date to set for the document, or if null the date is set to 'now'
+ * @param lastModifiedDate The lastModified date to set for the document, or if null the date is set to the {@code createdDate}
+ * @param permission A specific permission to set on the document, or null for the default permission
+ * @param documentType A document type declaration, or null if absent or a binary document is being stored
+ * @param xmlReader A custom XML Reader (e.g. a HTML to XHTML converting reader), or null to use the default XML reader or if a binary document is being stored
+ *
+ * @throws PermissionDeniedException if user has not sufficient rights
+ * @throws LockException if broker is locked
+ * @throws IOException in case of I/O errors
+ * @throws TriggerException in case of trigger error
+ * @throws EXistException general exception
+ * @throws SAXException internal SAXException
+ */
+ void storeDocument(Txn transaction, DBBroker broker, XmldbURI name, InputSource source, @Nullable MediaType mediaType, @Nullable Date createdDate, @Nullable Date lastModifiedDate, @Nullable Permission permission, @Nullable DocumentType documentType, @Nullable XMLReader xmlReader) throws EXistException, PermissionDeniedException, TriggerException, SAXException, LockException, IOException;
+
+ /**
+ * Stores a document.
+ * Since the process is dependent on the collection configuration,
+ * the collection acquires a write lock during the process.
+ *
+ * NOTE: This should only be called from {@link NativeBroker#storeDocument(Txn, XmldbURI, Node, MediaType, Collection)}
*
* @param transaction The database transaction
* @param broker The database broker
@@ -701,10 +782,13 @@ void removeBinaryResource(Txn transaction, DBBroker broker, DocumentImpl doc)
* @throws PermissionDeniedException if user has not sufficient rights
* @throws LockException if broker is locked
* @throws IOException in case of I/O errors
- * @throws TriggerException in case of eXist-db trigger error
- * @throws EXistException general eXist-db exception
+ * @throws TriggerException in case of trigger error
+ * @throws EXistException general exception
* @throws SAXException internal SAXException
+ *
+ * @deprecated Use {@link #storeDocument(Txn, DBBroker, XmldbURI, Node, MediaType)} instead.
*/
+ @Deprecated
void storeDocument(Txn transaction, DBBroker broker, XmldbURI name, Node node, @Nullable MimeType mimeType) throws EXistException, PermissionDeniedException, TriggerException, SAXException, LockException, IOException;
/**
@@ -712,7 +796,29 @@ void removeBinaryResource(Txn transaction, DBBroker broker, DocumentImpl doc)
* Since the process is dependent on the collection configuration,
* the collection acquires a write lock during the process.
*
- * NOTE: This should only be called from {@link NativeBroker#storeDocument(Txn, XmldbURI, Node, MimeType, Date, Date, Permission, DocumentType, XMLReader, Collection)}
+ * NOTE: This should only be called from {@link NativeBroker#storeDocument(Txn, XmldbURI, Node, MediaType, Collection)}
+ *
+ * @param transaction The database transaction
+ * @param broker The database broker
+ * @param name The name (without path) of the document
+ * @param node The DOM Node to store as a new document
+ * @param mediaType The Internet Media Type of the document to store, or null if unknown.
+ *
+ * @throws PermissionDeniedException if user has not sufficient rights
+ * @throws LockException if broker is locked
+ * @throws IOException in case of I/O errors
+ * @throws TriggerException in case of trigger error
+ * @throws EXistException general exception
+ * @throws SAXException internal SAXException
+ */
+ void storeDocument(Txn transaction, DBBroker broker, XmldbURI name, Node node, @Nullable MediaType mediaType) throws EXistException, PermissionDeniedException, TriggerException, SAXException, LockException, IOException;
+
+ /**
+ * Stores a document.
+ * Since the process is dependent on the collection configuration,
+ * the collection acquires a write lock during the process.
+ *
+ * NOTE: This should only be called from {@link NativeBroker#storeDocument(Txn, XmldbURI, Node, MediaType, Date, Date, Permission, DocumentType, XMLReader, Collection)}
*
* @param transaction The database transaction
* @param broker The database broker
@@ -729,12 +835,43 @@ void removeBinaryResource(Txn transaction, DBBroker broker, DocumentImpl doc)
* @throws PermissionDeniedException if user has not sufficient rights
* @throws LockException if broker is locked
* @throws IOException in case of I/O errors
- * @throws TriggerException in case of eXist-db trigger error
- * @throws EXistException general eXist-db exception
+ * @throws TriggerException in case of trigger error
+ * @throws EXistException general exception
* @throws SAXException internal SAXException
+ *
+ * @deprecated Use {@link #storeDocument(Txn, DBBroker, XmldbURI, Node, MediaType, Date, Date, Permission, DocumentType, XMLReader)} instead.
*/
+ @Deprecated
void storeDocument(Txn transaction, DBBroker broker, XmldbURI name, Node node, @Nullable MimeType mimeType, @Nullable Date createdDate, @Nullable Date lastModifiedDate, @Nullable Permission permission, @Nullable DocumentType documentType, @Nullable XMLReader xmlReader) throws EXistException, PermissionDeniedException, TriggerException, SAXException, LockException, IOException;
+ /**
+ * Stores a document.
+ * Since the process is dependent on the collection configuration,
+ * the collection acquires a write lock during the process.
+ *
+ * NOTE: This should only be called from {@link NativeBroker#storeDocument(Txn, XmldbURI, Node, MediaType, Date, Date, Permission, DocumentType, XMLReader, Collection)}
+ *
+ * @param transaction The database transaction
+ * @param broker The database broker
+ * @param name The name (without path) of the document
+ * @param node The DOM Node to store as a new document
+ * @param mediaType The Internet Media Type of the document to store, or null if unknown.
+ * If null, application/octet-stream will be used to store a binary document.
+ * @param createdDate The created date to set for the document, or if null the date is set to 'now'
+ * @param lastModifiedDate The lastModified date to set for the document, or if null the date is set to the {@code createdDate}
+ * @param permission A specific permission to set on the document, or null for the default permission
+ * @param documentType A document type declaration, or null if absent or a binary document is being stored
+ * @param xmlReader A custom XML Reader (e.g. a HTML to XHTML converting reader), or null to use the default XML reader or if a binary document is being stored
+ *
+ * @throws PermissionDeniedException if user has not sufficient rights
+ * @throws LockException if broker is locked
+ * @throws IOException in case of I/O errors
+ * @throws TriggerException in case of trigger error
+ * @throws EXistException general exception
+ * @throws SAXException internal SAXException
+ */
+ void storeDocument(Txn transaction, DBBroker broker, XmldbURI name, Node node, @Nullable MediaType mediaType, @Nullable Date createdDate, @Nullable Date lastModifiedDate, @Nullable Permission permission, @Nullable DocumentType documentType, @Nullable XMLReader xmlReader) throws EXistException, PermissionDeniedException, TriggerException, SAXException, LockException, IOException;
+
/**
* Validates an XML document and prepares it for further storage.
* Launches prepare and postValidate triggers.
@@ -751,11 +888,11 @@ void removeBinaryResource(Txn transaction, DBBroker broker, DocumentImpl doc)
* @throws PermissionDeniedException if user has not sufficient rights
* @throws LockException if broker is locked
* @throws IOException in case of I/O errors
- * @throws TriggerException in case of eXist-db trigger error
- * @throws EXistException general eXist-db exception
+ * @throws TriggerException in case of trigger error
+ * @throws EXistException general exception
* @throws SAXException internal SAXException
*
- * @deprecated Use {@link DBBroker#storeDocument(Txn, XmldbURI, InputSource, MimeType, Date, Date, Permission, DocumentType, XMLReader, Collection)} instead.
+ * @deprecated Use {@link DBBroker#storeDocument(Txn, XmldbURI, InputSource, MediaType, Date, Date, Permission, DocumentType, XMLReader, Collection)} instead.
*/
@Deprecated
IndexInfo validateXMLResource(Txn transaction, DBBroker broker, XmldbURI name, InputSource source)
@@ -779,11 +916,11 @@ IndexInfo validateXMLResource(Txn transaction, DBBroker broker, XmldbURI name, I
* @throws PermissionDeniedException if user has not sufficient rights
* @throws LockException if broker is locked
* @throws IOException in case of I/O errors
- * @throws TriggerException in case of eXist-db trigger error
- * @throws EXistException general eXist-db exception
+ * @throws TriggerException in case of trigger error
+ * @throws EXistException general exception
* @throws SAXException internal SAXException
*
- * @deprecated Use {@link DBBroker#storeDocument(Txn, XmldbURI, InputSource, MimeType, Date, Date, Permission, DocumentType, XMLReader, Collection)} instead.
+ * @deprecated Use {@link DBBroker#storeDocument(Txn, XmldbURI, InputSource, MediaType, Date, Date, Permission, DocumentType, XMLReader, Collection)} instead.
*/
@Deprecated
IndexInfo validateXMLResource(Txn transaction, DBBroker broker, XmldbURI name, InputSource source, XMLReader reader)
@@ -805,11 +942,11 @@ IndexInfo validateXMLResource(Txn transaction, DBBroker broker, XmldbURI name, I
* @throws PermissionDeniedException if user has not sufficient rights
* @throws LockException if broker is locked
* @throws IOException in case of I/O errors
- * @throws TriggerException in case of eXist-db trigger error
- * @throws EXistException general eXist-db exception
+ * @throws TriggerException in case of trigger error
+ * @throws EXistException general exception
* @throws SAXException internal SAXException
*
- * @deprecated Use {@link DBBroker#storeDocument(Txn, XmldbURI, InputSource, MimeType, Date, Date, Permission, DocumentType, XMLReader, Collection)} instead.
+ * @deprecated Use {@link DBBroker#storeDocument(Txn, XmldbURI, InputSource, MediaType, Date, Date, Permission, DocumentType, XMLReader, Collection)} instead.
*/
@Deprecated
IndexInfo validateXMLResource(Txn transaction, DBBroker broker, XmldbURI name, String data)
@@ -831,11 +968,11 @@ IndexInfo validateXMLResource(Txn transaction, DBBroker broker, XmldbURI name, S
* @throws PermissionDeniedException if user has not sufficient rights
* @throws LockException if broker is locked
* @throws IOException in case of I/O errors
- * @throws TriggerException in case of eXist-db trigger error
- * @throws EXistException general eXist-db exception
+ * @throws TriggerException in case of trigger error
+ * @throws EXistException general exception
* @throws SAXException internal SAXException
*
- * @deprecated Use {@link DBBroker#storeDocument(Txn, XmldbURI, Node, MimeType, Date, Date, Permission, DocumentType, XMLReader, Collection)} instead.
+ * @deprecated Use {@link DBBroker#storeDocument(Txn, XmldbURI, Node, MediaType, Date, Date, Permission, DocumentType, XMLReader, Collection)} instead.
*/
@Deprecated
IndexInfo validateXMLResource(Txn transaction, DBBroker broker, XmldbURI name, Node node)
@@ -854,11 +991,11 @@ IndexInfo validateXMLResource(Txn transaction, DBBroker broker, XmldbURI name, N
*
* @throws PermissionDeniedException if user has not sufficient rights
* @throws LockException if broker is locked
- * @throws TriggerException in case of eXist-db trigger error
- * @throws EXistException general eXist-db exception
+ * @throws TriggerException in case of trigger error
+ * @throws EXistException general exception
* @throws SAXException internal SAXException
*
- * @deprecated Use {@link DBBroker#storeDocument(Txn, XmldbURI, InputSource, MimeType, Date, Date, Permission, DocumentType, XMLReader, Collection)} instead.
+ * @deprecated Use {@link DBBroker#storeDocument(Txn, XmldbURI, InputSource, MediaType, Date, Date, Permission, DocumentType, XMLReader, Collection)} instead.
*/
@Deprecated
void store(Txn transaction, DBBroker broker, IndexInfo info, InputSource source)
@@ -878,11 +1015,11 @@ void store(Txn transaction, DBBroker broker, IndexInfo info, InputSource source)
*
* @throws PermissionDeniedException if user has not sufficient rights
* @throws LockException if broker is locked*
- * @throws TriggerException in case of eXist-db trigger error
- * @throws EXistException general eXist-db exception
+ * @throws TriggerException in case of trigger error
+ * @throws EXistException general exception
* @throws SAXException internal SAXException
*
- * @deprecated Use {@link DBBroker#storeDocument(Txn, XmldbURI, InputSource, MimeType, Date, Date, Permission, DocumentType, XMLReader, Collection)} instead.
+ * @deprecated Use {@link DBBroker#storeDocument(Txn, XmldbURI, InputSource, MediaType, Date, Date, Permission, DocumentType, XMLReader, Collection)} instead.
*/
@Deprecated
void store(final Txn transaction, final DBBroker broker, final IndexInfo info, final InputSource source, final XMLReader reader)
@@ -901,11 +1038,11 @@ void store(final Txn transaction, final DBBroker broker, final IndexInfo info, f
*
* @throws PermissionDeniedException if user has not sufficient rights
* @throws LockException if broker is locked
- * @throws TriggerException in case of eXist-db trigger error
- * @throws EXistException general eXist-db exception
+ * @throws TriggerException in case of trigger error
+ * @throws EXistException general exception
* @throws SAXException internal SAXException
*
- * @deprecated Use {@link DBBroker#storeDocument(Txn, XmldbURI, InputSource, MimeType, Date, Date, Permission, DocumentType, XMLReader, Collection)} instead.
+ * @deprecated Use {@link DBBroker#storeDocument(Txn, XmldbURI, InputSource, MediaType, Date, Date, Permission, DocumentType, XMLReader, Collection)} instead.
*/
@Deprecated
void store(Txn transaction, DBBroker broker, IndexInfo info, String data)
@@ -924,11 +1061,11 @@ void store(Txn transaction, DBBroker broker, IndexInfo info, String data)
*
* @throws PermissionDeniedException if user has not sufficient rights
* @throws LockException if broker is locked
- * @throws TriggerException in case of eXist-db trigger error
- * @throws EXistException general eXist-db exception
+ * @throws TriggerException in case of trigger error
+ * @throws EXistException general exception
* @throws SAXException internal SAXException
*
- * @deprecated Use {@link DBBroker#storeDocument(Txn, XmldbURI, Node, MimeType, Date, Date, Permission, DocumentType, XMLReader, Collection)} instead.
+ * @deprecated Use {@link DBBroker#storeDocument(Txn, XmldbURI, Node, MediaType, Date, Date, Permission, DocumentType, XMLReader, Collection)} instead.
*/
@Deprecated
void store(Txn transaction, DBBroker broker, IndexInfo info, Node node)
@@ -946,9 +1083,9 @@ void store(Txn transaction, DBBroker broker, IndexInfo info, Node node)
* @throws PermissionDeniedException if user has not sufficient rights
* @throws LockException if broker is locked
* @throws IOException in case of I/O errors
- * @throws TriggerException in case of eXist-db trigger error
+ * @throws TriggerException in case of trigger error
*
- * @deprecated Use {@link DBBroker#storeDocument(Txn, XmldbURI, InputSource, MimeType, Date, Date, Permission, DocumentType, XMLReader, Collection)} instead.
+ * @deprecated Use {@link DBBroker#storeDocument(Txn, XmldbURI, InputSource, MediaType, Date, Date, Permission, DocumentType, XMLReader, Collection)} instead.
*/
@Deprecated
BinaryDocument validateBinaryResource(Txn transaction, DBBroker broker, XmldbURI name)
@@ -966,7 +1103,7 @@ BinaryDocument validateBinaryResource(Txn transaction, DBBroker broker, XmldbURI
* @param broker The database broker
* @param name the name (without path) of the document
* @param is The content for the document
- * @param mimeType The Internet Media Type of the document
+ * @param mediaType The Internet Media Type of the document
* @param size The size in bytes of the document (unused - size is calculated during storage)
* @param created The created timestamp of the document
* @param modified The modified timestamp of the document
@@ -976,13 +1113,13 @@ BinaryDocument validateBinaryResource(Txn transaction, DBBroker broker, XmldbURI
* @throws PermissionDeniedException if user has not sufficient rights
* @throws LockException if broker is locked
* @throws IOException in case of I/O errors
- * @throws TriggerException in case of eXist-db trigger error
- * @throws EXistException general eXist-db exception*
+ * @throws TriggerException in case of trigger error
+ * @throws EXistException general exception*
*
- * @deprecated Use {@link DBBroker#storeDocument(Txn, XmldbURI, InputSource, MimeType, Date, Date, Permission, DocumentType, XMLReader, Collection)} instead.
+ * @deprecated Use {@link DBBroker#storeDocument(Txn, XmldbURI, InputSource, MediaType, Date, Date, Permission, DocumentType, XMLReader, Collection)} instead.
*/
@Deprecated
- BinaryDocument addBinaryResource(Txn transaction, DBBroker broker, XmldbURI name, InputStream is, String mimeType,
+ BinaryDocument addBinaryResource(Txn transaction, DBBroker broker, XmldbURI name, InputStream is, String mediaType,
@Deprecated long size, Date created, Date modified) throws EXistException, PermissionDeniedException, LockException,
TriggerException, IOException;
@@ -998,7 +1135,7 @@ BinaryDocument addBinaryResource(Txn transaction, DBBroker broker, XmldbURI name
* @param broker The database broker
* @param name the name (without path) of the document
* @param is The content for the document
- * @param mimeType The Internet Media Type of the document
+ * @param mediaType The Internet Media Type of the document
* @param size The size in bytes of the document (unused - size is calculated during storage)
* @param created The created timestamp of the document
* @param modified The modified timestamp of the document
@@ -1009,13 +1146,13 @@ BinaryDocument addBinaryResource(Txn transaction, DBBroker broker, XmldbURI name
* @throws PermissionDeniedException if user has not sufficient rights
* @throws LockException if broker is locked
* @throws IOException in case of I/O errors
- * @throws TriggerException in case of eXist-db trigger error
- * @throws EXistException general eXist-db exception*
+ * @throws TriggerException in case of trigger error
+ * @throws EXistException general exception*
*
- * @deprecated Use {@link DBBroker#storeDocument(Txn, XmldbURI, InputSource, MimeType, Date, Date, Permission, DocumentType, XMLReader, Collection)} instead.
+ * @deprecated Use {@link DBBroker#storeDocument(Txn, XmldbURI, InputSource, MediaType, Date, Date, Permission, DocumentType, XMLReader, Collection)} instead.
*/
@Deprecated
- BinaryDocument addBinaryResource(Txn transaction, DBBroker broker, XmldbURI name, InputStream is, String mimeType,
+ BinaryDocument addBinaryResource(Txn transaction, DBBroker broker, XmldbURI name, InputStream is, String mediaType,
@Deprecated long size, Date created, Date modified, @Nullable Permission permission) throws EXistException, PermissionDeniedException, LockException,
TriggerException, IOException;
@@ -1031,20 +1168,20 @@ BinaryDocument addBinaryResource(Txn transaction, DBBroker broker, XmldbURI name
* @param broker The database broker
* @param name the name (without path) of the document
* @param data The content for the document
- * @param mimeType The Internet Media Type of the document
+ * @param mediaType The Internet Media Type of the document
*
* @return The stored Binary Document object
*
* @throws PermissionDeniedException if user has not sufficient rights
* @throws LockException if broker is locked
* @throws IOException in case of I/O errors
- * @throws TriggerException in case of eXist-db trigger error
- * @throws EXistException general eXist-db exception
+ * @throws TriggerException in case of trigger error
+ * @throws EXistException general exception
*
* @deprecated Use {@link #addBinaryResource(Txn, DBBroker, XmldbURI, InputStream, String, long)}
*/
@Deprecated
- BinaryDocument addBinaryResource(Txn transaction, DBBroker broker, XmldbURI name, byte[] data, String mimeType)
+ BinaryDocument addBinaryResource(Txn transaction, DBBroker broker, XmldbURI name, byte[] data, String mediaType)
throws EXistException, PermissionDeniedException, LockException, TriggerException, IOException;
/**
@@ -1059,7 +1196,7 @@ BinaryDocument addBinaryResource(Txn transaction, DBBroker broker, XmldbURI name
* @param broker The database broker
* @param name the name (without path) of the document
* @param data The content for the document
- * @param mimeType The Internet Media Type of the document
+ * @param mediaType The Internet Media Type of the document
* @param created The created timestamp of the document
* @param modified The modified timestamp of the document
*
@@ -1068,13 +1205,13 @@ BinaryDocument addBinaryResource(Txn transaction, DBBroker broker, XmldbURI name
* @throws PermissionDeniedException if user has not sufficient rights
* @throws LockException if broker is locked
* @throws IOException in case of I/O errors
- * @throws TriggerException in case of eXist-db trigger error
- * @throws EXistException general eXist-db exception
+ * @throws TriggerException in case of trigger error
+ * @throws EXistException general exception
*
* @deprecated Use {@link #addBinaryResource(Txn, DBBroker, BinaryDocument, InputStream, String, long, Date, Date)}
*/
@Deprecated
- BinaryDocument addBinaryResource(Txn transaction, DBBroker broker, XmldbURI name, byte[] data, String mimeType,
+ BinaryDocument addBinaryResource(Txn transaction, DBBroker broker, XmldbURI name, byte[] data, String mediaType,
Date created, Date modified) throws EXistException, PermissionDeniedException, LockException,
TriggerException, IOException;
@@ -1090,7 +1227,7 @@ BinaryDocument addBinaryResource(Txn transaction, DBBroker broker, XmldbURI name
* @param broker The database broker
* @param name the name (without path) of the document
* @param is The content for the document
- * @param mimeType The Internet Media Type of the document
+ * @param mediaType The Internet Media Type of the document
* @param size The size in bytes of the document (unused - size is calculated during storage)
*
* @return The stored Binary Document object
@@ -1098,14 +1235,14 @@ BinaryDocument addBinaryResource(Txn transaction, DBBroker broker, XmldbURI name
* @throws PermissionDeniedException if user has not sufficient rights
* @throws LockException if broker is locked
* @throws IOException in case of I/O errors
- * @throws TriggerException in case of eXist-db trigger error
- * @throws EXistException general eXist-db exception
+ * @throws TriggerException in case of trigger error
+ * @throws EXistException general exception
*
* @deprecated Use {@link DBBroker#storeDocument(Txn, XmldbURI, InputSource, MimeType, Date, Date, Permission, DocumentType, XMLReader, Collection)} instead.
*/
@Deprecated
BinaryDocument addBinaryResource(Txn transaction, DBBroker broker, XmldbURI name, InputStream is,
- String mimeType, @Deprecated long size) throws EXistException, PermissionDeniedException, LockException,
+ String mediaType, @Deprecated long size) throws EXistException, PermissionDeniedException, LockException,
TriggerException, IOException;
/**
@@ -1120,7 +1257,7 @@ BinaryDocument addBinaryResource(Txn transaction, DBBroker broker, XmldbURI name
* @param broker The database broker
* @param blob the binary resource to store the data into
* @param is The content for the document
- * @param mimeType The Internet Media Type of the document
+ * @param mediaType The Internet Media Type of the document
* @param size The size in bytes of the document (unused - size is calculated during storage)
* @param created The created timestamp of the document
* @param modified The modified timestamp of the document
@@ -1130,14 +1267,14 @@ BinaryDocument addBinaryResource(Txn transaction, DBBroker broker, XmldbURI name
* @throws PermissionDeniedException if user has not sufficient rights
* @throws LockException if broker is locked
* @throws IOException in case of I/O errors
- * @throws TriggerException in case of eXist-db trigger error
- * @throws EXistException general eXist-db exception
+ * @throws TriggerException in case of trigger error
+ * @throws EXistException general exception
*
- * @deprecated Use {@link DBBroker#storeDocument(Txn, XmldbURI, InputSource, MimeType, Date, Date, Permission, DocumentType, XMLReader, Collection)} instead.
+ * @deprecated Use {@link DBBroker#storeDocument(Txn, XmldbURI, InputSource, MediaType, Date, Date, Permission, DocumentType, XMLReader, Collection)} instead.
*/
@Deprecated
BinaryDocument addBinaryResource(Txn transaction, DBBroker broker, BinaryDocument blob, InputStream is,
- String mimeType, @Deprecated long size, Date created, Date modified) throws EXistException, PermissionDeniedException,
+ String mediaType, @Deprecated long size, Date created, Date modified) throws EXistException, PermissionDeniedException,
LockException, TriggerException, IOException;
/**
@@ -1152,7 +1289,7 @@ BinaryDocument addBinaryResource(Txn transaction, DBBroker broker, BinaryDocumen
* @param broker The database broker
* @param blob the binary resource to store the data into
* @param is The content for the document
- * @param mimeType The Internet Media Type of the document
+ * @param mediaType The Internet Media Type of the document
* @param size The size in bytes of the document (unused - size is calculated during storage)
* @param created The created timestamp of the document
* @param modified The modified timestamp of the document
@@ -1165,14 +1302,14 @@ BinaryDocument addBinaryResource(Txn transaction, DBBroker broker, BinaryDocumen
* @throws PermissionDeniedException if user has not sufficient rights
* @throws LockException if broker is locked
* @throws IOException in case of I/O errors
- * @throws TriggerException in case of eXist-db trigger error
- * @throws EXistException general eXist-db exception
+ * @throws TriggerException in case of trigger error
+ * @throws EXistException general exception
*
- * @deprecated Use {@link DBBroker#storeDocument(Txn, XmldbURI, InputSource, MimeType, Date, Date, Permission, DocumentType, XMLReader, Collection)} instead.
+ * @deprecated Use {@link DBBroker#storeDocument(Txn, XmldbURI, InputSource, MediaType, Date, Date, Permission, DocumentType, XMLReader, Collection)} instead.
*/
@Deprecated
BinaryDocument addBinaryResource(Txn transaction, DBBroker broker, BinaryDocument blob, InputStream is,
- String mimeType, @Deprecated long size, Date created, Date modified, DBBroker.PreserveType preserve)
+ String mediaType, @Deprecated long size, Date created, Date modified, DBBroker.PreserveType preserve)
throws EXistException, PermissionDeniedException, LockException, TriggerException, IOException;
/**
@@ -1183,7 +1320,7 @@ BinaryDocument addBinaryResource(Txn transaction, DBBroker broker, BinaryDocumen
* @throws IOException in case of I/O errors
*/
- @EnsureContainerLocked(mode=READ_LOCK) void serialize(final VariableByteOutputStream outputStream) throws IOException, LockException;
+ @EnsureContainerLocked(mode=READ_LOCK) void serialize(final VariableByteOutput outputStream) throws IOException, LockException;
@Override void close();
diff --git a/exist-core/src/main/java/org/exist/collections/CollectionConfiguration.java b/exist-core/src/main/java/org/exist/collections/CollectionConfiguration.java
index 1da819c20e..0ae78e2016 100644
--- a/exist-core/src/main/java/org/exist/collections/CollectionConfiguration.java
+++ b/exist-core/src/main/java/org/exist/collections/CollectionConfiguration.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -160,7 +184,7 @@ protected void read(final DBBroker broker, final Document doc, final boolean che
} else if (VALIDATION_ELEMENT.equals(node.getLocalName())) {
final Element elem = (Element) node;
final String mode = elem.getAttribute(VALIDATION_MODE_ATTR);
- if (mode == null) {
+ if (mode.isEmpty()) {
LOG.debug("Unable to determine validation mode in {}", srcCollectionURI);
validationMode = XMLReaderObjectFactory.VALIDATION_SETTING.UNKNOWN;
} else {
diff --git a/exist-core/src/main/java/org/exist/collections/CollectionConfigurationManager.java b/exist-core/src/main/java/org/exist/collections/CollectionConfigurationManager.java
index 824fbb5967..c6de4bf4b0 100644
--- a/exist-core/src/main/java/org/exist/collections/CollectionConfigurationManager.java
+++ b/exist-core/src/main/java/org/exist/collections/CollectionConfigurationManager.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -36,7 +60,6 @@
import org.exist.storage.txn.TransactionManager;
import org.exist.storage.txn.Txn;
import org.exist.util.LockException;
-import org.exist.util.MimeType;
import org.exist.util.StringInputSource;
import org.exist.util.XMLReaderPool;
import org.exist.util.sanity.SanityCheck;
@@ -45,6 +68,7 @@
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
+import xyz.elemental.mediatype.MediaType;
import java.io.IOException;
import java.io.StringReader;
@@ -102,7 +126,7 @@ public void startSystem(final DBBroker systemBroker, final Txn transaction) thro
*
* @param txn The transaction that will hold the WRITE locks until they are
* released by commit()/abort()
- * @param broker the eXist-db broker
+ * @param broker the broker
* @param collection the collection to which the configuration applies.
* @param config the xconf document as a String.
* @throws CollectionConfigurationException if config is invalid
@@ -131,7 +155,8 @@ public void addConfiguration(final Txn txn, final DBBroker broker, final Collect
broker.saveCollection(txn, confCol);
- broker.storeDocument(txn, configurationDocumentName, new StringInputSource(config), MimeType.XML_TYPE, confCol);
+ final MediaType xmlMediaType = broker.getBrokerPool().getMediaTypeService().getMediaTypeResolver().fromString(MediaType.APPLICATION_XML);
+ broker.storeDocument(txn, configurationDocumentName, new StringInputSource(config), xmlMediaType, confCol);
// broker.sync(Sync.MAJOR_SYNC);
} catch (final CollectionConfigurationException e) {
@@ -366,7 +391,7 @@ public void invalidate(final XmldbURI collectionPath, final BrokerPool pool) {
* Check if the collection exists below the system collection. If not,
* create it.
*
- * @param broker eXist-db broker
+ * @param broker the broker
* @param txn according transaction
* @param uri to the collection to create
* @throws EXistException if something goes wrong
diff --git a/exist-core/src/main/java/org/exist/collections/LockedCollection.java b/exist-core/src/main/java/org/exist/collections/LockedCollection.java
index 10138374e3..6ab9bf34ce 100644
--- a/exist-core/src/main/java/org/exist/collections/LockedCollection.java
+++ b/exist-core/src/main/java/org/exist/collections/LockedCollection.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -29,7 +53,7 @@
import org.exist.security.PermissionDeniedException;
import org.exist.security.Subject;
import org.exist.storage.*;
-import org.exist.storage.io.VariableByteOutputStream;
+import org.exist.storage.io.VariableByteOutput;
import org.exist.storage.lock.Lock;
import org.exist.storage.lock.LockedDocumentMap;
import org.exist.storage.lock.ManagedCollectionLock;
@@ -42,6 +66,7 @@
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
+import xyz.elemental.mediatype.MediaType;
import javax.annotation.Nullable;
import java.io.IOException;
@@ -362,21 +387,41 @@ public void storeDocument(final Txn transaction, final DBBroker broker, final Xm
broker.storeDocument(transaction, name, source, mimeType, collection);
}
+ @Override
+ public void storeDocument(final Txn transaction, final DBBroker broker, final XmldbURI name, final InputSource source, @Nullable final MediaType mediaType) throws EXistException, PermissionDeniedException, TriggerException, SAXException, LockException, IOException {
+ broker.storeDocument(transaction, name, source, mediaType, collection);
+ }
+
@Override
public void storeDocument(final Txn transaction, final DBBroker broker, final XmldbURI name, final InputSource source, @Nullable final MimeType mimeType, @Nullable final Date createdDate, @Nullable final Date lastModifiedDate, @Nullable final Permission permission, @Nullable final DocumentType documentType, @Nullable final XMLReader xmlReader) throws EXistException, PermissionDeniedException, TriggerException, SAXException, LockException, IOException {
collection.storeDocument(transaction, broker, name, source, mimeType, createdDate, lastModifiedDate, permission, documentType, xmlReader);
}
+ @Override
+ public void storeDocument(final Txn transaction, final DBBroker broker, final XmldbURI name, final InputSource source, @Nullable final MediaType mediaType, @Nullable final Date createdDate, @Nullable final Date lastModifiedDate, @Nullable final Permission permission, @Nullable final DocumentType documentType, @Nullable final XMLReader xmlReader) throws EXistException, PermissionDeniedException, TriggerException, SAXException, LockException, IOException {
+ collection.storeDocument(transaction, broker, name, source, mediaType, createdDate, lastModifiedDate, permission, documentType, xmlReader);
+ }
+
@Override
public void storeDocument(final Txn transaction, final DBBroker broker, final XmldbURI name, final Node node, @Nullable final MimeType mimeType) throws EXistException, PermissionDeniedException, TriggerException, SAXException, LockException, IOException {
broker.storeDocument(transaction, name, node, mimeType, collection);
}
+ @Override
+ public void storeDocument(final Txn transaction, final DBBroker broker, final XmldbURI name, final Node node, @Nullable final MediaType mediaType) throws EXistException, PermissionDeniedException, TriggerException, SAXException, LockException, IOException {
+ broker.storeDocument(transaction, name, node, mediaType, collection);
+ }
+
@Override
public void storeDocument(final Txn transaction, final DBBroker broker, final XmldbURI name, final Node node, @Nullable final MimeType mimeType, @Nullable final Date createdDate, @Nullable final Date lastModifiedDate, @Nullable final Permission permission, @Nullable final DocumentType documentType, @Nullable final XMLReader xmlReader) throws EXistException, PermissionDeniedException, TriggerException, SAXException, LockException, IOException {
collection.storeDocument(transaction, broker, name, node, mimeType, createdDate, lastModifiedDate, permission, documentType, xmlReader);
}
+ @Override
+ public void storeDocument(final Txn transaction, final DBBroker broker, final XmldbURI name, final Node node, @Nullable final MediaType mediaType, @Nullable final Date createdDate, @Nullable final Date lastModifiedDate, @Nullable final Permission permission, @Nullable final DocumentType documentType, @Nullable final XMLReader xmlReader) throws EXistException, PermissionDeniedException, TriggerException, SAXException, LockException, IOException {
+ collection.storeDocument(transaction, broker, name, node, mediaType, createdDate, lastModifiedDate, permission, documentType, xmlReader);
+ }
+
@Deprecated
@Override
public IndexInfo validateXMLResource(final Txn transaction, final DBBroker broker, final XmldbURI name, final InputSource source) throws EXistException, PermissionDeniedException, TriggerException, SAXException, LockException, IOException {
@@ -473,7 +518,7 @@ public BinaryDocument addBinaryResource(final Txn transaction, final DBBroker br
}
@Override
- public void serialize(final VariableByteOutputStream outputStream) throws IOException, LockException {
+ public void serialize(final VariableByteOutput outputStream) throws IOException, LockException {
collection.serialize(outputStream);
}
diff --git a/exist-core/src/main/java/org/exist/collections/MutableCollection.java b/exist-core/src/main/java/org/exist/collections/MutableCollection.java
index c8bbd757f5..03eb981dc0 100644
--- a/exist-core/src/main/java/org/exist/collections/MutableCollection.java
+++ b/exist-core/src/main/java/org/exist/collections/MutableCollection.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -48,7 +72,7 @@
import org.exist.security.Subject;
import org.exist.storage.*;
import org.exist.storage.io.VariableByteInput;
-import org.exist.storage.io.VariableByteOutputStream;
+import org.exist.storage.io.VariableByteOutput;
import org.exist.storage.lock.*;
import org.exist.storage.lock.Lock.LockMode;
import org.exist.storage.lock.Lock.LockType;
@@ -68,6 +92,8 @@
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
+import xyz.elemental.mediatype.MediaType;
+import xyz.elemental.mediatype.StorageType;
import javax.annotation.Nullable;
@@ -171,7 +197,7 @@ private MutableCollection(final DBBroker broker, final int collectionId,
/**
* Deserializes a Collection object
*
- * Counterpart method to {@link #serialize(VariableByteOutputStream)}
+ * Counterpart method to {@link #serialize(VariableByteOutput)}
*
* @param broker The database broker
* @param path The path of the Collection
@@ -860,7 +886,7 @@ public Iterator iteratorNoLock(final DBBroker broker) throws Permi
* @param outputStream The output stream to write the collection contents to
*/
@Override
- public void serialize(final VariableByteOutputStream outputStream) throws IOException, LockException {
+ public void serialize(final VariableByteOutput outputStream) throws IOException, LockException {
outputStream.writeInt(collectionId);
final int size;
@@ -890,7 +916,7 @@ public void close() {
/**
* Read collection contents from the stream
*
- * Counterpart method to {@link #serialize(VariableByteOutputStream)}
+ * Counterpart method to {@link #serialize(VariableByteOutput)}
*
* @param broker The database broker
* @param path The path of the Collection
@@ -1100,17 +1126,27 @@ public void removeBinaryResource(final Txn transaction, final DBBroker broker, f
}
@Override
- public void storeDocument(final Txn transaction, final DBBroker broker, final XmldbURI name, final InputSource source, @Nullable MimeType mimeType) throws EXistException, PermissionDeniedException, SAXException, LockException, IOException {
+ public void storeDocument(final Txn transaction, final DBBroker broker, final XmldbURI name, final InputSource source, @Nullable final MimeType mimeType) throws EXistException, PermissionDeniedException, SAXException, LockException, IOException {
storeDocument(transaction, broker, name, source, mimeType, null, null, null, null, null);
}
@Override
- public void storeDocument(final Txn transaction, final DBBroker broker, final XmldbURI name, final InputSource source, @Nullable MimeType mimeType, final @Nullable Date createdDate, final @Nullable Date lastModifiedDate, final @Nullable Permission permission, final @Nullable DocumentType documentType, @Nullable final XMLReader xmlReader) throws EXistException, PermissionDeniedException, SAXException, LockException, IOException {
- if (mimeType == null) {
- mimeType = MimeType.BINARY_TYPE;
+ public void storeDocument(final Txn transaction, final DBBroker broker, final XmldbURI name, final InputSource source, @Nullable final MediaType mediaType) throws EXistException, PermissionDeniedException, SAXException, LockException, IOException {
+ storeDocument(transaction, broker, name, source, mediaType, null, null, null, null, null);
+ }
+
+ @Override
+ public void storeDocument(final Txn transaction, final DBBroker broker, final XmldbURI name, final InputSource source, @Nullable final MimeType mimeType, final @Nullable Date createdDate, final @Nullable Date lastModifiedDate, final @Nullable Permission permission, final @Nullable DocumentType documentType, @Nullable final XMLReader xmlReader) throws EXistException, PermissionDeniedException, SAXException, LockException, IOException {
+ storeDocument(transaction, broker, name, source, mimeType.toMediaType(), createdDate, lastModifiedDate, permission, documentType, xmlReader);
+ }
+
+ @Override
+ public void storeDocument(final Txn transaction, final DBBroker broker, final XmldbURI name, final InputSource source, @Nullable MediaType mediaType, final @Nullable Date createdDate, final @Nullable Date lastModifiedDate, final @Nullable Permission permission, final @Nullable DocumentType documentType, @Nullable final XMLReader xmlReader) throws EXistException, PermissionDeniedException, SAXException, LockException, IOException {
+ if (mediaType == null) {
+ mediaType = broker.getBrokerPool().getMediaTypeService().getMediaTypeResolver().forUnknown();
}
- if (mimeType.isXMLType()) {
+ if (mediaType.getStorageType() == StorageType.XML) {
// Store XML Document
final BiConsumer2E validatorFn = (xmlReader1, validateIndexInfo) -> {
@@ -1133,7 +1169,7 @@ public void storeDocument(final Txn transaction, final DBBroker broker, final Xm
}
};
- storeXmlDocument(transaction, broker, name, mimeType, createdDate, lastModifiedDate, permission, documentType, xmlReader, validatorFn, parserFn);
+ storeXmlDocument(transaction, broker, name, mediaType, createdDate, lastModifiedDate, permission, documentType, xmlReader, validatorFn, parserFn);
} else {
// Store Binary Document
@@ -1141,23 +1177,33 @@ public void storeDocument(final Txn transaction, final DBBroker broker, final Xm
if (is == null) {
throw new IOException("storeDocument received a null InputStream when trying to store a Binary Document");
}
- addBinaryResource(transaction, broker, name, is, mimeType.getName(), -1, createdDate, lastModifiedDate, permission);
+ addBinaryResource(transaction, broker, name, is, mediaType.getIdentifier(), -1, createdDate, lastModifiedDate, permission);
}
}
}
@Override
- public void storeDocument(final Txn transaction, final DBBroker broker, final XmldbURI name, final Node node, @Nullable MimeType mimeType) throws EXistException, PermissionDeniedException, SAXException, LockException, IOException {
- storeDocument(transaction, broker, name, node, mimeType);
+ public void storeDocument(final Txn transaction, final DBBroker broker, final XmldbURI name, final Node node, @Nullable final MimeType mimeType) throws EXistException, PermissionDeniedException, SAXException, LockException, IOException {
+ storeDocument(transaction, broker, name, node, mimeType, null, null, null, null, null);
+ }
+
+ @Override
+ public void storeDocument(final Txn transaction, final DBBroker broker, final XmldbURI name, final Node node, @Nullable final MediaType mediaType) throws EXistException, PermissionDeniedException, SAXException, LockException, IOException {
+ storeDocument(transaction, broker, name, node, mediaType, null, null, null, null, null);
+ }
+
+ @Override
+ public void storeDocument(final Txn transaction, final DBBroker broker, final XmldbURI name, final Node node, @Nullable final MimeType mimeType, final @Nullable Date createdDate, final @Nullable Date lastModifiedDate, final @Nullable Permission permission, final @Nullable DocumentType documentType, @Nullable final XMLReader xmlReader) throws EXistException, PermissionDeniedException, SAXException, LockException, IOException {
+ storeDocument(transaction, broker, name, node, mimeType.toMediaType(), createdDate, lastModifiedDate, permission, documentType, xmlReader);
}
@Override
- public void storeDocument(final Txn transaction, final DBBroker broker, final XmldbURI name, final Node node, @Nullable MimeType mimeType, final @Nullable Date createdDate, final @Nullable Date lastModifiedDate, final @Nullable Permission permission, final @Nullable DocumentType documentType, @Nullable final XMLReader xmlReader) throws EXistException, PermissionDeniedException, SAXException, LockException, IOException {
- if (mimeType == null) {
- mimeType = MimeType.BINARY_TYPE;
+ public void storeDocument(final Txn transaction, final DBBroker broker, final XmldbURI name, final Node node, @Nullable MediaType mediaType, final @Nullable Date createdDate, final @Nullable Date lastModifiedDate, final @Nullable Permission permission, final @Nullable DocumentType documentType, @Nullable final XMLReader xmlReader) throws EXistException, PermissionDeniedException, SAXException, LockException, IOException {
+ if (mediaType == null) {
+ mediaType = broker.getBrokerPool().getMediaTypeService().getMediaTypeResolver().forUnknown();
}
- if (mimeType.isXMLType()) {
+ if (mediaType.getStorageType() == StorageType.XML) {
// Store XML Document
final BiConsumer2E validatorFn = (xmlReader1, validateIndexInfo) -> {
validateIndexInfo.setReader(xmlReader1, null);
@@ -1170,14 +1216,14 @@ public void storeDocument(final Txn transaction, final DBBroker broker, final Xm
storeIndexInfo.getDOMStreamer().serialize(node, true);
};
- storeXmlDocument(transaction, broker, name, mimeType, createdDate, lastModifiedDate, permission, documentType, xmlReader, validatorFn, parserFn);
+ storeXmlDocument(transaction, broker, name, mediaType, createdDate, lastModifiedDate, permission, documentType, xmlReader, validatorFn, parserFn);
} else {
throw new EXistException("Cannot store DOM Node as a Binary Document to URI: " + getURI().append(name));
}
}
- private void storeXmlDocument(final Txn transaction, final DBBroker broker, final XmldbURI name, final MimeType mimeType, final @Nullable Date createdDate, final @Nullable Date lastModifiedDate, final @Nullable Permission permission, final @Nullable DocumentType documentType, @Nullable final XMLReader xmlReader, final BiConsumer2E validatorFn, final BiConsumer2E parserFn) throws EXistException, PermissionDeniedException, SAXException, LockException, IOException {
+ private void storeXmlDocument(final Txn transaction, final DBBroker broker, final XmldbURI name, final MediaType mediaType, final @Nullable Date createdDate, final @Nullable Date lastModifiedDate, final @Nullable Permission permission, final @Nullable DocumentType documentType, @Nullable final XMLReader xmlReader, final BiConsumer2E validatorFn, final BiConsumer2E parserFn) throws EXistException, PermissionDeniedException, SAXException, LockException, IOException {
final CollectionConfiguration colconf = getConfiguration(broker);
// borrow a default XML Reader if needed
@@ -1196,7 +1242,7 @@ private void storeXmlDocument(final Txn transaction, final DBBroker broker, fina
// Phase 2 of 3 - Set the metadata for the document
final DocumentImpl document = indexInfo.getDocument();
- document.setMimeType(mimeType.getName());
+ document.setMediaType(mediaType.getIdentifier());
if (createdDate != null) {
document.setCreated(createdDate.getTime());
if (lastModifiedDate == null) {
@@ -1808,7 +1854,7 @@ public BinaryDocument addBinaryResource(final Txn transaction, final DBBroker br
}
private BinaryDocument addBinaryResource(final Database db, final Txn transaction, final DBBroker broker,
- final BinaryDocument blob, final InputStream is, final String mimeType, @Deprecated final long size, final Date created,
+ final BinaryDocument blob, final InputStream is, final String mediaType, @Deprecated final long size, final Date created,
final Date modified, @Nullable final Permission permission, final DBBroker.PreserveType preserve, final DocumentImpl oldDoc,
final ManagedCollectionLock collectionLock) throws EXistException, PermissionDeniedException, LockException, TriggerException, IOException {
@@ -1822,7 +1868,7 @@ private BinaryDocument addBinaryResource(final Database db, final Txn transactio
if (!broker.preserveOnCopy(preserve)) {
blob.copyOf(broker, blob, oldDoc);
}
- blob.setMimeType(mimeType == null ? MimeType.BINARY_TYPE.getName() : mimeType);
+ blob.setMediaType(mediaType != null ? mediaType : MediaType.APPLICATION_OCTET_STREAM);
if (created != null) {
blob.setCreated(created.getTime());
}
diff --git a/exist-core/src/main/java/org/exist/collections/triggers/CollectionTrigger.java b/exist-core/src/main/java/org/exist/collections/triggers/CollectionTrigger.java
index 97b6384a69..d8ee5d4160 100644
--- a/exist-core/src/main/java/org/exist/collections/triggers/CollectionTrigger.java
+++ b/exist-core/src/main/java/org/exist/collections/triggers/CollectionTrigger.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -37,7 +61,7 @@ public interface CollectionTrigger extends Trigger {
* This method is called once before the database will actually create, remove or rename a collection. You may
* take any action here, using the supplied broker instance.
*
- * @param broker eXist-db broker
+ * @param broker the broker
* @param txn the transaction
* @param uri of the collection the trigger listens on
* @throws TriggerException if an error in the trigger function is thrown
@@ -47,7 +71,7 @@ public interface CollectionTrigger extends Trigger {
/**
* This method is called after the operation has completed.
*
- * @param broker eXist-db broker
+ * @param broker the broker
* @param txn the transaction
* @param collection the trigger listens on
* @throws TriggerException if an error in the trigger function is thrown
diff --git a/exist-core/src/main/java/org/exist/collections/triggers/CollectionTriggers.java b/exist-core/src/main/java/org/exist/collections/triggers/CollectionTriggers.java
index 412b0e08aa..94ec596c30 100644
--- a/exist-core/src/main/java/org/exist/collections/triggers/CollectionTriggers.java
+++ b/exist-core/src/main/java/org/exist/collections/triggers/CollectionTriggers.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -39,119 +63,146 @@ public class CollectionTriggers implements CollectionTrigger {
private final List triggers;
- public CollectionTriggers(DBBroker broker, Txn transaction) throws TriggerException {
+ public CollectionTriggers(final DBBroker broker, final Txn transaction) throws TriggerException {
this(broker, transaction, null, null);
}
- public CollectionTriggers(DBBroker broker, Txn transaction, Collection collection) throws TriggerException {
+ public CollectionTriggers(final DBBroker broker, final Txn transaction, final Collection collection) throws TriggerException {
this(broker, transaction, collection, collection.getConfiguration(broker));
}
- public CollectionTriggers(DBBroker broker, Txn transaction, Collection collection, CollectionConfiguration config) throws TriggerException {
-
- List> colTriggers = null;
- if (config != null) {
- colTriggers = config.collectionTriggers();
- }
-
- java.util.Collection> masterTriggers = broker.getDatabase().getCollectionTriggers();
+ public CollectionTriggers(final DBBroker broker, final Txn transaction, final Collection collection, final CollectionConfiguration config) throws TriggerException {
+ final List> colTriggers = config != null ? config.collectionTriggers() : null;
+ final java.util.Collection> masterTriggers = broker.getDatabase().getCollectionTriggers();
triggers = new ArrayList<>(masterTriggers.size() + (colTriggers == null ? 0 : colTriggers.size()));
- for (TriggerProxy extends CollectionTrigger> colTrigger : masterTriggers) {
-
- CollectionTrigger instance = colTrigger.newInstance(broker, transaction, collection);
-
+ for (final TriggerProxy extends CollectionTrigger> colTrigger : masterTriggers) {
+ final CollectionTrigger instance = colTrigger.newInstance(broker, transaction, collection);
register(instance);
}
if (colTriggers != null) {
- for (TriggerProxy extends CollectionTrigger> colTrigger : colTriggers) {
-
- CollectionTrigger instance = colTrigger.newInstance(broker, transaction, collection);
-
+ for (final TriggerProxy extends CollectionTrigger> colTrigger : colTriggers) {
+ final CollectionTrigger instance = colTrigger.newInstance(broker, transaction, collection);
register(instance);
}
}
}
- private void register(CollectionTrigger trigger) {
+ private void register(final CollectionTrigger trigger) {
triggers.add(trigger);
}
@Override
- public void configure(DBBroker broker, Txn transaction, Collection col, Map> parameters) throws TriggerException {
+ public void configure(final DBBroker broker, final Txn transaction, final Collection col, final Map> parameters) throws TriggerException {
}
@Override
- public void beforeCreateCollection(DBBroker broker, Txn txn, XmldbURI uri) throws TriggerException {
- for (CollectionTrigger trigger : triggers) {
- trigger.beforeCreateCollection(broker, txn, uri);
+ public void beforeCreateCollection(final DBBroker broker, final Txn txn, final XmldbURI uri) throws TriggerException {
+ for (final CollectionTrigger trigger : triggers) {
+ try {
+ trigger.beforeCreateCollection(broker, txn, uri);
+ } catch (final Exception e) {
+ logAndThrowError("beforeCreateCollection", trigger, uri, e);
+ }
}
}
@Override
- public void afterCreateCollection(DBBroker broker, Txn txn, Collection collection) {
- for (CollectionTrigger trigger : triggers) {
+ public void afterCreateCollection(final DBBroker broker, final Txn txn, final Collection collection) {
+ for (final CollectionTrigger trigger : triggers) {
try {
trigger.afterCreateCollection(broker, txn, collection);
- } catch (Exception e) {
- Trigger.LOG.error(e.getMessage(), e);
+ } catch (final Exception e) {
+ logError("afterCreateCollection", trigger, collection.getURI(), e);
}
}
}
@Override
- public void beforeCopyCollection(DBBroker broker, Txn txn, Collection collection, XmldbURI newUri) throws TriggerException {
- for (CollectionTrigger trigger : triggers) {
- trigger.beforeCopyCollection(broker, txn, collection, newUri);
+ public void beforeCopyCollection(final DBBroker broker, final Txn txn, final Collection collection, final XmldbURI newUri) throws TriggerException {
+ for (final CollectionTrigger trigger : triggers) {
+ try {
+ trigger.beforeCopyCollection(broker, txn, collection, newUri);
+ } catch (final Exception e) {
+ logAndThrowError("beforeCopyCollection", trigger, collection.getURI(), e);
+ }
}
}
@Override
- public void afterCopyCollection(DBBroker broker, Txn txn, Collection collection, XmldbURI oldUri) {
- for (CollectionTrigger trigger : triggers) {
+ public void afterCopyCollection(final DBBroker broker, final Txn txn, final Collection collection, final XmldbURI oldUri) {
+ for (final CollectionTrigger trigger : triggers) {
try {
trigger.afterCopyCollection(broker, txn, collection, oldUri);
- } catch (Exception e) {
- Trigger.LOG.error(e.getMessage(), e);
+ } catch (final Exception e) {
+ logError("afterCopyCollection", trigger, oldUri, e);
}
}
}
@Override
- public void beforeMoveCollection(DBBroker broker, Txn txn, Collection collection, XmldbURI newUri) throws TriggerException {
- for (CollectionTrigger trigger : triggers) {
- trigger.beforeMoveCollection(broker, txn, collection, newUri);
+ public void beforeMoveCollection(final DBBroker broker, final Txn txn, final Collection collection, final XmldbURI newUri) throws TriggerException {
+ for (final CollectionTrigger trigger : triggers) {
+ try {
+ trigger.beforeMoveCollection(broker, txn, collection, newUri);
+ } catch (final Exception e) {
+ logAndThrowError("beforeMoveCollection", trigger, collection.getURI(), e);
+ }
}
}
@Override
- public void afterMoveCollection(DBBroker broker, Txn txn, Collection collection, XmldbURI oldUri) {
- for (CollectionTrigger trigger : triggers) {
+ public void afterMoveCollection(final DBBroker broker, final Txn txn, final Collection collection, final XmldbURI oldUri) {
+ for (final CollectionTrigger trigger : triggers) {
try {
trigger.afterMoveCollection(broker, txn, collection, oldUri);
- } catch (Exception e) {
- Trigger.LOG.error(e.getMessage(), e);
+ } catch (final Exception e) {
+ logError("afterMoveCollection", trigger, oldUri, e);
}
}
}
@Override
- public void beforeDeleteCollection(DBBroker broker, Txn txn, Collection collection) throws TriggerException {
- for (CollectionTrigger trigger : triggers) {
- trigger.beforeDeleteCollection(broker, txn, collection);
+ public void beforeDeleteCollection(final DBBroker broker, final Txn txn, final Collection collection) throws TriggerException {
+ for (final CollectionTrigger trigger : triggers) {
+ try {
+ trigger.beforeDeleteCollection(broker, txn, collection);
+ } catch (final Exception e) {
+ logAndThrowError("beforeDeleteCollection", trigger, collection.getURI(), e);
+ }
}
}
@Override
- public void afterDeleteCollection(DBBroker broker, Txn txn, XmldbURI uri) {
- for (CollectionTrigger trigger : triggers) {
+ public void afterDeleteCollection(final DBBroker broker, final Txn txn, final XmldbURI uri) {
+ for (final CollectionTrigger trigger : triggers) {
try {
trigger.afterDeleteCollection(broker, txn, uri);
- } catch (Exception e) {
- Trigger.LOG.error(e.getMessage(), e);
+ } catch (final Exception e) {
+ logError("afterDeleteCollection", trigger, uri, e);
}
}
}
+
+ private void logAndThrowError(final String eventName, final CollectionTrigger collectionTrigger, final XmldbURI source, final Exception e) throws TriggerException {
+ logError(eventName, collectionTrigger, source, e);
+ throwError(e);
+ }
+
+ private void logError(final String eventName, final CollectionTrigger collectionTrigger, final XmldbURI source, final Exception e) {
+ final String message = String.format("Error in %s#%s triggered by: %s, %s", collectionTrigger.getClass().getSimpleName(), eventName, source, e.getMessage());
+ Trigger.LOG.error(message, e);
+ }
+
+ private void throwError(final Exception e) throws TriggerException {
+ if (e instanceof TriggerException) {
+ throw (TriggerException) e;
+ } else if (e instanceof RuntimeException) {
+ throw (RuntimeException) e;
+ } else {
+ throw new TriggerException(e);
+ }
+ }
}
diff --git a/exist-core/src/main/java/org/exist/collections/triggers/DocumentTrigger.java b/exist-core/src/main/java/org/exist/collections/triggers/DocumentTrigger.java
index 5177163ebf..3c4d4ca669 100644
--- a/exist-core/src/main/java/org/exist/collections/triggers/DocumentTrigger.java
+++ b/exist-core/src/main/java/org/exist/collections/triggers/DocumentTrigger.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -79,7 +103,7 @@ public interface DocumentTrigger extends Trigger {
* This method is called once before the database will actually parse the input data. You may take any action
* here, using the supplied broker instance.
*
- * @param broker eXist-db DBBroker
+ * @param broker the DBBroker
* @param txn transaction
* @param uri the uri
* @throws TriggerException in case of an error
@@ -90,7 +114,7 @@ public interface DocumentTrigger extends Trigger {
* This method is called after the operation completed. At this point, the document has already
* been stored.
*
- * @param broker eXist-db DBBroker
+ * @param broker the DBBroker
* @param txn transaction
* @param document stored document
* @throws TriggerException in case of an error
diff --git a/exist-core/src/main/java/org/exist/collections/triggers/DocumentTriggers.java b/exist-core/src/main/java/org/exist/collections/triggers/DocumentTriggers.java
index 6a9e3a9a77..c3da578b0c 100644
--- a/exist-core/src/main/java/org/exist/collections/triggers/DocumentTriggers.java
+++ b/exist-core/src/main/java/org/exist/collections/triggers/DocumentTriggers.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -58,37 +82,28 @@ public class DocumentTriggers implements DocumentTrigger, ContentHandler, Lexica
private final List triggers;
- public DocumentTriggers(DBBroker broker, Txn transaction) throws TriggerException {
+ public DocumentTriggers(final DBBroker broker, final Txn transaction) throws TriggerException {
this(broker, transaction, null, null, null);
}
- public DocumentTriggers(DBBroker broker, Txn transaction, Collection collection) throws TriggerException {
+ public DocumentTriggers(final DBBroker broker, final Txn transaction, final Collection collection) throws TriggerException {
this(broker, transaction, null, collection, broker.isTriggersEnabled() ? collection.getConfiguration(broker) : null);
}
- public DocumentTriggers(DBBroker broker, Txn transaction, Indexer indexer, Collection collection, CollectionConfiguration config) throws TriggerException {
-
- List> docTriggers = null;
- if (config != null) {
- docTriggers = config.documentTriggers();
- }
-
- java.util.Collection> masterTriggers = broker.getDatabase().getDocumentTriggers();
+ public DocumentTriggers(final DBBroker broker, final Txn transaction, final Indexer indexer, final Collection collection, final CollectionConfiguration config) throws TriggerException {
+ final List> docTriggers = config != null ? config.documentTriggers() : null;
+ final java.util.Collection> masterTriggers = broker.getDatabase().getDocumentTriggers();
triggers = new ArrayList<>(masterTriggers.size() + (docTriggers == null ? 0 : docTriggers.size()));
- for (TriggerProxy extends DocumentTrigger> docTrigger : masterTriggers) {
-
- DocumentTrigger instance = docTrigger.newInstance(broker, transaction, collection);
-
+ for (final TriggerProxy extends DocumentTrigger> docTrigger : masterTriggers) {
+ final DocumentTrigger instance = docTrigger.newInstance(broker, transaction, collection);
register(instance);
}
if (docTriggers != null) {
- for (TriggerProxy extends DocumentTrigger> docTrigger : docTriggers) {
-
- DocumentTrigger instance = docTrigger.newInstance(broker, transaction, collection);
-
+ for (final TriggerProxy extends DocumentTrigger> docTrigger : docTriggers) {
+ final DocumentTrigger instance = docTrigger.newInstance(broker, transaction, collection);
register(instance);
}
}
@@ -100,7 +115,7 @@ public DocumentTriggers(DBBroker broker, Txn transaction, Indexer indexer, Colle
last = null;
}
- private void finishPreparation(Indexer indexer) {
+ private void finishPreparation(final Indexer indexer) {
if (last == null) {
contentHandler = indexer;
lexicalHandler = indexer;
@@ -112,9 +127,8 @@ private void finishPreparation(Indexer indexer) {
this.indexer = indexer;
}
- private void register(DocumentTrigger trigger) {
+ private void register(final DocumentTrigger trigger) {
if (trigger instanceof SAXTrigger filteringTrigger) {
-
if (last == null) {
contentHandler = filteringTrigger;
lexicalHandler = filteringTrigger;
@@ -131,11 +145,11 @@ private void register(DocumentTrigger trigger) {
}
@Override
- public void configure(DBBroker broker, Txn txn, Collection parent, Map> parameters) throws TriggerException {
+ public void configure(final DBBroker broker, final Txn txn, final Collection parent, final Map> parameters) throws TriggerException {
}
@Override
- public void setDocumentLocator(Locator locator) {
+ public void setDocumentLocator(final Locator locator) {
contentHandler.setDocumentLocator(locator);
}
@@ -155,12 +169,12 @@ public void endDocument() throws SAXException {
}
@Override
- public void startPrefixMapping(String prefix, String uri) throws SAXException {
+ public void startPrefixMapping(final String prefix, final String uri) throws SAXException {
contentHandler.startPrefixMapping(prefix, uri);
}
@Override
- public void endPrefixMapping(String prefix) throws SAXException {
+ public void endPrefixMapping(final String prefix) throws SAXException {
contentHandler.endPrefixMapping(prefix);
}
@@ -170,32 +184,32 @@ public void startElement(String uri, String localName, String qName, Attributes
}
@Override
- public void endElement(String uri, String localName, String qName) throws SAXException {
+ public void endElement(final String uri, final String localName, final String qName) throws SAXException {
contentHandler.endElement(uri, localName, qName);
}
@Override
- public void characters(char[] ch, int start, int length) throws SAXException {
+ public void characters(final char[] ch, final int start, final int length) throws SAXException {
contentHandler.characters(ch, start, length);
}
@Override
- public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
+ public void ignorableWhitespace(final char[] ch, final int start, final int length) throws SAXException {
contentHandler.ignorableWhitespace(ch, start, length);
}
@Override
- public void processingInstruction(String target, String data) throws SAXException {
+ public void processingInstruction(final String target, final String data) throws SAXException {
contentHandler.processingInstruction(target, data);
}
@Override
- public void skippedEntity(String name) throws SAXException {
+ public void skippedEntity(final String name) throws SAXException {
contentHandler.skippedEntity(name);
}
@Override
- public void startDTD(String name, String publicId, String systemId) throws SAXException {
+ public void startDTD(final String name, final String publicId, final String systemId) throws SAXException {
lexicalHandler.startDTD(name, publicId, systemId);
}
@@ -205,12 +219,12 @@ public void endDTD() throws SAXException {
}
@Override
- public void startEntity(String name) throws SAXException {
+ public void startEntity(final String name) throws SAXException {
lexicalHandler.startEntity(name);
}
@Override
- public void endEntity(String name) throws SAXException {
+ public void endEntity(final String name) throws SAXException {
lexicalHandler.endEntity(name);
}
@@ -225,114 +239,138 @@ public void endCDATA() throws SAXException {
}
@Override
- public void comment(char[] ch, int start, int length) throws SAXException {
+ public void comment(final char[] ch, final int start, final int length) throws SAXException {
lexicalHandler.comment(ch, start, length);
}
@Override
- public void beforeCreateDocument(DBBroker broker, Txn txn, XmldbURI uri) throws TriggerException {
- for (DocumentTrigger trigger : triggers) {
- trigger.beforeCreateDocument(broker, txn, uri);
+ public void beforeCreateDocument(final DBBroker broker, final Txn txn, final XmldbURI uri) throws TriggerException {
+ for (final DocumentTrigger trigger : triggers) {
+ try {
+ trigger.beforeCreateDocument(broker, txn, uri);
+ } catch (final Exception e) {
+ logAndThrowError("beforeCreateDocument", trigger, uri, e);
+ }
}
}
@Override
- public void afterCreateDocument(DBBroker broker, Txn txn, DocumentImpl document) {
- for (DocumentTrigger trigger : triggers) {
+ public void afterCreateDocument(final DBBroker broker, final Txn txn, final DocumentImpl document) {
+ for (final DocumentTrigger trigger : triggers) {
try {
trigger.afterCreateDocument(broker, txn, document);
- } catch (Exception e) {
- Trigger.LOG.error(e.getMessage(), e);
+ } catch (final Exception e) {
+ logError("afterCreateDocument", trigger, document.getURI(), e);
}
}
}
@Override
- public void beforeUpdateDocument(DBBroker broker, Txn txn, DocumentImpl document) throws TriggerException {
- for (DocumentTrigger trigger : triggers) {
- trigger.beforeUpdateDocument(broker, txn, document);
+ public void beforeUpdateDocument(final DBBroker broker, final Txn txn, final DocumentImpl document) throws TriggerException {
+ for (final DocumentTrigger trigger : triggers) {
+ try {
+ trigger.beforeUpdateDocument(broker, txn, document);
+ } catch (final Exception e) {
+ logAndThrowError("beforeUpdateDocument", trigger, document.getURI(), e);
+ }
}
}
@Override
- public void afterUpdateDocument(DBBroker broker, Txn txn, DocumentImpl document) {
- for (DocumentTrigger trigger : triggers) {
+ public void afterUpdateDocument(final DBBroker broker, final Txn txn, final DocumentImpl document) {
+ for (final DocumentTrigger trigger : triggers) {
try {
trigger.afterUpdateDocument(broker, txn, document);
- } catch (Exception e) {
- Trigger.LOG.error(e.getMessage(), e);
+ } catch (final Exception e) {
+ logError("afterUpdateDocument", trigger, document.getURI(), e);
}
}
}
@Override
- public void beforeUpdateDocumentMetadata(DBBroker broker, Txn txn, DocumentImpl document) throws TriggerException {
- for (DocumentTrigger trigger : triggers) {
- trigger.beforeUpdateDocumentMetadata(broker, txn, document);
+ public void beforeUpdateDocumentMetadata(final DBBroker broker, final Txn txn, final DocumentImpl document) throws TriggerException {
+ for (final DocumentTrigger trigger : triggers) {
+ try {
+ trigger.beforeUpdateDocumentMetadata(broker, txn, document);
+ } catch (final Exception e) {
+ logAndThrowError("beforeUpdateDocumentMetadata", trigger, document.getURI(), e);
+ }
}
}
@Override
- public void afterUpdateDocumentMetadata(DBBroker broker, Txn txn, DocumentImpl document) {
- for (DocumentTrigger trigger : triggers) {
+ public void afterUpdateDocumentMetadata(final DBBroker broker, final Txn txn, final DocumentImpl document) {
+ for (final DocumentTrigger trigger : triggers) {
try {
trigger.afterUpdateDocumentMetadata(broker, txn, document);
- } catch (Exception e) {
- Trigger.LOG.error(e.getMessage(), e);
+ } catch (final Exception e) {
+ logError("afterUpdateDocumentMetadata", trigger, document.getURI(), e);
}
}
}
@Override
- public void beforeCopyDocument(DBBroker broker, Txn txn, DocumentImpl document, XmldbURI newUri) throws TriggerException {
- for (DocumentTrigger trigger : triggers) {
- trigger.beforeCopyDocument(broker, txn, document, newUri);
+ public void beforeCopyDocument(final DBBroker broker, final Txn txn, final DocumentImpl document, final XmldbURI newUri) throws TriggerException {
+ for (final DocumentTrigger trigger : triggers) {
+ try {
+ trigger.beforeCopyDocument(broker, txn, document, newUri);
+ } catch (final Exception e) {
+ logAndThrowError("beforeCopyDocument", trigger, document.getURI(), e);
+ }
}
}
@Override
- public void afterCopyDocument(DBBroker broker, Txn txn, DocumentImpl document, XmldbURI oldUri) {
- for (DocumentTrigger trigger : triggers) {
+ public void afterCopyDocument(final DBBroker broker, final Txn txn, final DocumentImpl document, final XmldbURI oldUri) {
+ for (final DocumentTrigger trigger : triggers) {
try {
trigger.afterCopyDocument(broker, txn, document, oldUri);
- } catch (Exception e) {
- Trigger.LOG.error(e.getMessage(), e);
+ } catch (final Exception e) {
+ logError("afterCopyDocument", trigger, oldUri, e);
}
}
}
@Override
- public void beforeMoveDocument(DBBroker broker, Txn txn, DocumentImpl document, XmldbURI newUri) throws TriggerException {
- for (DocumentTrigger trigger : triggers) {
- trigger.beforeMoveDocument(broker, txn, document, newUri);
+ public void beforeMoveDocument(final DBBroker broker, final Txn txn, final DocumentImpl document, final XmldbURI newUri) throws TriggerException {
+ for (final DocumentTrigger trigger : triggers) {
+ try {
+ trigger.beforeMoveDocument(broker, txn, document, newUri);
+ } catch (final Exception e) {
+ logAndThrowError("beforeMoveDocument", trigger, document.getURI(), e);
+ }
}
}
@Override
- public void afterMoveDocument(DBBroker broker, Txn txn, DocumentImpl document, XmldbURI oldUri) {
- for (DocumentTrigger trigger : triggers) {
+ public void afterMoveDocument(final DBBroker broker, final Txn txn, final DocumentImpl document, final XmldbURI oldUri) {
+ for (final DocumentTrigger trigger : triggers) {
try {
trigger.afterMoveDocument(broker, txn, document, oldUri);
- } catch (Exception e) {
- Trigger.LOG.error(e.getMessage(), e);
+ } catch (final Exception e) {
+ logError("afterMoveDocument", trigger, oldUri, e);
}
}
}
@Override
- public void beforeDeleteDocument(DBBroker broker, Txn txn, DocumentImpl document) throws TriggerException {
- for (DocumentTrigger trigger : triggers) {
- trigger.beforeDeleteDocument(broker, txn, document);
+ public void beforeDeleteDocument(final DBBroker broker, final Txn txn, final DocumentImpl document) throws TriggerException {
+ for (final DocumentTrigger trigger : triggers) {
+ try {
+ trigger.beforeDeleteDocument(broker, txn, document);
+ } catch (final Exception e) {
+ logAndThrowError("beforeDeleteDocument", trigger, document.getURI(), e);
+ }
}
}
@Override
- public void afterDeleteDocument(DBBroker broker, Txn txn, XmldbURI uri) {
- for (DocumentTrigger trigger : triggers) {
+ public void afterDeleteDocument(final DBBroker broker, final Txn txn, final XmldbURI uri) {
+ for (final DocumentTrigger trigger : triggers) {
try {
trigger.afterDeleteDocument(broker, txn, uri);
- } catch (Exception e) {
- Trigger.LOG.error(e.getMessage(), e);
+ } catch (final Exception e) {
+ logError("afterDeleteDocument", trigger, uri, e);
}
}
}
@@ -343,8 +381,8 @@ public boolean isValidating() {
}
@Override
- public void setValidating(boolean validating) {
- for (DocumentTrigger trigger : triggers) {
+ public void setValidating(final boolean validating) {
+ for (final DocumentTrigger trigger : triggers) {
trigger.setValidating(validating);
}
@@ -352,20 +390,43 @@ public void setValidating(boolean validating) {
}
@Override
- public void warning(SAXParseException exception) throws SAXException {
- if (errorHandler != null)
+ public void warning(final SAXParseException exception) throws SAXException {
+ if (errorHandler != null) {
errorHandler.warning(exception);
+ }
}
@Override
- public void error(SAXParseException exception) throws SAXException {
- if (errorHandler != null)
+ public void error(final SAXParseException exception) throws SAXException {
+ if (errorHandler != null) {
errorHandler.error(exception);
+ }
}
@Override
- public void fatalError(SAXParseException exception) throws SAXException {
- if (errorHandler != null)
+ public void fatalError(final SAXParseException exception) throws SAXException {
+ if (errorHandler != null) {
errorHandler.fatalError(exception);
+ }
+ }
+
+ private void logAndThrowError(final String eventName, final DocumentTrigger documentTrigger, final XmldbURI source, final Exception e) throws TriggerException {
+ logError(eventName, documentTrigger, source, e);
+ throwError(e);
+ }
+
+ private void logError(final String eventName, final DocumentTrigger documentTrigger, final XmldbURI source, final Exception e) {
+ final String message = String.format("Error in %s#%s triggered by: %s, %s", documentTrigger.getClass().getSimpleName(), eventName, source, e.getMessage());
+ Trigger.LOG.error(message, e);
+ }
+
+ private void throwError(final Exception e) throws TriggerException {
+ if (e instanceof TriggerException) {
+ throw (TriggerException) e;
+ } else if (e instanceof RuntimeException) {
+ throw (RuntimeException) e;
+ } else {
+ throw new TriggerException(e);
+ }
}
}
diff --git a/exist-core/src/main/java/org/exist/collections/triggers/XQueryStartupTrigger.java b/exist-core/src/main/java/org/exist/collections/triggers/XQueryStartupTrigger.java
index 15e16e53d4..5c7d909028 100644
--- a/exist-core/src/main/java/org/exist/collections/triggers/XQueryStartupTrigger.java
+++ b/exist-core/src/main/java/org/exist/collections/triggers/XQueryStartupTrigger.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -23,7 +47,6 @@
import java.util.*;
-import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.exist.collections.Collection;
@@ -44,6 +67,10 @@
import org.exist.xquery.XQuery;
import org.exist.xquery.XQueryContext;
import org.exist.xquery.value.Sequence;
+import xyz.elemental.mediatype.MediaType;
+
+import static org.exist.util.StringUtil.endsWith;
+import static org.exist.util.StringUtil.substringBeforeLast;
/**
* Startup Trigger to fire XQuery scripts during database startup.
@@ -78,7 +105,7 @@ public class XQueryStartupTrigger implements StartupTrigger {
private static final String XQUERY = "xquery";
private static final String AUTOSTART_COLLECTION = "/db/system/autostart";
private static final String[] XQUERY_EXTENSIONS = {".xq", ".xquery", ".xqy"};
- private static final String REQUIRED_MIMETYPE = "application/xquery";
+ private static final String REQUIRED_MIMETYPE = MediaType.APPLICATION_XQUERY;
@Override
public void execute(DBBroker broker, final Txn transaction, Map> params) {
@@ -124,7 +151,7 @@ private List getScriptsInStartupCollection(DBBroker broker) {
if (isPermissionsOK(document)) {
- if (StringUtils.endsWithAny(docPath, XQUERY_EXTENSIONS)) {
+ if (endsWith(docPath, XQUERY_EXTENSIONS)) {
paths.add(XmldbURI.EMBEDDED_SERVER_URI_PREFIX + docPath);
} else {
@@ -182,7 +209,7 @@ private boolean isPermissionsOK(final DocumentImpl document) {
return (perms.getOwner().hasDbaRole()
&& perms.getGroup().getName().equals(SecurityManager.DBA_GROUP)
&& perms.getMode() == Permission.DEFAULT_SYSTEM_SECURITY_COLLECTION_PERM
- && document.getMimeType().equals(REQUIRED_MIMETYPE));
+ && document.getMediaType().equals(REQUIRED_MIMETYPE));
}
@@ -255,7 +282,7 @@ private void executeQuery(DBBroker broker, String path) {
context = new XQueryContext(broker.getBrokerPool());
// Allow use of modules with relative paths
- String moduleLoadPath = StringUtils.substringBeforeLast(path, "/");
+ String moduleLoadPath = substringBeforeLast(path, "/");
context.setModuleLoadPath(moduleLoadPath);
// Compile query
diff --git a/exist-core/src/main/java/org/exist/collections/triggers/XQueryTrigger.java b/exist-core/src/main/java/org/exist/collections/triggers/XQueryTrigger.java
index e05ae35d8f..4ca09b7e63 100644
--- a/exist-core/src/main/java/org/exist/collections/triggers/XQueryTrigger.java
+++ b/exist-core/src/main/java/org/exist/collections/triggers/XQueryTrigger.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -49,6 +73,8 @@
import org.exist.xquery.value.Sequence;
import org.exist.xquery.value.StringValue;
+import javax.annotation.Nullable;
+
import static com.evolvedbinary.j8fu.tuple.Tuple.Tuple;
/**
@@ -232,33 +258,47 @@ private void prepare(final TriggerEvent event, final DBBroker broker, final Txn
LOG.warn(e.getMessage());
return;
}
-
- final XQueryContext context = new XQueryContext(broker.getBrokerPool());
- CompiledXQuery compiledQuery = null;
- try {
- //compile the XQuery
- compiledQuery = service.compile(context, query);
- declareExternalVariables(context, TriggerPhase.BEFORE, event, src, dst, isCollection);
-
- } catch (final XPathException | IOException | PermissionDeniedException e) {
- TriggerStatePerThread.clear();
- throw new TriggerException(PREPARE_EXCEPTION_MESSAGE, e);
- }
- //execute the XQuery
+ @Nullable CompiledXQuery compiled = null;
+ @Nullable XQueryContext context = null;
try {
- //TODO : should we provide another contextSet ?
- final NodeSet contextSet = NodeSet.EMPTY_SET;
- service.execute(broker, compiledQuery, contextSet);
- //TODO : should we have a special processing ?
- if (LOG.isDebugEnabled()) {
- LOG.debug("Trigger fired for prepare");
- }
- } catch (final XPathException | PermissionDeniedException e) {
- TriggerStatePerThread.clear();
- throw new TriggerException(PREPARE_EXCEPTION_MESSAGE, e);
+
+ compiled = broker.getBrokerPool().getXQueryPool().borrowCompiledXQuery(broker, query);
+ if (compiled == null) {
+ context = new XQueryContext(broker.getBrokerPool());
+ } else {
+ context = compiled.getContext();
+ context.prepareForReuse();
+ }
+
+ if (compiled == null) {
+ compiled = service.compile(context, query);
+ } else {
+ compiled.getContext().updateContext(context);
+ context.getWatchDog().reset();
+ }
+
+ declareExternalVariables(context, TriggerPhase.BEFORE, event, src, dst, isCollection);
+
+ //execute the XQuery
+ //TODO : should we provide another contextSet ?
+ final NodeSet contextSet = NodeSet.EMPTY_SET;
+ service.execute(broker, compiled, contextSet);
+ //TODO : should we have a special processing ?
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Trigger fired for prepare");
+ }
+
+ } catch (final XPathException | IOException | PermissionDeniedException e) {
+ TriggerStatePerThread.clear();
+ throw new TriggerException(PREPARE_EXCEPTION_MESSAGE, e);
} finally {
- context.runCleanupTasks();
+ if (context != null) {
+ context.runCleanupTasks();
+ }
+ if (compiled != null) {
+ broker.getBrokerPool().getXQueryPool().returnCompiledXQuery(query, compiled);
+ }
}
}
@@ -276,33 +316,42 @@ private void finish(final TriggerEvent event, final DBBroker broker, final Txn t
LOG.warn(e.getMessage());
return;
}
-
- final XQueryContext context = new XQueryContext(broker.getBrokerPool());
- CompiledXQuery compiledQuery = null;
+
+ @Nullable CompiledXQuery compiled = null;
+ @Nullable XQueryContext context = null;
try {
- //compile the XQuery
- compiledQuery = service.compile(context, query);
- declareExternalVariables(context, TriggerPhase.AFTER, event, src, dst, isCollection);
+ compiled = broker.getBrokerPool().getXQueryPool().borrowCompiledXQuery(broker, query);
+ if (compiled == null) {
+ context = new XQueryContext(broker.getBrokerPool());
+ } else {
+ context = compiled.getContext();
+ context.prepareForReuse();
+ }
+
+ if (compiled == null) {
+ compiled = service.compile(context, query);
+ } else {
+ compiled.getContext().updateContext(context);
+ context.getWatchDog().reset();
+ }
+
+ declareExternalVariables(context, TriggerPhase.AFTER, event, src, dst, isCollection);
+
+ //execute the XQuery
+ //TODO : should we provide another contextSet ?
+ final NodeSet contextSet = NodeSet.EMPTY_SET;
+ service.execute(broker, compiled, contextSet);
+ //TODO : should we have a special processing ?
} catch (final XPathException | IOException | PermissionDeniedException e) {
- //Should never be reached
- LOG.error(e);
- }
-
- //execute the XQuery
- try {
- //TODO : should we provide another contextSet ?
- final NodeSet contextSet = NodeSet.EMPTY_SET;
- service.execute(broker, compiledQuery, contextSet);
- //TODO : should we have a special processing ?
- } catch (final XPathException e) {
- //Should never be reached
- LOG.error("Error during trigger finish", e);
- } catch (final PermissionDeniedException e) {
- //Should never be reached
- LOG.error(e);
+ LOG.error("Error during trigger finish", e);
} finally {
- context.runCleanupTasks();
+ if (context != null) {
+ context.runCleanupTasks();
+ }
+ if (compiled != null) {
+ broker.getBrokerPool().getXQueryPool().returnCompiledXQuery(query, compiled);
+ }
}
TriggerStatePerThread.clearIfFinished(TriggerPhase.AFTER);
@@ -314,28 +363,28 @@ private void finish(final TriggerEvent event, final DBBroker broker, final Txn t
private void declareExternalVariables(final XQueryContext context, final TriggerPhase phase, final TriggerEvent event, final XmldbURI src, final XmldbURI dst, final boolean isCollection) throws XPathException {
//declare external variables
- context.declareVariable(bindingPrefix + "type", new StringValue(phase.legacyPhaseName()));
- context.declareVariable(bindingPrefix + "event", new StringValue(event.legacyEventName()));
+ context.declareVariable(bindingPrefix + "type", true, new StringValue(phase.legacyPhaseName()));
+ context.declareVariable(bindingPrefix + "event", true, new StringValue(event.legacyEventName()));
if (isCollection) {
- context.declareVariable(bindingPrefix + "collection", new AnyURIValue(src));
+ context.declareVariable(bindingPrefix + "collection", true, new AnyURIValue(src));
} else {
- context.declareVariable(bindingPrefix + "collection", new AnyURIValue(src.removeLastSegment()));
+ context.declareVariable(bindingPrefix + "collection", true, new AnyURIValue(src.removeLastSegment()));
}
- context.declareVariable(bindingPrefix + "uri", new AnyURIValue(src));
+ context.declareVariable(bindingPrefix + "uri", true, new AnyURIValue(src));
if (dst == null) {
- context.declareVariable(bindingPrefix + "new-uri", Sequence.EMPTY_SEQUENCE);
+ context.declareVariable(bindingPrefix + "new-uri", true, Sequence.EMPTY_SEQUENCE);
} else {
- context.declareVariable(bindingPrefix + "new-uri", new AnyURIValue(dst));
+ context.declareVariable(bindingPrefix + "new-uri", true, new AnyURIValue(dst));
}
// For backward compatibility
- context.declareVariable(bindingPrefix + "eventType", new StringValue(phase.legacyPhaseName()));
- context.declareVariable(bindingPrefix + "triggerEvent", new StringValue(event.legacyEventName()));
+ context.declareVariable(bindingPrefix + "eventType", true, new StringValue(phase.legacyPhaseName()));
+ context.declareVariable(bindingPrefix + "triggerEvent", true, new StringValue(event.legacyEventName()));
if (isCollection) {
- context.declareVariable(bindingPrefix + "collectionName", new AnyURIValue(src));
+ context.declareVariable(bindingPrefix + "collectionName", true, new AnyURIValue(src));
} else {
- context.declareVariable(bindingPrefix + "collectionName", new AnyURIValue(src.removeLastSegment()));
- context.declareVariable(bindingPrefix + "documentName", new AnyURIValue(src));
+ context.declareVariable(bindingPrefix + "collectionName", true, new AnyURIValue(src.removeLastSegment()));
+ context.declareVariable(bindingPrefix + "documentName", true, new AnyURIValue(src));
}
//declare user defined parameters as external variables
@@ -344,7 +393,7 @@ private void declareExternalVariables(final XQueryContext context, final Trigger
final String varName = (String) o;
final String varValue = userDefinedVariables.getProperty(varName);
- context.declareVariable(bindingPrefix + varName, new StringValue(varValue));
+ context.declareVariable(bindingPrefix + varName, true, new StringValue(varValue));
}
}
}
@@ -356,16 +405,29 @@ private CompiledXQuery getScript(final DBBroker broker, final Txn transaction) t
if(query == null) {
return null;
}
-
- final XQueryContext context = new XQueryContext(broker.getBrokerPool());
- if (query instanceof DBSource) {
- context.setModuleLoadPath(XmldbURI.EMBEDDED_SERVER_URI_PREFIX + ((DBSource)query).getDocumentPath().removeLastSegment().toString());
- }
- CompiledXQuery compiledQuery;
+ @Nullable CompiledXQuery compiled = null;
+ @Nullable XQueryContext context = null;
try {
+ compiled = broker.getBrokerPool().getXQueryPool().borrowCompiledXQuery(broker, query);
+ if (compiled == null) {
+ context = new XQueryContext(broker.getBrokerPool());
+ } else {
+ context = compiled.getContext();
+ context.prepareForReuse();
+ }
+
+ if (query instanceof DBSource) {
+ context.setModuleLoadPath(XmldbURI.EMBEDDED_SERVER_URI_PREFIX + ((DBSource)query).getDocumentPath().removeLastSegment().toString());
+ }
+
//compile the XQuery
- compiledQuery = service.compile(context, query);
+ if (compiled == null) {
+ compiled = service.compile(context, query);
+ } else {
+ compiled.getContext().updateContext(context);
+ context.getWatchDog().reset();
+ }
//declare user defined parameters as external variables
if (userDefinedVariables != null) {
@@ -373,20 +435,18 @@ private CompiledXQuery getScript(final DBBroker broker, final Txn transaction) t
final String varName = (String) o;
final String varValue = userDefinedVariables.getProperty(varName);
- context.declareVariable(bindingPrefix + varName, new StringValue(varValue));
+ context.declareVariable(bindingPrefix + varName, true, new StringValue(varValue));
}
}
-
- //reset & prepareForExecution for execution
- compiledQuery.reset();
- context.getWatchDog().reset();
-
- //do any preparation before execution
- context.prepareForExecution();
-
- return compiledQuery;
+ return compiled;
} catch(final XPathException | IOException | PermissionDeniedException e) {
+ if (context != null) {
+ context.runCleanupTasks();
+ }
+ if (compiled != null) {
+ broker.getBrokerPool().getXQueryPool().returnCompiledXQuery(query, compiled);
+ }
LOG.warn(e.getMessage(), e);
throw new TriggerException(PREPARE_EXCEPTION_MESSAGE, e);
}
@@ -406,23 +466,18 @@ private void execute(final TriggerPhase phase, final TriggerEvent event, final D
LOG.debug("Execute: {} {}({}): {}", phase, event, src, getClass().getSimpleName());
}
- final CompiledXQuery compiledQuery;
+ @Nullable CompiledXQuery compiled = null;
+ @Nullable XQueryContext context = null;
try {
- compiledQuery = getScript(broker, transaction);
- if (compiledQuery == null) {
+ compiled = getScript(broker, transaction);
+ if (compiled == null) {
// NOTE: can occur if there is no such XQueryTrigger library module available in the database
TriggerStatePerThread.clearIfFinished(phase);
return;
}
- } catch (final TriggerException e) {
- TriggerStatePerThread.clear();
- throw e;
- }
-
- final XQueryContext context = compiledQuery.getContext();
+ context = compiled.getContext();
- //execute the XQuery
- try {
+ //execute the XQuery
final int nParams;
if (dst != null) {
nParams = 2;
@@ -443,13 +498,18 @@ private void execute(final TriggerPhase phase, final TriggerEvent event, final D
args.add(new LiteralValue(context, new AnyURIValue(src)));
}
- service.execute(broker, compiledQuery, Tuple(functionName, args, Optional.empty()), null, null, true);
+ service.execute(broker, compiled, Tuple(functionName, args, Optional.empty()), null, null, true);
+
+ } catch (final TriggerException e) {
+ TriggerStatePerThread.clear();
+ throw e;
+
} catch (final XPathException | PermissionDeniedException e) {
// if the exception just indicates that there is no function in the trigger to call, then we can just log and return
if (e instanceof XPathException xpe) {
if (xpe.getErrorCode() == ErrorCodes.EXXQDY0005 || xpe.getErrorCode() == ErrorCodes.EXXQDY0006) {
if (LOG.isDebugEnabled()) {
- LOG.debug("No such function '" + functionName + "' in XQueryTrigger: " + compiledQuery.getSource());
+ LOG.debug("No such function '" + functionName + "' in XQueryTrigger: " + compiled.getSource());
}
TriggerStatePerThread.clearIfFinished(phase);
return;
@@ -459,8 +519,12 @@ private void execute(final TriggerPhase phase, final TriggerEvent event, final D
TriggerStatePerThread.clear();
throw new TriggerException(PREPARE_EXCEPTION_MESSAGE, e);
} finally {
- compiledQuery.reset();
- context.runCleanupTasks();
+ if (context != null) {
+ context.runCleanupTasks();
+ }
+ if (compiled != null) {
+ broker.getBrokerPool().getXQueryPool().returnCompiledXQuery(compiled.getSource(), compiled);
+ }
}
TriggerStatePerThread.clearIfFinished(phase);
diff --git a/exist-core/src/main/java/org/exist/config/Configuration.java b/exist-core/src/main/java/org/exist/config/Configuration.java
index 372b2f52c9..e49ec56b6b 100644
--- a/exist-core/src/main/java/org/exist/config/Configuration.java
+++ b/exist-core/src/main/java/org/exist/config/Configuration.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -167,7 +191,7 @@ public interface Configuration {
/**
* Save configuration.
*
- * @param broker eXist-db DBBroker
+ * @param broker the DBBroker
* @throws PermissionDeniedException if permission to save the configuration is denied
* @throws ConfigurationException if there is an error in the configuration
*/
diff --git a/exist-core/src/main/java/org/exist/config/ConfigurationImpl.java b/exist-core/src/main/java/org/exist/config/ConfigurationImpl.java
index e577dbd3ee..99ce65eaaf 100644
--- a/exist-core/src/main/java/org/exist/config/ConfigurationImpl.java
+++ b/exist-core/src/main/java/org/exist/config/ConfigurationImpl.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -122,20 +146,20 @@ private void cache() {
Node child = element.getFirstChild();
while (child != null) {
- if (child.getNodeType() == Node.ELEMENT_NODE) {
+ if (child instanceof Element) {
+ final Element childElement = (Element) child;
- final String ns = child.getNamespaceURI();
- if (ns != null && NS.equals(ns)) {
-
- String name = child.getLocalName();
+ final String ns = childElement.getNamespaceURI();
+ if (NS.equals(ns)) {
+ final String name = childElement.getLocalName();
+
if (names.contains(name)) {
-
- if (props.containsKey(name)) {
- props.remove(name);
- }
+ props.remove(name);
} else {
- props.put(name, child.getTextContent());
+ if (!childElement.hasAttribute("key")) { // NOTE(AR) Skip Map entries
+ props.put(name, childElement.getTextContent());
+ }
names.add(name);
}
}
@@ -342,7 +366,7 @@ public Long getPropertyLong(final String name, final Long defaultValue, final bo
public Integer getPropertyMegabytes(String name, Integer defaultValue) {
String cacheMem = element.getAttribute(name);
- if (cacheMem != null) {
+ if (!cacheMem.isEmpty()) {
if (cacheMem.endsWith("M") || cacheMem.endsWith("m")) {
cacheMem = cacheMem.substring(0, cacheMem.length() - 1);
}
diff --git a/exist-core/src/main/java/org/exist/config/Configurator.java b/exist-core/src/main/java/org/exist/config/Configurator.java
index 286523eb57..ada04750a9 100644
--- a/exist-core/src/main/java/org/exist/config/Configurator.java
+++ b/exist-core/src/main/java/org/exist/config/Configurator.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -47,6 +71,7 @@
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
+import org.apache.commons.io.output.StringBuilderWriter;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.exist.Database;
@@ -68,7 +93,6 @@
import org.exist.storage.txn.Txn;
import org.exist.util.ExistSAXParserFactory;
import org.exist.util.LockException;
-import org.exist.util.MimeType;
import com.evolvedbinary.j8fu.function.ConsumerE;
import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
import org.exist.util.StringInputSource;
@@ -80,6 +104,7 @@
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
+import xyz.elemental.mediatype.MediaType;
import static java.lang.invoke.MethodType.methodType;
import static javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING;
@@ -1267,24 +1292,22 @@ public static DocumentImpl save(final DBBroker broker, final Configurable instan
protected static final Set saving = new ConcurrentSkipListSet<>();
public static DocumentImpl save(final Configurable instance, final DBBroker broker, final Collection collection, final XmldbURI uri) throws IOException, ConfigurationException {
-
- final StringWriter writer = new StringWriter();
- final SAXSerializer serializer = new SAXSerializer(writer, null);
-
- try {
+ final String data;
+ try (final StringBuilderWriter writer = new StringBuilderWriter()) {
+ final SAXSerializer serializer = new SAXSerializer(writer, null);
+
serializer.startDocument();
serialize(instance, serializer);
serializer.endDocument();
-
+
+ data = writer.toString();
+ if (data == null || data.isEmpty()) {
+ return null;
+ }
} catch (final SAXException saxe) {
throw new ConfigurationException(saxe.getMessage(), saxe);
}
- final String data = writer.toString();
- if (data == null || data.length() == 0) {
- return null;
- }
-
FullXmldbURI fullURI = null;
final BrokerPool pool = broker.getBrokerPool();
final TransactionManager transact = pool.getTransactionManager();
@@ -1311,7 +1334,8 @@ public static DocumentImpl save(final Configurable instance, final DBBroker brok
systemResourcePermission.setGroup(systemSubject.getDefaultGroup());
systemResourcePermission.setMode(Permission.DEFAULT_SYSTEM_RESOURCE_PERM);
- broker.storeDocument(txn, uri, new StringInputSource(data), MimeType.XML_TYPE, null, null, systemResourcePermission, null, null, collection);
+ final MediaType xmlMediaType = broker.getBrokerPool().getMediaTypeService().getMediaTypeResolver().fromString(MediaType.APPLICATION_XML);
+ broker.storeDocument(txn, uri, new StringInputSource(data), xmlMediaType, null, null, systemResourcePermission, null, null, collection);
broker.saveCollection(txn, collection);
if (!txnInProgress) {
diff --git a/exist-core/src/main/java/org/exist/dom/NodeListImpl.java b/exist-core/src/main/java/org/exist/dom/NodeListImpl.java
index 4bcf9aa664..33ebb60bb2 100644
--- a/exist-core/src/main/java/org/exist/dom/NodeListImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/NodeListImpl.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -46,6 +70,26 @@ public boolean add(final Node node) {
return super.add(node);
}
+ /**
+ * Add all elements of the other NodeListImpl to
+ * this NodeListImpl.
+ *
+ * @param other NodeListImpl to add.
+ *
+ * @return true if the list was modified, false otherwise.
+ */
+ public boolean addAll(final NodeListImpl other) {
+ if (other == null) {
+ return false;
+ }
+
+ if (other.isEmpty()) {
+ return false;
+ }
+
+ return addAll((ArrayList) other);
+ }
+
/**
* Add all elements of the other NodeList to
* this NodeList
@@ -54,18 +98,26 @@ public boolean add(final Node node) {
* if none or only some were added.
*/
public boolean addAll(final NodeList other) {
+ if (other == null) {
+ return false;
+ }
+
+ if (other instanceof NodeListImpl) {
+ return addAll((NodeListImpl) other);
+ }
+
if (other.getLength() == 0) {
return false;
- } else {
- boolean result = true;
- for(int i = 0; i < other.getLength(); i++) {
- if(!add(other.item(i))) {
- result = false;
- break;
- }
+ }
+
+ boolean result = true;
+ for (int i = 0; i < other.getLength(); i++) {
+ if (!add(other.item(i))) {
+ result = false;
+ break;
}
- return result;
}
+ return result;
}
@Override
diff --git a/exist-core/src/main/java/org/exist/dom/QName.java b/exist-core/src/main/java/org/exist/dom/QName.java
index 3ff7753c66..ef73420d91 100644
--- a/exist-core/src/main/java/org/exist/dom/QName.java
+++ b/exist-core/src/main/java/org/exist/dom/QName.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -26,16 +50,19 @@
import org.exist.util.XMLNames;
import org.exist.xquery.Constants;
+import javax.annotation.Nullable;
import javax.xml.XMLConstants;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.exist.dom.QName.Validity.*;
+import static org.exist.util.StringUtil.isNullOrEmpty;
/**
* Represents a QName, consisting of a local name, a namespace URI and a prefix.
*
* @author Wolfgang
+ * @author Adam Retter
*/
public class QName implements Comparable {
@@ -134,7 +161,18 @@ public byte getNameType() {
* @return the string representation of this qualified name.
* */
public String getStringValue() {
- return getStringRepresentation(false);
+ return getStringRepresentation(false, false);
+ }
+
+ /**
+ * Get an extended string representation of this qualified name.
+ *
+ * Will be of the format `local-name`, `{namespace}local-name`, or `{namespace}prefix:local-name`.
+ *
+ * @return the string representation of this qualified name.
+ */
+ public String getExtendedStringValue() {
+ return getStringRepresentation(false, true);
}
/**
@@ -146,23 +184,32 @@ public String getStringValue() {
*/
@Override
public String toString() {
- return getStringRepresentation(true);
+ return getStringRepresentation(true, false);
}
/**
* Get a string representation of this qualified name.
*
* @param showNsWithoutPrefix true if the namespace should be shown even when there is no prefix, false otherwise.
- * When shown, it will be output using Clark notation, e.g. `{http://namespace}local-name`.
+ * When shown, it will be output using Clark notation, e.g. `{namespace}local-name`.
+ *
+ * @param extended true if the namespace and prefix should be shown, requires showNsWithoutPrefix == false.
*
* @return the string representation of this qualified name.
*/
- private String getStringRepresentation(final boolean showNsWithoutPrefix) {
+ private String getStringRepresentation(final boolean showNsWithoutPrefix, final boolean extended) {
if (prefix != null && !prefix.isEmpty()) {
- return prefix + COLON + localPart;
- } else if (showNsWithoutPrefix && namespaceURI != null && !XMLConstants.NULL_NS_URI.equals(namespaceURI)) {
+ if (extended) {
+ return LEFT_BRACE + namespaceURI + RIGHT_BRACE + prefix + COLON + localPart;
+ } else {
+ return prefix + COLON + localPart;
+ }
+ }
+
+ if (showNsWithoutPrefix && namespaceURI != null && !XMLConstants.NULL_NS_URI.equals(namespaceURI)) {
return LEFT_BRACE + namespaceURI + RIGHT_BRACE + localPart;
}
+
return localPart;
}
@@ -330,6 +377,52 @@ public static QName parse(final String namespaceURI, final String qname) throws
return new QName(qname.substring(p + 1), namespaceURI, qname.substring(0, p));
}
+ /**
+ * Extract a QName from a namespace and qualified name string.
+ *
+ * @param extendedStringValue a string representation as produced by {@link #getExtendedStringValue()}, i.e.: `local-name`, `{namespace}local-name`, or `{namespace}prefix:local-name`.
+ * @return The QName
+ * @throws IllegalQNameException if the qname component is invalid
+ */
+ public static QName parse(String extendedStringValue) throws IllegalQNameException {
+ if (isNullOrEmpty(extendedStringValue)) {
+ throw new IllegalQNameException(ILLEGAL_FORMAT.val, "Illegal extended string QName is empty");
+ }
+
+ final String namespaceUri;
+ if (extendedStringValue.charAt(0) == LEFT_BRACE) {
+ final int idxNsEnd = extendedStringValue.indexOf(RIGHT_BRACE);
+ if (idxNsEnd == Constants.STRING_NOT_FOUND) {
+ throw new IllegalQNameException(ILLEGAL_FORMAT.val, "Illegal extended string QName, missing right brace: '" + extendedStringValue + "'");
+ }
+ namespaceUri = extendedStringValue.substring(1, idxNsEnd);
+ extendedStringValue = extendedStringValue.substring(idxNsEnd + 1);
+ } else if (extendedStringValue.indexOf(RIGHT_BRACE) != Constants.STRING_NOT_FOUND) {
+ throw new IllegalQNameException(ILLEGAL_FORMAT.val, "Illegal extended string QName, missing left brace: '" + extendedStringValue + "'");
+ } else {
+ namespaceUri = XMLConstants.NULL_NS_URI;
+ }
+
+ @Nullable final String prefix;
+ final int idxColon = extendedStringValue.indexOf(COLON);
+ if (idxColon == Constants.STRING_NOT_FOUND) {
+ prefix = null;
+ } else {
+ prefix = extendedStringValue.substring(0, idxColon);
+ if (!XMLNames.isNCName(prefix)) {
+ throw new IllegalQNameException(INVALID_PREFIX.val, "Illegal extended string QName, invalid prefix: '" + extendedStringValue + "'");
+ }
+ extendedStringValue = extendedStringValue.substring(idxColon + 1);
+ }
+
+ final String localPart = extendedStringValue;
+ if (!XMLNames.isNCName(localPart)) {
+ throw new IllegalQNameException(INVALID_LOCAL_PART.val, "Illegal extended string QName, invalid prefix: '" + extendedStringValue + "'");
+ }
+
+ return new QName(localPart, namespaceUri, prefix);
+ }
+
/**
* Parses the given string into a QName. The method uses context to look up
* a namespace URI for an existing prefix.
diff --git a/exist-core/src/main/java/org/exist/dom/memtree/AbstractCharacterData.java b/exist-core/src/main/java/org/exist/dom/memtree/AbstractCharacterData.java
index ca40125edb..8d1e7be027 100644
--- a/exist-core/src/main/java/org/exist/dom/memtree/AbstractCharacterData.java
+++ b/exist-core/src/main/java/org/exist/dom/memtree/AbstractCharacterData.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -280,11 +304,6 @@ public String getStringValue() {
return getData();
}
- @Override
- public Node getFirstChild() {
- return null;
- }
-
@Override
public void selectAttributes(final NodeTest test, final Sequence result)
throws XPathException {
diff --git a/exist-core/src/main/java/org/exist/dom/memtree/AttrImpl.java b/exist-core/src/main/java/org/exist/dom/memtree/AttrImpl.java
index 019a03737f..ba9dcf0479 100644
--- a/exist-core/src/main/java/org/exist/dom/memtree/AttrImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/memtree/AttrImpl.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -52,7 +76,7 @@ public NodeId getNodeId() {
@Override
public String getName() {
- return getQName().getStringValue();
+ return getNodeName();
}
@Override
@@ -75,7 +99,7 @@ public String getBaseURI() {
}
@Override
- public Node getFirstChild() {
+ public Node getPreviousSibling() {
return null;
}
diff --git a/exist-core/src/main/java/org/exist/dom/memtree/DOMIndexer.java b/exist-core/src/main/java/org/exist/dom/memtree/DOMIndexer.java
index 03fe4bfb11..dcad5549eb 100644
--- a/exist-core/src/main/java/org/exist/dom/memtree/DOMIndexer.java
+++ b/exist-core/src/main/java/org/exist/dom/memtree/DOMIndexer.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -99,7 +123,7 @@ public DOMIndexer(final DBBroker broker, final Txn transaction, final DocumentIm
*/
public void scan() throws EXistException {
//Creates a dummy DOCTYPE
- final DocumentTypeImpl dt = new DocumentTypeImpl((doc != null) ? doc.getExpression() : null, "temp", null, "");
+ final org.exist.dom.persistent.DocumentTypeImpl dt = new org.exist.dom.persistent.DocumentTypeImpl((doc != null) ? doc.getExpression() : null, "temp", null, "");
targetDoc.setDocumentType(dt);
}
diff --git a/exist-core/src/main/java/org/exist/dom/memtree/DocumentBuilderReceiver.java b/exist-core/src/main/java/org/exist/dom/memtree/DocumentBuilderReceiver.java
index 31e9986e8b..7856237ea8 100644
--- a/exist-core/src/main/java/org/exist/dom/memtree/DocumentBuilderReceiver.java
+++ b/exist-core/src/main/java/org/exist/dom/memtree/DocumentBuilderReceiver.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -56,8 +80,11 @@ public class DocumentBuilderReceiver implements ContentHandler, LexicalHandler,
private boolean suppressWhitespace = true;
+ private StringBuilder cdataBuffer;
+
private final Expression expression;
+
public DocumentBuilderReceiver() {
this((Expression) null);
}
@@ -195,12 +222,20 @@ public void addNamespaceNode(final QName qname) throws SAXException {
@Override
public void characters(final CharSequence seq) throws SAXException {
- builder.characters(seq);
+ if (cdataBuffer != null) {
+ cdataBuffer.append(seq);
+ } else {
+ builder.characters(seq);
+ }
}
@Override
public void characters(final char[] ch, final int start, final int len) throws SAXException {
- builder.characters(ch, start, len);
+ if (cdataBuffer != null) {
+ cdataBuffer.append(ch, start, len);
+ } else {
+ builder.characters(ch, start, len);
+ }
}
@Override
@@ -234,15 +269,14 @@ public void skippedEntity(final String name) throws SAXException {
}
@Override
- public void endCDATA() throws SAXException {
- }
-
- @Override
- public void endDTD() throws SAXException {
+ public void startCDATA() throws SAXException {
+ this.cdataBuffer = new StringBuilder();
}
@Override
- public void startCDATA() throws SAXException {
+ public void endCDATA() throws SAXException {
+ builder.cdataSection(this.cdataBuffer);
+ this.cdataBuffer = null;
}
@Override
@@ -256,17 +290,21 @@ public void comment(final char[] ch, final int start, final int length) throws S
}
@Override
- public void endEntity(final String name) throws SAXException {
+ public void startEntity(final String name) throws SAXException {
}
@Override
- public void startEntity(final String name) throws SAXException {
+ public void endEntity(final String name) throws SAXException {
}
@Override
public void startDTD(final String name, final String publicId, final String systemId) throws SAXException {
}
+ @Override
+ public void endDTD() throws SAXException {
+ }
+
@Override
public void highlightText(final CharSequence seq) {
// not supported with this receiver
diff --git a/exist-core/src/main/java/org/exist/dom/memtree/DocumentImpl.java b/exist-core/src/main/java/org/exist/dom/memtree/DocumentImpl.java
index 180fc01e96..9270b1652f 100644
--- a/exist-core/src/main/java/org/exist/dom/memtree/DocumentImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/memtree/DocumentImpl.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -27,6 +51,7 @@
import org.exist.dom.NodeListImpl;
import org.exist.dom.QName;
import org.exist.dom.QName.IllegalQNameException;
+import org.exist.dom.memtree.reference.*;
import org.exist.dom.persistent.NodeProxy;
import org.exist.numbering.NodeId;
import org.exist.numbering.NodeIdFactory;
@@ -47,6 +72,7 @@
import org.w3c.dom.*;
import org.xml.sax.SAXException;
+import javax.annotation.Nullable;
import javax.xml.XMLConstants;
import java.util.Arrays;
import java.util.Objects;
@@ -71,19 +97,21 @@
* for example {@code int nextNodeNum = next[nodeNum]}.
*
* The following arrays hold the data of the nodes themselves:
- * * {@link #namespaceParent}
- * * {@link #namespaceCode}
- * * {@link #nodeName}
- * * {@link #alpha}
- * * {@link #alphaLen}
- * * {@link #characters}
- * * {@link #nodeId}
- * * {@link #attrName}
- * * {@link #attrType}
- * * {@link #attrNodeId}
- * * {@link #attrParent}
- * * {@link #attrValue}
- * * {@link #references}
+ *
+ *
{@link #namespaceParent}
+ *
{@link #namespaceCode}
+ *
{@link #nodeName}
+ *
{@link #alpha}
+ *
{@link #alphaLen} For Element nodes, this is the ID of the first namespace for that Element. For Text, CData Section, Comment, and Processing Instruction nodes this is the lengh of their character data.
+ *
{@link #characters}
+ *
{@link #nodeId}
+ *
{@link #attrName}
+ *
{@link #attrType}
+ *
{@link #attrNodeId}
+ *
{@link #attrParent}
+ *
{@link #attrValue}
+ *
{@link #references}
+ *
*
* This implementation stores all node data in the document object. Nodes from another document, i.e. a persistent document in the database, can be
* stored as reference nodes, i.e. the nodes are not copied into this document object. Instead a reference is inserted which will only be expanded
@@ -98,6 +126,8 @@ public class DocumentImpl extends NodeImpl implements Document {
private static final int CHAR_BUF_SIZE = 256;
private static final int REF_SIZE = 8;
+ protected DocumentType docType = null;
+
// holds the node type of a node
protected short[] nodeKind = null;
@@ -222,11 +252,11 @@ public boolean isExplicitlyCreated() {
return explicitlyCreated;
}
- public int addNode(final short kind, final short level, final QName qname) {
- if(nodeKind == null) {
+ public int addNode(final short kind, final short level, @Nullable final QName qname) {
+ if (nodeKind == null) {
init();
}
- if(size == nodeKind.length) {
+ if (size == nodeKind.length) {
grow();
}
nodeKind[size] = kind;
@@ -317,11 +347,11 @@ public void appendChars(final int nodeNum, final CharSequence s) {
}
}
- public void addReferenceNode(final int nodeNum, final NodeProxy proxy) {
- if(nodeKind == null) {
+ void addReferenceNode(final int nodeNum, final NodeProxy proxy) {
+ if (nodeKind == null) {
init();
}
- if((references == null) || (nextReferenceIdx == references.length)) {
+ if (references == null || nextReferenceIdx == references.length) {
growReferences();
}
references[nextReferenceIdx] = proxy;
@@ -513,21 +543,71 @@ public NodeImpl getNamespaceNode(final int nodeNum) throws DOMException {
}
public NodeImpl getNode(final int nodeNum) throws DOMException {
- if(nodeNum == 0) {
+ if (nodeNum == 0) {
return this;
}
- if(nodeNum >= size) {
+
+ if (nodeNum >= size) {
throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "node not found");
}
- final NodeImpl node = switch (nodeKind[nodeNum]) {
- case Node.ELEMENT_NODE -> new ElementImpl(getExpression(), this, nodeNum);
- case Node.TEXT_NODE -> new TextImpl(getExpression(), this, nodeNum);
- case Node.COMMENT_NODE -> new CommentImpl(getExpression(), this, nodeNum);
- case Node.PROCESSING_INSTRUCTION_NODE -> new ProcessingInstructionImpl(getExpression(), this, nodeNum);
- case Node.CDATA_SECTION_NODE -> new CDATASectionImpl(getExpression(), this, nodeNum);
- case NodeImpl.REFERENCE_NODE -> new ReferenceNode(getExpression(), this, nodeNum);
- default -> throw new DOMException(DOMException.NOT_FOUND_ERR, "node not found");
- };
+
+ final NodeImpl> node;
+ switch (nodeKind[nodeNum]) {
+ case Node.ELEMENT_NODE:
+ node = new ElementImpl(getExpression(), this, nodeNum);
+ break;
+
+ case Node.TEXT_NODE:
+ node = new TextImpl(getExpression(), this, nodeNum);
+ break;
+
+ case Node.COMMENT_NODE:
+ node = new CommentImpl(getExpression(), this, nodeNum);
+ break;
+
+ case Node.PROCESSING_INSTRUCTION_NODE:
+ node = new ProcessingInstructionImpl(getExpression(), this, nodeNum);
+ break;
+
+ case Node.CDATA_SECTION_NODE:
+ node = new CDATASectionImpl(getExpression(), this, nodeNum);
+ break;
+
+ case NodeImpl.REFERENCE_NODE:
+ final NodeProxy nodeProxy = references[alpha[nodeNum]];
+ node = referenceFromNodeProxy(nodeNum, nodeProxy);
+ break;
+
+ default:
+ throw new DOMException(DOMException.NOT_FOUND_ERR, "node not found");
+ }
+ return node;
+ }
+
+ private NodeImpl referenceFromNodeProxy(final int nodeNum, final NodeProxy nodeProxy) {
+ final NodeImpl> node;
+ final int nodeType = nodeProxy.getNodeType();
+ switch (nodeType) {
+ case Node.ELEMENT_NODE:
+ node = new ElementReferenceImpl(getExpression(), this, nodeNum, nodeProxy);
+ break;
+
+ case Node.TEXT_NODE:
+ node = new TextReferenceImpl(getExpression(), this, nodeNum, nodeProxy);
+ break;
+
+ case Node.PROCESSING_INSTRUCTION_NODE:
+ node = new ProcessingInstructionReferenceImpl(getExpression(), this, nodeNum, nodeProxy);
+ break;
+
+ case Node.COMMENT_NODE:
+ node = new CommentReferenceImpl(getExpression(), this, nodeNum, nodeProxy);
+ break;
+
+ default:
+ throw new DOMException(DOMException.NOT_FOUND_ERR, "reference node not found");
+ }
+
return node;
}
@@ -545,7 +625,11 @@ public Node getParentNode() {
@Override
public DocumentType getDoctype() {
- return null;
+ return docType;
+ }
+
+ public void setDoctype(final DocumentType docType) {
+ this.docType = docType;
}
@Override
@@ -570,7 +654,7 @@ public Element getDocumentElement() {
@Override
public Node getFirstChild() {
- if(size > 1) {
+ if (size > 1) {
return getNode(1);
}
return null;
@@ -578,7 +662,17 @@ public Node getFirstChild() {
@Override
public Node getLastChild() {
- return getFirstChild();
+ if (size > 1) {
+ int nodeNum = 1;
+ for (; nodeNum < size; nodeNum++) {
+ if (treeLevel[nodeNum] > 1) {
+ nodeNum--;
+ break;
+ }
+ }
+ return getNode(nodeNum);
+ }
+ return null;
}
public int getAttributesCountFor(final int nodeNumber) {
@@ -625,9 +719,10 @@ public int getFirstChildFor(final int nodeNumber) {
final short level = treeLevel[nodeNumber];
final int nextNode = nodeNumber + 1;
- if((nextNode < size) && (treeLevel[nextNode] > level)) {
+ if ((nextNode < size) && (treeLevel[nextNode] > level)) {
return nextNode;
}
+
return -1;
}
@@ -1083,33 +1178,41 @@ public DocumentImpl getOwnerDocument() {
* @throws SAXException DOCUMENT ME!
*/
public void copyTo(final NodeImpl node, final DocumentBuilderReceiver receiver) throws SAXException {
- copyTo(node, receiver, false);
+ copyTo(null, node, receiver);
}
- protected void copyTo(NodeImpl node, final DocumentBuilderReceiver receiver, final boolean expandRefs)
- throws SAXException {
+ private void copyTo(@Nullable final Serializer serializer, NodeImpl node, final DocumentBuilderReceiver receiver) throws SAXException {
final NodeImpl top = node;
- while(node != null) {
- copyStartNode(node, receiver, expandRefs);
- NodeImpl nextNode;
- if(node instanceof ReferenceNode) {
- //Nothing more to stream ?
- nextNode = null;
+
+ @Nullable NodeImpl nextNode;
+ while (node != null) {
+ if (node instanceof AbstractReferenceNodeImpl) {
+ if (serializer != null) {
+ serializer.toReceiver(((AbstractReferenceNodeImpl) node).getNodeProxy(), false, false);
+ } else {
+ receiver.addReferenceNode(document.references[document.alpha[node.nodeNumber]]);
+ }
+ nextNode = (NodeImpl) node.getNextSibling();
+
} else {
+ copyStartNode(node, receiver);
nextNode = (NodeImpl) node.getFirstChild();
}
- while(nextNode == null) {
- if (node != null) {
+
+ while (nextNode == null) {
+ if (!(node instanceof AbstractReferenceNodeImpl)) {
copyEndNode(node, receiver);
+
+ if (top.nodeNumber == node.nodeNumber) {
+ break;
+ }
}
- if((top != null) && (top.nodeNumber == node.nodeNumber)) {
- break;
- }
+
//No nextNode if the top node is a Document node
nextNode = (NodeImpl) node.getNextSibling();
- if(nextNode == null) {
+ if (nextNode == null) {
node = (NodeImpl) node.getParentNode();
- if((node == null) || ((top != null) && (top.nodeNumber == node.nodeNumber))) {
+ if (node == null || top.nodeNumber == node.nodeNumber) {
if (node != null) {
copyEndNode(node, receiver);
}
@@ -1117,14 +1220,14 @@ protected void copyTo(NodeImpl node, final DocumentBuilderReceiver receiver, fin
}
}
}
+
node = nextNode;
}
}
- private void copyStartNode(final NodeImpl node, final DocumentBuilderReceiver receiver, final boolean expandRefs)
- throws SAXException {
+ private void copyStartNode(final NodeImpl node, final DocumentBuilderReceiver receiver) throws SAXException {
final int nr = node.nodeNumber;
- switch(node.getNodeType()) {
+ switch (node.getNodeType()) {
case Node.ELEMENT_NODE: {
final QName nodeName = document.nodeName[nr];
receiver.startElement(nodeName, null);
@@ -1146,51 +1249,38 @@ private void copyStartNode(final NodeImpl node, final DocumentBuilderReceiver re
}
break;
}
+
case Node.TEXT_NODE:
receiver.characters(document.characters, document.alpha[nr], document.alphaLen[nr]);
break;
+
case Node.CDATA_SECTION_NODE:
receiver.cdataSection(document.characters, document.alpha[nr], document.alphaLen[nr]);
break;
+
case Node.ATTRIBUTE_NODE:
final QName attrQName = document.attrName[nr];
receiver.attribute(attrQName, attrValue[nr]);
break;
+
case Node.COMMENT_NODE:
receiver.comment(document.characters, document.alpha[nr], document.alphaLen[nr]);
break;
+
case Node.PROCESSING_INSTRUCTION_NODE:
final QName piQName = document.nodeName[nr];
final String data = new String(document.characters, document.alpha[nr], document.alphaLen[nr]);
receiver.processingInstruction(piQName.getLocalPart(), data);
break;
+
case NodeImpl.NAMESPACE_NODE:
receiver.addNamespaceNode(document.namespaceCode[nr]);
break;
- case NodeImpl.REFERENCE_NODE:
- if(expandRefs) {
- try(final DBBroker broker = getDatabase().getBroker()) {
- final Serializer serializer = broker.borrowSerializer();
- try {
- serializer.setProperty(Serializer.GENERATE_DOC_EVENTS, "false");
- serializer.setReceiver(receiver);
- serializer.toReceiver(document.references[document.alpha[nr]], false, false);
- } finally {
- broker.returnSerializer(serializer);
- }
- } catch(final EXistException e) {
- throw new SAXException(e);
- }
- } else {
- receiver.addReferenceNode(document.references[document.alpha[nr]]);
- }
- break;
}
}
- private void copyEndNode(final NodeImpl node, final DocumentBuilderReceiver receiver)
- throws SAXException {
- if(node.getNodeType() == Node.ELEMENT_NODE) {
+ private void copyEndNode(final NodeImpl node, final DocumentBuilderReceiver receiver) throws SAXException {
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
receiver.endElement(node.getQName());
}
}
@@ -1205,6 +1295,7 @@ private void copyEndNode(final NodeImpl node, final DocumentBuilderReceiver rece
*/
@Override
public void expand() throws DOMException {
+ // TODO(AR) see if we can get rid of expansion now we have org.exist.dom.memtree.reference.* classes
if(size == 0) {
return;
}
@@ -1212,31 +1303,36 @@ public void expand() throws DOMException {
copyDocContents(newDoc);
}
+ // TODO(AR) see if we can get rid of expansion now we have org.exist.dom.memtree.reference.* classes
public DocumentImpl expandRefs(final NodeImpl rootNode) throws DOMException {
- try {
- if(nextReferenceIdx == 0) {
- computeNodeIds();
- return this;
- }
- final MemTreeBuilder builder = new MemTreeBuilder(getExpression(), context);
- final DocumentBuilderReceiver receiver = new DocumentBuilderReceiver(getExpression(), builder);
+ if(nextReferenceIdx == 0) {
+ computeNodeIds();
+ return this;
+ }
+ final MemTreeBuilder builder = new MemTreeBuilder(getExpression(), context);
+ final DocumentBuilderReceiver receiver = new DocumentBuilderReceiver(getExpression(), builder);
+ try (final DBBroker broker = getDatabase().getBroker()) {
+ final Serializer serializer = broker.borrowSerializer();
try {
+ serializer.setProperty(Serializer.GENERATE_DOC_EVENTS, "false");
+ serializer.setReceiver(receiver);
+
builder.startDocument();
NodeImpl node = (rootNode == null) ? (NodeImpl) getFirstChild() : rootNode;
- while(node != null) {
- copyTo(node, receiver, true);
+ while (node != null) {
+ copyTo(serializer, node, receiver);
node = (NodeImpl) node.getNextSibling();
}
receiver.endDocument();
- } catch(final SAXException e) {
- throw new DOMException(DOMException.INVALID_STATE_ERR, e.getMessage());
+ } finally {
+ broker.returnSerializer(serializer);
}
- final DocumentImpl newDoc = builder.getDocument();
- newDoc.computeNodeIds();
- return newDoc;
- } catch(final EXistException e) {
+ } catch (final SAXException | EXistException e) {
throw new DOMException(DOMException.INVALID_STATE_ERR, e.getMessage());
}
+ final DocumentImpl newDoc = builder.getDocument();
+ newDoc.computeNodeIds();
+ return newDoc;
}
public NodeImpl getNodeById(final NodeId id) {
@@ -1249,7 +1345,7 @@ public NodeImpl getNodeById(final NodeId id) {
return null;
}
- private void computeNodeIds() throws EXistException {
+ private void computeNodeIds() {
if(nodeId[0] != null) {
return;
}
@@ -1330,48 +1426,62 @@ private void copyDocContents(final DocumentImpl newDoc) {
* @param receiver the receiveer
* @throws SAXException DOCUMENT ME
*/
- public void streamTo(final Serializer serializer, NodeImpl node, final Receiver receiver)
- throws SAXException {
+ public void streamTo(final Serializer serializer, NodeImpl node, final Receiver receiver) throws SAXException {
final NodeImpl top = node;
- while(node != null) {
- startNode(serializer, node, receiver);
- NodeImpl nextNode;
- if(node instanceof ReferenceNode) {
- //Nothing more to stream ?
- nextNode = null;
+
+ int level = node.getNodeType() == Node.DOCUMENT_NODE ? 0 : 1;
+
+ while (node != null) {
+
+ @Nullable NodeImpl nextNode;
+ if (node instanceof AbstractReferenceNodeImpl) {
+ serializer.toReceiver(((AbstractReferenceNodeImpl) node).getNodeProxy(), true, level == 1);
+ nextNode = (NodeImpl) node.getNextSibling();
+
} else {
+ startNode(node, receiver);
nextNode = (NodeImpl) node.getFirstChild();
+ level++;
}
- while(nextNode == null) {
- endNode(node, receiver);
- if((top != null) && (top.nodeNumber == node.nodeNumber)) {
- break;
+
+ while (nextNode == null) {
+ if (!(node instanceof AbstractReferenceNodeImpl)) {
+ endNode(node, receiver);
+ level--;
+
+ if (top.nodeNumber == node.nodeNumber) {
+ break;
+ }
}
+
+ //No nextNode if the top node is a Document node
nextNode = (NodeImpl) node.getNextSibling();
- if(nextNode == null) {
+ if (nextNode == null) {
node = (NodeImpl) node.getParentNode();
- if((node == null) || ((top != null) && (top.nodeNumber == node.nodeNumber))) {
+ if (node == null || top.nodeNumber == node.nodeNumber) {
if (node != null) {
endNode(node, receiver);
+ level--;
}
break;
}
}
}
+
node = nextNode;
}
}
- private void startNode(final Serializer serializer, final NodeImpl node, final Receiver receiver)
- throws SAXException {
- final int nr = node.nodeNumber;
- switch(node.getNodeType()) {
+ private void startNode(final NodeImpl node, final Receiver receiver) throws SAXException {
+ final int nodeNumber = node.nodeNumber;
+ switch (node.getNodeType()) {
case Node.ELEMENT_NODE:
- final QName nodeName = document.nodeName[nr];
+ final QName nodeName = node.getQName();
+
//Output required namespace declarations
- int ns = document.alphaLen[nr];
- if(ns > -1) {
- while((ns < document.nextNamespace) && (document.namespaceParent[ns] == nr)) {
+ int ns = document.alphaLen[nodeNumber];
+ if (ns > -1) {
+ while((ns < document.nextNamespace) && (document.namespaceParent[ns] == nodeNumber)) {
final QName nsQName = document.namespaceCode[ns];
if(XMLConstants.XMLNS_ATTRIBUTE.equals(nsQName.getLocalPart())) {
receiver.startPrefixMapping(XMLConstants.DEFAULT_NS_PREFIX, nsQName.getNamespaceURI());
@@ -1381,40 +1491,32 @@ private void startNode(final Serializer serializer, final NodeImpl node, final R
++ns;
}
}
+
//Create the attribute list
- AttrList attribs = null;
- int attr = document.alpha[nr];
- if(attr > -1) {
- attribs = new AttrList();
- while((attr < document.nextAttr) && (document.attrParent[attr] == nr)) {
- final QName attrQName = document.attrName[attr];
- attribs.addAttribute(attrQName, attrValue[attr]);
- ++attr;
- }
- }
+ @Nullable final AttrList attribs = node.getAttrList();
receiver.startElement(nodeName, attribs);
break;
+
case Node.TEXT_NODE:
- receiver.characters(new String(document.characters, document.alpha[nr],
- document.alphaLen[nr]));
+ receiver.characters(((TextImpl) node).getData());
break;
+
case Node.ATTRIBUTE_NODE:
- final QName attrQName = document.attrName[nr];
- receiver.attribute(attrQName, attrValue[nr]);
+ receiver.attribute(node.getQName(), ((Attr) node).getValue());
break;
+
case Node.COMMENT_NODE:
- receiver.comment(document.characters, document.alpha[nr], document.alphaLen[nr]);
+ final char[] commentData = ((Comment) node).getData().toCharArray();
+ receiver.comment(commentData, 0, commentData.length);
break;
+
case Node.PROCESSING_INSTRUCTION_NODE:
- final QName qn = document.nodeName[nr];
- final String data = new String(document.characters, document.alpha[nr], document.alphaLen[nr]);
- receiver.processingInstruction(qn.getLocalPart(), data);
+ receiver.processingInstruction(node.getQName().getLocalPart(), ((ProcessingInstruction) node).getData());
break;
+
case Node.CDATA_SECTION_NODE:
- receiver.cdataSection(document.characters, document.alpha[nr], document.alphaLen[nr]);
- break;
- case NodeImpl.REFERENCE_NODE:
- serializer.toReceiver(document.references[document.alpha[nr]], true, false);
+ final char[] cdataSectionData = ((CDATASection) node).getData().toCharArray();
+ receiver.cdataSection(cdataSectionData, 0, cdataSectionData.length);
break;
}
}
@@ -1635,4 +1737,61 @@ public Node appendChild(final Node newChild) throws DOMException {
throw unsupported();
}
+
+ @Override
+ public String lookupNamespaceURI(final String prefix) {
+ if (prefix == null || prefix == XMLConstants.DEFAULT_NS_PREFIX) {
+ return XMLConstants.NULL_NS_URI;
+ }
+
+ for (int i = nextNamespace - 1; i >= 0; i--) {
+ final QName namespaceMapping = namespaceCode[i];
+ if (prefix.equals(namespaceMapping.getLocalPart())) {
+ return namespaceMapping.getNamespaceURI();
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the in-scope namespace URI for the namespace prefix.
+ *
+ * @param prefix the namespace prefix to lookup.
+ * @param nodeNumber the node to retrieve the in-scope namespace URI for.
+ *
+ * @return the namespace URI bound to the namespace prefix, or null if there is no such binding.
+ */
+ public @Nullable String getInScopePrefix(String prefix, final int nodeNumber) {
+ if (prefix == null) {
+ prefix = XMLConstants.DEFAULT_NS_PREFIX;
+ }
+
+ // First, look at the Namespaces on the current node
+ if (alphaLen != null) {
+ int ns = alphaLen[nodeNumber];
+ if (ns != -1) {
+ while (ns < nextNamespace && namespaceParent[ns] == nodeNumber) {
+ final QName nsQName = namespaceCode[ns];
+ if (prefix.equals(nsQName.getPrefix()) || (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX) && nsQName.getPrefix() == null && XMLConstants.XMLNS_ATTRIBUTE.equals(nsQName.getLocalPart()))) {
+ return nsQName.getNamespaceURI();
+ }
+ ++ns;
+ }
+ }
+ }
+
+ // Second, look at the parent, and so on...
+ if (next != null) {
+ int parent = next[nodeNumber];
+ while (parent > nodeNumber) {
+ parent = next[parent];
+ }
+ if (parent != -1 && !(nodeNumber == 0 && parent == 0)) {
+ return getInScopePrefix(prefix, parent);
+ }
+ }
+
+ return null;
+ }
}
diff --git a/exist-core/src/main/java/org/exist/dom/memtree/DocumentTypeImpl.java b/exist-core/src/main/java/org/exist/dom/memtree/DocumentTypeImpl.java
new file mode 100644
index 0000000000..0f55e3ddc6
--- /dev/null
+++ b/exist-core/src/main/java/org/exist/dom/memtree/DocumentTypeImpl.java
@@ -0,0 +1,148 @@
+/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package org.exist.dom.memtree;
+
+import net.jcip.annotations.ThreadSafe;
+import org.exist.xquery.Expression;
+import org.exist.xquery.NodeTest;
+import org.exist.xquery.XPathException;
+import org.exist.xquery.value.Sequence;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.NamedNodeMap;
+
+import javax.annotation.Nullable;
+
+/**
+ * @author Adam Retter
+ */
+@ThreadSafe
+public class DocumentTypeImpl extends NodeImpl implements DocumentType {
+
+ private final String publicId;
+ private final String systemId;
+ private final String name;
+
+ public DocumentTypeImpl(final DocumentImpl doc, final int nodeNumber, final String name, final String publicId, final String systemId) {
+ this(null, doc, nodeNumber, name, publicId, systemId);
+ }
+
+ public DocumentTypeImpl(@Nullable final Expression expression, final DocumentImpl doc, final int nodeNumber, final String name, final String publicId, final String systemId) {
+ super(expression, doc, nodeNumber);
+ this.name = name;
+ this.publicId = publicId;
+ this.systemId = systemId;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public String getPublicId() {
+ return publicId;
+ }
+
+ @Override
+ public String getSystemId() {
+ return systemId;
+ }
+
+ @Override
+ public NamedNodeMap getEntities() {
+ return null;
+ }
+
+ @Override
+ public NamedNodeMap getNotations() {
+ return null;
+ }
+
+ @Override
+ public String getInternalSubset() {
+ return null;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+
+ builder.append("");
+
+ return builder.toString();
+ }
+
+ @Override
+ public void selectAttributes(final NodeTest test, final Sequence result) throws XPathException {
+ }
+
+ @Override
+ public void selectDescendantAttributes(final NodeTest test, final Sequence result) throws XPathException {
+ }
+
+ @Override
+ public void selectChildren(final NodeTest test, final Sequence result) throws XPathException {
+
+ }
+
+ @Override
+ public int compareTo(final DocumentTypeImpl other) {
+ int comparison = name.compareTo(other.name);
+ if (comparison != 0) {
+ return comparison;
+ }
+
+ if (publicId == null && other.publicId != null) {
+ return -1;
+ } else if (publicId != null && other.publicId == null) {
+ return 1;
+ }
+ comparison = publicId.compareTo(other.publicId);
+ if (comparison != 0) {
+ return comparison;
+ }
+
+ if (systemId == null && other.systemId != null) {
+ return -1;
+ } else if (systemId != null && other.systemId == null) {
+ return 1;
+ }
+ comparison = systemId.compareTo(other.systemId);
+ if (comparison != 0) {
+ return comparison;
+ }
+
+ return 0;
+ }
+}
diff --git a/exist-core/src/main/java/org/exist/dom/memtree/ElementImpl.java b/exist-core/src/main/java/org/exist/dom/memtree/ElementImpl.java
index 892f4e9ff9..ab1b674080 100644
--- a/exist-core/src/main/java/org/exist/dom/memtree/ElementImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/memtree/ElementImpl.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -27,6 +51,7 @@
import org.exist.dom.QName;
import org.exist.dom.QName.IllegalQNameException;
import org.exist.storage.ElementValue;
+import org.exist.util.serializer.AttrList;
import org.exist.xmldb.XmldbURI;
import org.exist.xquery.Expression;
import org.exist.xquery.NodeTest;
@@ -68,12 +93,12 @@ public boolean hasChildNodes() {
@Override
public Node getFirstChild() {
- final short level = document.treeLevel[nodeNumber];
- final int nextNode = nodeNumber + 1;
- if(nextNode < document.size && document.treeLevel[nextNode] > level) {
- return document.getNode(nextNode);
+ final int firstChildNodeNumber = document.getFirstChildFor(nodeNumber);
+ if (firstChildNodeNumber == -1) {
+ return null;
}
- return null;
+
+ return document.getNode(firstChildNodeNumber);
}
@Override
@@ -102,28 +127,31 @@ public boolean hasAttributes() {
@Override
public String getAttribute(final String name) {
int attr = document.alpha[nodeNumber];
+
if(-1 < attr) {
- while(attr < document.nextAttr && document.attrParent[attr] == nodeNumber) {
+ while (attr < document.nextAttr && document.attrParent[attr] == nodeNumber) {
final QName attrQName = document.attrName[attr];
- if(attrQName.getStringValue().equals(name)) {
+ if (attrQName.getStringValue().equals(name)) {
return document.attrValue[attr];
}
++attr;
}
}
- if(name.startsWith(XMLConstants.XMLNS_ATTRIBUTE + ":")) {
+
+ if (name.startsWith(XMLConstants.XMLNS_ATTRIBUTE + ":")) {
int ns = document.alphaLen[nodeNumber];
- if(-1 < ns) {
- while(ns < document.nextNamespace && document.namespaceParent[ns] == nodeNumber) {
+ if (-1 < ns) {
+ while (ns < document.nextNamespace && document.namespaceParent[ns] == nodeNumber) {
final QName nsQName = document.namespaceCode[ns];
- if(nsQName.getStringValue().equals(name)) {
+ if (nsQName.getStringValue().equals(name)) {
return nsQName.getNamespaceURI();
}
++ns;
}
}
}
- return null;
+
+ return "";
}
@Override
@@ -220,6 +248,22 @@ public NamedNodeMap getAttributes() {
return map;
}
+ @Override
+ public AttrList getAttrList() {
+ //Create the attribute list
+ AttrList attrList = null;
+ int attr = document.alpha[nodeNumber];
+ if (attr > -1) {
+ attrList = new AttrList();
+ while((attr < document.nextAttr) && (document.attrParent[attr] == nodeNumber)) {
+ final QName attrQName = document.attrName[attr];
+ attrList.addAttribute(attrQName, document.attrValue[attr]);
+ ++attr;
+ }
+ }
+ return attrList;
+ }
+
@Override
public Attr getAttributeNode(final String name) {
int attr = document.alpha[nodeNumber];
@@ -411,28 +455,31 @@ private NodeList getElementsByTagName(final QName qname) {
@Override
public String getAttributeNS(final String namespaceURI, final String localName) {
int attr = document.alpha[nodeNumber];
- if(-1 < attr) {
- while(attr < document.nextAttr && document.attrParent[attr] == nodeNumber) {
+
+ if (-1 < attr) {
+ while (attr < document.nextAttr && document.attrParent[attr] == nodeNumber) {
final QName name = document.attrName[attr];
- if(name.getLocalPart().equals(localName) && name.getNamespaceURI().equals(namespaceURI)) {
+ if (name.getLocalPart().equals(localName) && name.getNamespaceURI().equals(namespaceURI)) {
return document.attrValue[attr];
}
++attr;
}
}
- if(Namespaces.XMLNS_NS.equals(namespaceURI)) {
+
+ if (Namespaces.XMLNS_NS.equals(namespaceURI)) {
int ns = document.alphaLen[nodeNumber];
- if(-1 < ns) {
- while(ns < document.nextNamespace && document.namespaceParent[ns] == nodeNumber) {
+ if (-1 < ns) {
+ while (ns < document.nextNamespace && document.namespaceParent[ns] == nodeNumber) {
final QName nsQName = document.namespaceCode[ns];
- if(nsQName.getLocalPart().equals(localName)) {
+ if (nsQName.getLocalPart().equals(localName)) {
return nsQName.getNamespaceURI();
}
++ns;
}
}
}
- return null;
+
+ return "";
}
@Override
@@ -473,7 +520,32 @@ public Attr setAttributeNodeNS(final Attr newAttr) throws DOMException {
@Override
public boolean hasAttribute(final String name) {
- return getAttribute(name) != null;
+ int attr = document.alpha[nodeNumber];
+
+ if (-1 < attr) {
+ while (attr < document.nextAttr && document.attrParent[attr] == nodeNumber) {
+ final QName attrQName = document.attrName[attr];
+ if (attrQName.getStringValue().equals(name)) {
+ return true;
+ }
+ ++attr;
+ }
+ }
+
+ if (name.startsWith(XMLConstants.XMLNS_ATTRIBUTE + ":")) {
+ int ns = document.alphaLen[nodeNumber];
+ if (-1 < ns) {
+ while (ns < document.nextNamespace && document.namespaceParent[ns] == nodeNumber) {
+ final QName nsQName = document.namespaceCode[ns];
+ if (nsQName.getStringValue().equals(name)) {
+ return true;
+ }
+ ++ns;
+ }
+ }
+ }
+
+ return false;
}
@Override
@@ -556,46 +628,43 @@ public String getBaseURI() {
return "";//UNDERSTAND: is it ok?
}
- //TODO please, keep in sync with org.exist.dom.persistent.ElementImpl
+ // NOTE(AR) please keep in sync with org.exist.dom.persistent.ElementImpl
private XmldbURI calculateBaseURI() {
XmldbURI baseURI = null;
final String nodeBaseURI = getAttributeNS(Namespaces.XML_NS, "base");
- if(nodeBaseURI != null) {
+ if (!nodeBaseURI.isEmpty()) {
baseURI = XmldbURI.create(nodeBaseURI, false);
- if(baseURI.isAbsolute()) {
+ if (baseURI.isAbsolute()) {
return baseURI;
}
}
int parent = -1;
final int test = document.getParentNodeFor(nodeNumber);
- if(document.nodeKind[test] != Node.DOCUMENT_NODE) {
+ if (document.nodeKind[test] != Node.DOCUMENT_NODE) {
parent = test;
}
- if(parent != -1) {
- if(nodeBaseURI == null) {
+ if (parent != -1) {
+ if (nodeBaseURI.isEmpty()) {
baseURI = ((ElementImpl) document.getNode(parent))
.calculateBaseURI();
} else {
- XmldbURI parentsBaseURI = ((ElementImpl) document.getNode(parent))
- .calculateBaseURI();
-
- if(nodeBaseURI.isEmpty()) {
- baseURI = parentsBaseURI;
- } else {
+ final XmldbURI parentsBaseURI = ((ElementImpl) document.getNode(parent)).calculateBaseURI();
+ if (parentsBaseURI.toString().endsWith("/") || !parentsBaseURI.toString().contains("/")) {
baseURI = parentsBaseURI.append(baseURI);
+ } else {
+ // there is a filename, remove it
+ baseURI = parentsBaseURI.removeLastSegment().append(baseURI);
}
}
} else {
- if(nodeBaseURI == null) {
+ if (nodeBaseURI.isEmpty()) {
return XmldbURI.create(getOwnerDocument().getBaseURI(), false);
- } else if(nodeNumber == 1) {
- //nothing to do
- } else {
+ } else if (nodeNumber != 1) {
final String docBaseURI = getOwnerDocument().getBaseURI();
- if(docBaseURI.endsWith("/")) {
+ if (docBaseURI.endsWith("/")) {
baseURI = XmldbURI.create(getOwnerDocument().getBaseURI(), false);
baseURI.append(baseURI);
} else {
@@ -605,6 +674,7 @@ private XmldbURI calculateBaseURI() {
}
}
}
+
return baseURI;
}
diff --git a/exist-core/src/main/java/org/exist/dom/memtree/MemTreeBuilder.java b/exist-core/src/main/java/org/exist/dom/memtree/MemTreeBuilder.java
index bf0424dc5d..10b18bbab7 100644
--- a/exist-core/src/main/java/org/exist/dom/memtree/MemTreeBuilder.java
+++ b/exist-core/src/main/java/org/exist/dom/memtree/MemTreeBuilder.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -30,12 +54,15 @@
import org.exist.xquery.XQueryContext;
import org.w3c.dom.DOMException;
import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
import org.xml.sax.Attributes;
import javax.annotation.Nullable;
import javax.xml.XMLConstants;
import java.util.Arrays;
+import static org.exist.util.StringUtil.nullIfEmpty;
+
/**
* Use this class to build a new in-memory DOM document.
@@ -244,9 +271,9 @@ public void endElement() {
public int addReferenceNode(final NodeProxy proxy) {
final int lastNode = doc.getLastNode();
- if((lastNode > 0) && (level == doc.getTreeLevel(lastNode))) {
+ if (lastNode > 0 && level == doc.getTreeLevel(lastNode)) {
- if((doc.getNodeType(lastNode) == Node.TEXT_NODE) && (proxy.getNodeType() == Node.TEXT_NODE)) {
+ if (doc.getNodeType(lastNode) == Node.TEXT_NODE && proxy.getNodeType() == Node.TEXT_NODE) {
// if the last node is a text node, we have to append the
// characters to this node. XML does not allow adjacent text nodes.
@@ -254,12 +281,12 @@ public int addReferenceNode(final NodeProxy proxy) {
return lastNode;
}
- if(doc.getNodeType(lastNode) == NodeImpl.REFERENCE_NODE) {
+ if (doc.getNodeType(lastNode) == NodeImpl.REFERENCE_NODE) {
// check if the previous node is a reference node. if yes, check if it is a text node
final int p = doc.alpha[lastNode];
- if((doc.references[p].getNodeType() == Node.TEXT_NODE) && (proxy.getNodeType() == Node.TEXT_NODE)) {
+ if (doc.references[p].getNodeType() == Node.TEXT_NODE && proxy.getNodeType() == Node.TEXT_NODE) {
// found a text node reference. create a new char sequence containing
// the concatenated text of both nodes
@@ -269,10 +296,40 @@ public int addReferenceNode(final NodeProxy proxy) {
}
}
}
- final int nodeNr = doc.addNode(NodeImpl.REFERENCE_NODE, level, null);
- doc.addReferenceNode(nodeNr, proxy);
- linkNode(nodeNr);
- return nodeNr;
+
+ // check if the node is a Document Node, if so we don't add the document, but instead we add all of its children
+ final NodeProxy[] proxies;
+ if (proxy.getNodeType() == Node.DOCUMENT_NODE) {
+ final org.exist.dom.persistent.DocumentImpl document = (org.exist.dom.persistent.DocumentImpl) proxy.getNode();
+ final NodeList documentChildren = document.getChildNodes();
+ proxies = new NodeProxy[documentChildren.getLength()];
+ for (int i = 0; i < documentChildren.getLength(); i++) {
+ final org.exist.dom.persistent.NodeImpl> child = (org.exist.dom.persistent.NodeImpl>) documentChildren.item(i);
+ proxies[i] = NodeProxy.wrap(proxy.getExpression(), child);
+ }
+
+ // if we are at the top of the in-memory doc, copy over any doctype decl
+ if (level == 1 && document.getDoctype() != null) {
+ final DocumentTypeImpl documentType = new DocumentTypeImpl(document.getExpression(), doc, -1, document.getDoctype().getName(), document.getDoctype().getPublicId(), document.getDoctype().getSystemId());
+ doc.setDoctype(documentType);
+ }
+ } else {
+ proxies = new NodeProxy[1];
+ proxies[0] = proxy;
+ }
+
+ // add the node proxy(s) as reference node(s)
+ int firstProxyNodeNr = -1;
+ for (int i = 0; i < proxies.length; i++) {
+ final int nodeNr = doc.addNode(NodeImpl.REFERENCE_NODE, level, null);
+ doc.addReferenceNode(nodeNr, proxies[i]);
+ linkNode(nodeNr);
+
+ if (firstProxyNodeNr == -1) {
+ firstProxyNodeNr = nodeNr;
+ }
+ }
+ return firstProxyNodeNr;
}
@@ -305,22 +362,22 @@ public int addAttribute(final QName qname, final String value) {
public int characters(final char[] ch, final int start, final int len) {
final int lastNode = doc.getLastNode();
- if((lastNode > 0) && (level == doc.getTreeLevel(lastNode))) {
+ if (lastNode > 0 && level == doc.getTreeLevel(lastNode)) {
- if(doc.getNodeType(lastNode) == Node.TEXT_NODE) {
+ if (doc.getNodeType(lastNode) == Node.TEXT_NODE || doc.getNodeType(lastNode) == Node.CDATA_SECTION_NODE) {
- // if the last node is a text node, we have to append the
+ // if the last node is a Text or CDATA node, we have to append the
// characters to this node. XML does not allow adjacent text nodes.
doc.appendChars(lastNode, ch, start, len);
return lastNode;
}
- if(doc.getNodeType(lastNode) == NodeImpl.REFERENCE_NODE) {
+ if (doc.getNodeType(lastNode) == NodeImpl.REFERENCE_NODE) {
- // check if the previous node is a reference node. if yes, check if it is a text node
+ // check if the previous node is a reference node. if yes, check if it is a Text or CDATA node
final int p = doc.alpha[lastNode];
- if(doc.references[p].getNodeType() == Node.TEXT_NODE) {
+ if (doc.references[p].getNodeType() == Node.TEXT_NODE || doc.references[p].getNodeType() == Node.CDATA_SECTION_NODE) {
// found a text node reference. create a new char sequence containing
// the concatenated text of both nodes
@@ -346,28 +403,28 @@ public int characters(final char[] ch, final int start, final int len) {
* @return the node number of the created node, -1 if no node was created
*/
public int characters(final CharSequence s) {
- if(s == null) {
+ if (s == null) {
return -1;
}
final int lastNode = doc.getLastNode();
- if((lastNode > 0) && (level == doc.getTreeLevel(lastNode))) {
+ if (lastNode > 0 && level == doc.getTreeLevel(lastNode)) {
- if((doc.getNodeType(lastNode) == Node.TEXT_NODE) || (doc.getNodeType(lastNode) == Node.CDATA_SECTION_NODE)) {
+ if (doc.getNodeType(lastNode) == Node.TEXT_NODE || doc.getNodeType(lastNode) == Node.CDATA_SECTION_NODE) {
- // if the last node is a text node, we have to append the
+ // if the last node is a Text or CDATA node, we have to append the
// characters to this node. XML does not allow adjacent text nodes.
doc.appendChars(lastNode, s);
return lastNode;
}
- if(doc.getNodeType(lastNode) == NodeImpl.REFERENCE_NODE) {
+ if (doc.getNodeType(lastNode) == NodeImpl.REFERENCE_NODE) {
- // check if the previous node is a reference node. if yes, check if it is a text node
final int p = doc.alpha[lastNode];
+ // check if the previous node is a reference node. if yes, check if it is a Text or CDATA node
- if((doc.references[p].getNodeType() == Node.TEXT_NODE) || (doc.references[p].getNodeType() == Node.CDATA_SECTION_NODE)) {
+ if (doc.references[p].getNodeType() == Node.TEXT_NODE || doc.references[p].getNodeType() == Node.CDATA_SECTION_NODE) {
// found a text node reference. create a new char sequence containing
// the concatenated text of both nodes
@@ -403,9 +460,9 @@ public int comment(final char[] ch, final int start, final int len) {
public int cdataSection(final CharSequence data) {
final int lastNode = doc.getLastNode();
- if((lastNode > 0) && (level == doc.getTreeLevel(lastNode))) {
+ if (lastNode > 0 && level == doc.getTreeLevel(lastNode)) {
- if((doc.getNodeType(lastNode) == Node.TEXT_NODE) || (doc.getNodeType(lastNode) == Node.CDATA_SECTION_NODE)) {
+ if (doc.getNodeType(lastNode) == Node.TEXT_NODE || doc.getNodeType(lastNode) == Node.CDATA_SECTION_NODE) {
// if the last node is a text node, we have to append the
// characters to this node. XML does not allow adjacent text nodes.
@@ -413,12 +470,12 @@ public int cdataSection(final CharSequence data) {
return lastNode;
}
- if(doc.getNodeType(lastNode) == NodeImpl.REFERENCE_NODE) {
+ if (doc.getNodeType(lastNode) == NodeImpl.REFERENCE_NODE) {
// check if the previous node is a reference node. if yes, check if it is a text node
final int p = doc.alpha[lastNode];
- if((doc.references[p].getNodeType() == Node.TEXT_NODE) || (doc.references[p].getNodeType() == Node.CDATA_SECTION_NODE)) {
+ if (doc.references[p].getNodeType() == Node.TEXT_NODE || doc.references[p].getNodeType() == Node.CDATA_SECTION_NODE) {
// found a text node reference. create a new char sequence containing
// the concatenated text of both nodes
@@ -458,14 +515,16 @@ public int namespaceNode(final QName qname) {
}
public int namespaceNode(final QName qname, final boolean checkNS) {
+ final String qnPrefix = qname.getPrefix() == null ? XMLConstants.DEFAULT_NS_PREFIX : qname.getPrefix();
+ final String qnNs = qname.getNamespaceURI() == null ? XMLConstants.NULL_NS_URI : qname.getNamespaceURI();
+ @Nullable final String qnLocalPart = nullIfEmpty(qname.getLocalPart());
+
final int lastNode = doc.getLastNode();
- boolean addNode = true;
if(doc.nodeName != null) {
final QName elemQN = doc.nodeName[lastNode];
if(elemQN != null) {
- final String elemPrefix = (elemQN.getPrefix() == null) ? XMLConstants.DEFAULT_NS_PREFIX : elemQN.getPrefix();
- final String elemNs = (elemQN.getNamespaceURI() == null) ? XMLConstants.NULL_NS_URI : elemQN.getNamespaceURI();
- final String qnPrefix = (qname.getPrefix() == null) ? XMLConstants.DEFAULT_NS_PREFIX : qname.getPrefix();
+ final String elemPrefix = elemQN.getPrefix() == null ? XMLConstants.DEFAULT_NS_PREFIX : elemQN.getPrefix();
+ final String elemNs = elemQN.getNamespaceURI() == null ? XMLConstants.NULL_NS_URI : elemQN.getNamespaceURI();
if (checkNS
&& XMLConstants.DEFAULT_NS_PREFIX.equals(elemPrefix)
&& XMLConstants.NULL_NS_URI.equals(elemNs)
@@ -477,12 +536,23 @@ public int namespaceNode(final QName qname, final boolean checkNS) {
"Cannot output a namespace node for the default namespace when the element is in no namespace."
);
}
- if(elemPrefix.equals(qname.getLocalPart()) && (elemQN.getNamespaceURI() != null)) {
- addNode = false;
- }
}
}
- return (addNode ? doc.addNamespace(lastNode, qname) : -1);
+
+ final String prefix;
+ if (XMLConstants.XMLNS_ATTRIBUTE.equals(qnPrefix) && qnLocalPart != null) {
+ prefix = qnLocalPart;
+ } else {
+ prefix = XMLConstants.DEFAULT_NS_PREFIX;
+ }
+
+ @Nullable final String existingNs = doc.getInScopePrefix(prefix, lastNode);
+ if (!qnNs.equals(existingNs)) {
+ return doc.addNamespace(lastNode, qname);
+
+ } else {
+ return -1;
+ }
}
diff --git a/exist-core/src/main/java/org/exist/dom/memtree/NamespaceNode.java b/exist-core/src/main/java/org/exist/dom/memtree/NamespaceNode.java
index 55402f9a0e..feffedf9c7 100644
--- a/exist-core/src/main/java/org/exist/dom/memtree/NamespaceNode.java
+++ b/exist-core/src/main/java/org/exist/dom/memtree/NamespaceNode.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -66,7 +90,7 @@ public boolean getSpecified() {
@Override
public String getName() {
- return getQName().getStringValue();
+ return getNodeName();
}
@Override
@@ -78,11 +102,6 @@ public String getValue() {
public void setValue(final String value) throws DOMException {
}
- @Override
- public Node getFirstChild() {
- return null;
- }
-
@Override
public Node getLastChild() {
return null;
diff --git a/exist-core/src/main/java/org/exist/dom/memtree/NodeImpl.java b/exist-core/src/main/java/org/exist/dom/memtree/NodeImpl.java
index 40754e5e81..0f5cbfa870 100644
--- a/exist-core/src/main/java/org/exist/dom/memtree/NodeImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/memtree/NodeImpl.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -34,6 +58,7 @@
import org.exist.numbering.NodeId;
import org.exist.storage.DBBroker;
import org.exist.storage.serializers.Serializer;
+import org.exist.util.serializer.AttrList;
import org.exist.util.serializer.Receiver;
import org.exist.xquery.*;
import org.exist.xquery.value.*;
@@ -55,13 +80,13 @@ public abstract class NodeImpl> implements INode document.attrName[nodeNumber];
- case Node.ELEMENT_NODE, Node.PROCESSING_INSTRUCTION_NODE -> document.nodeName[nodeNumber];
- case NodeImpl.NAMESPACE_NODE -> document.namespaceCode[nodeNumber];
- case Node.DOCUMENT_NODE, Node.COMMENT_NODE, Node.TEXT_NODE, Node.CDATA_SECTION_NODE -> QName.EMPTY_QNAME;
- default -> QName.EMPTY_QNAME;
- };
+ public QName getQName() {
+ switch(getNodeType()) {
+ case Node.ATTRIBUTE_NODE:
+ return document.attrName[nodeNumber];
+
+ case Node.ELEMENT_NODE:
+ case Node.PROCESSING_INSTRUCTION_NODE:
+ return document.nodeName[nodeNumber];
+
+ case NodeImpl.NAMESPACE_NODE:
+ return document.namespaceCode[nodeNumber];
+
+ case Node.DOCUMENT_NODE:
+ return QName.EMPTY_QNAME;
+
+ case Node.COMMENT_NODE:
+ return QName.EMPTY_QNAME;
+
+ case Node.TEXT_NODE:
+ return QName.EMPTY_QNAME;
+
+ case Node.CDATA_SECTION_NODE:
+ return QName.EMPTY_QNAME;
+
+ default:
+ return null;
+ }
}
@Override
@@ -117,24 +161,57 @@ public final void setQName(final QName qname) {
@Override
public final String getNodeName() {
- return switch (getNodeType()) {
- case Node.DOCUMENT_NODE -> "#document";
- case Node.DOCUMENT_FRAGMENT_NODE -> "#document-fragment";
- case Node.ELEMENT_NODE, Node.ATTRIBUTE_NODE, NAMESPACE_NODE -> getQName().getStringValue();
- case Node.PROCESSING_INSTRUCTION_NODE -> ((ProcessingInstructionImpl) this).getTarget();
- case Node.TEXT_NODE -> "#text";
- case Node.COMMENT_NODE -> "#comment";
- case Node.CDATA_SECTION_NODE -> "#cdata-section";
- default -> "#unknown";
- };
+ switch(getNodeType()) {
+ case Node.DOCUMENT_NODE:
+ return "#document";
+
+ case Node.DOCUMENT_FRAGMENT_NODE:
+ return "#document-fragment";
+
+ case Node.ELEMENT_NODE:
+ case Node.ATTRIBUTE_NODE:
+ return getQName().getStringValue();
+
+ case NAMESPACE_NODE:
+ if (XMLConstants.XMLNS_ATTRIBUTE.equals(getQName().getPrefix()) && XMLConstants.DEFAULT_NS_PREFIX.equals(getQName().getLocalPart())) {
+ return XMLConstants.XMLNS_ATTRIBUTE;
+ } else {
+ return getQName().getStringValue();
+ }
+
+ case Node.PROCESSING_INSTRUCTION_NODE:
+ return ((ProcessingInstructionImpl)this).getTarget();
+
+ case Node.TEXT_NODE:
+ return "#text";
+
+ case Node.COMMENT_NODE:
+ return "#comment";
+
+ case Node.CDATA_SECTION_NODE:
+ return "#cdata-section";
+
+ default:
+ return "#unknown";
+ }
}
@Override
public String getLocalName() {
- return switch (getNodeType()) {
- case Node.ELEMENT_NODE, Node.ATTRIBUTE_NODE, NAMESPACE_NODE -> getQName().getLocalPart();
- default -> null;
- };
+ switch(getNodeType()) {
+ case Node.ELEMENT_NODE:
+ case Node.ATTRIBUTE_NODE:
+ return getQName().getLocalPart();
+ case NAMESPACE_NODE:
+ if (XMLConstants.XMLNS_ATTRIBUTE.equals(getQName().getPrefix()) && XMLConstants.DEFAULT_NS_PREFIX.equals(getQName().getLocalPart())) {
+ return null;
+ } else {
+ return getQName().getLocalPart();
+ }
+
+ default:
+ return null;
+ }
}
@Override
@@ -187,6 +264,7 @@ public NodeId getNodeId() {
return document.nodeId[nodeNumber];
}
+ // TODO(AR) see if we can get rid of expansion now we have org.exist.dom.memtree.reference.* classes
public void expand() throws DOMException {
document.expand();
}
@@ -364,6 +442,15 @@ public NamedNodeMap getAttributes() {
return null;
}
+ /**
+ * Get a list of attributes.
+ *
+ * @return the attribute list, or null if there are no attributes.
+ */
+ public @Nullable AttrList getAttrList() {
+ return null;
+ }
+
@Override
public DocumentImpl getOwnerDocument() {
return document;
@@ -867,7 +954,7 @@ public boolean isDefaultNamespace(final String namespaceURI) {
@Override
public String lookupNamespaceURI(final String prefix) {
- throw unsupported();
+ return document.lookupNamespaceURI(prefix);
}
@Override
diff --git a/exist-core/src/main/java/org/exist/dom/memtree/ProcessingInstructionImpl.java b/exist-core/src/main/java/org/exist/dom/memtree/ProcessingInstructionImpl.java
index ad2c3a79ec..913682b992 100644
--- a/exist-core/src/main/java/org/exist/dom/memtree/ProcessingInstructionImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/memtree/ProcessingInstructionImpl.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -111,12 +135,6 @@ public String getBaseURI() {
return (baseURI);
}
- @Override
- public Node getFirstChild() {
- //No child
- return null;
- }
-
@Override
public int getItemType() {
return Type.PROCESSING_INSTRUCTION;
diff --git a/exist-core/src/main/java/org/exist/dom/memtree/ReferenceNode.java b/exist-core/src/main/java/org/exist/dom/memtree/ReferenceNode.java
deleted file mode 100644
index 5f80f8a007..0000000000
--- a/exist-core/src/main/java/org/exist/dom/memtree/ReferenceNode.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * eXist-db Open Source Native XML Database
- * Copyright (C) 2001 The eXist-db Authors
- *
- * info@exist-db.org
- * http://www.exist-db.org
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-package org.exist.dom.memtree;
-
-import org.exist.dom.persistent.NodeProxy;
-import org.exist.xquery.Expression;
-import org.exist.xquery.NodeTest;
-import org.exist.xquery.XPathException;
-import org.exist.xquery.value.Sequence;
-import org.w3c.dom.DOMException;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-
-
-/**
- * DOCUMENT ME!
- *
- * @author wolf
- */
-public class ReferenceNode extends NodeImpl {
-
- public ReferenceNode(final DocumentImpl doc, final int nodeNumber) {
- this(null, doc, nodeNumber);
- }
-
- public ReferenceNode(final Expression expression, final DocumentImpl doc, final int nodeNumber) {
- super(expression, doc, nodeNumber);
- }
-
- public NodeProxy getReference() {
- final int p = document.alpha[nodeNumber];
- return document.references[p];
- }
-
- @Override
- public String toString() {
- return "reference[ " + getReference().getNode().toString() + " ]";
- }
-
- @Override
- public String getNamespaceURI() {
- return getReference().getNode().getNamespaceURI();
- }
-
- @Override
- public String getLocalName() {
- return getReference().getNode().getLocalName();
- }
-
- @Override
- public NamedNodeMap getAttributes() {
- return getReference().getNode().getAttributes();
- }
-
- @Override
- public Node getFirstChild() {
- //TODO : how to make this node a reference as well ?
- return getReference().getNode().getFirstChild();
- }
-
- @Override
- public void selectAttributes(final NodeTest test, final Sequence result)
- throws XPathException {
- }
-
- @Override
- public void selectChildren(final NodeTest test, final Sequence result)
- throws XPathException {
- }
-
- @Override
- public void selectDescendantAttributes(final NodeTest test, final Sequence result)
- throws XPathException {
- }
-
- @Override
- public String getNodeValue() throws DOMException {
- return getReference().getNode().getNodeValue();
- }
-}
\ No newline at end of file
diff --git a/exist-core/src/main/java/org/exist/dom/memtree/reference/AbstractReferenceCharacterData.java b/exist-core/src/main/java/org/exist/dom/memtree/reference/AbstractReferenceCharacterData.java
new file mode 100644
index 0000000000..94ce237fb1
--- /dev/null
+++ b/exist-core/src/main/java/org/exist/dom/memtree/reference/AbstractReferenceCharacterData.java
@@ -0,0 +1,81 @@
+/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package org.exist.dom.memtree.reference;
+
+import org.exist.dom.memtree.DocumentImpl;
+import org.exist.dom.persistent.NodeProxy;
+import org.exist.xquery.Expression;
+import org.w3c.dom.CharacterData;
+import org.w3c.dom.DOMException;
+
+import javax.annotation.Nullable;
+
+public class AbstractReferenceCharacterData, P extends org.exist.dom.persistent.AbstractCharacterData
> extends AbstractReferenceNodeImpl implements CharacterData {
+
+ public AbstractReferenceCharacterData(@Nullable final Expression expression, final DocumentImpl doc, final int nodeNumber, final NodeProxy nodeProxy) {
+ super(expression, doc, nodeNumber, nodeProxy);
+ }
+
+ @Override
+ public int compareTo(final T other) {
+ return getProxiedNode().compareTo(other.getProxiedNode());
+ }
+
+ @Override
+ public String getData() throws DOMException {
+ return getProxiedNode().getData();
+ }
+
+ @Override
+ public void setData(final String data) throws DOMException {
+ getProxiedNode().setData(data);
+ }
+
+ @Override
+ public int getLength() {
+ return getProxiedNode().getLength();
+ }
+
+ @Override
+ public String substringData(final int offset, final int count) throws DOMException {
+ return getProxiedNode().substringData(offset, count);
+ }
+
+ @Override
+ public void appendData(final String arg) throws DOMException {
+ getProxiedNode().appendData(arg);
+ }
+
+ @Override
+ public void insertData(final int offset, final String arg) throws DOMException {
+ getProxiedNode().insertData(offset, arg);
+ }
+
+ @Override
+ public void deleteData(int offset, int count) throws DOMException {
+
+ }
+
+ @Override
+ public void replaceData(int offset, int count, String arg) throws DOMException {
+
+ }
+}
diff --git a/exist-core/src/main/java/org/exist/dom/memtree/reference/AbstractReferenceNodeImpl.java b/exist-core/src/main/java/org/exist/dom/memtree/reference/AbstractReferenceNodeImpl.java
new file mode 100644
index 0000000000..80109afdab
--- /dev/null
+++ b/exist-core/src/main/java/org/exist/dom/memtree/reference/AbstractReferenceNodeImpl.java
@@ -0,0 +1,176 @@
+/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package org.exist.dom.memtree.reference;
+
+import org.exist.dom.QName;
+import org.exist.dom.memtree.DocumentImpl;
+import org.exist.dom.memtree.NodeImpl;
+import org.exist.dom.persistent.AttrImpl;
+import org.exist.dom.persistent.NodeProxy;
+import org.exist.xquery.Expression;
+import org.exist.xquery.NodeTest;
+import org.exist.xquery.XPathException;
+import org.exist.xquery.value.Sequence;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.annotation.Nullable;
+
+/**
+ * DOM Wrapper around a NodeProxy for use in the in-memory DOM.
+ *
+ * @author Adam Retter
+ */
+public abstract class AbstractReferenceNodeImpl, P extends org.exist.dom.persistent.NodeImpl
> extends NodeImpl {
+
+ protected final NodeProxy nodeProxy;
+
+ public AbstractReferenceNodeImpl(@Nullable final Expression expression, final DocumentImpl doc, final int nodeNumber, final NodeProxy nodeProxy) {
+ super(expression, doc, nodeNumber);
+ this.nodeProxy = nodeProxy;
+ }
+
+ /**
+ * Get the node proxy.
+ *
+ * @return the node proxy.
+ */
+ public NodeProxy getNodeProxy() {
+ return nodeProxy;
+ }
+
+ @SuppressWarnings("unchchecked")
+ protected P getProxiedNode() {
+ return (P) nodeProxy.getNode();
+ }
+
+ @Override
+ public String toString() {
+ return "reference[ " + getProxiedNode().toString() + " ]";
+ }
+
+ @Override
+ public String getNamespaceURI() {
+ final QName qname = getNodeProxy().getQName();
+ if (qname == null) {
+ return null;
+ }
+ return qname.getNamespaceURI();
+ }
+
+ @Override
+ public String getLocalName() {
+ final QName qname = getNodeProxy().getQName();
+ if (qname == null) {
+ return null;
+ }
+ return qname.getLocalPart();
+ }
+
+ @Override
+ public NamedNodeMap getAttributes() {
+ return getProxiedNode().getAttributes();
+ }
+
+ @Override
+ public NodeList getChildNodes() {
+ return getProxiedNode().getChildNodes();
+ }
+
+ @Override
+ public Node getFirstChild() {
+ return getProxiedNode().getFirstChild();
+ }
+
+ @Override
+ public Node getLastChild() {
+ return getProxiedNode().getLastChild();
+ }
+
+ @Override
+ public boolean hasAttributes() {
+ return getProxiedNode().hasAttributes();
+ }
+
+ @Override
+ public void selectAttributes(final NodeTest test, final Sequence result) throws XPathException {
+ selectAttributes(getProxiedNode(), test, result);
+ }
+
+ @Override
+ public boolean hasChildNodes() {
+ return getProxiedNode().hasChildNodes();
+ }
+
+ private void selectAttributes(final Node node, final NodeTest test, final Sequence result) throws XPathException {
+ @Nullable final NamedNodeMap attrs = node.getAttributes();
+ if (attrs != null) {
+ for (int i = 0; i < attrs.getLength(); i++) {
+ final Node attr = attrs.item(i);
+ if (test.matches(attr)) {
+ result.add(new NodeProxy((org.exist.dom.persistent.AttrImpl) attr));
+ }
+ }
+ }
+ }
+
+ @Override
+ public void selectChildren(final NodeTest test, final Sequence result) throws XPathException {
+ @Nullable final NodeList children = getProxiedNode().getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ final Node child = children.item(i);
+ if (test.matches(child)) {
+ result.add(new NodeProxy((org.exist.dom.persistent.NodeHandle) child));
+ }
+ }
+ }
+
+ @Override
+ public void selectDescendantAttributes(final NodeTest test, final Sequence result) throws XPathException {
+ selectDescendantAttributes(getProxiedNode(), test, result);
+ }
+
+ private void selectDescendantAttributes(final Node node, final NodeTest test, final Sequence result) throws XPathException {
+ final NodeList children = node.getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ final Node child = children.item(i);
+ selectAttributes(child, test, result);
+ selectDescendantAttributes(child, test, result);
+ }
+ }
+
+ @Override
+ public String getNodeValue() throws DOMException {
+ return getProxiedNode().getNodeValue();
+ }
+
+ @Override
+ public short getNodeType() {
+ return getNodeProxy().getNodeType();
+ }
+
+ @Override
+ public QName getQName() {
+ return getNodeProxy().getQName();
+ }
+}
\ No newline at end of file
diff --git a/exist-core/src/main/java/org/exist/dom/memtree/reference/CommentReferenceImpl.java b/exist-core/src/main/java/org/exist/dom/memtree/reference/CommentReferenceImpl.java
new file mode 100644
index 0000000000..073ebea62e
--- /dev/null
+++ b/exist-core/src/main/java/org/exist/dom/memtree/reference/CommentReferenceImpl.java
@@ -0,0 +1,40 @@
+/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package org.exist.dom.memtree.reference;
+
+import org.exist.dom.memtree.DocumentImpl;
+import org.exist.dom.persistent.NodeProxy;
+import org.exist.xquery.Expression;
+import org.w3c.dom.Comment;
+
+import javax.annotation.Nullable;
+
+/**
+ * Comment wrapper around a NodeProxy for use in the in-memory DOM.
+ *
+ * @author Adam Retter
+ */
+public class CommentReferenceImpl extends AbstractReferenceCharacterData implements Comment {
+
+ public CommentReferenceImpl(@Nullable final Expression expression, final DocumentImpl doc, final int nodeNumber, final NodeProxy nodeProxy) {
+ super(expression, doc, nodeNumber, nodeProxy);
+ }
+}
diff --git a/exist-core/src/main/java/org/exist/dom/memtree/reference/ElementReferenceImpl.java b/exist-core/src/main/java/org/exist/dom/memtree/reference/ElementReferenceImpl.java
new file mode 100644
index 0000000000..850d00e5f7
--- /dev/null
+++ b/exist-core/src/main/java/org/exist/dom/memtree/reference/ElementReferenceImpl.java
@@ -0,0 +1,174 @@
+/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package org.exist.dom.memtree.reference;
+
+import org.exist.dom.QName;
+import org.exist.dom.memtree.DocumentImpl;
+import org.exist.dom.persistent.AttrImpl;
+import org.exist.dom.persistent.NodeProxy;
+import org.exist.dom.persistent.StoredNode;
+import org.exist.numbering.NodeId;
+import org.exist.storage.ElementValue;
+import org.exist.util.serializer.AttrList;
+import org.exist.xquery.Expression;
+import org.w3c.dom.*;
+
+import javax.annotation.Nullable;
+
+/**
+ * Element wrapper around a NodeProxy for use in the in-memory DOM.
+ *
+ * @author Adam Retter
+ */
+public class ElementReferenceImpl extends AbstractReferenceNodeImpl implements Element {
+
+ public ElementReferenceImpl(@Nullable final Expression expression, final DocumentImpl doc, final int nodeNumber, final NodeProxy nodeProxy) {
+ super(expression, doc, nodeNumber, nodeProxy);
+ }
+
+ @Override
+ public int compareTo(final ElementReferenceImpl other) {
+ return 0;
+ }
+
+ @Override
+ public String getTagName() {
+ final QName qname = getNodeProxy().getQName();
+ if (qname == null) {
+ return null;
+ }
+ return qname.getStringValue();
+ }
+
+ @Override
+ public @Nullable AttrList getAttrList() {
+ @Nullable AttrList attrList = null;
+ @Nullable final NamedNodeMap attributes = getProxiedNode().getAttributes();
+ if (attributes != null) {
+ final int attrsLength = attributes.getLength();
+ for (int i = 0; i > attrsLength; i++) {
+ if (attrList == null) {
+ attrList = new AttrList(attrsLength);
+ }
+ final Attr attr = (Attr) attributes.item(i);
+ final QName attrQname = new QName(attr.getLocalName(), attr.getNamespaceURI(), attr.getPrefix(), ElementValue.ATTRIBUTE);
+ final NodeId attrNodeId = attr instanceof StoredNode ? ((StoredNode) attr).getNodeId() : null;
+ attrList.addAttribute(attrQname, attr.getValue(), AttrImpl.CDATA, attrNodeId);
+ }
+ }
+ return attrList;
+ }
+
+ @Override
+ public String getAttribute(final String name) {
+ return getProxiedNode().getAttribute(name);
+ }
+
+ @Override
+ public void setAttribute(final String name, final String value) throws DOMException {
+ getProxiedNode().setAttribute(name, value);
+ }
+
+ @Override
+ public void removeAttribute(final String name) throws DOMException {
+ getProxiedNode().removeAttribute(name);
+ }
+
+ @Override
+ public Attr getAttributeNode(final String name) {
+ return getProxiedNode().getAttributeNode(name);
+ }
+
+ @Override
+ public Attr setAttributeNode(final Attr attr) throws DOMException {
+ return getProxiedNode().setAttributeNode(attr);
+ }
+
+ @Override
+ public Attr removeAttributeNode(final Attr attr) throws DOMException {
+ return getProxiedNode().removeAttributeNode(attr);
+ }
+
+ @Override
+ public NodeList getElementsByTagName(final String name) {
+ return getProxiedNode().getElementsByTagName(name);
+ }
+
+ @Override
+ public String getAttributeNS(final String namespaceUri, final String localName) throws DOMException {
+ return getProxiedNode().getAttributeNS(namespaceUri, localName);
+ }
+
+ @Override
+ public void setAttributeNS(final String namespaceUri, final String qualifiedName, final String value) throws DOMException {
+ getProxiedNode().setAttributeNS(namespaceUri, qualifiedName, value);
+ }
+
+ @Override
+ public void removeAttributeNS(final String namespaceUri, final String localName) throws DOMException {
+ getProxiedNode().removeAttributeNS(namespaceUri, localName);
+ }
+
+ @Override
+ public Attr getAttributeNodeNS(final String namespaceUri, final String localName) throws DOMException {
+ return getProxiedNode().getAttributeNodeNS(namespaceUri, localName);
+ }
+
+ @Override
+ public Attr setAttributeNodeNS(final Attr attr) throws DOMException {
+ return getProxiedNode().setAttributeNodeNS(attr);
+ }
+
+ @Override
+ public NodeList getElementsByTagNameNS(final String namespaceUri, final String localName) throws DOMException {
+ return getProxiedNode().getElementsByTagNameNS(namespaceUri, localName);
+ }
+
+ @Override
+ public boolean hasAttribute(final String name) {
+ return getProxiedNode().hasAttribute(name);
+ }
+
+ @Override
+ public boolean hasAttributeNS(final String namespaceUri, final String localName) throws DOMException {
+ return getProxiedNode().hasAttributeNS(namespaceUri, localName);
+ }
+
+ @Override
+ public TypeInfo getSchemaTypeInfo() {
+ return getProxiedNode().getSchemaTypeInfo();
+ }
+
+ @Override
+ public void setIdAttribute(final String name, final boolean isId) throws DOMException {
+ getProxiedNode().setIdAttribute(name, isId);
+ }
+
+ @Override
+ public void setIdAttributeNS(final String namespaceUri, final String localName, final boolean isId) throws DOMException {
+ getProxiedNode().setIdAttributeNS(namespaceUri, localName, isId);
+ }
+
+ @Override
+ public void setIdAttributeNode(final Attr attr, final boolean isId) throws DOMException {
+ getProxiedNode().setIdAttributeNode(attr, isId);
+ }
+}
diff --git a/exist-core/src/main/java/org/exist/dom/memtree/reference/ProcessingInstructionReferenceImpl.java b/exist-core/src/main/java/org/exist/dom/memtree/reference/ProcessingInstructionReferenceImpl.java
new file mode 100644
index 0000000000..cc4982ad56
--- /dev/null
+++ b/exist-core/src/main/java/org/exist/dom/memtree/reference/ProcessingInstructionReferenceImpl.java
@@ -0,0 +1,61 @@
+/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package org.exist.dom.memtree.reference;
+
+import org.exist.dom.memtree.DocumentImpl;
+import org.exist.dom.persistent.NodeProxy;
+import org.exist.xquery.Expression;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.ProcessingInstruction;
+
+import javax.annotation.Nullable;
+
+/**
+ * Processing Instruction wrapper around a NodeProxy for use in the in-memory DOM.
+ *
+ * @author Adam Retter
+ */
+public class ProcessingInstructionReferenceImpl extends AbstractReferenceNodeImpl implements ProcessingInstruction {
+
+ public ProcessingInstructionReferenceImpl(@Nullable final Expression expression, final DocumentImpl doc, final int nodeNumber, final NodeProxy nodeProxy) {
+ super(expression, doc, nodeNumber, nodeProxy);
+ }
+
+ @Override
+ public int compareTo(final ProcessingInstructionReferenceImpl other) {
+ return 0;
+ }
+
+ @Override
+ public String getTarget() {
+ return getProxiedNode().getTarget();
+ }
+
+ @Override
+ public String getData() {
+ return getProxiedNode().getData();
+ }
+
+ @Override
+ public void setData(final String data) throws DOMException {
+ getProxiedNode().setData(data);
+ }
+}
diff --git a/exist-core/src/main/java/org/exist/dom/memtree/reference/TextReferenceImpl.java b/exist-core/src/main/java/org/exist/dom/memtree/reference/TextReferenceImpl.java
new file mode 100644
index 0000000000..730e3d470e
--- /dev/null
+++ b/exist-core/src/main/java/org/exist/dom/memtree/reference/TextReferenceImpl.java
@@ -0,0 +1,61 @@
+/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package org.exist.dom.memtree.reference;
+
+import org.exist.dom.memtree.DocumentImpl;
+import org.exist.dom.persistent.NodeProxy;
+import org.exist.xquery.Expression;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Text;
+
+import javax.annotation.Nullable;
+
+/**
+ * Text wrapper around a NodeProxy for use in the in-memory DOM.
+ *
+ * @author Adam Retter
+ */
+public class TextReferenceImpl extends AbstractReferenceCharacterData implements Text {
+
+ public TextReferenceImpl(@Nullable final Expression expression, final DocumentImpl doc, final int nodeNumber, final NodeProxy nodeProxy) {
+ super(expression, doc, nodeNumber, nodeProxy);
+ }
+
+ @Override
+ public Text splitText(final int offset) throws DOMException {
+ return getProxiedNode().splitText(offset);
+ }
+
+ @Override
+ public boolean isElementContentWhitespace() {
+ return getProxiedNode().isElementContentWhitespace();
+ }
+
+ @Override
+ public String getWholeText() {
+ return getProxiedNode().getWholeText();
+ }
+
+ @Override
+ public Text replaceWholeText(final String content) throws DOMException {
+ return getProxiedNode().replaceWholeText(content);
+ }
+}
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/AbstractArrayNodeSet.java b/exist-core/src/main/java/org/exist/dom/persistent/AbstractArrayNodeSet.java
index 634edb1c70..9b85afccae 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/AbstractArrayNodeSet.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/AbstractArrayNodeSet.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/AbstractCharacterData.java b/exist-core/src/main/java/org/exist/dom/persistent/AbstractCharacterData.java
index b23d6f2c8d..9ad53845d3 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/AbstractCharacterData.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/AbstractCharacterData.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -30,7 +54,7 @@
import org.w3c.dom.DOMException;
import org.w3c.dom.Node;
-public abstract class AbstractCharacterData extends StoredNode implements CharacterData {
+public abstract class AbstractCharacterData> extends StoredNode implements CharacterData {
protected XMLString cdata = null;
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/AbstractNodeSet.java b/exist-core/src/main/java/org/exist/dom/persistent/AbstractNodeSet.java
index 250070ecfc..c600b75b5e 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/AbstractNodeSet.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/AbstractNodeSet.java
@@ -547,7 +547,7 @@ public NodeSet getContextNodes(final int contextId) {
if (Expression.NO_CONTEXT_ID != contextId) {
context.addContextNode(contextId, context);
}
- if (lastDoc != null && lastDoc.getDocId() != context.getOwnerDocument().getDocId()) {
+ if (lastDoc == null || lastDoc.getDocId() != context.getOwnerDocument().getDocId()) {
lastDoc = context.getOwnerDocument();
result.add(context, getSizeHint(lastDoc));
} else {
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/AttrImpl.java b/exist-core/src/main/java/org/exist/dom/persistent/AttrImpl.java
index f46530fe92..a829fb5639 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/AttrImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/AttrImpl.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -376,6 +400,11 @@ public Node getFirstChild() {
return null;
}
+ @Override
+ public Node getPreviousSibling() {
+ return null;
+ }
+
@Override
public Node getNextSibling() {
return null;
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/BinaryDocument.java b/exist-core/src/main/java/org/exist/dom/persistent/BinaryDocument.java
index f9c12b3666..36583072a0 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/BinaryDocument.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/BinaryDocument.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -27,7 +51,7 @@
import org.exist.storage.BrokerPool;
import org.exist.storage.blob.BlobId;
import org.exist.storage.io.VariableByteInput;
-import org.exist.storage.io.VariableByteOutputStream;
+import org.exist.storage.io.VariableByteOutput;
import org.exist.xmldb.XmldbURI;
import org.exist.xquery.Expression;
import org.w3c.dom.DocumentType;
@@ -167,7 +191,7 @@ public void setBlobId(final BlobId blobId) {
}
@Override
- public void write(final VariableByteOutputStream ostream) throws IOException {
+ public void write(final VariableByteOutput ostream) throws IOException {
ostream.writeInt(getDocId());
ostream.writeUTF(getFileURI().toString());
@@ -181,7 +205,7 @@ public void write(final VariableByteOutputStream ostream) throws IOException {
// document attributes
ostream.writeLong(created);
ostream.writeLong(lastModified);
- ostream.writeInt(pool.getSymbols().getMimeTypeId(mimeType));
+ ostream.writeInt(pool.getSymbols().getMimeTypeId(mediaType));
ostream.writeInt(pageCount);
ostream.writeInt(userLock);
if (docType != null) {
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/CommentImpl.java b/exist-core/src/main/java/org/exist/dom/persistent/CommentImpl.java
index 91af39abf2..99d7ec3c7a 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/CommentImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/CommentImpl.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -31,7 +55,7 @@
import static java.nio.charset.StandardCharsets.UTF_8;
-public class CommentImpl extends AbstractCharacterData implements Comment {
+public class CommentImpl extends AbstractCharacterData implements Comment {
public CommentImpl() {
this((Expression) null);
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/DocumentImpl.java b/exist-core/src/main/java/org/exist/dom/persistent/DocumentImpl.java
index be75909778..e5a0f919b8 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/DocumentImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/DocumentImpl.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -35,11 +59,10 @@
import org.exist.security.*;
import org.exist.storage.*;
import org.exist.storage.io.VariableByteInput;
-import org.exist.storage.io.VariableByteOutputStream;
+import org.exist.storage.io.VariableByteOutput;
import org.exist.storage.lock.EnsureContainerLocked;
import org.exist.storage.lock.EnsureLocked;
import org.exist.storage.txn.Txn;
-import org.exist.util.MimeType;
import org.exist.util.XMLString;
import org.exist.xmldb.XmldbURI;
import org.exist.xquery.Constants;
@@ -47,6 +70,7 @@
import org.exist.xquery.NameTest;
import org.exist.xquery.value.Type;
import org.w3c.dom.*;
+import xyz.elemental.mediatype.MediaType;
import javax.annotation.Nullable;
import javax.xml.XMLConstants;
@@ -121,7 +145,7 @@ public class DocumentImpl extends NodeImpl implements Resource, Do
/**
* The mimeType of the document
*/
- protected String mimeType = MimeType.XML_TYPE.getName();
+ protected String mediaType = MediaType.APPLICATION_XML;
/**
* The creation time of this document
@@ -248,7 +272,7 @@ public DocumentImpl(final Expression expression, final int docId, final Document
* @param childAddress the addresses of the child nodes
* @param created the created time of the document
* @param lastModified the last modified time of the document, or null to use the {@code created} time
- * @param mimeType the media type of the document, or null for application/xml
+ * @param mediaType the media type of the document, or null for application/xml
* @param docType the document type, or null
*
* @deprecated Use {@link DocumentImpl(BrokerPool, Collection, int, XmldbURI, Permission, int, long[], long, Long, String, XMLDeclarationImpl, DocumentType)}
@@ -257,9 +281,9 @@ public DocumentImpl(final Expression expression, final int docId, final Document
public DocumentImpl(final BrokerPool pool, @Nullable final Collection collection,
final int docId, final XmldbURI fileURI, final Permission permissions,
final int children, @Nullable final long[] childAddress,
- final long created, @Nullable final Long lastModified, @Nullable final String mimeType,
+ final long created, @Nullable final Long lastModified, @Nullable final String mediaType,
@Nullable final DocumentType docType) {
- this(null, pool, collection, docId, fileURI, permissions, children, childAddress, created, lastModified, mimeType, null, docType);
+ this(null, pool, collection, docId, fileURI, permissions, children, childAddress, created, lastModified, mediaType, null, docType);
}
/**
@@ -274,16 +298,16 @@ public DocumentImpl(final BrokerPool pool, @Nullable final Collection collection
* @param childAddress the addresses of the child nodes
* @param created the created time of the document
* @param lastModified the last modified time of the document, or null to use the {@code created} time
- * @param mimeType the media type of the document, or null for application/xml
+ * @param mediaType the media type of the document, or null for application/xml
* @param xmlDecl the XML Declaration, or null
* @param docType the document type, or null
*/
public DocumentImpl(final BrokerPool pool, @Nullable final Collection collection,
final int docId, final XmldbURI fileURI, final Permission permissions,
final int children, @Nullable final long[] childAddress,
- final long created, @Nullable final Long lastModified, @Nullable final String mimeType,
+ final long created, @Nullable final Long lastModified, @Nullable final String mediaType,
@Nullable final XMLDeclarationImpl xmlDecl, @Nullable final DocumentType docType) {
- this(null, pool, collection, docId, fileURI, permissions, children, childAddress, created, lastModified, mimeType, xmlDecl, docType);
+ this(null, pool, collection, docId, fileURI, permissions, children, childAddress, created, lastModified, mediaType, xmlDecl, docType);
}
/**
@@ -299,7 +323,7 @@ public DocumentImpl(final BrokerPool pool, @Nullable final Collection collection
* @param childAddress the addresses of the child nodes
* @param created the created time of the document
* @param lastModified the last modified time of the document, or null to use the {@code created} time
- * @param mimeType the media type of the document, or null for application/xml
+ * @param mediaType the media type of the document, or null for application/xml
* @param docType the document type, or null
*
* @deprecated Use {@link DocumentImpl(Expression, BrokerPool, Collection, int ,XmldbURI, Permission, int, long[], long, Long, String, XMLDeclarationImpl, DocumentType)}
@@ -308,9 +332,9 @@ public DocumentImpl(final BrokerPool pool, @Nullable final Collection collection
public DocumentImpl(final Expression expression, final BrokerPool pool, @Nullable final Collection collection,
final int docId, final XmldbURI fileURI, final Permission permissions,
final int children, @Nullable final long[] childAddress,
- final long created, @Nullable final Long lastModified, @Nullable final String mimeType,
+ final long created, @Nullable final Long lastModified, @Nullable final String mediaType,
@Nullable final DocumentType docType) {
- this(expression, pool, collection, docId, fileURI, permissions, children, childAddress, created, lastModified, mimeType, null, docType);
+ this(expression, pool, collection, docId, fileURI, permissions, children, childAddress, created, lastModified, mediaType, null, docType);
}
/**
@@ -326,14 +350,14 @@ public DocumentImpl(final Expression expression, final BrokerPool pool, @Nullabl
* @param childAddress the addresses of the child nodes
* @param created the created time of the document
* @param lastModified the last modified time of the document, or null to use the {@code created} time
- * @param mimeType the media type of the document, or null for application/xml
+ * @param mediaType the media type of the document, or null for application/xml
* @param xmlDecl the XML Declaration, or null
* @param docType the document type, or null
*/
public DocumentImpl(final Expression expression, final BrokerPool pool, @Nullable final Collection collection,
final int docId, final XmldbURI fileURI, final Permission permissions,
final int children, @Nullable final long[] childAddress,
- final long created, @Nullable final Long lastModified, @Nullable final String mimeType,
+ final long created, @Nullable final Long lastModified, @Nullable final String mediaType,
@Nullable final XMLDeclarationImpl xmlDecl, @Nullable final DocumentType docType) {
super(expression);
this.pool = pool;
@@ -348,7 +372,7 @@ public DocumentImpl(final Expression expression, final BrokerPool pool, @Nullabl
this.childAddress = childAddress;
this.created = created;
this.lastModified = lastModified == null ? created : lastModified;
- this.mimeType = mimeType == null ? MimeType.XML_TYPE.getName() : mimeType;
+ this.mediaType = mediaType != null ? mediaType : MediaType.APPLICATION_XML;
this.xmlDecl = xmlDecl;
this.docType = docType;
@@ -465,12 +489,42 @@ public void setLastModified(final long lastModified) {
this.lastModified = lastModified;
}
+ /**
+ * Get the Internet Media Type of the document.
+ *
+ * @return the Internet Media Type of the document.
+ *
+ * @deprecated Use {@link #getMediaType()} instead.
+ */
+ @Deprecated
public String getMimeType() {
- return mimeType;
+ return mediaType;
}
+ /**
+ * Set the Internet Media Type of the document.
+ *
+ * @deprecated Use {@link #setMediaType(String)} instead.
+ */
+ @Deprecated
public void setMimeType(final String mimeType) {
- this.mimeType = mimeType;
+ this.mediaType = mimeType;
+ }
+
+ /**
+ * Get the Internet Media Type of the document.
+ *
+ * @return the Internet Media Type of the document.
+ */
+ public String getMediaType() {
+ return mediaType;
+ }
+
+ /**
+ * Set the Internet Media Type of the document.
+ */
+ public void setMediaType(final String mediaType) {
+ this.mediaType = mediaType;
}
/**
@@ -521,6 +575,14 @@ public void setLockToken(final LockToken token) {
lockToken = token;
}
+ /**
+ * Get the Document Type.
+ *
+ * @return the document type.
+ *
+ * @deprecated use {@link #getDoctype()}.
+ */
+ @Deprecated
public DocumentType getDocType() {
return docType;
}
@@ -612,7 +674,7 @@ public DocumentMetadata getMetadata() {
* Copy the relevant internal fields from the specified document object.
* This is called by {@link Collection} when replacing a document.
*
- * @param broker eXist-db DBBroker
+ * @param broker the DBBroker
* @param other a DocumentImpl value
* @param prev if there was an existing document which we are replacing,
* we will copy the mode, ACL, and birth time from the existing document.
@@ -625,7 +687,7 @@ public void copyOf(final DBBroker broker, final DocumentImpl other, @EnsureLocke
/**
* Copy the relevant internal fields from the specified document object.
* This is called by {@link Collection} when replacing a document.
- * @param broker eXist-db DBBroker
+ * @param broker the DBBroker
* @param other a DocumentImpl value
* @param prev if there was an existing document which we are replacing,
* we will copy the mode, ACL, and birth time from the existing document.
@@ -651,7 +713,7 @@ private void copyOf(final DBBroker broker, @EnsureLocked(mode=READ_LOCK) final D
this.created = other.created;
this.lastModified = other.lastModified;
- this.mimeType = other.mimeType;
+ this.mediaType = other.mediaType;
this.docType = other.docType;
final long timestamp = System.currentTimeMillis();
@@ -689,7 +751,7 @@ private void copyModeAcl(final DBBroker broker, final Permission srcPermissions,
PermissionFactory.chmod(broker, destPermissions, Optional.of(srcPermissions.getMode()), Optional.empty());
if (srcPermissions instanceof SimpleACLPermission srcAclPermissions && destPermissions instanceof SimpleACLPermission destAclPermissions) {
- if (!destAclPermissions.equalsAcl(srcAclPermissions)) {
+ if (!destAclPermissions.aclEquals(srcAclPermissions)) {
PermissionFactory.chacl(destAclPermissions, newAcl ->
((SimpleACLPermission)newAcl).copyAclOf(srcAclPermissions)
);
@@ -761,12 +823,14 @@ public void triggerDefrag() {
}
/**
- * The method getNode
+ * Retrieve a node from the document
+ * by its nodeId
*
- * @param nodeId a NodeId value
- * @return a Node value
+ * @param nodeId the nodeId of the node to find.
+ *
+ * @return the node, or null if it does not exist.
*/
- public Node getNode(final NodeId nodeId) {
+ @Nullable Node getNode(final NodeId nodeId) {
try(final DBBroker broker = pool.getBroker()) {
return broker.objectWith(this, nodeId);
} catch(final EXistException e) {
@@ -776,16 +840,21 @@ public Node getNode(final NodeId nodeId) {
}
/**
- * The method getNode
+ * Retrieve a node from the document
+ * by its nodeProxy
*
- * @param p a NodeProxy value
- * @return a Node value
+ * This should only be called from {@link NodeProxy#getNode()}.
+ *
+ * @param p the proxy of the node to find.
+ *
+ * @return the node, or null if it does not exist.
*/
- public Node getNode(final NodeProxy p) {
- if(p.getNodeId().getTreeLevel() == 1) {
- return getDocumentElement();
+ Node getNode(final NodeProxy p) {
+ if (p.getNodeId() == NodeId.DOCUMENT_NODE || p.getNodeId().equals(NodeId.DOCUMENT_NODE)) {
+ return this;
}
- try(final DBBroker broker = pool.getBroker()) {
+
+ try (final DBBroker broker = pool.getBroker()) {
return broker.objectWith(p);
} catch(final Exception e) {
LOG.warn("Error occurred while retrieving node: {}", e.getMessage(), e);
@@ -820,11 +889,11 @@ public void appendChild(final NodeHandle child) throws DOMException {
/**
* The method write
*
- * @param ostream a VariableByteOutputStream value
+ * @param ostream a VariableByteOutput value
* @throws IOException if an error occurs
*/
@EnsureContainerLocked(mode=READ_LOCK)
- public void write(final VariableByteOutputStream ostream) throws IOException {
+ public void write(final VariableByteOutput ostream) throws IOException {
try {
ostream.writeInt(docId);
ostream.writeUTF(fileURI.toString());
@@ -846,10 +915,10 @@ public void write(final VariableByteOutputStream ostream) throws IOException {
}
}
- void writeDocumentAttributes(final SymbolTable symbolTable, final VariableByteOutputStream ostream) throws IOException {
+ void writeDocumentAttributes(final SymbolTable symbolTable, final VariableByteOutput ostream) throws IOException {
ostream.writeLong(created);
ostream.writeLong(lastModified);
- ostream.writeInt(symbolTable.getMimeTypeId(mimeType));
+ ostream.writeInt(symbolTable.getMimeTypeId(mediaType));
ostream.writeInt(pageCount);
ostream.writeInt(userLock);
if (xmlDecl != null) {
@@ -990,14 +1059,13 @@ public IStoredNode updateChild(final Txn transaction, final Node oldChild, final
@Override
@EnsureContainerLocked(mode=READ_LOCK)
public Node getFirstChild() {
- if(children == 0) {
+ if (children == 0) {
return null;
}
- try(final DBBroker broker = pool.getBroker()) {
- return broker.objectWith(new NodeProxy(getExpression(), this, NodeId.DOCUMENT_NODE, childAddress[0]));
- } catch(final EXistException e) {
+ try (final DBBroker broker = pool.getBroker()) {
+ return broker.objectWith(getFirstChildProxy());
+ } catch (final EXistException e) {
LOG.warn("Exception while inserting node: {}", e.getMessage(), e);
- //TODO : throw exception ?
}
return null;
}
@@ -1008,9 +1076,9 @@ protected NodeProxy getFirstChildProxy() {
}
/**
- * The method getFirstChildAddress
+ * Get the address of the first child.
*
- * @return a long value
+ * @return the address of the first child.
*/
@EnsureContainerLocked(mode=READ_LOCK)
public long getFirstChildAddress() {
@@ -1020,6 +1088,37 @@ public long getFirstChildAddress() {
return childAddress[0];
}
+ @Override
+ @EnsureContainerLocked(mode=READ_LOCK)
+ public Node getLastChild() {
+ if (children == 0) {
+ return null;
+ }
+ try (final DBBroker broker = pool.getBroker()) {
+ return broker.objectWith(getLastChildProxy());
+ } catch (final EXistException e) {
+ LOG.warn("Exception while inserting node: {}", e.getMessage(), e);
+ }
+ return null;
+ }
+
+ @EnsureContainerLocked(mode=READ_LOCK)
+ protected NodeProxy getLastChildProxy() {
+ return new NodeProxy(getExpression(), this, NodeId.ROOT_NODE, Node.ELEMENT_NODE, childAddress[children - 1]);
+ }
+
+ /**
+ * Get the address of the last child.
+ *
+ * @return the address of the last child.
+ */
+ @EnsureContainerLocked(mode=READ_LOCK)
+ public long getLastChildAddress() {
+ if (children == 0) {
+ return StoredNode.UNKNOWN_NODE_IMPL_ADDRESS;
+ }
+ return childAddress[children - 1];
+ }
@Override
public boolean hasChildNodes() {
@@ -1030,14 +1129,18 @@ public boolean hasChildNodes() {
@EnsureContainerLocked(mode=READ_LOCK)
public NodeList getChildNodes() {
final org.exist.dom.NodeListImpl list = new org.exist.dom.NodeListImpl();
- try(final DBBroker broker = pool.getBroker()) {
- for(int i = 0; i < children; i++) {
- final Node child = broker.objectWith(new NodeProxy(getExpression(), this, NodeId.DOCUMENT_NODE, childAddress[i]));
+
+ @Nullable final NodeProxy nodeProxy = children > 0 ? new NodeProxy(getExpression(), this, NodeId.DOCUMENT_NODE) : null;
+ try (final DBBroker broker = pool.getBroker()) {
+ for (int i = 0; i < children; i++) {
+ nodeProxy.setInternalAddress(childAddress[i]);
+ final Node child = broker.objectWith(nodeProxy);
list.add(child);
}
- } catch(final EXistException e) {
+ } catch (final EXistException e) {
LOG.warn("Exception while retrieving child nodes: {}", e.getMessage(), e);
}
+
return list;
}
@@ -1357,12 +1460,19 @@ public Text createTextNode(final String data) {
*/
@Override
public Element getDocumentElement() {
- final NodeList cl = getChildNodes();
- for(int i = 0; i < cl.getLength(); i++) {
- if(cl.item(i).getNodeType() == Node.ELEMENT_NODE) {
- return (Element) cl.item(i);
+ try (final DBBroker broker = pool.getBroker()) {
+ @Nullable final NodeProxy childNodeProxy = children > 0 ? new NodeProxy(getExpression(), this, NodeId.DOCUMENT_NODE) : null;
+ for (int i = 0; i < children; i++) {
+ childNodeProxy.setInternalAddress(childAddress[i]);
+ final Node child = broker.objectWith(childNodeProxy);
+ if (child.getNodeType() == Node.ELEMENT_NODE) {
+ return (Element) child;
+ }
}
+ } catch(final EXistException e) {
+ LOG.warn("Exception while retrieving document element: {}", e.getMessage(), e);
}
+
return null;
}
@@ -1572,8 +1682,9 @@ public String getBaseURI() {
@Override
public String toString() {
+ @Nullable final Element documentElement = getDocumentElement();
return getURI() + " - <" +
- (getDocumentElement() != null ? getDocumentElement().getNodeName() : null) + ">";
+ (documentElement != null ? documentElement.getNodeName() : null) + ">";
}
@Override
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/DocumentMetadata.java b/exist-core/src/main/java/org/exist/dom/persistent/DocumentMetadata.java
index 77bdb4bd2c..6b6252f1b3 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/DocumentMetadata.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/DocumentMetadata.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -23,7 +47,7 @@
import org.exist.ResourceMetadata;
import org.exist.storage.io.VariableByteInput;
-import org.exist.storage.io.VariableByteOutputStream;
+import org.exist.storage.io.VariableByteOutput;
import org.w3c.dom.DocumentType;
import java.io.IOException;
@@ -71,12 +95,12 @@ public void setLastModified(final long lastModified) {
@Deprecated
public String getMimeType() {
- return doc.getMimeType();
+ return doc.getMediaType();
}
@Deprecated
public void setMimeType(final String mimeType) {
- doc.setMimeType(mimeType);
+ doc.setMediaType(mimeType);
}
@Deprecated
@@ -100,7 +124,7 @@ public void decPageCount() {
}
@Deprecated
- public void write(final SymbolTable symbolTable, final VariableByteOutputStream ostream) throws IOException {
+ public void write(final SymbolTable symbolTable, final VariableByteOutput ostream) throws IOException {
doc.writeDocumentAttributes(symbolTable, ostream);
}
@@ -109,7 +133,7 @@ public void read(final SymbolTable symbolTable, final VariableByteInput istream)
final long created = istream.readLong();
final long lastModified = istream.readLong();
final int mimeTypeSymbolsIndex = istream.readInt();
- final String mimeType = symbolTable.getMimeType(mimeTypeSymbolsIndex);
+ final String mediaType = symbolTable.getMimeType(mimeTypeSymbolsIndex);
final int pageCount = istream.readInt();
final int userLock = istream.readInt();
final DocumentTypeImpl docType;
@@ -127,7 +151,7 @@ public void read(final SymbolTable symbolTable, final VariableByteInput istream)
doc.setCreated(created);
doc.setLastModified(lastModified);
- doc.setMimeType(mimeType);
+ doc.setMediaType(mediaType);
doc.setPageCount(pageCount);
doc.setUserLock(userLock);
doc.setDocType(docType);
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/DocumentSet.java b/exist-core/src/main/java/org/exist/dom/persistent/DocumentSet.java
index 520e5ce238..05c1d1fb27 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/DocumentSet.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/DocumentSet.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -55,7 +79,7 @@ public interface DocumentSet {
/**
* Locks all of the documents currently in the document set.
*
- * @param broker the eXist-db DBBroker
+ * @param broker the DBBroker
* @param exclusive true if a WRITE_LOCK is required, false if a READ_LOCK is required
* @return The locks
* @throws LockException if locking any document fails, when thrown no locks will be held on any documents in the set
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/DocumentTypeImpl.java b/exist-core/src/main/java/org/exist/dom/persistent/DocumentTypeImpl.java
index 4fb48d3f7e..e1bfb1d470 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/DocumentTypeImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/DocumentTypeImpl.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -23,7 +47,7 @@
import net.jcip.annotations.ThreadSafe;
import org.exist.storage.io.VariableByteInput;
-import org.exist.storage.io.VariableByteOutputStream;
+import org.exist.storage.io.VariableByteOutput;
import org.exist.xquery.Expression;
import org.w3c.dom.DocumentType;
import org.w3c.dom.NamedNodeMap;
@@ -79,7 +103,7 @@ public String getInternalSubset() {
return null;
}
- protected void write(final VariableByteOutputStream ostream) throws IOException {
+ protected void write(final VariableByteOutput ostream) throws IOException {
ostream.writeUTF(name);
ostream.writeUTF(systemId != null ? systemId : "");
ostream.writeUTF(publicId != null ? publicId : "");
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/ElementImpl.java b/exist-core/src/main/java/org/exist/dom/persistent/ElementImpl.java
index a0fb05c65b..c58e77d777 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/ElementImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/ElementImpl.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -51,6 +75,7 @@
import org.exist.xquery.value.StringValue;
import org.w3c.dom.*;
+import javax.annotation.Nullable;
import javax.xml.XMLConstants;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
@@ -171,10 +196,7 @@ public int getPosition() {
}
public boolean declaresNamespacePrefixes() {
- if(namespaceMappings == null) {
- return false;
- }
- return namespaceMappings.size() > 0;
+ return namespaceMappings != null && !namespaceMappings.isEmpty();
}
/**
@@ -450,13 +472,13 @@ public static void readNamespaceDecls(final List namespaces, final Val
}
public void addNamespaceMapping(final String prefix, final String ns) {
- if(prefix == null) {
+ if (prefix == null) {
return;
}
- if(namespaceMappings == null) {
+ if (namespaceMappings == null) {
namespaceMappings = new HashMap<>(1);
- } else if(namespaceMappings.containsKey(prefix)) {
+ } else if (namespaceMappings.containsKey(prefix)) {
return;
}
@@ -803,8 +825,7 @@ public String getAttribute(final String name) {
@Override
public String getAttributeNS(final String namespaceURI, final String localName) {
final Attr attr = findAttribute(new QName(localName, namespaceURI));
- return attr != null ? attr.getValue() : XMLConstants.NULL_NS_URI;
- //XXX: if not present must return null
+ return attr != null ? attr.getValue() : "";
}
@Deprecated //move as soon as getAttributeNS null issue resolved
@@ -1088,7 +1109,7 @@ private Node getLastChild(final boolean attributesAreChildren) {
Node node = null;
if (!isDirty) {
final NodeId child = nodeId.getChild(children);
- node = ownerDocument.getNode(new NodeProxy(getExpression(), ownerDocument, child));
+ node = new NodeProxy(getExpression(), ownerDocument, child).getNode();
}
if (node == null) {
final NodeList cl;
@@ -1338,8 +1359,13 @@ public void setChildCount(final int count) {
}
public void setNamespaceMappings(final Map map) {
- this.namespaceMappings = new HashMap<>(map);
- for(final String ns : namespaceMappings.values()) {
+ if (this.namespaceMappings == null) {
+ this.namespaceMappings = new HashMap<>(map);
+ } else {
+ this.namespaceMappings.clear();
+ this.namespaceMappings.putAll(map);
+ }
+ for (final String ns : namespaceMappings.values()) {
ownerDocument.getBrokerPool().getSymbols().getNSSymbol(ns);
}
}
@@ -1359,6 +1385,10 @@ public String getNamespaceForPrefix(final String prefix) {
return namespaceMappings.get(prefix);
}
+ public @Nullable Map getNamespaceMappings() {
+ return namespaceMappings;
+ }
+
/**
* @see java.lang.Object#toString()
*/
@@ -1518,7 +1548,7 @@ public void insertBefore(final Txn transaction, final NodeList nodes, final Node
}
final IStoredNode> following = (IStoredNode>) refChild;
- final IStoredNode> previous = (IStoredNode>) following.getPreviousSibling();
+ final IStoredNode> previous = (IStoredNode>) ((StoredNode>) following).getPreviousSibling(true);
if(previous == null) {
// there's no sibling node before the new node
final NodeId newId = following.getNodeId().insertBefore();
@@ -1650,8 +1680,11 @@ public void update(final Txn transaction, final NodeList newContent) throws DOME
* Update a child node. This method will only update the child node
* but not its potential descendant nodes.
*
- * @param oldChild to be replace
+ * @param oldChild to be replaced
* @param newChild to be added
+ *
+ * @return the new node
+ *
* @throws DOMException in case of a DOM error
*/
@Override
@@ -1671,7 +1704,7 @@ public IStoredNode updateChild(final Txn transaction, final Node oldChild, final
attr.setValue(StringValue.trimWhitespace(StringValue.collapseWhitespace(attr.getValue())));
attr.setType(AttrImpl.ID);
}
- IStoredNode> previousNode = (IStoredNode>) oldNode.getPreviousSibling();
+ IStoredNode> previousNode = (IStoredNode>) ((StoredNode>) oldNode).getPreviousSibling(true);
if(previousNode == null) {
previousNode = this;
} else {
@@ -1842,13 +1875,16 @@ public boolean visit(final IStoredNode node) {
}
/**
- * Replaces the oldNode with the newChild
+ * Replaces the oldChild with the newChild
*
* @param transaction the transaction
* @param newChild to replace oldChild
- * @param oldChild to be replace by newChild
+ * @param oldChild to be replaced by newChild
+ *
* @return The new node (this differs from the {@link org.w3c.dom.Node#replaceChild(Node, Node)} specification)
+ *
* @throws DOMException in case of a DOM error
+ *
* @see org.w3c.dom.Node#replaceChild(org.w3c.dom.Node, org.w3c.dom.Node)
*/
@Override
@@ -1862,7 +1898,7 @@ public Node replaceChild(final Txn transaction, final Node newChild, final Node
}
final NodePath thisPath = getPath();
- IStoredNode> previous = (IStoredNode>) oldNode.getPreviousSibling();
+ IStoredNode> previous = (IStoredNode>) ((StoredNode>) oldNode).getPreviousSibling(true);
if(previous == null) {
previous = this;
} else {
@@ -1973,41 +2009,37 @@ public String getBaseURI() {
return ""; //UNDERSTAND: is it ok?
}
- //TODO Please, keep in sync with org.exist.dom.memtree.ElementImpl
+ // NOTE(AR) please keep in sync with org.exist.dom.memtree.ElementImpl
private XmldbURI calculateBaseURI() {
XmldbURI baseURI = null;
- final String nodeBaseURI = _getAttributeNS(Namespaces.XML_NS, "base");
- if(nodeBaseURI != null) {
+ final String nodeBaseURI = getAttributeNS(Namespaces.XML_NS, "base");
+ if (!nodeBaseURI.isEmpty()) {
baseURI = XmldbURI.create(nodeBaseURI, false);
- if(baseURI.isAbsolute()) {
+ if (baseURI.isAbsolute()) {
return baseURI;
}
}
- final IStoredNode parent = getParentStoredNode();
- if(parent != null) {
- if(nodeBaseURI == null) {
+ final IStoredNode> parent = getParentStoredNode();
+ if (parent != null) {
+ if (nodeBaseURI.isEmpty()) {
baseURI = ((ElementImpl) parent).calculateBaseURI();
} else {
- XmldbURI parentsBaseURI = ((ElementImpl) parent).calculateBaseURI();
- if(nodeBaseURI.isEmpty()) {
- baseURI = parentsBaseURI;
+ final XmldbURI parentsBaseURI = ((ElementImpl) parent).calculateBaseURI();
+ if (parentsBaseURI.toString().endsWith("/") || !parentsBaseURI.toString().contains("/")) {
+ baseURI = parentsBaseURI.append(baseURI);
} else {
- if(parentsBaseURI.toString().endsWith("/") || !parentsBaseURI.toString().contains("/")){
- baseURI = parentsBaseURI.append(baseURI);
- } else {
- // there is a filename, remove it
- baseURI = parentsBaseURI.removeLastSegment().append(baseURI);
- }
+ // there is a filename, remove it
+ baseURI = parentsBaseURI.removeLastSegment().append(baseURI);
}
}
} else {
- if(nodeBaseURI == null) {
+ if (nodeBaseURI.isEmpty()) {
return XmldbURI.create(getOwnerDocument().getBaseURI(), false);
} else {
final String docBaseURI = getOwnerDocument().getBaseURI();
- if(docBaseURI.endsWith("/")) {
+ if (docBaseURI.endsWith("/")) {
baseURI = XmldbURI.create(getOwnerDocument().getBaseURI(), false);
baseURI.append(baseURI);
} else {
@@ -2017,6 +2049,7 @@ private XmldbURI calculateBaseURI() {
}
}
}
+
return baseURI;
}
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/EmptyNodeSet.java b/exist-core/src/main/java/org/exist/dom/persistent/EmptyNodeSet.java
index 8fe090e118..451ae11896 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/EmptyNodeSet.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/EmptyNodeSet.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -67,10 +91,12 @@ public boolean hasOne() {
@Override
public void add(final NodeProxy proxy) {
+ throw new IllegalStateException("Cannot add a NodeProxy to an EmptyNodeSet because it is immutable");
}
@Override
public void addAll(final NodeSet other) {
+ throw new IllegalStateException("Cannot add a NodeSet to an EmptyNodeSet because it is immutable");
}
@Override
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/LockToken.java b/exist-core/src/main/java/org/exist/dom/persistent/LockToken.java
index 7b9d60f926..57f5bd413d 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/LockToken.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/LockToken.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -22,7 +46,7 @@
package org.exist.dom.persistent;
import org.exist.storage.io.VariableByteInput;
-import org.exist.storage.io.VariableByteOutputStream;
+import org.exist.storage.io.VariableByteOutput;
import org.exist.util.UUIDGenerator;
import javax.annotation.Nullable;
@@ -123,7 +147,8 @@ public static String generateUUID() {
return UUIDGenerator.getUUID();
}
- public void write(final VariableByteOutputStream ostream) throws IOException {
+ public void write(final VariableByteOutput
+ ostream) throws IOException {
// TODO(AR) these 3 bytes could be encoded into 1
ostream.writeByte(type.getValue());
ostream.writeByte(depth.getValue());
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/NewArrayNodeSet.java b/exist-core/src/main/java/org/exist/dom/persistent/NewArrayNodeSet.java
index ed5f630028..2bd6097478 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/NewArrayNodeSet.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/NewArrayNodeSet.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -41,7 +65,12 @@
import org.w3c.dom.Node;
import javax.annotation.Nullable;
-import java.util.*;
+import java.lang.ref.WeakReference;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Set;
/**
* A fast node set implementation, based on arrays to store nodes and documents.
@@ -67,7 +96,7 @@
*/
public class NewArrayNodeSet extends AbstractArrayNodeSet implements ExtNodeSet, DocumentSet {
- private Set cachedCollections = null;
+ @Nullable private WeakReference> cachedCollectionsRef = null;
private int documentCount = 0;
@@ -935,10 +964,10 @@ public NodeSet getContextNodes(final int contextId) {
if(contextNode.getContextId() == contextId) {
final NodeProxy context = contextNode.getNode();
context.addMatches(current);
- if(Expression.NO_CONTEXT_ID != contextId) {
+ if (Expression.NO_CONTEXT_ID != contextId) {
context.addContextNode(contextId, context);
}
- if(lastDoc != null && lastDoc.getDocId() != context.getOwnerDocument().getDocId()) {
+ if (lastDoc == null || lastDoc.getDocId() != context.getOwnerDocument().getDocId()) {
lastDoc = context.getOwnerDocument();
result.add(context, getSizeHint(lastDoc));
} else {
@@ -1014,16 +1043,27 @@ public boolean equalDocs(final DocumentSet other) {
@Override
public Iterator getCollectionIterator() {
- sort();
- if(cachedCollections == null) {
- cachedCollections = new HashSet<>();
- for(int i = 0; i < documentCount; i++) {
- final DocumentImpl doc = nodes[documentNodesOffset[i]].getOwnerDocument();
- if(!cachedCollections.contains(doc.getCollection())) {
- cachedCollections.add(doc.getCollection());
- }
+ // First, try and retrieve from Cache
+ Set cachedCollections;
+ if (this.cachedCollectionsRef != null) {
+ cachedCollections = this.cachedCollectionsRef.get();
+ if (cachedCollections != null) {
+ return cachedCollections.iterator();
}
}
+
+ sort();
+
+ // Second, Cache is empty, so create a Cache and return
+ cachedCollections = new HashSet<>();
+ for (int i = 0; i < documentCount; i++) {
+ final DocumentImpl doc = nodes[documentNodesOffset[i]].getOwnerDocument();
+ final Collection collection = doc.getCollection();
+ cachedCollections.add(collection);
+ }
+
+ this.cachedCollectionsRef = new WeakReference<>(cachedCollections);
+
return cachedCollections.iterator();
}
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/NodeProxy.java b/exist-core/src/main/java/org/exist/dom/persistent/NodeProxy.java
index 16dd1bb34f..93a0832368 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/NodeProxy.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/NodeProxy.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -49,6 +73,7 @@
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.IOException;
+import java.lang.ref.WeakReference;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Properties;
@@ -58,17 +83,18 @@
*
* NodeProxy is an internal proxy class, acting as a placeholder for all types of persistent XML nodes
* during query processing. NodeProxy just stores the node's unique id and the document it belongs to.
- * Query processing deals with these proxys most of the time. Using a NodeProxy is much cheaper
+ * Query processing deals with these proxy most of the time. Using a NodeProxy is much cheaper
* than loading the actual node from the database. The real DOM node is only loaded,
* if further information is required for the evaluation of an XPath expression. To obtain
* the real node for a proxy, simply call {@link #getNode()}.
*
- * All sets of type NodeSet operate on NodeProxys. A node set is a special type of
- * sequence, so NodeProxy does also implement {@link org.exist.xquery.value.Item} and
- * can thus be an item in a sequence. Since, according to XPath 2, a single node is also
- * a sequence, NodeProxy does itself extend NodeSet. It thus represents a node set containing
- * just one, single node.
+ * All sets of type NodeSet operate on NodeProxy objects. A node set is a special type of
+ * sequence, so NodeProxy also implements {@link org.exist.xquery.value.Item}, and
+ * can thus be an item in a sequence. Since according to XPath 2, a single node is also
+ * a sequence, NodeProxy itself extends NodeSet. It thus represents a node set containing
+ * just one single node.
*
+ * @author Adam Retter
* @author Wolfgang Meier
*/
public class NodeProxy implements NodeSet, NodeValue, NodeHandle, DocumentSet, Comparable