diff --git a/packaging/.gitattributes b/packaging/.gitattributes
new file mode 100644
index 00000000000..8303247a395
--- /dev/null
+++ b/packaging/.gitattributes
@@ -0,0 +1,8 @@
+.* eol=crlf
+*.html eol=crlf
+*.java eol=crlf
+*.txt eol=crlf
+*.css eol=crlf
+*.xml eol=crlf
+*.js eol=crlf
+*.properties eol=crlf
\ No newline at end of file
diff --git a/packaging/.gitbugtraq b/packaging/.gitbugtraq
new file mode 100644
index 00000000000..bacffb702d6
--- /dev/null
+++ b/packaging/.gitbugtraq
@@ -0,0 +1,4 @@
+# For SmartGit
+[bugtraq "jira"]
+ url = https://issues.alfresco.com/jira/browse/%BUGID%
+ logRegex = ([A-Z]+-\\d+)
diff --git a/packaging/.gitignore b/packaging/.gitignore
new file mode 100644
index 00000000000..f9983e601ee
--- /dev/null
+++ b/packaging/.gitignore
@@ -0,0 +1,41 @@
+*.class
+
+# Eclipse
+.classpath
+.settings
+.project
+
+# Intellij
+.idea/
+*.iml
+*.iws
+
+#VSCode
+/.vscode
+
+# Mac
+.DS_Store
+
+# Maven
+target
+*.log
+*.log.*
+
+
+# Package Files #
+*.jar
+*.war
+*.ear
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+# Alfresco
+alf_data/
+
+helm/alfresco-content-services-community/charts/*
+helm/alfresco-content-services-community/requirements.lock
+helm/alfresco-content-services-community*.tgz
+
+# Travis deployment folder
+deploy_dir
\ No newline at end of file
diff --git a/packaging/.travis.settings.xml b/packaging/.travis.settings.xml
new file mode 100644
index 00000000000..48b88983e0f
--- /dev/null
+++ b/packaging/.travis.settings.xml
@@ -0,0 +1,49 @@
+
+
+
+ alfresco-internal
+
+ true
+
+
+
+ alfresco-internal
+
+ true
+
+
+ true
+
+ Alfresco Internal Repository
+ https://artifacts.alfresco.com/nexus/content/groups/internal
+
+
+
+
+ alfresco-internal
+ Alfresco Internal Repository
+ https://artifacts.alfresco.com/nexus/content/groups/public
+
+
+
+
+
+
+
+
+ alfresco-internal
+ ${env.MAVEN_USERNAME}
+ ${env.MAVEN_PASSWORD}
+
+
+ quay.io
+ ${env.QUAY_USERNAME}
+ ${env.QUAY_PASSWORD}
+
+
+ docker.io
+ ${env.DOCKERHUB_USERNAME}
+ ${env.DOCKERHUB_PASSWORD}
+
+
+
diff --git a/packaging/.travis.yml b/packaging/.travis.yml
new file mode 100644
index 00000000000..1e0b9de3e1c
--- /dev/null
+++ b/packaging/.travis.yml
@@ -0,0 +1,143 @@
+dist: xenial
+os: linux
+language: java
+jdk:
+ - openjdk11
+
+services:
+ - docker
+
+cache:
+ directories:
+ - $HOME/.m2
+# the cache can grow constantly
+before_cache:
+ - rm -rf $HOME/.m2/repository/org/alfresco/acs-community-packaging
+env:
+ global:
+ - VERSION_EDITION=Community
+ # Must be in the format - ie. 6.3.0-repo-xxxx-x or 6.3.0-Ax
+ - RELEASE_VERSION=6.2.2-RC1
+ - DEVELOPMENT_VERSION=6.2.2-SNAPSHOT
+branches:
+ only:
+ - master
+ - develop
+
+stages:
+ - name: test
+ if: commit_message !~ /\[skip tests\]/
+ - release
+ - publish
+
+before_install: "cp .travis.settings.xml $HOME/.m2/settings.xml"
+
+jobs:
+ include:
+ - stage: test
+ name: "WhiteSource scan"
+ # only on master or develop and if it is not a PR
+ if: fork = false AND branch =~ ^(master|develop)$ AND type != pull_request
+ install:
+ - travis_retry travis_wait 30 mvn -q install "-Dversion.edition=${VERSION_EDITION}" -f war/pom.xml
+ script:
+ # Download the latest version of WhiteSource Unified Agent
+ - curl -LJO https://github.com/whitesource/unified-agent-distribution/releases/latest/download/wss-unified-agent.jar
+ # Run WhiteSource Unified Agent
+ - java -jar wss-unified-agent.jar -apiKey ${WHITESOURCE_API_KEY} -c .wss-unified-agent.config -d ./war
+ - name: "REST API TAS tests part1"
+ jdk: openjdk11
+ install:
+ - travis_retry travis_wait 40 mvn install -q "-Dversion.edition=${VERSION_EDITION}" -Dmaven.javadoc.skip=true -PcommunityDocker
+ - ./tests/scripts/start-compose.sh ./tests/environment/docker-compose-minimal+transforms.yml
+ - ./tests/scripts/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
+ script:
+ - travis_wait 60 mvn install -f tests/tas-restapi/pom.xml -Pall-tas-tests,run-restapi-part1 -Denvironment=default -DrunBugs=false
+ - name: "REST API TAS tests part2"
+ jdk: openjdk11
+ install:
+ - travis_retry travis_wait 40 mvn install -q "-Dversion.edition=${VERSION_EDITION}" -Dmaven.javadoc.skip=true -PcommunityDocker
+ - ./tests/scripts/start-compose.sh ./tests/environment/docker-compose-minimal+transforms.yml
+ - ./tests/scripts/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
+ script:
+ - travis_wait 60 mvn install -f tests/tas-restapi/pom.xml -Pall-tas-tests,run-restapi-part2 -Denvironment=default -DrunBugs=false
+ - name: "REST API TAS tests part3"
+ jdk: openjdk11
+ install:
+ - travis_retry travis_wait 40 mvn install -q "-Dversion.edition=${VERSION_EDITION}" -Dmaven.javadoc.skip=true -PcommunityDocker
+ - ./tests/scripts/start-compose.sh ./tests/environment/docker-compose-minimal+transforms.yml
+ - ./tests/scripts/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
+ script:
+ - travis_wait 60 mvn install -f tests/tas-restapi/pom.xml -Pall-tas-tests,run-restapi-part3 -Denvironment=default -DrunBugs=false
+ - name: "CMIS TAS tests"
+ jdk: openjdk11
+ install:
+ - travis_retry travis_wait 40 mvn install -q "-Dversion.edition=${VERSION_EDITION}" -Dmaven.javadoc.skip=true -PcommunityDocker
+ - ./tests/scripts/start-compose.sh ./tests/environment/docker-compose-minimal+transforms.yml
+ - ./tests/scripts/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
+ script:
+ - travis_wait 40 mvn install -q -f tests/tas-cmis/pom.xml -Pall-tas-tests -Denvironment=default -DrunBugs=false
+ - name: "Email TAS tests"
+ jdk: openjdk11
+ install:
+ - travis_retry travis_wait 40 mvn install -q "-Dversion.edition=${VERSION_EDITION}" -Dmaven.javadoc.skip=true -PcommunityDocker
+ - ./tests/scripts/start-compose.sh ./tests/environment/docker-compose-minimal.yml
+ - ./tests/scripts/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
+ script:
+ - travis_wait 30 mvn install -q -f tests/tas-email/pom.xml -Pall-tas-tests -Denvironment=default -DrunBugs=false
+ - name: "WebDAV TAS tests"
+ jdk: openjdk11
+ install:
+ - travis_retry travis_wait 40 mvn install -q "-Dversion.edition=${VERSION_EDITION}" -Dmaven.javadoc.skip=true -PcommunityDocker
+ - ./tests/scripts/start-compose.sh ./tests/environment/docker-compose-minimal.yml
+ - ./tests/scripts/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
+ script:
+ - travis_wait 30 mvn install -q -f tests/tas-webdav/pom.xml -Pall-tas-tests -Denvironment=default -DrunBugs=false
+ - name: "Integration TAS tests"
+ jdk: openjdk11
+ install:
+ - travis_retry travis_wait 40 mvn install -q "-Dversion.edition=${VERSION_EDITION}" -Dmaven.javadoc.skip=true -PcommunityDocker
+ - ./tests/scripts/start-compose.sh ./tests/environment/docker-compose-minimal.yml
+ - ./tests/scripts/wait-for-alfresco-start.sh "http://localhost:8082/alfresco"
+ script:
+ - travis_wait 30 mvn install -q -f tests/tas-integration/pom.xml -Pall-tas-tests -Denvironment=default -DrunBugs=false
+ - stage: Release
+ name: "Maven release"
+ if: commit_message ~= /\[release\]/ AND fork = false AND branch =~ ^(master|develop)$ AND type != pull_request
+ install: travis_retry travis_wait 40 mvn clean install -DskipTests=true "-Dversion.edition=${VERSION_EDITION}" -Dmaven.javadoc.skip=true -B -V
+ # Fail the job if there is a docker image tag that matches the RELEASE_VERSION (or project version in the POM if not set)
+ before_script: ./scripts/travis/verify_release_tag.sh
+ script: travis_wait 40 ./scripts/travis/maven_release.sh ${RELEASE_VERSION} ${DEVELOPMENT_VERSION}
+ # Copy alfresco.war and the distribution zip to deploy_dir
+ before_deploy:
+ # Move the final artifacts to a single folder (deploy_dir) to be copied to S3
+ - mkdir -p deploy_dir
+ - cp war/target/alfresco.war deploy_dir
+ - cp distribution/target/*-distribution*.zip deploy_dir
+ deploy:
+ - provider: s3
+ access_key_id: ${AWS_STAGING_ACCESS_KEY}
+ secret_access_key: ${AWS_STAGING_SECRET_KEY}
+ bucket: "alfresco-artefacts-staging"
+ region: "eu-west-1"
+ skip_cleanup: true
+ acl: private
+ local_dir: deploy_dir
+ upload_dir: "alfresco-content-services-community/release/${TRAVIS_BRANCH}/${TRAVIS_BUILD_NUMBER}"
+ on:
+ all_branches: true
+ condition: $TRAVIS_BRANCH =~ ^(master|develop)$
+ - stage: "Publish"
+ name: "Copy to S3 Release"
+ if: commit_message ~= /\[publish\]/ AND fork = false AND branch = master AND type != pull_request
+ # Nothing to build/install as we are just copying from S3 buckets
+ install: skip
+ script: skip
+ before_deploy: pip install awscli
+ deploy:
+ - provider: script
+ script: ./scripts/travis/copy_to_release_bucket.sh ${TRAVIS_BUILD_NUMBER} ${TRAVIS_BRANCH}
+ on:
+ branch: master
+
+
diff --git a/packaging/.whitesource b/packaging/.whitesource
new file mode 100644
index 00000000000..f0569521415
--- /dev/null
+++ b/packaging/.whitesource
@@ -0,0 +1,8 @@
+{
+ "generalSettings": {
+ "shouldScanRepo": true
+ },
+ "checkRunSettings": {
+ "vulnerableCheckRunConclusionLevel": "failure"
+ }
+}
\ No newline at end of file
diff --git a/packaging/.wss-unified-agent.config b/packaging/.wss-unified-agent.config
new file mode 100644
index 00000000000..9039a34c86d
--- /dev/null
+++ b/packaging/.wss-unified-agent.config
@@ -0,0 +1,228 @@
+####################################################################
+# WhiteSource Unified-Agent configuration file
+####################################################################
+##########################################
+# GENERAL SCAN MODE: Files and Package Managers
+##########################################
+
+checkPolicies=true
+forceCheckAllDependencies=true
+forceUpdate=true
+forceUpdate.failBuildOnPolicyViolation=true
+offline=false
+#ignoreSourceFiles=true
+#scanComment=
+#updateInventory=false
+#resolveAllDependencies=false
+#failErrorLevel=ALL
+#requireKnownSha1=false
+#generateScanReport=true
+#scanReportTimeoutMinutes=10
+#excludeDependenciesFromNodes=.*commons-io.*,.*maven-model
+
+#projectPerFolder=true
+#projectPerFolderIncludes=
+#projectPerFolderExcludes=
+
+#wss.connectionTimeoutMinutes=60
+# Change the below URL to your WhiteSource server.
+# Use the 'WhiteSource Server URL' which can be retrieved
+# from your 'Profile' page on the 'Server URLs' panel.
+# Then, add the '/agent' path to it.
+wss.url=https://saas.whitesourcesoftware.com/agent
+
+#npm.resolveDependencies=false
+#npm.ignoreSourceFiles=false
+#npm.includeDevDependencies=true
+#npm.runPreStep=true
+#npm.ignoreNpmLsErrors=true
+#npm.ignoreScripts=true
+#npm.yarnProject=true
+#npm.accessToken=
+#npm.identifyByNameAndVersion=true
+
+#bower.resolveDependencies=false
+#bower.ignoreSourceFiles=true
+#bower.runPreStep=true
+
+#nuget.resolvePackagesConfigFiles=false
+#nuget.resolveCsProjFiles=false
+#nuget.resolveDependencies=false
+#nuget.restoreDependencies=true
+#nuget.ignoreSourceFiles=true
+#nuget.runPreStep=true
+#nuget.resolveNuspecFiles=false
+
+#python.resolveDependencies=false
+#python.ignoreSourceFiles=false
+#python.ignorePipInstallErrors=true
+#python.installVirtualenv=true
+#python.resolveHierarchyTree=false
+#python.requirementsFileIncludes=requirements.txt
+#python.resolveSetupPyFiles=true
+#python.runPipenvPreStep=true
+#python.pipenvDevDependencies=true
+#python.IgnorePipenvInstallErrors=true
+
+#maven.ignoredScopes=test provided
+maven.resolveDependencies=true
+#maven.ignoreSourceFiles=true
+#maven.aggregateModules=true
+maven.ignorePomModules=false
+#maven.runPreStep=true
+#maven.ignoreMvnTreeErrors=true
+#maven.environmentPath=
+#maven.m2RepositoryPath=
+
+#gradle.ignoredScopes=
+#gradle.resolveDependencies=false
+#gradle.runAssembleCommand=false
+#gradle.runPreStep=true
+#gradle.ignoreSourceFiles=true
+#gradle.aggregateModules=true
+#gradle.preferredEnvironment=wrapper
+#gradle.localRepositoryPath=
+
+#paket.resolveDependencies=false
+#paket.ignoredGroups=
+#paket.ignoreSourceFiles=false
+#paket.runPreStep=true
+#paket.exePath=
+
+#go.resolveDependencies=false
+#go.collectDependenciesAtRuntime=true
+#go.dependencyManager=
+#go.ignoreSourceFiles=true
+#go.glide.ignoreTestPackages=false
+#go.gogradle.enableTaskAlias=true
+
+#ruby.resolveDependencies = false
+#ruby.ignoreSourceFiles = false
+#ruby.installMissingGems = true
+#ruby.runBundleInstall = true
+#ruby.overwriteGemFile = true
+
+#sbt.resolveDependencies=false
+#sbt.ignoreSourceFiles=true
+#sbt.aggregateModules=true
+#sbt.runPreStep=true
+#sbt.targetFolder=
+
+#php.resolveDependencies=false
+#php.runPreStep=true
+#php.includeDevDependencies=true
+
+#html.resolveDependencies=false
+
+#cocoapods.resolveDependencies=false
+#cocoapods.runPreStep=true
+#cocoapods.ignoreSourceFiles=false
+
+#hex.resolveDependencies=false
+#hex.runPreStep=true
+#hex.ignoreSourceFiles=false
+#hex.aggregateModules=true
+
+##################################
+# Organization tokens:
+##################################
+apiKey=
+
+#userKey is required if WhiteSource administrator has enabled "Enforce user level access" option
+#userKey=
+
+projectName=content-services-community
+projectVersion=
+projectToken=
+
+productName=ACS Community
+productVersion=
+productToken=
+#updateType=APPEND
+#requesterEmail=user@provider.com
+
+#########################################################################################
+# Includes/Excludes Glob patterns - PLEASE USE ONLY ONE EXCLUDE LINE AND ONE INCLUDE LINE
+#########################################################################################
+#includes=**/*.c **/*.cc **/*.cp **/*.cpp **/*.cxx **/*.c++ **/*.h **/*.hpp **/*.hxx
+
+#includes=**/*.m **/*.mm **/*.js **/*.php
+includes=**/*.jar
+#includes=**/*.gem **/*.rb
+#includes=**/*.dll **/*.cs **/*.nupkg
+#includes=**/*.tgz **/*.deb **/*.gzip **/*.rpm **/*.tar.bz2
+#includes=**/*.zip **/*.tar.gz **/*.egg **/*.whl **/*.py
+
+## Exclude file extensions or specific directories by adding **/*. or **/**
+excludes=**/*sources.jar **/*javadoc.jar
+
+case.sensitive.glob=false
+followSymbolicLinks=true
+
+##################################
+# Archive properties
+##################################
+#archiveExtractionDepth=2
+#archiveIncludes=**/*.war **/*.ear
+#archiveExcludes=**/*sources.jar
+
+##################################
+# Proxy settings
+##################################
+#proxy.host=
+#proxy.port=
+#proxy.user=
+#proxy.pass=
+
+##################################
+# SCM settings
+##################################
+#scm.type=
+#scm.user=
+#scm.pass=
+#scm.ppk=
+#scm.url=
+#scm.branch=
+#scm.tag=
+#scm.npmInstall=
+#scm.npmInstallTimeoutMinutes=
+#scm.repositoriesFile=
+
+##############################################
+# SCAN MODE: Linux package manager settings
+##############################################
+#scanPackageManager=true
+
+##################################
+# SCAN MODE: Docker images
+##################################
+#docker.scanImages=true
+#docker.includes=.*.*
+#docker.excludes=
+#docker.pull.enable=true
+#docker.pull.images=.*.*
+#docker.pull.maxImages=10
+#docker.pull.tags=.*.*
+#docker.pull.digest=
+#docker.delete.force=true
+#docker.login.sudo=false
+
+#docker.aws.enable=true
+#docker.aws.registryIds=
+
+##################################
+# SCAN MODE: Docker containers
+##################################
+#docker.scanContainers=true
+#docker.containerIncludes=.*.*
+#docker.containerExcludes=
+
+################################
+# Serverless settings
+################################
+#serverless.provider=
+#serverless.scanFunctions=true
+#serverless.includes=
+#serverless.excludes=
+#serverless.region=
+#serverless.maxFunctions=10
diff --git a/packaging/CHANGELOG.md b/packaging/CHANGELOG.md
new file mode 100644
index 00000000000..8a484069fba
--- /dev/null
+++ b/packaging/CHANGELOG.md
@@ -0,0 +1,218 @@
+ Release Notes - Alfresco - Version Community Edition 201911 GA
+
+ Bug
+
+
+[MNT-20436 ] - “POST /nodes/{nodeId}/children” RestAPI does not create a node without having a mandatory value object, but it outputs the 201 successful response.
+
+[MNT-20714 ] - [HotFix] /nodes/{nodeId}/content REST API fails for content created by a deleted user
+
+[MNT-20770 ] - Share non responsive during direct download from S3 if content store selector is also configured
+
+[MNT-20863 ] - Changing cm:name with REST API /nodes/{nodeId} does not update Primary Path
+
+
+
+ Release Notes - Alfresco - Version Community Edition 201910 EA
+
+
+ New Features
+
+
+
+ Custom Transforms and Renditions
+ Alfresco Content Services (ACS) provides a number of content
+ transforms, but also allows custom transforms to be added.
+
It is now possible to create custom transforms that run in
+ separate processes known as T-Engines (short for Transformer
+ Engines). The same engines may be used in Community and
+ Enterprise Editions. They may be directly connected to the ACS
+ repository as Local Transforms, but in the Enterprise edition there
+ is the option to include them as part of the Transform Service
+ which provides more balanced throughput and better administration
+ capabilities.
+
For more information see Custom Transforms and Renditions
+
+
+ Open-source Transformation Engines
+ The core T-Engine images can now be used in Community
+ Edition.
+ T-Engines code has been Open-Sourced and is available on Github:
+
+ Images are available on Docker Hub:
+
+
+
+
+
+
+
+
+ Removal of external executables from docker image
+ With the introduction of the new Local Transform Service
+ in Alfresco Community Edition, the capability of executing
+ remote transformations on T-Engines was enabled. Because of
+ this, the external executables (Alfresco-Pdf-renderer, Libreoffice
+ and Imagemagick) have been removed from the docker container to
+ facilitate the usage of out-of-process transformations.
+
+
+
+ Bug
+
+
+[ALF-22013 ] - Docker Image for Base Tomcat locale is POSIX
+
+[ALF-22060 ] - Reader on the backing store is obtained twice in CachingContentStore
+
+[ALF-22056 ] - onCopyCompleteBehaviour not called in order of copy-action
+
+[ALF-22073 ] - MailActionExecutor doesn't consider email bodies with a HTML doctype as HTML
+
+[ALF-21988 ] - Tab order for number ranges not ok
+
+[ALF-22097 ] - T Engine - add source nodeId parameter
+
+
+ Improvement
+
+
+[REPO-4318 ] - [COMPLETE] Extraction of transformers and metadata extractors
+
+
+
+
+ Release Notes - Alfresco - Version Community Edition 201901 GA
+
+
+ New Features
+
+
+
+ ActiveMQ:
+ Alfresco ActiveMQ Docker images: GitHub Repo DockerHub Repo
+
+
+ Alfresco Benchmark Framework:
+ The benchmark framework project provides a way to run highly scalable, easy-to-run Java-based load and benchmark tests on an Alfresco instance.
+ It comprises the following: Alfresco BM Manager and Alfresco BM Drivers.
+ The currently provided drivers are:
+
+
+
+ Java 11 support
+ ACS is now runnable with OpenJDK 11.0.1. It still remains compatible with JDK 1.8.
+
+
+ Bug
+
+
+[ALF-22049 ] - Alfresco does not start
+
+[ALF-22041 ] - EKS deployment - SOLR_ALFRESCO_HOST set to wrong host name
+
+[ALF-22031 ] - REST API calls silently rollback after the returning a success status
+
+[ALF-21963 ] - Workflow - backslash in nodeRef properties url.
+
+[ALF-21803 ] - Unable to add users to sites whose 'short name' is a substring of 'site'
+
+[ALF-21664 ] - Exception on workflow image by REST API
+
+[ALF-20854 ] - webdav error opening Spanish Accent files
+
+
+ Improvement
+
+
+[REPO-3668 ] - Renditions: Transform event consumer
+
+[REPO-7 ] - Embed ActiveMQ in the Platform
+
+[REPO-1957 ] - Transformations Improvement Plan
+
+
+
+ Deprecations
+
+
+
+ TransformService and RenditionService: All Java APIs related to TransformService and RenditionService have been deprecated; the ability to perform arbitrary transformations will be phased out as the new DBP Transform Service takes effect. Renditions can be triggered using the existing repository REST API but will be processed asynchronously using the new services.
+
+
+
+ Known issues
+
+
+
+ Due to the changes to the RenditionService the Media Management AMP is not supported yet.
+
+
+
+
+ Release Notes - Alfresco - Version Community Edition 201810 EA
+
+
+ Bug
+
+
+[ALF-21783 ] - ScriptAuthorityService: No way to get more than 100 results with some methods
+
+[ALF-21917 ] - Document list edit metadata incorrect url escaping
+
+[ALF-22001 ] - Faceted search does not work in Japanese
+
+[ALF-22030 ] - ADF UI freezes noticeably on a periodic basis during KeyCloak auth requests
+
+
+ Improvement
+
+
+[REPO-2491 ] - Renditions: Rendition Testing
+
+[REPO-3651 ] - AWS Load Tests: Infrastructure and Revamp
+
+[REPO-3663 ] - AWS Load Tests: Initial AWS Cost Estimation with BMF
+
+[REPO-3667 ] - Renditions: Transform event producer
+
+[REPO-3677 ] - AWS Services: Basic Deployment
+
+[REPO-3703 ] - AWS Services: Native Services of ACS
+
+
+
+
+ Release Notes - Alfresco - Version Community Edition 201808 EA
+
+ Bug
+
+
+[ALF-21992 ] - BehaviourFilterImpl.isEnabled(NodeRef, QName) is checking wrong QName in case of subClass
+
+[ALF-22006 ] - VersionServicePolicies cannot be disabled on a specific node
+
+[ALF-22007 ] - TransactionListeners are executed in unpredictable order
+
+
+ Improvement
+
+
+
+ Release Notes - Alfresco - Version Community Edition 201806 GA
+
+ Bug
+
+
+[ALF-22000 ] - Docker: HTML link 693ce565f4c4:8080/share but name
+
+[ALF-22008 ] - It is not possible to upload a document without versions using CMIS
+
+
diff --git a/packaging/CONTRIBUTING.md b/packaging/CONTRIBUTING.md
new file mode 100644
index 00000000000..8d059e27ca0
--- /dev/null
+++ b/packaging/CONTRIBUTING.md
@@ -0,0 +1,16 @@
+### Contributing
+Thanks for your interest in contributing to this project!
+
+The following is a set of guidelines for contributing to this library. Most of them will make the life of the reviewer easier and therefore decrease the time required for the patch be included in the next version.
+
+Because this project forms a part of Alfresco Content Services, the guidelines are hosted in the [Alfresco Social Community](http://community.alfresco.com/community/ecm) where they can be referenced from multiple projects.
+
+Read an [overview on how this project is goverened](https://community.alfresco.com/docs/DOC-6385-project-overview-repository).
+
+You can report an issue in the ALF project of the [Alfresco issue tracker](http://issues.alfresco.com).
+
+Read [instructions for a good issue report](https://community.alfresco.com/docs/DOC-6263-reporting-an-issue).
+
+Read [instructions for making a contribution](https://community.alfresco.com/docs/DOC-6269-submitting-contributions).
+
+Please follow [the coding standards](https://community.alfresco.com/docs/DOC-4658-coding-standards).
diff --git a/packaging/LICENSE b/packaging/LICENSE
new file mode 100644
index 00000000000..ed08681f12b
--- /dev/null
+++ b/packaging/LICENSE
@@ -0,0 +1,191 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ Copyright 2018 Alfresco Software, Inc. All Rights Reserved.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
\ No newline at end of file
diff --git a/packaging/README.md b/packaging/README.md
new file mode 100644
index 00000000000..2bad172990f
--- /dev/null
+++ b/packaging/README.md
@@ -0,0 +1,37 @@
+
+# Alfresco Content Services Community Packaging
+This project is producing packaging for [Alfresco Content Services Repository](https://community.alfresco.com/docs/DOC-6385-project-overview-repository).
+
+The SNAPSHOT version of the artifacts is **never** published.
+
+### Contributing guide
+Please use [this guide](CONTRIBUTING.md) to make a contribution to the project.
+
+This produces the docker images for alfresco-content-repository-community and the distribution zip for the entire Alfresco Content Services Community product
+
+# General
+
+### Build:
+* ```mvn clean install``` in the root of the project will build everything.
+
+## Docker Alfresco
+On official releases, the image is published: https://hub.docker.com/r/alfresco/alfresco-content-repository-community/tags/
+
+For testing locally:
+1. Go to docker-alfresco folder
+2. Run *mvn clean install* if you have not done so
+3. Build the docker image: ```docker build . --tag acr-community:6.0.tag```
+4. Check that the image has been created locally with your desired name/tag: ```docker images```
+
+### Docker-compose & Kubernetes
+Use the deployment project if you want the sample docker-compose or helm: https://github.com/Alfresco/acs-community-deployment
+
+## Distribution zip
+In this folder the distribution zip is build. It contains all the war files, libraries, certificates and settings files you need to deploy Alfresco Content Services Community on the supported application servers.
+
+## How to
+
+* [Create a custom Docker image](https://github.com/Alfresco/acs-packaging/blob/master/docs/create-custom-image.md)
+* [Creating customized Docker images using an existing Docker image](https://github.com/Alfresco/acs-packaging/blob/master/docs/create-custom-image-using-existing-docker-image.md)
+* [Verifying that AMPs have been applied](https://github.com/Alfresco/acs-packaging/blob/master/docs/verify-the-amp-has-been-applied.md)
+* [Create and configure custom Transforms](https://github.com/Alfresco/acs-packaging/blob/master/docs/custom-transforms-and-renditions.md)
diff --git a/packaging/distribution/pom.xml b/packaging/distribution/pom.xml
new file mode 100644
index 00000000000..ffc3bb67ac1
--- /dev/null
+++ b/packaging/distribution/pom.xml
@@ -0,0 +1,175 @@
+
+ 4.0.0
+ alfresco-content-services-community-distribution
+ Alfresco Content Services Community Distribution zip
+ jar
+
+
+ org.alfresco
+ acs-community-packaging
+ 6.2.2-SNAPSHOT
+ ../pom.xml
+
+
+
+
+
+ org.alfresco
+ content-services-community
+ ${project.version}
+ war
+
+
+ org.alfresco
+ alfresco-repository
+
+
+ org.alfresco
+ alfresco-data-model
+
+
+ org.alfresco
+ alfresco-server-root
+ war
+
+
+ org.alfresco
+ alfresco-mmt
+
+
+
+ org.postgresql
+ postgresql
+ ${dependency.postgresql.version}
+
+
+
+ org.alfresco
+ alfresco-pdf-renderer
+ linux
+ tgz
+
+
+ org.alfresco
+ alfresco-pdf-renderer
+ win64
+ tgz
+
+
+
+ org.alfresco
+ alfresco-content-services-share-distribution
+ zip
+
+
+ *
+ *
+
+
+
+
+
+
+ ${project.artifactId}-${project.version}
+
+
+ src/main/resources
+ true
+
+
+
+
+ maven-dependency-plugin
+
+
+ extract-keystore
+ generate-resources
+
+ unpack
+
+
+
+
+
+ org.alfresco
+ alfresco-repository
+ alfresco/keystore/**
+
+
+
+ org.alfresco
+ alfresco-content-services-share-distribution
+ zip
+
+
+
+
+
+ extract-jlan-dll
+ generate-resources
+
+ unpack
+
+
+
+
+ org.alfresco
+ alfresco-jlan-embed
+ windll
+ *.dll
+
+
+
+
+
+
+
+ copy-resources
+ generate-resources
+
+ copy
+
+
+
+
+ org.alfresco
+ alfresco-server-root
+ war
+ ${project.build.outputDirectory}/web-server/webapps
+ ROOT.war
+
+
+ org.alfresco.aos-module
+ alfresco-vti-bin
+ war
+ ${project.build.outputDirectory}/web-server/webapps
+ _vti_bin.war
+
+
+
+
+
+
+
+
+ maven-assembly-plugin
+
+
+ make-assembly
+ package
+
+ single
+
+
+ false
+
+ src/assembly/distribution.xml
+
+
+
+
+
+
+
+
+
diff --git a/packaging/distribution/src/assembly/distribution.xml b/packaging/distribution/src/assembly/distribution.xml
new file mode 100644
index 00000000000..e1d5d3da9a0
--- /dev/null
+++ b/packaging/distribution/src/assembly/distribution.xml
@@ -0,0 +1,118 @@
+
+ distribution
+
+
+
+ zip
+
+
+
+
+
+ target/classes
+
+
+
+
+ ${highest.basedir}/installer/bitrock/licenses
+ licenses
+
+
+
+ target/dependency/alfresco/keystore
+ alf_data/keystore
+
+
+
+ target/dependency
+ bin
+
+ *.dll
+
+
+
+
+
+ ${project.build.directory}/dependency/alfresco-content-services-share-distribution-${alfresco.share.version}
+
+
+ web-server/**
+ modules/**
+ amps/**
+
+
+
+ ${project.build.directory}/dependency/alfresco-content-services-share-distribution-${alfresco.share.version}/web-extension-samples
+ web-server/shared/classes/alfresco/web-extension
+
+
+
+
+
+
+ false
+ amps
+ ${artifact.artifactId}.${artifact.extension}
+
+ *:*:amp
+
+
+
+
+ false
+ true
+ bin
+ ${artifact.artifactId}.${artifact.extension}
+
+ org.alfresco:alfresco-mmt
+
+
+
+
+
+ false
+ true
+ web-server/webapps
+ alfresco.war
+
+ org.alfresco:content-services*:war
+
+
+
+ false
+ true
+ web-server/lib
+
+ org.postgresql:*
+
+
+
+ false
+ true
+ web-server/shared/classes
+
+ org.alfresco:*:jar
+
+ true
+
+
+ alfresco/extension/**
+ alfresco-global.properties.sample
+
+
+
+
+
+
+ false
+ true
+ alfresco-pdf-renderer
+
+ org.alfresco:alfresco-pdf-renderer
+
+
+
+
+
+
diff --git a/packaging/distribution/src/main/resources/README.txt b/packaging/distribution/src/main/resources/README.txt
new file mode 100644
index 00000000000..ca56b88ec5e
--- /dev/null
+++ b/packaging/distribution/src/main/resources/README.txt
@@ -0,0 +1,8 @@
+Alfresco Community (Build: ${installer.version.name})
+===============================
+
+Contains:
+ - Alfresco Content Services Community: ${project.version}
+ - Alfresco Share: ${alfresco.share.version}
+
+For users of Alfresco Community Edition, more information on this release is available at https://community.alfresco.com/community/ecm
diff --git a/packaging/distribution/src/main/resources/bin/apply_amps.bat b/packaging/distribution/src/main/resources/bin/apply_amps.bat
new file mode 100644
index 00000000000..87008216d56
--- /dev/null
+++ b/packaging/distribution/src/main/resources/bin/apply_amps.bat
@@ -0,0 +1,41 @@
+@echo off
+rem -------
+rem Script for apply AMPs to installed WAR
+rem -------
+
+set ALF_AMP_PARAMS=
+set ALF_AMP_NOWAIT=
+
+:ParamsLoop
+if "%~1"=="" goto ParamsLoopContinue
+if "%~1"=="nowait" shift & set ALF_AMP_NOWAIT=yes& goto ParamsLoop
+set ALF_AMP_PARAMS=%ALF_AMP_PARAMS% %1
+shift
+goto :ParamsLoop
+
+:ParamsLoopContinue
+for /D %%D IN (%~dp0..\) do set ALF_HOME=%%~dpD
+set CATALINA_HOME=%ALF_HOME%tomcat
+
+if exist "%CATALINA_HOME%\bin\setenv.bat" call "%CATALINA_HOME%\bin\setenv.bat"
+
+:start
+echo This script will apply all the AMPs in %ALF_HOME%amps to the alfresco.war and share.war files in %CATALINA_HOME%\webapps
+if "%ALF_AMP_NOWAIT%" == "yes" goto nowait1
+echo Press control-c to stop this script . . .
+pause
+:nowait1
+"%JAVA_HOME%\bin\java" -jar "%ALF_HOME%bin\alfresco-mmt.jar" install "%ALF_HOME%amps" "%CATALINA_HOME%\webapps\alfresco.war" -directory%ALF_AMP_PARAMS%
+"%JAVA_HOME%\bin\java" -jar "%ALF_HOME%bin\alfresco-mmt.jar" list "%CATALINA_HOME%\webapps\alfresco.war"
+"%JAVA_HOME%\bin\java" -jar "%ALF_HOME%bin\alfresco-mmt.jar" install "%ALF_HOME%amps_share" "%CATALINA_HOME%\webapps\share.war" -directory%ALF_AMP_PARAMS%
+"%JAVA_HOME%\bin\java" -jar "%ALF_HOME%bin\alfresco-mmt.jar" list "%CATALINA_HOME%\webapps\share.war"
+echo .
+echo About to clean out tomcat/webapps/alfresco directory and temporary files...
+if "%ALF_AMP_NOWAIT%" == "yes" goto nowait2
+pause
+:nowait2
+set ALF_AMP_PARAMS=
+set ALF_AMP_NOWAIT=
+rmdir /S /Q "%CATALINA_HOME%\webapps\alfresco"
+rmdir /S /Q "%CATALINA_HOME%\webapps\share"
+call "%ALF_HOME%bin\clean_tomcat.bat"
\ No newline at end of file
diff --git a/packaging/distribution/src/main/resources/bin/apply_amps.sh b/packaging/distribution/src/main/resources/bin/apply_amps.sh
new file mode 100644
index 00000000000..c8095bd1de9
--- /dev/null
+++ b/packaging/distribution/src/main/resources/bin/apply_amps.sh
@@ -0,0 +1,66 @@
+#!/bin/bash
+# -------
+# Script for apply AMPs to installed WAR
+# -------
+pushd $(dirname $0)>/dev/null
+export SCRIPTPATH=$(pwd)
+export ALF_HOME=${SCRIPTPATH%/*}
+export CATALINA_HOME=$ALF_HOME/tomcat
+required_java_version="1.7"
+
+if [ -f $CATALINA_HOME/bin/setenv.sh ]; then
+ . $CATALINA_HOME/bin/setenv.sh
+fi
+
+# Verify Java installation into ALF_HOME folder
+if [ -f $ALF_HOME/java/bin/java ] && [ -x $ALF_HOME/java/bin/java ]; then
+ echo
+ echo "Found java executable in $ALF_HOME/java"
+ _java=$ALF_HOME/java/bin/java
+
+# Verify Java installation into JAVA_HOME
+elif [ -n "$JAVA_HOME" ] && [ -x "$JAVA_HOME/bin/java" ]; then
+ echo
+ echo "Found java executable in JAVA_HOME: $JAVA_HOME"
+
+ _java="$JAVA_HOME/bin/java"
+
+# Verify Java installation from linux repositories
+elif type -p java; then
+ echo
+ echo "Found installed java executable on the system"
+
+ _java=java
+
+else
+ echo
+ echo "Java is not installed . . . The required Java version is $required_java_version or higher"
+ echo "Please install Java and try again. Script will be closed. "
+ read DUMMY
+ exit 15
+fi
+
+echo
+echo "This script will apply all the AMPs in amps and amps_share to the alfresco.war and share.war files in $CATALINA_HOME/webapps"
+echo "Press control-c to stop this script . . ."
+echo "Press any other key to continue . . ."
+read RESP
+{
+$_java -jar $ALF_HOME/bin/alfresco-mmt.jar install $ALF_HOME/amps $CATALINA_HOME/webapps/alfresco.war -directory $*
+$_java -jar $ALF_HOME/bin/alfresco-mmt.jar list $CATALINA_HOME/webapps/alfresco.war
+$_java -jar $ALF_HOME/bin/alfresco-mmt.jar install $ALF_HOME/amps_share $CATALINA_HOME/webapps/share.war -directory $*
+$_java -jar $ALF_HOME/bin/alfresco-mmt.jar list $CATALINA_HOME/webapps/share.war
+} ||
+{
+ echo
+ echo "Error. Appling of the AMPs is failed. See error message above."
+ echo
+}
+echo "About to clean out $ALF_HOME/tomcat/webapps/alfresco and share directories and temporary files..."
+echo "Press control-c to stop this script . . ."
+echo "Press any other key to continue . . ."
+read DUMMY
+rm -rf $CATALINA_HOME/webapps/alfresco
+rm -rf $CATALINA_HOME/webapps/share
+. $ALF_HOME/bin/clean_tomcat.sh
+popd>/dev/null
\ No newline at end of file
diff --git a/packaging/distribution/src/main/resources/bin/clean_tomcat.bat b/packaging/distribution/src/main/resources/bin/clean_tomcat.bat
new file mode 100644
index 00000000000..5014e508d6c
--- /dev/null
+++ b/packaging/distribution/src/main/resources/bin/clean_tomcat.bat
@@ -0,0 +1,13 @@
+rem @echo off
+rem ---------------------------------
+rem Script to clean Tomcat temp files
+rem ---------------------------------
+
+set ALF_HOME=%~dp0..
+set CATALINA_HOME=%ALF_HOME%\tomcat
+
+echo Cleaning temporary Alfresco files from Tomcat...
+rmdir /S /Q "%CATALINA_HOME%\temp\Alfresco" "%CATALINA_HOME%\work\Catalina\localhost\alfresco"
+rmdir /S /Q "%CATALINA_HOME%\work\Catalina\localhost\share"
+rmdir /S /Q "%CATALINA_HOME%\work\Catalina\localhost\awe"
+rmdir /S /Q "%CATALINA_HOME%\work\Catalina\localhost\wcmqs"
\ No newline at end of file
diff --git a/packaging/distribution/src/main/resources/bin/clean_tomcat.sh b/packaging/distribution/src/main/resources/bin/clean_tomcat.sh
new file mode 100644
index 00000000000..0298283e6f6
--- /dev/null
+++ b/packaging/distribution/src/main/resources/bin/clean_tomcat.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+# ---------------------------------
+# Script to clean Tomcat temp files
+# ---------------------------------
+echo "Cleaning temporary Alfresco files from Tomcat..."
+rm -rf tomcat/temp/Alfresco tomcat/work/Catalina/localhost/alfresco
+rm -rf tomcat/work/Catalina/localhost/share
+rm -rf tomcat/work/Catalina/localhost/awe
+rm -rf tomcat/work/Catalina/localhost/wcmqs
\ No newline at end of file
diff --git a/packaging/distribution/src/main/resources/keystore/CreateSSLKeystores.txt b/packaging/distribution/src/main/resources/keystore/CreateSSLKeystores.txt
new file mode 100644
index 00000000000..a949d3e5764
--- /dev/null
+++ b/packaging/distribution/src/main/resources/keystore/CreateSSLKeystores.txt
@@ -0,0 +1,141 @@
+Instructions for Generating Repository SSL Keystores
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ is the keystore password. The file ${dir.keystore}/ssl-keystore-passwords.properties contains passwords for the SSL keystore,
+${dir.keystore}/ssl-truststore-passwords.properties contains passwords for the SSL truststore.
+
+These instructions will create an RSA public/private key pair for the repository with a certificate that has been signed by the Alfresco Certificate Authority (CA).
+It will also create a truststore for the repository containing the CA certificate; this will be used to authenticate connections to specific repository
+URLs from Solr. It assumes the existence of the Alfresco CA key and certificate to sign the repository certificate; for security reasons these are not generally available.
+You can either generate your own CA key and certificate (see instructions below) or use a recognised Certificate Authority such as Verisign. For Alfresco employees the key
+and certificate are available in svn.
+
+(i) Generate the repository public/private key pair in a keystore:
+
+$ keytool -genkey -alias ssl.repo -keyalg RSA -keystore ssl.keystore -storetype JCEKS -storepass
+Enter keystore password:
+Re-enter new password:
+What is your first and last name?
+ [Unknown]: Alfresco Repository
+What is the name of your organizational unit?
+ [Unknown]:
+What is the name of your organization?
+ [Unknown]: Alfresco Software Ltd.
+What is the name of your City or Locality?
+ [Unknown]: Maidenhead
+What is the name of your State or Province?
+ [Unknown]: UK
+What is the two-letter country code for this unit?
+ [Unknown]: GB
+Is CN=Alfresco Repository, OU=Unknown, O=Alfresco Software Ltd., L=Maidenhead, ST=UK, C=GB correct?
+ [no]: yes
+
+Enter key password for
+ (RETURN if same as keystore password):
+
+(ii) Generate a certificate request for the repository key
+
+$ keytool -keystore ssl.keystore -alias ssl.repo -certreq -file repo.csr -storetype JCEKS -storepass
+
+(iii) Alfresco CA signs the certificate request, creating a certificate that is valid for 365 days.
+
+$ openssl x509 -CA ca.crt -CAkey ca.key -CAcreateserial -req -in repo.csr -out repo.crt -days 365
+Signature ok
+subject=/C=GB/ST=UK/L=Maidenhead/O=Alfresco Software Ltd./OU=Unknown/CN=Alfresco Repository
+Getting CA Private Key
+Enter pass phrase for ca.key:
+
+(iv) Import the Alfresco CA key into the repository key store
+
+$ keytool -import -alias ssl.alfreco.ca -file ca.crt -keystore ssl.keystore -storetype JCEKS -storepass
+Enter keystore password:
+Owner: CN=Alfresco CA, O=Alfresco Software Ltd., L=Maidenhead, ST=UK, C=GB
+Issuer: CN=Alfresco CA, O=Alfresco Software Ltd., L=Maidenhead, ST=UK, C=GB
+Serial number: 805ba6dc8f62f8b8
+Valid from: Fri Aug 12 13:28:58 BST 2011 until: Mon Aug 09 13:28:58 BST 2021
+Certificate fingerprints:
+ MD5: 4B:45:94:2D:8E:98:E8:12:04:67:AD:AE:48:3C:F5:A0
+ SHA1: 74:42:22:D0:52:AD:82:7A:FD:37:46:37:91:91:F4:77:89:3A:C9:A3
+ Signature algorithm name: SHA1withRSA
+ Version: 3
+
+Extensions:
+
+#1: ObjectId: 2.5.29.14 Criticality=false
+SubjectKeyIdentifier [
+KeyIdentifier [
+0000: 08 42 40 DC FE 4A 50 87 05 2B 38 4D 92 70 8E 51 .B@..JP..+8M.p.Q
+0010: 4E 38 71 D6 N8q.
+]
+]
+
+#2: ObjectId: 2.5.29.19 Criticality=false
+BasicConstraints:[
+ CA:true
+ PathLen:2147483647
+]
+
+#3: ObjectId: 2.5.29.35 Criticality=false
+AuthorityKeyIdentifier [
+KeyIdentifier [
+0000: 08 42 40 DC FE 4A 50 87 05 2B 38 4D 92 70 8E 51 .B@..JP..+8M.p.Q
+0010: 4E 38 71 D6 N8q.
+]
+
+[CN=Alfresco CA, O=Alfresco Software Ltd., L=Maidenhead, ST=UK, C=GB]
+SerialNumber: [ 805ba6dc 8f62f8b8]
+]
+
+Trust this certificate? [no]: yes
+Certificate was added to keystore
+
+(v) Import the CA-signed repository certificate into the repository keystore
+
+$ keytool -import -alias ssl.repo -file repo.crt -keystore ssl.keystore -storetype JCEKS -storepass
+Enter keystore password:
+Certificate reply was installed in keystore
+
+(vi) Convert the repository keystore to a pkcs12 keystore (for use in browsers such as Firefox). Give the pkcs12 key store the key store password 'alfresco'.
+
+keytool -importkeystore -srckeystore ssl.keystore -srcstorepass -srcstoretype JCEKS -srcalias ssl.repo -srckeypass kT9X6oe68t -destkeystore firefox.p12 -deststoretype pkcs12 -deststorepass alfresco -destalias ssl.repo -destkeypass alfresco
+
+(vi) Create a repository truststore containing the Alfresco CA certificate
+
+keytool -import -alias ssl.alfreco.ca -file ca.crt -keystore ssl.keystore -storetype JCEKS -storepass
+keytool -import -alias alfreco.ca -file ca.crt -keystore ssl.truststore -storetype JCEKS -storepass
+
+(vii) Copy the keystore and truststore to the repository keystore location defined by the property 'dir.keystore'.
+(viii) Update the SSL properties i.e. properties starting with the prefixes 'alfresco.encryption.ssl.keystore' and 'alfresco.encryption.ssl.truststore'.
+
+Instructions for Generating a Certificate Authority (CA) Key and Certificate
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(i) Generate the CA private key
+
+$ openssl genrsa -des3 -out ca.key 1024
+Generating RSA private key, 1024 bit long modulus
+..........++++++
+..++++++
+e is 65537 (0x10001)
+Enter pass phrase for ca.key:
+Verifying - Enter pass phrase for ca.key:
+
+(ii) Generate the CA self-signed certificate
+
+$ openssl req -new -x509 -days 3650 -key ca.key -out ca.crt
+Enter pass phrase for ca.key:
+You are about to be asked to enter information that will be incorporated
+into your certificate request.
+What you are about to enter is what is called a Distinguished Name or a DN.
+There are quite a few fields but you can leave some blank
+For some fields there will be a default value,
+If you enter '.', the field will be left blank.
+-----
+Country Name (2 letter code) [AU]:GB
+State or Province Name (full name) [Some-State]:UK
+Locality Name (eg, city) []:Maidenhead
+Organization Name (eg, company) [Internet Widgits Pty Ltd]:Alfresco Software Ltd.
+Organizational Unit Name (eg, section) []:
+Common Name (eg, YOUR name) []:Alfresco CA
+Email Address []:
+
diff --git a/packaging/distribution/src/main/resources/keystore/generate_keystores.bat b/packaging/distribution/src/main/resources/keystore/generate_keystores.bat
new file mode 100644
index 00000000000..5aed5e9fa01
--- /dev/null
+++ b/packaging/distribution/src/main/resources/keystore/generate_keystores.bat
@@ -0,0 +1,58 @@
+@rem Please edit the variables below to suit your installation
+@rem Note: for an installation created by the Alfresco installer, you only need to edit ALFRESCO_HOME
+
+@rem Alfresco installation directory
+set ALFRESCO_HOME=C:\Alfresco-5.2
+@rem The directory containing the alfresco keystores, as referenced by keystoreFile and truststoreFile attributes in tomcat\conf\server.xml
+set ALFRESCO_KEYSTORE_HOME=%ALFRESCO_HOME%\alf_data\keystore
+@rem Java installation directory
+set JAVA_HOME=%ALFRESCO_HOME%\java
+@rem Location in which new keystore files will be generated
+set CERTIFICATE_HOME=%USERPROFILE%
+@rem The repository server certificate subject name, as specified in tomcat\conf\tomcat-users.xml with roles="repository"
+set REPO_CERT_DNAME=CN=Alfresco Repository, OU=Unknown, O=Alfresco Software Ltd., L=Maidenhead, ST=UK, C=GB
+@rem The SOLR client certificate subject name, as specified in tomcat\conf\tomcat-users.xml with roles="repoclient"
+set SOLR_CLIENT_CERT_DNAME=CN=Alfresco Repository Client, OU=Unknown, O=Alfresco Software Ltd., L=Maidenhead, ST=UK, C=GB
+@rem The number of days before the certificate expires
+set CERTIFICATE_VALIDITY=36525
+
+@rem Ensure certificate output dir exists
+@if not exist "%CERTIFICATE_HOME%" mkdir "%CERTIFICATE_HOME%"
+
+@rem Remove old output files (note they are backed up elsewhere)
+@if exist "%CERTIFICATE_HOME%\ssl.keystore" del "%CERTIFICATE_HOME%\ssl.keystore"
+@if exist "%CERTIFICATE_HOME%\ssl.truststore" del "%CERTIFICATE_HOME%\ssl.truststore"
+@if exist "%CERTIFICATE_HOME%\browser.p12" del "%CERTIFICATE_HOME%\browser.p12"
+@if exist "%CERTIFICATE_HOME%\ssl.repo.client.keystore" del "%CERTIFICATE_HOME%\ssl.repo.client.keystore"
+@if exist "%CERTIFICATE_HOME%\ssl.repo.client.truststore" del "%CERTIFICATE_HOME%\ssl.repo.client.truststore"
+
+@rem Generate new self-signed certificates for the repository and solr
+"%JAVA_HOME%\bin\keytool" -genkeypair -keyalg RSA -dname "%REPO_CERT_DNAME%" -validity %CERTIFICATE_VALIDITY% -alias ssl.repo -keypass kT9X6oe68t -keystore "%CERTIFICATE_HOME%\ssl.keystore" -storetype JCEKS -storepass kT9X6oe68t
+"%JAVA_HOME%\bin\keytool" -exportcert -alias ssl.repo -file "%CERTIFICATE_HOME%\ssl.repo.crt" -keystore "%CERTIFICATE_HOME%\ssl.keystore" -storetype JCEKS -storepass kT9X6oe68t
+"%JAVA_HOME%\bin\keytool" -genkeypair -keyalg RSA -dname "%SOLR_CLIENT_CERT_DNAME%" -validity %CERTIFICATE_VALIDITY% -alias ssl.repo.client -keypass kT9X6oe68t -keystore "%CERTIFICATE_HOME%\ssl.repo.client.keystore" -storetype JCEKS -storepass kT9X6oe68t
+"%JAVA_HOME%\bin\keytool" -exportcert -alias ssl.repo.client -file "%CERTIFICATE_HOME%\ssl.repo.client.crt" -keystore "%CERTIFICATE_HOME%\ssl.repo.client.keystore" -storetype JCEKS -storepass kT9X6oe68t
+
+@rem Create trust relationship between repository and solr
+"%JAVA_HOME%\bin\keytool" -importcert -noprompt -alias ssl.repo.client -file "%CERTIFICATE_HOME%\ssl.repo.client.crt" -keystore "%CERTIFICATE_HOME%\ssl.truststore" -storetype JCEKS -storepass kT9X6oe68t
+@rem Create trust relationship between repository and itself - used for searches
+"%JAVA_HOME%\bin\keytool" -importcert -noprompt -alias ssl.repo -file "%CERTIFICATE_HOME%\ssl.repo.crt" -keystore "%CERTIFICATE_HOME%\ssl.truststore" -storetype JCEKS -storepass kT9X6oe68t
+@rem Create trust relationship between solr and repository
+"%JAVA_HOME%\bin\keytool" -importcert -noprompt -alias ssl.repo -file "%CERTIFICATE_HOME%\ssl.repo.crt" -keystore "%CERTIFICATE_HOME%\ssl.repo.client.truststore" -storetype JCEKS -storepass kT9X6oe68t
+@rem Export repository keystore to pkcs12 format for browser compatibility
+"%JAVA_HOME%\bin\keytool" -importkeystore -srckeystore "%CERTIFICATE_HOME%\ssl.keystore" -srcstorepass kT9X6oe68t -srcstoretype JCEKS -srcalias ssl.repo -srckeypass kT9X6oe68t -destkeystore "%CERTIFICATE_HOME%\browser.p12" -deststoretype pkcs12 -deststorepass alfresco -destalias ssl.repo -destkeypass alfresco
+
+@rem Ensure keystore dir actually exists
+@if not exist "%ALFRESCO_KEYSTORE_HOME%" mkdir "%ALFRESCO_KEYSTORE_HOME%"
+
+@rem Install the new files
+copy /Y "%CERTIFICATE_HOME%\ssl.keystore" "%ALFRESCO_KEYSTORE_HOME%\ssl.keystore"
+copy /Y "%CERTIFICATE_HOME%\ssl.truststore" "%ALFRESCO_KEYSTORE_HOME%\ssl.truststore"
+copy /Y "%CERTIFICATE_HOME%\browser.p12" "%ALFRESCO_KEYSTORE_HOME%\browser.p12"
+
+@echo ****************************************
+@echo You must copy the following files to the correct location.
+@echo %CERTIFICATE_HOME%\ssl.repo.client.keystore
+@echo %CERTIFICATE_HOME%\ssl.repo.client.truststore
+@echo eg. for Solr 4 the location is SOLR_HOME\workspace-SpacesStore\conf and SOLR_HOME\archive-SpacesStore\conf
+@echo Please ensure that you set dir.keystore=%ALFRESCO_KEYSTORE_HOME% in alfresco-global.properties
+@echo ****************************************
\ No newline at end of file
diff --git a/packaging/distribution/src/main/resources/keystore/generate_keystores.sh b/packaging/distribution/src/main/resources/keystore/generate_keystores.sh
new file mode 100644
index 00000000000..180c9909455
--- /dev/null
+++ b/packaging/distribution/src/main/resources/keystore/generate_keystores.sh
@@ -0,0 +1,82 @@
+#! /bin/sh
+# Please edit the variables below to suit your installation
+# Note: for an installation created by the Alfresco installer, you only need to edit ALFRESCO_HOME
+
+# Alfresco installation directory
+if [ -z "$ALFRESCO_HOME" ]; then
+ ALFRESCO_HOME=/opt/alfresco-5.2
+ echo "Setting ALFRESCO_HOME to $ALFRESCO_HOME"
+fi
+
+# The directory containing the alfresco keystores, as referenced by keystoreFile and truststoreFile attributes in tomcat/conf/server.xml
+ALFRESCO_KEYSTORE_HOME=$ALFRESCO_HOME/alf_data/keystore
+
+# Location in which new keystore files will be generated
+if [ -z "$CERTIFICATE_HOME" ]; then
+ CERTIFICATE_HOME=$HOME
+ echo "Certificates will be generated in $CERTIFICATE_HOME and then moved to $ALFRESCO_KEYSTORE_HOME"
+fi
+
+# Java installation directory
+JAVA_HOME=$ALFRESCO_HOME/java
+
+# The repository server certificate subject name, as specified in tomcat/conf/tomcat-users.xml with roles="repository"
+REPO_CERT_DNAME="CN=Alfresco Repository, OU=Unknown, O=Alfresco Software Ltd., L=Maidenhead, ST=UK, C=GB"
+# The SOLR client certificate subject name, as specified in tomcat/conf/tomcat-users.xml with roles="repoclient"
+SOLR_CLIENT_CERT_DNAME="CN=Alfresco Repository Client, OU=Unknown, O=Alfresco Software Ltd., L=Maidenhead, ST=UK, C=GB"
+# The number of days before the certificate expires
+CERTIFICATE_VALIDITY=36525
+
+# Stop
+if [ -f "$ALFRESCO_HOME/alfresco.sh" ]; then "$ALFRESCO_HOME/alfresco.sh" stop; fi
+
+# Ensure certificate output dir exists
+mkdir -p "$CERTIFICATE_HOME"
+
+# Remove old output files (note they are backed up elsewhere)
+if [ -f "$CERTIFICATE_HOME/ssl.keystore" ]; then rm "$CERTIFICATE_HOME/ssl.keystore"; fi
+if [ -f "$CERTIFICATE_HOME/ssl.truststore" ]; then rm "$CERTIFICATE_HOME/ssl.truststore"; fi
+if [ -f "$CERTIFICATE_HOME/browser.p12" ]; then rm "$CERTIFICATE_HOME/browser.p12"; fi
+if [ -f "$CERTIFICATE_HOME/ssl.repo.client.keystore" ]; then rm "$CERTIFICATE_HOME/ssl.repo.client.keystore"; fi
+if [ -f "$CERTIFICATE_HOME/ssl.repo.client.truststore" ]; then rm "$CERTIFICATE_HOME/ssl.repo.client.truststore"; fi
+
+# Generate new self-signed certificates for the repository and solr
+"$JAVA_HOME/bin/keytool" -genkeypair -keyalg RSA -dname "$REPO_CERT_DNAME" -validity $CERTIFICATE_VALIDITY -alias ssl.repo -keypass kT9X6oe68t -keystore "$CERTIFICATE_HOME/ssl.keystore" -storetype JCEKS -storepass kT9X6oe68t
+"$JAVA_HOME/bin/keytool" -exportcert -alias ssl.repo -file "$CERTIFICATE_HOME/ssl.repo.crt" -keystore "$CERTIFICATE_HOME/ssl.keystore" -storetype JCEKS -storepass kT9X6oe68t
+"$JAVA_HOME/bin/keytool" -genkeypair -keyalg RSA -dname "$SOLR_CLIENT_CERT_DNAME" -validity $CERTIFICATE_VALIDITY -alias ssl.repo.client -keypass kT9X6oe68t -keystore "$CERTIFICATE_HOME/ssl.repo.client.keystore" -storetype JCEKS -storepass kT9X6oe68t
+"$JAVA_HOME/bin/keytool" -exportcert -alias ssl.repo.client -file "$CERTIFICATE_HOME/ssl.repo.client.crt" -keystore "$CERTIFICATE_HOME/ssl.repo.client.keystore" -storetype JCEKS -storepass kT9X6oe68t
+
+# Create trust relationship between repository and solr
+"$JAVA_HOME/bin/keytool" -importcert -noprompt -alias ssl.repo.client -file "$CERTIFICATE_HOME/ssl.repo.client.crt" -keystore "$CERTIFICATE_HOME/ssl.truststore" -storetype JCEKS -storepass kT9X6oe68t
+# Create trust relationship between repository and itself - used for searches
+"$JAVA_HOME/bin/keytool" -importcert -noprompt -alias ssl.repo -file "$CERTIFICATE_HOME/ssl.repo.crt" -keystore "$CERTIFICATE_HOME/ssl.truststore" -storetype JCEKS -storepass kT9X6oe68t
+# Create trust relationship between solr and repository
+"$JAVA_HOME/bin/keytool" -importcert -noprompt -alias ssl.repo -file "$CERTIFICATE_HOME/ssl.repo.crt" -keystore "$CERTIFICATE_HOME/ssl.repo.client.truststore" -storetype JCEKS -storepass kT9X6oe68t
+# Export repository keystore to pkcs12 format for browser compatibility
+"$JAVA_HOME/bin/keytool" -importkeystore -srckeystore "$CERTIFICATE_HOME/ssl.keystore" -srcstorepass kT9X6oe68t -srcstoretype JCEKS -srcalias ssl.repo -srckeypass kT9X6oe68t -destkeystore "$CERTIFICATE_HOME/browser.p12" -deststoretype pkcs12 -deststorepass alfresco -destalias ssl.repo -destkeypass alfresco
+
+# Ensure keystore dir actually exists
+mkdir -p "$ALFRESCO_KEYSTORE_HOME"
+
+# Back up old files
+cp "$ALFRESCO_KEYSTORE_HOME/ssl.keystore" "$ALFRESCO_KEYSTORE_HOME/ssl.keystore.old"
+cp "$ALFRESCO_KEYSTORE_HOME/ssl.truststore" "$ALFRESCO_KEYSTORE_HOME/ssl.truststore.old"
+cp "$ALFRESCO_KEYSTORE_HOME/browser.p12" "$ALFRESCO_KEYSTORE_HOME/browser.p12.old"
+
+# Install the new files
+cp "$CERTIFICATE_HOME/ssl.keystore" "$ALFRESCO_KEYSTORE_HOME/ssl.keystore"
+cp "$CERTIFICATE_HOME/ssl.truststore" "$ALFRESCO_KEYSTORE_HOME/ssl.truststore"
+cp "$CERTIFICATE_HOME/browser.p12" "$ALFRESCO_KEYSTORE_HOME/browser.p12"
+
+echo " "
+echo "*******************************************"
+echo "You must copy the following files to the correct location."
+echo " "
+echo " $CERTIFICATE_HOME/ssl.repo.client.keystore"
+echo " $CERTIFICATE_HOME/ssl.repo.client.truststore"
+echo " eg. for Solr 4 the location is SOLR_HOME/workspace-SpacesStore/conf/ and SOLR_HOME/archive-SpacesStore/conf/"
+echo " "
+echo "$ALFRESCO_KEYSTORE_HOME/browser.p12 has also been generated."
+echo " "
+echo "Please ensure that you set dir.keystore=$ALFRESCO_KEYSTORE_HOME in alfresco-global.properties"
+echo "*******************************************"
diff --git a/packaging/distribution/src/main/resources/keystore/readme.txt b/packaging/distribution/src/main/resources/keystore/readme.txt
new file mode 100644
index 00000000000..25f317223c9
--- /dev/null
+++ b/packaging/distribution/src/main/resources/keystore/readme.txt
@@ -0,0 +1,7 @@
+See https://wiki.alfresco.com/wiki/Data_Encryption and https://wiki.alfresco.com/wiki/Alfresco_And_SOLR.
+
+keystore is the secret key keystore, containing the secret key used to encrypt and decrypt node properties.
+ssl.keystore is the repository keystore, containing the repository private/public key pair and certificate.
+ssl.truststore is the repository truststore, containing certificates that the repository trusts.
+
+browser.p12 is a pkcs12 keystore generated from ssl.keystore that contains the repository private key and certificate for use in browsers such as Firefox.
\ No newline at end of file
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/Apache 2.0.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/Apache 2.0.txt
new file mode 100644
index 00000000000..b09cd7856d5
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/Apache 2.0.txt
@@ -0,0 +1,201 @@
+Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/Apache-like-JDOM.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/Apache-like-JDOM.txt
new file mode 100644
index 00000000000..c18f7bb852a
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/Apache-like-JDOM.txt
@@ -0,0 +1,54 @@
+/*--
+
+ Copyright (C) 2000-2012 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions, and the disclaimer that follows
+ these conditions in the documentation and/or other materials
+ provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+ derived from this software without prior written permission. For
+ written permission, please contact .
+
+ 4. Products derived from this software may not be called "JDOM", nor
+ may "JDOM" appear in their name, without prior written permission
+ from the JDOM Project Management .
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+ "This product includes software developed by the
+ JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter and
+ Brett McLaughlin . For more information
+ on the JDOM Project, please see .
+
+ */
+
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/Apache-like-XPP.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/Apache-like-XPP.txt
new file mode 100644
index 00000000000..104f189ae0e
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/Apache-like-XPP.txt
@@ -0,0 +1,58 @@
+LICENSE FOR THE Extreme! Lab PullParser
+------------------------------------------------------------------------
+
+Copyright 2002 The Trustees of Indiana University.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1) All redistributions of source code must retain the above
+ copyright notice, the list of authors in the original source
+ code, this list of conditions and the disclaimer listed in this
+ license;
+
+2) All redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the disclaimer
+ listed in this license in the documentation and/or other
+ materials provided with the distribution;
+
+3) Any documentation included with all redistributions must include
+ the following acknowledgement:
+
+ "This product includes software developed by the Indiana
+ University Extreme! Lab. For further information please visit
+ http://www.extreme.indiana.edu/"
+
+ Alternatively, this acknowledgment may appear in the software
+ itself, and wherever such third-party acknowledgments normally
+ appear.
+
+4) The name "Indiana Univeristy" and "Indiana Univeristy
+ Extreme! Lab" shall not be used to endorse or promote
+ products derived from this software without prior written
+ permission from Indiana University. For written permission,
+ please contact http://www.extreme.indiana.edu/.
+
+5) Products derived from this software may not use "Indiana
+ Univeristy" name nor may "Indiana Univeristy" appear in their name,
+ without prior written permission of the Indiana University.
+
+Indiana University provides no reassurances that the source code
+provided does not infringe the patent or any other intellectual
+property rights of any other entity. Indiana University disclaims any
+liability to any recipient for claims brought by any other entity
+based on infringement of intellectual property rights or otherwise.
+
+LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH
+NOWARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA
+UNIVERSITY GIVES NO WARRANTIES AND MAKES NO REPRESENTATION THAT
+SOFTWARE IS FREE OF INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR
+OTHER PROPRIETARY RIGHTS. INDIANA UNIVERSITY MAKES NO WARRANTIES THAT
+SOFTWARE IS FREE FROM "BUGS", "VIRUSES", "TROJAN HORSES", "TRAP
+DOORS", "WORMS", OR OTHER HARMFUL CODE. LICENSEE ASSUMES THE ENTIRE
+RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR ASSOCIATED MATERIALS,
+AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION GENERATED USING
+SOFTWARE.
+
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/ApachePortableRuntime.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/ApachePortableRuntime.txt
new file mode 100644
index 00000000000..02418e19136
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/ApachePortableRuntime.txt
@@ -0,0 +1,341 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+
+APACHE PORTABLE RUNTIME SUBCOMPONENTS:
+
+The Apache Portable Runtime includes a number of subcomponents with
+separate copyright notices and license terms. Your use of the source
+code for the these subcomponents is subject to the terms and
+conditions of the following licenses.
+
+From strings/apr_fnmatch.c, include/apr_fnmatch.h, misc/unix/getopt.c,
+file_io/unix/mktemp.c, strings/apr_strings.c:
+
+/*
+ * Copyright (c) 1987, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+
+From network_io/unix/inet_ntop.c, network_io/unix/inet_pton.c:
+
+/* Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+
+From dso/aix/dso.c:
+
+ * Based on libdl (dlfcn.c/dlfcn.h) which is
+ * Copyright (c) 1992,1993,1995,1996,1997,1988
+ * Jens-Uwe Mager, Helios Software GmbH, Hannover, Germany.
+ *
+ * Not derived from licensed software.
+ *
+ * Permission is granted to freely use, copy, modify, and redistribute
+ * this software, provided that the author is not construed to be liable
+ * for any results of using the software, alterations are clearly marked
+ * as such, and this notice is not modified.
+
+From strings/apr_strnatcmp.c, include/apr_strings.h:
+
+ strnatcmp.c -- Perform 'natural order' comparisons of strings in C.
+ Copyright (C) 2000 by Martin Pool
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+From strings/apr_snprintf.c:
+
+ *
+ * cvt - IEEE floating point formatting routines.
+ * Derived from UNIX V7, Copyright(C) Caldera International Inc.
+ *
+
+ Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ Redistributions of source code and documentation must retain the above
+ copyright notice, this list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:
+
+ This product includes software developed or owned by Caldera
+ International, Inc.
+
+ Neither the name of Caldera International, Inc. nor the names of other
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
+ INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE FOR ANY DIRECT,
+ INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/BEA-JSR181-WebServicesMetadata.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/BEA-JSR181-WebServicesMetadata.txt
new file mode 100644
index 00000000000..e0e0cb691d1
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/BEA-JSR181-WebServicesMetadata.txt
@@ -0,0 +1,284 @@
+
+BEA SYSTEMS, INC. ("BEA") IS WILLING TO LICENSE THIS
+SPECIFICATION TO YOU ONLY
+UPON THE CONDITION THAT YOU ACCEPT ALL OF THE TERMS
+CONTAINED IN THIS LICENSE
+AGREEMENT ("AGREEMENT").? PLEASE READ THE TERMS AND
+CONDITIONS OF THIS AGR
+EEMENT
+CAREFULLY. BY DOWNLOADING THIS SPECIFICATION, YOU
+ACCEPT THE TERMS AND
+CONDITIONS OF THE AGREEMENT. IF YOU ARE NOT WILL?ING
+TO BE BOUND BY IT, SELECT
+THE "DECLINE" BUTTON AT THE BOTTOM OF THIS PAGE AND
+THE DOWNLOADING PROCES
+S WILL
+NOT CONTINUE.
+Web Services Metadata for the JavaTM Platform
+Specification ("Specification")
+Version: 1.0
+Status: FCS
+Release: June 1, 2005
+Copyright 2002, 2003,2004,2005 BEA Systems, Inc.
+2315 North First Street, San
+Jose CA, 95131
+All rights reserved.
+
+NOTICE; LIMITED LICENSE GRANTS
+
+1. License for Evaluation Purposes. BEA hereby grants
+you a fully-paid,
+non-exclusive, non-transfer?able, worldwide, limited
+license (without the right
+to
+sublicense), under BEA's applicable intellectual
+property rights to view,
+download, use and reproduce the Specification only for
+the purpose of internal
+eval?uation, which shall be understood to include
+developing applications
+int
+ended to run on an implementation of the
+Specification provided that such
+applications do not themselves implement any
+portion(s) of the Specification.
+
+2. License for the Distribution of Compliant
+Implementations. BEA also grants
+
+you a perpetual, non-exclusive, non-transferable,
+worldwide, fully paid-up,
+royalty free, limited license (without the right to
+sub?license) under any
+applicable copyrights or, subject to the provisions of
+subsection 3 below,
+
+patent rights it may have covering the Specification
+to create and/or distribute
+an implementation of the Specification that: (a) fully
+implements the
+Specification including all its required interfaces
+and functionality, (b) does
+
+not modify, subset, superset or otherwise extend the
+Sun Name Space, or include
+any public or protected packages, classes, Java
+interfaces, fields or methods
+within the Sun Name Space other than those
+required/authorized by the
+Sp
+ecification or Specifications being implemented and
+(c) passes the Technology
+Compatibility Kit for such Specification ("Compliant
+Implementation").
+
+
+
+3. Reciprocity Concerning Patent Licenses.
+
+ a. With respect to any
+patent claims covered
+by the license granted
+under subparagraph 2 above that would be infringed by
+all technically feasible
+implementations of the Specification, such license is
+condi?tioned upon your
+offering on fair, reasonable a
+nd non-discriminatory
+terms, to any party seeking
+it from You, a perpetual, non-exclusive,
+non-transferable, worldwide license
+under Your patent rights which are or would be
+infringed by all technically
+feasible implementations of
+the Specification to
+develop, distribute and use a
+Compliant Implementation.
+
+
+ b With respect to any patent claims owned by
+BEA and covered by the
+license granted under subparagraph 2, whether or not
+their infringement can
+be
+avoided in a technically feasible manner when
+implementing the Specification,
+such license shall terminate with respect to such
+claims if You initiate a claim
+against BEA that it has, in the course of performing
+its responsibili
+ties as the
+Specification Lead, induced any other entity to
+infringe Your patent rights.
+
+ c Also with respect to any patent claims
+owned by BEA and covered by
+the license granted under subparagraph, where the
+infringement of su
+ch claims
+can be avoided in a technically feasible manner when
+implementing the
+Specification such license, with respect to such
+claims, shall terminate if You
+initiate a claim against BEA that its making, having
+made, using, offer
+ing to
+sell, selling or importing a Compli?ant Implementation
+infringes Your patent
+rights.
+
+4. Downstream Licenses for Compliant Implementations.
+ A Downstream Licensee
+need not include limitations (a)-(c) from Section 2,
+a
+bove, or any other
+particular "pass through" requirements in any license
+the Downstream Licensee
+grants concerning the use of its Compliant
+Implementation or products derived
+from it. However, except with respect to
+implementation
+s of the Specification
+(and products derived from them) by the Downstream
+Licensee's licensee that
+satisfy requirements (a)-(c) from Section 2, above,
+the Downstream Licensee may
+neither: (a) grant or otherwise pass through to its licensees any licensable
+copyrights and patent rights of BEA; nor (b) authorize
+its licensees to make any
+claims concerning their implementation's compliance
+with the Specification in
+question.
+
+5. Definitions. For the purposes
+of this Agreement:
+"Technology Compatibility
+Kit" or "TCK" shall mean the test suite and
+accompanying documentation provided
+by BEA which corresponds to the particular version of
+the Specification being
+tested; "Sun Name Space" sha
+ll mean the public class
+or interface declarations
+whose names begin with "java", "javax", "com.sun" or
+their equivalents in any
+subsequent naming convention adopted by Sun
+Microsystems, Inc., through the Java
+Community Process, or
+any recognized successors or
+replacements thereof;
+"Downstream Licensee" shall mean a company or
+individual that creates an
+Compliant Implementation under this Agreement.
+
+BEA shall have the right to terminate this Agreement
+imm
+ediately notice if you
+fail to comply with any material provision of or act
+outside the scope of the
+licenses granted above.
+
+
+
+TRADEMARKS
+
+No right, title, or interest in or to any trademarks,
+service marks, or trade names of BEA or BEA's licensors is granted hereunder.
+Java is a registered
+trademark of Sun Microsystems, Inc. in the United
+States and other countries.
+
+DISCLAIMER OF WARRANTIES
+THE SPECIFICATION IS PROVIDED "AS IS".? BEA MAKES NO
+
+REPRESENTATIONS OR
+WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO, WARRAN?TIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
+NON-INFRINGEMENT
+(INCLUDING AS A CONSEQUENCE OF ANY PRACTICE OR
+IMPLEMENT
+ATION OF THE
+SPECI?FICATION), OR THAT THE CONTENTS OF THE
+SPECIFICATION ARE SUITABLE FOR ANY
+PUR?POSE.
+THE SPECIFICATION COULD INCLUDE TECHNICAL INACCURACIES
+OR TYPOGRAPHICAL ERRORS.?
+CHANGES ARE PERIODICALLY ADDED TO THE INFORMATI
+ON
+THEREIN; THESE CHANGES WILL BE
+INCORPORATED INTO NEW VERSIONS OF THE SPECIFICATION,
+IF ANY.? BEA MAY MAKE
+IMPROVEMENTS AND/OR CHANGES TO THE PRODUCT(S) AND/OR
+THE PROGRAM(S) DESCRIBED IN
+THE SPECIFICATION AT ANY TIME.? Any use o
+f such
+changes in the Specification
+will be governed by the then-current license for the
+applicable version of the
+Specification.
+LIMITATION OF LIABILITY
+TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT WILL
+BEA OR ITS BEAS BE
+LIABLE
+FOR ANY DAMAGES, INCLUDING WITHOUT LIMITATION, LOST
+REVENUE, PROFITS OR DATA, OR
+FOR SPECIAL, INDIRECT, CONSEQUENTIAL, INCIDENTAL OR
+PUNI?TIVE DAMAGES, HOWEVER
+CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ARISING OUT OF
+OR RELATED TO
+ANY FURNISHING, PRACTICING, MODIFYING OR ANY USE OF
+THE SPECIFICATION, EVEN IF
+BEA AND/OR ITS BEAS HAVE BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+You will indemnify, hold harmless, and defend BEA and
+its licen
+sors from any
+claims arising or result?ing from: (i) your use of the
+Specification; (ii) the
+use or distribution of your application or applet
+written to and/or Your
+implementation of the Specification; and/or (iii) any
+claims that
+later versions
+or releases of any Specification furnished to you are
+incompatible with the
+Specification provided to you under this license.
+RESTRICTED RIGHTS LEGEND
+U.S. Government:? If this Specification is being
+acquired by or
+on behalf of the
+U.S. Government or by a U.S. Government prime
+contractor or subcontractor (at
+any tier), then the Government's rights in the
+Soft?ware and accompanying
+documentation shall be only as set forth in this
+license; this
+is in accordance
+with 48 C.F.R. 227.7201 through 227.7202-4 (for
+Department of Defense (DoD)
+acquisitions) and with 48 C.F.R. 2.101 and 12.212 (for
+non-DoD acquisitions).
+REPORT
+You may wish to report any ambiguities,
+inconsis
+tencies or inaccuracies you may
+find in connection with your use of the Specification
+("Feedback"). To the
+extent that you provide BEA with any Feedback, you
+hereby: (i) agree that such
+Feedback is provided on a non-proprietary and non-confidential basis, and (ii)
+grant BEA a perpetual, non-exclusive, worldwide, fully
+paid-up, irrevocable
+copyright license, with the right to sublicense
+through multiple levels of
+sublicensees, to incorporate, disclose, and use without limitation the Feedback
+for any purpose related to the Specification and
+future versions,
+implementations, and test suites thereof.
+
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-ASM.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-ASM.txt
new file mode 100644
index 00000000000..75ad085e2b5
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-ASM.txt
@@ -0,0 +1,29 @@
+Copyright (c) 2000-2005 INRIA, France Telecom
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holders nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-AntLR.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-AntLR.txt
new file mode 100644
index 00000000000..5ddbbcfc184
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-AntLR.txt
@@ -0,0 +1,26 @@
+[The "BSD license"]
+Copyright (c) 2014 Terence Parr, Sam Harwell
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-Dojo.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-Dojo.txt
new file mode 100644
index 00000000000..2640cee7838
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-Dojo.txt
@@ -0,0 +1,195 @@
+Dojo is available under *either* the terms of the modified BSD license *or* the
+Academic Free License version 2.1. As a recipient of Dojo, you may choose which
+license to receive this code under (except as noted in per-module LICENSE
+files). Some modules may not be the copyright of the Dojo Foundation. These
+modules contain explicit declarations of copyright in both the LICENSE files in
+the directories in which they reside and in the code itself. No external
+contributions are allowed under licenses which are fundamentally incompatible
+with the AFL or BSD licenses that Dojo is distributed under.
+
+The text of the AFL and BSD licenses is reproduced below.
+
+-------------------------------------------------------------------------------
+The "New" BSD License:
+**********************
+
+Copyright (c) 2005-2014, The Dojo Foundation
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of the Dojo Foundation nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+-------------------------------------------------------------------------------
+The Academic Free License, v. 2.1:
+**********************************
+
+This Academic Free License (the "License") applies to any original work of
+authorship (the "Original Work") whose owner (the "Licensor") has placed the
+following notice immediately following the copyright notice for the Original
+Work:
+
+Licensed under the Academic Free License version 2.1
+
+1) Grant of Copyright License. Licensor hereby grants You a world-wide,
+royalty-free, non-exclusive, perpetual, sublicenseable license to do the
+following:
+
+a) to reproduce the Original Work in copies;
+
+b) to prepare derivative works ("Derivative Works") based upon the Original
+Work;
+
+c) to distribute copies of the Original Work and Derivative Works to the
+public;
+
+d) to perform the Original Work publicly; and
+
+e) to display the Original Work publicly.
+
+2) Grant of Patent License. Licensor hereby grants You a world-wide,
+royalty-free, non-exclusive, perpetual, sublicenseable license, under patent
+claims owned or controlled by the Licensor that are embodied in the Original
+Work as furnished by the Licensor, to make, use, sell and offer for sale the
+Original Work and Derivative Works.
+
+3) Grant of Source Code License. The term "Source Code" means the preferred
+form of the Original Work for making modifications to it and all available
+documentation describing how to modify the Original Work. Licensor hereby
+agrees to provide a machine-readable copy of the Source Code of the Original
+Work along with each copy of the Original Work that Licensor distributes.
+Licensor reserves the right to satisfy this obligation by placing a
+machine-readable copy of the Source Code in an information repository
+reasonably calculated to permit inexpensive and convenient access by You for as
+long as Licensor continues to distribute the Original Work, and by publishing
+the address of that information repository in a notice immediately following
+the copyright notice that applies to the Original Work.
+
+4) Exclusions From License Grant. Neither the names of Licensor, nor the names
+of any contributors to the Original Work, nor any of their trademarks or
+service marks, may be used to endorse or promote products derived from this
+Original Work without express prior written permission of the Licensor. Nothing
+in this License shall be deemed to grant any rights to trademarks, copyrights,
+patents, trade secrets or any other intellectual property of Licensor except as
+expressly stated herein. No patent license is granted to make, use, sell or
+offer to sell embodiments of any patent claims other than the licensed claims
+defined in Section 2. No right is granted to the trademarks of Licensor even if
+such marks are included in the Original Work. Nothing in this License shall be
+interpreted to prohibit Licensor from licensing under different terms from this
+License any Original Work that Licensor otherwise would have a right to
+license.
+
+5) This section intentionally omitted.
+
+6) Attribution Rights. You must retain, in the Source Code of any Derivative
+Works that You create, all copyright, patent or trademark notices from the
+Source Code of the Original Work, as well as any notices of licensing and any
+descriptive text identified therein as an "Attribution Notice." You must cause
+the Source Code for any Derivative Works that You create to carry a prominent
+Attribution Notice reasonably calculated to inform recipients that You have
+modified the Original Work.
+
+7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that
+the copyright in and to the Original Work and the patent rights granted herein
+by Licensor are owned by the Licensor or are sublicensed to You under the terms
+of this License with the permission of the contributor(s) of those copyrights
+and patent rights. Except as expressly stated in the immediately proceeding
+sentence, the Original Work is provided under this License on an "AS IS" BASIS
+and WITHOUT WARRANTY, either express or implied, including, without limitation,
+the warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU.
+This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No
+license to Original Work is granted hereunder except under this disclaimer.
+
+8) Limitation of Liability. Under no circumstances and under no legal theory,
+whether in tort (including negligence), contract, or otherwise, shall the
+Licensor be liable to any person for any direct, indirect, special, incidental,
+or consequential damages of any character arising as a result of this License
+or the use of the Original Work including, without limitation, damages for loss
+of goodwill, work stoppage, computer failure or malfunction, or any and all
+other commercial damages or losses. This limitation of liability shall not
+apply to liability for death or personal injury resulting from Licensor's
+negligence to the extent applicable law prohibits such limitation. Some
+jurisdictions do not allow the exclusion or limitation of incidental or
+consequential damages, so this exclusion and limitation may not apply to You.
+
+9) Acceptance and Termination. If You distribute copies of the Original Work or
+a Derivative Work, You must make a reasonable effort under the circumstances to
+obtain the express assent of recipients to the terms of this License. Nothing
+else but this License (or another written agreement between Licensor and You)
+grants You permission to create Derivative Works based upon the Original Work
+or to exercise any of the rights granted in Section 1 herein, and any attempt
+to do so except under the terms of this License (or another written agreement
+between Licensor and You) is expressly prohibited by U.S. copyright law, the
+equivalent laws of other countries, and by international treaty. Therefore, by
+exercising any of the rights granted to You in Section 1 herein, You indicate
+Your acceptance of this License and all of its terms and conditions.
+
+10) Termination for Patent Action. This License shall terminate automatically
+and You may no longer exercise any of the rights granted to You by this License
+as of the date You commence an action, including a cross-claim or counterclaim,
+against Licensor or any licensee alleging that the Original Work infringes a
+patent. This termination provision shall not apply for an action alleging
+patent infringement by combinations of the Original Work with other software or
+hardware.
+
+11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this
+License may be brought only in the courts of a jurisdiction wherein the
+Licensor resides or in which Licensor conducts its primary business, and under
+the laws of that jurisdiction excluding its conflict-of-law provisions. The
+application of the United Nations Convention on Contracts for the International
+Sale of Goods is expressly excluded. Any use of the Original Work outside the
+scope of this License or after its termination shall be subject to the
+requirements and penalties of the U.S. Copyright Act, 17 U.S.C. § 101 et
+seq., the equivalent laws of other countries, and international treaty. This
+section shall survive the termination of this License.
+
+12) Attorneys Fees. In any action to enforce the terms of this License or
+seeking damages relating thereto, the prevailing party shall be entitled to
+recover its costs and expenses, including, without limitation, reasonable
+attorneys' fees and costs incurred in connection with such action, including
+any appeal of such action. This section shall survive the termination of this
+License.
+
+13) Miscellaneous. This License represents the complete agreement concerning
+the subject matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent necessary to
+make it enforceable.
+
+14) Definition of "You" in This License. "You" throughout this License, whether
+in upper or lower case, means an individual or a legal entity exercising rights
+under, and complying with all of the terms of, this License. For legal
+entities, "You" includes any entity that controls, is controlled by, or is
+under common control with you. For purposes of this definition, "control" means
+(i) the power, direct or indirect, to cause the direction or management of such
+entity, whether by contract or otherwise, or (ii) ownership of fifty percent
+(50%) or more of the outstanding shares, or (iii) beneficial ownership of such
+entity.
+
+15) Right to Use. You may use the Original Work in all ways not otherwise
+restricted or conditioned by this License or by law, and Licensor promises not
+to interfere with or be responsible for such uses by You.
+
+This license is Copyright (C) 2003-2004 Lawrence E. Rosen. All rights reserved.
+Permission is hereby granted to copy and distribute this license without
+modification. This license may not be modified without the express written
+permission of its copyright owner.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-FreeMarker.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-FreeMarker.txt
new file mode 100644
index 00000000000..1c53fd7e9ff
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-FreeMarker.txt
@@ -0,0 +1,69 @@
+FreeMarker 1.x was released under the LGPL license. Later, by community
+consensus, we have switched over to a BSD-style license. As of FreeMarker
+2.2pre1, the original author, Benjamin Geer, has relinquished the copyright in
+behalf of Visigoth Software Society. The current copyright holder is the
+Visigoth Software Society.
+
+------------------------------------------------------------------------------
+Copyright (c) 2003 The Visigoth Software Society. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+2. The end-user documentation included with the redistribution, if any, must
+ include the following acknowlegement:
+ "This product includes software developed by the
+ Visigoth Software Society (http://www.visigoths.org/)."
+ Alternately, this acknowlegement may appear in the software itself, if and
+ wherever such third-party acknowlegements normally appear.
+
+3. Neither the name "FreeMarker", "Visigoth", nor any of the names of the
+ project contributors may be used to endorse or promote products derived
+ from this software without prior written permission. For written
+ permission, please contact visigoths@visigoths.org.
+
+4. Products derived from this software may not be called "FreeMarker" or
+ "Visigoth" nor may "FreeMarker" or "Visigoth" appear in their names
+ without prior written permission of the Visigoth Software Society.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+VISIGOTH SOFTWARE SOCIETY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+------------------------------------------------------------------------------
+
+This software consists of voluntary contributions made by many individuals on
+behalf of the Visigoth Software Society. For more information on the Visigoth
+Software Society, please see http://www.visigoths.org/
+
+------------------------------------------------------------------------------
+
+FREEMARKER SUBCOMPONENTS UNDER DIFFERENT LICENSE:
+
+FreeMarker includes a number of subcomponents that are licensed by the Apache
+Software Foundation under the Apache License, Version 2.0. Your use of these
+subcomponents is subject to the terms and conditions of the Apache License,
+Version 2.0. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+The subcomponents under this licence are the following files, which are
+included both in freemarker.jar and in the source code:
+
+ freemarker/ext/jsp/web-app_2_2.dtd
+ freemarker/ext/jsp/web-app_2_3.dtd
+ freemarker/ext/jsp/web-app_2_4.xsd
+ freemarker/ext/jsp/web-app_2_5.xsd
+ freemarker/ext/jsp/web-jsptaglibrary_1_1.dtd
+ freemarker/ext/jsp/web-jsptaglibrary_1_2.dtd
+ freemarker/ext/jsp/web-jsptaglibrary_2_0.xsd
+ freemarker/ext/jsp/web-jsptaglibrary_2_1.xsd
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-FreeType.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-FreeType.txt
new file mode 100644
index 00000000000..bbaba33f47d
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-FreeType.txt
@@ -0,0 +1,169 @@
+ The FreeType Project LICENSE
+ ----------------------------
+
+ 2006-Jan-27
+
+ Copyright 1996-2002, 2006 by
+ David Turner, Robert Wilhelm, and Werner Lemberg
+
+
+
+Introduction
+============
+
+ The FreeType Project is distributed in several archive packages;
+ some of them may contain, in addition to the FreeType font engine,
+ various tools and contributions which rely on, or relate to, the
+ FreeType Project.
+
+ This license applies to all files found in such packages, and
+ which do not fall under their own explicit license. The license
+ affects thus the FreeType font engine, the test programs,
+ documentation and makefiles, at the very least.
+
+ This license was inspired by the BSD, Artistic, and IJG
+ (Independent JPEG Group) licenses, which all encourage inclusion
+ and use of free software in commercial and freeware products
+ alike. As a consequence, its main points are that:
+
+ o We don't promise that this software works. However, we will be
+ interested in any kind of bug reports. (`as is' distribution)
+
+ o You can use this software for whatever you want, in parts or
+ full form, without having to pay us. (`royalty-free' usage)
+
+ o You may not pretend that you wrote this software. If you use
+ it, or only parts of it, in a program, you must acknowledge
+ somewhere in your documentation that you have used the
+ FreeType code. (`credits')
+
+ We specifically permit and encourage the inclusion of this
+ software, with or without modifications, in commercial products.
+ We disclaim all warranties covering The FreeType Project and
+ assume no liability related to The FreeType Project.
+
+
+ Finally, many people asked us for a preferred form for a
+ credit/disclaimer to use in compliance with this license. We thus
+ encourage you to use the following text:
+
+ """
+ Portions of this software are copyright The FreeType
+ Project (www.freetype.org). All rights reserved.
+ """
+
+ Please replace with the value from the FreeType version you
+ actually use.
+
+
+Legal Terms
+===========
+
+0. Definitions
+--------------
+
+ Throughout this license, the terms `package', `FreeType Project',
+ and `FreeType archive' refer to the set of files originally
+ distributed by the authors (David Turner, Robert Wilhelm, and
+ Werner Lemberg) as the `FreeType Project', be they named as alpha,
+ beta or final release.
+
+ `You' refers to the licensee, or person using the project, where
+ `using' is a generic term including compiling the project's source
+ code as well as linking it to form a `program' or `executable'.
+ This program is referred to as `a program using the FreeType
+ engine'.
+
+ This license applies to all files distributed in the original
+ FreeType Project, including all source code, binaries and
+ documentation, unless otherwise stated in the file in its
+ original, unmodified form as distributed in the original archive.
+ If you are unsure whether or not a particular file is covered by
+ this license, you must contact us to verify this.
+
+ The FreeType Project is copyright (C) 1996-2000 by David Turner,
+ Robert Wilhelm, and Werner Lemberg. All rights reserved except as
+ specified below.
+
+1. No Warranty
+--------------
+
+ THE FREETYPE PROJECT IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OR THE INABILITY TO
+ USE, OF THE FREETYPE PROJECT.
+
+2. Redistribution
+-----------------
+
+ This license grants a worldwide, royalty-free, perpetual and
+ irrevocable right and license to use, execute, perform, compile,
+ display, copy, create derivative works of, distribute and
+ sublicense the FreeType Project (in both source and object code
+ forms) and derivative works thereof for any purpose; and to
+ authorize others to exercise some or all of the rights granted
+ herein, subject to the following conditions:
+
+ o Redistribution of source code must retain this license file
+ (`FTL.TXT') unaltered; any additions, deletions or changes to
+ the original files must be clearly indicated in accompanying
+ documentation. The copyright notices of the unaltered,
+ original files must be preserved in all copies of source
+ files.
+
+ o Redistribution in binary form must provide a disclaimer that
+ states that the software is based in part of the work of the
+ FreeType Team, in the distribution documentation. We also
+ encourage you to put an URL to the FreeType web page in your
+ documentation, though this isn't mandatory.
+
+ These conditions apply to any software derived from or based on
+ the FreeType Project, not just the unmodified files. If you use
+ our work, you must acknowledge us. However, no fee need be paid
+ to us.
+
+3. Advertising
+--------------
+
+ Neither the FreeType authors and contributors nor you shall use
+ the name of the other for commercial, advertising, or promotional
+ purposes without specific prior written permission.
+
+ We suggest, but do not require, that you use one or more of the
+ following phrases to refer to this software in your documentation
+ or advertising materials: `FreeType Project', `FreeType Engine',
+ `FreeType library', or `FreeType Distribution'.
+
+ As you have not signed this license, you are not required to
+ accept it. However, as the FreeType Project is copyrighted
+ material, only this license, or another one contracted with the
+ authors, grants you the right to use, distribute, and modify it.
+ Therefore, by using, distributing, or modifying the FreeType
+ Project, you indicate that you understand and accept all the terms
+ of this license.
+
+4. Contacts
+-----------
+
+ There are two mailing lists related to FreeType:
+
+ o freetype@nongnu.org
+
+ Discusses general use and applications of FreeType, as well as
+ future and wanted additions to the library and distribution.
+ If you are looking for support, start in this list if you
+ haven't found anything to help you in the documentation.
+
+ o freetype-devel@nongnu.org
+
+ Discusses bugs, as well as engine internals, design issues,
+ specific licenses, porting, etc.
+
+ Our home page can be found at
+
+ http://www.freetype.org
+
+
+--- end of FTL.TXT ---
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-GIFLIB.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-GIFLIB.txt
new file mode 100644
index 00000000000..b9c0b501260
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-GIFLIB.txt
@@ -0,0 +1,19 @@
+The GIFLIB distribution is Copyright (c) 1997 Eric S. Raymond
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-Hamcrest.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-Hamcrest.txt
new file mode 100644
index 00000000000..dcdcc423479
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-Hamcrest.txt
@@ -0,0 +1,27 @@
+BSD License
+
+Copyright (c) 2000-2006, www.hamcrest.org
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list of
+conditions and the following disclaimer. Redistributions in binary form must reproduce
+the above copyright notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the distribution.
+
+Neither the name of Hamcrest nor the names of its contributors may be used to endorse
+or promote products derived from this software without specific prior written
+permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-JGraph.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-JGraph.txt
new file mode 100644
index 00000000000..7fdadcf7a9b
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-JGraph.txt
@@ -0,0 +1,24 @@
+Copyright (c) 2001-2014, JGraph Ltd
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the JGraph nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL JGRAPH BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-Jaxen.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-Jaxen.txt
new file mode 100644
index 00000000000..815a72b202a
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-Jaxen.txt
@@ -0,0 +1,33 @@
+/*
+ $Id: LICENSE.txt 1128 2006-02-05 21:49:04Z elharo $
+
+ Copyright 2003-2006 The Werken Company. All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the Jaxen Project nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ */
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-JiBX.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-JiBX.txt
new file mode 100644
index 00000000000..c71dcb2f03f
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-JiBX.txt
@@ -0,0 +1,25 @@
+Copyright (c) 2003-2010, Dennis M. Sosnoski.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of JiBX nor the names of its contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-PostgreSQL.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-PostgreSQL.txt
new file mode 100644
index 00000000000..9660827d7f7
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-PostgreSQL.txt
@@ -0,0 +1,23 @@
+PostgreSQL Database Management System
+(formerly known as Postgres, then as Postgres95)
+
+Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
+
+Portions Copyright (c) 1994, The Regents of the University of California
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose, without fee, and without a written agreement
+is hereby granted, provided that the above copyright notice and this
+paragraph and the following two paragraphs appear in all copies.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
+LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
+DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO
+PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-XMP.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-XMP.txt
new file mode 100644
index 00000000000..52653d2bbbc
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-XMP.txt
@@ -0,0 +1,13 @@
+The BSD License
+
+Copyright (c) 2009, Adobe Systems Incorporated All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+* Neither the name of Adobe Systems Incorporated, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANT ABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-XStream.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-XStream.txt
new file mode 100644
index 00000000000..fa11e3855d8
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-XStream.txt
@@ -0,0 +1,28 @@
+(BSD Style License)
+
+Copyright (c) 2003-2006, Joe Walnes
+Copyright (c) 2006-2011, XStream Committers
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list of
+conditions and the following disclaimer. Redistributions in binary form must reproduce
+the above copyright notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the distribution.
+
+Neither the name of XStream nor the names of its contributors may be used to endorse
+or promote products derived from this software without specific prior written
+permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-YUI.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-YUI.txt
new file mode 100644
index 00000000000..9864324cedd
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-YUI.txt
@@ -0,0 +1,145 @@
+Software License Agreement (BSD License)
+========================================
+
+Copyright (c) 2013, Yahoo! Inc. All rights reserved.
+----------------------------------------------------
+
+Redistribution and use of this software in source and binary forms, with or
+without modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of Yahoo! Inc. nor the names of YUI's contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission of Yahoo! Inc.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+Sources of Intellectual Property Included in the YUI Library
+------------------------------------------------------------
+
+YUI is issued by Yahoo! under the BSD license above. Below is a list of certain
+publicly available software that is the source of intellectual property in YUI,
+along with the licensing terms that pertain to those sources of IP. This list is
+for informational purposes only and is not intended to represent an exhaustive
+list of third party contributions to YUI.
+
+ * **Douglas Crockford's JSON parsing and stringifying methods:** In the JSON
+ Utility, Douglas Crockford's JSON parsing and stringifying methods are
+ adapted from work published at [JSON.org](http://json.org/). The adapted
+ work is in the public domain.
+
+ * **Robert Penner's animation-easing algorithms:** In the Animation Utility,
+ YUI makes use of Robert Penner's algorithms for easing.
+
+ * **Diego Perini's IEContentLoaded technique:** The Event Utility employs
+ [a technique developed by Diego Perini](http://javascript.nwbox.com/IEContentLoaded/)
+ and licensed under GPL. YUI's use of this technique is included under our
+ BSD license with the author's permission.
+
+ * **Handlebars.js**: The Handlebars component is a YUI port of
+ [Handlebars.js](https://github.com/wycats/handlebars.js) by Yehuda Katz. It
+ is distributed with YUI under the terms of the MIT License below.
+
+ * **asap.js**: The timers component includes the Asap.js module by Kris Kowal.
+ It is distributed with YUI under the terms of the MIT License below.
+
+
+Handlebars.js MIT License
+-------------------------
+
+Copyright (C) 2011 by Yehuda Katz
+
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+Normalize.css MIT License
+-------------------------
+
+Copyright (c) Nicolas Gallagher and Jonathan Neal
+
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+Benchmark.js MIT License
+-------------------------
+Copyright 2010-2013 Mathias Bynens
+Based on JSLitmus.js, copyright Robert Kieffer
+Modified by John-David Dalton
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+Asap.js MIT License
+-------------------
+Copyright 2009–2013 Contributors. All rights reserved.
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-bubblinglibrary.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-bubblinglibrary.txt
new file mode 100644
index 00000000000..ec4b88c884d
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-bubblinglibrary.txt
@@ -0,0 +1,17 @@
+Software License Agreement (BSD License)
+
+
+
+ * Javascript Bubbling Library
+
+ * http://www.bubbling-library.com
+
+ Copyright (c) 2007, Caridy Patio. All rights reserved.
+
+ Redistribution and use of this software in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-dom4j.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-dom4j.txt
new file mode 100644
index 00000000000..7cae050cadb
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-dom4j.txt
@@ -0,0 +1,40 @@
+Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
+
+Redistribution and use of this software and associated documentation
+("Software"), with or without modification, are permitted provided
+that the following conditions are met:
+
+1. Redistributions of source code must retain copyright
+ statements and notices. Redistributions must also contain a
+ copy of this document.
+
+2. Redistributions in binary form must reproduce the
+ above copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+3. The name "DOM4J" must not be used to endorse or promote
+ products derived from this Software without prior written
+ permission of MetaStuff, Ltd. For written permission,
+ please contact dom4j-info@metastuff.com.
+
+4. Products derived from this Software may not be called "DOM4J"
+ nor may "DOM4J" appear in their names without prior written
+ permission of MetaStuff, Ltd. DOM4J is a registered
+ trademark of MetaStuff, Ltd.
+
+5. Due credit should be given to the DOM4J Project -
+ http://www.dom4j.org
+
+THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-libjpeg.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-libjpeg.txt
new file mode 100644
index 00000000000..01bc31eecd3
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-libjpeg.txt
@@ -0,0 +1,71 @@
+The authors make NO WARRANTY or representation, either express or implied,
+with respect to this software, its quality, accuracy, merchantability, or
+fitness for a particular purpose. This software is provided "AS IS", and you,
+its user, assume the entire risk as to its quality and accuracy.
+
+This software is copyright (C) 1991-1998, Thomas G. Lane.
+All Rights Reserved except as specified below.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+software (or portions thereof) for any purpose, without fee, subject to these
+conditions:
+(1) If any part of the source code for this software is distributed, then this
+README file must be included, with this copyright and no-warranty notice
+unaltered; and any additions, deletions, or changes to the original files
+must be clearly indicated in accompanying documentation.
+(2) If only executable code is distributed, then the accompanying
+documentation must state that "this software is based in part on the work of
+the Independent JPEG Group".
+(3) Permission for use of this software is granted only if the user accepts
+full responsibility for any undesirable consequences; the authors accept
+NO LIABILITY for damages of any kind.
+
+These conditions apply to any software derived from or based on the IJG code,
+not just to the unmodified library. If you use our work, you ought to
+acknowledge us.
+
+Permission is NOT granted for the use of any IJG author's name or company name
+in advertising or publicity relating to this software or products derived from
+it. This software may be referred to only as "the Independent JPEG Group's
+software".
+
+We specifically permit and encourage the use of this software as the basis of
+commercial products, provided that all warranty or liability claims are
+assumed by the product vendor.
+
+
+ansi2knr.c is included in this distribution by permission of L. Peter Deutsch,
+sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA.
+ansi2knr.c is NOT covered by the above copyright and conditions, but instead
+by the usual distribution terms of the Free Software Foundation; principally,
+that you must include source code if you redistribute it. (See the file
+ansi2knr.c for full details.) However, since ansi2knr.c is not needed as part
+of any program generated from the IJG code, this does not limit you more than
+the foregoing paragraphs do.
+
+The Unix configuration script "configure" was produced with GNU Autoconf.
+It is copyright by the Free Software Foundation but is freely distributable.
+The same holds for its supporting scripts (config.guess, config.sub,
+ltconfig, ltmain.sh). Another support script, install-sh, is copyright
+by M.I.T. but is also freely distributable.
+
+It appears that the arithmetic coding option of the JPEG spec is covered by
+patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot
+legally be used without obtaining one or more licenses. For this reason,
+support for arithmetic coding has been removed from the free JPEG software.
+(Since arithmetic coding provides only a marginal gain over the unpatented
+Huffman mode, it is unlikely that very many implementations will support it.)
+So far as we are aware, there are no patent restrictions on the remaining
+code.
+
+The IJG distribution formerly included code to read and write GIF files.
+To avoid entanglement with the Unisys LZW patent, GIF reading support has
+been removed altogether, and the GIF writer has been simplified to produce
+"uncompressed GIFs". This technique does not use the LZW algorithm; the
+resulting GIF files are larger than usual, but are readable by all standard
+GIF decoders.
+
+We are required to state that
+ "The Graphics Interchange Format(c) is the Copyright property of
+ CompuServe Incorporated. GIF(sm) is a Service Mark property of
+ CompuServe Incorporated."
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-libpng.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-libpng.txt
new file mode 100644
index 00000000000..63920b369a6
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-libpng.txt
@@ -0,0 +1,111 @@
+
+This copy of the libpng notices is provided for your convenience. In case of
+any discrepancy between this copy and the notices in the file png.h that is
+included in the libpng distribution, the latter shall prevail.
+
+COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+
+If you modify libpng you may insert additional notices immediately following
+this sentence.
+
+This code is released under the libpng license.
+
+libpng versions 1.2.6, August 15, 2004, through 1.6.14, October 23, 2014, are
+Copyright (c) 2004, 2006-2014 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-1.2.5
+with the following individual added to the list of Contributing Authors
+
+ Cosmin Truta
+
+libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are
+Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-1.0.6
+with the following individuals added to the list of Contributing Authors
+
+ Simon-Pierre Cadieux
+ Eric S. Raymond
+ Gilles Vollant
+
+and with the following additions to the disclaimer:
+
+ There is no warranty against interference with your enjoyment of the
+ library or against infringement. There is no warranty that our
+ efforts or the library will fulfill any of your particular purposes
+ or needs. This library is provided with all faults, and the entire
+ risk of satisfactory quality, performance, accuracy, and effort is with
+ the user.
+
+libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
+Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-0.96,
+with the following individuals added to the list of Contributing Authors:
+
+ Tom Lane
+ Glenn Randers-Pehrson
+ Willem van Schaik
+
+libpng versions 0.89, June 1996, through 0.96, May 1997, are
+Copyright (c) 1996, 1997 Andreas Dilger
+Distributed according to the same disclaimer and license as libpng-0.88,
+with the following individuals added to the list of Contributing Authors:
+
+ John Bowler
+ Kevin Bracey
+ Sam Bushell
+ Magnus Holmgren
+ Greg Roelofs
+ Tom Tanner
+
+libpng versions 0.5, May 1995, through 0.88, January 1996, are
+Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+
+For the purposes of this copyright and license, "Contributing Authors"
+is defined as the following set of individuals:
+
+ Andreas Dilger
+ Dave Martindale
+ Guy Eric Schalnat
+ Paul Schmidt
+ Tim Wegner
+
+The PNG Reference Library is supplied "AS IS". The Contributing Authors
+and Group 42, Inc. disclaim all warranties, expressed or implied,
+including, without limitation, the warranties of merchantability and of
+fitness for any purpose. The Contributing Authors and Group 42, Inc.
+assume no liability for direct, indirect, incidental, special, exemplary,
+or consequential damages, which may result from the use of the PNG
+Reference Library, even if advised of the possibility of such damage.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+source code, or portions hereof, for any purpose, without fee, subject
+to the following restrictions:
+
+1. The origin of this source code must not be misrepresented.
+
+2. Altered versions must be plainly marked as such and must not
+ be misrepresented as being the original source.
+
+3. This Copyright notice may not be removed or altered from any
+ source or altered source distribution.
+
+The Contributing Authors and Group 42, Inc. specifically permit, without
+fee, and encourage the use of this source code as a component to
+supporting the PNG file format in commercial products. If you use this
+source code in a product, acknowledgment is not required but would be
+appreciated.
+
+
+A "png_get_copyright" function is available, for convenient use in "about"
+boxes and the like:
+
+ printf("%s",png_get_copyright(NULL));
+
+Also, the PNG logo (in PNG format, of course) is supplied in the
+files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+
+Libpng is OSI Certified Open Source Software. OSI Certified Open Source is a
+certification mark of the Open Source Initiative.
+
+Glenn Randers-Pehrson
+glennrp at users.sourceforge.net
+October 23, 2014
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-libtiff.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-libtiff.txt
new file mode 100644
index 00000000000..8282186151e
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-libtiff.txt
@@ -0,0 +1,21 @@
+Copyright (c) 1988-1997 Sam Leffler
+Copyright (c) 1991-1997 Silicon Graphics, Inc.
+
+Permission to use, copy, modify, distribute, and sell this software and
+its documentation for any purpose is hereby granted without fee, provided
+that (i) the above copyright notices and this permission notice appear in
+all copies of the software and related documentation, and (ii) the names of
+Sam Leffler and Silicon Graphics may not be used in any advertising or
+publicity relating to the software without the specific, prior written
+permission of Sam Leffler and Silicon Graphics.
+
+THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+OF THIS SOFTWARE.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-staxutils.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-staxutils.txt
new file mode 100644
index 00000000000..39ad8ce0d3d
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-staxutils.txt
@@ -0,0 +1,33 @@
+Copyright (c) 2004, Christian Niles, unit12.net
+Copyright (c) 2004, Sun Microsystems, Inc.
+Copyright (c) 2006, John Kristian
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+
+ * Neither the name of the listed copyright holders nor the names
+ of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-urlrewritefilter.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-urlrewritefilter.txt
new file mode 100644
index 00000000000..dd0476a6627
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-urlrewritefilter.txt
@@ -0,0 +1,38 @@
+
+Copyright (c) 2005-2012, Paul Tuckey
+All rights reserved.
+====================================================================
+Licensed under the BSD License. Text as follows.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ - Neither the name tuckey.org nor the names of its contributors
+ may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+====================================================================
+
+Please note that some code used in UrlRewriteFilter is under other
+permissive licenses.
+
+====================================================================
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-yuicompressor.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-yuicompressor.txt
new file mode 100644
index 00000000000..8a1c7a1af2e
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/BSDlike-yuicompressor.txt
@@ -0,0 +1,54 @@
+YUI Compressor Copyright License Agreement (BSD License)
+
+Copyright (c) 2013, Yahoo! Inc.
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the
+ following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+* Neither the name of Yahoo! Inc. nor the names of its
+ contributors may be used to endorse or promote products
+ derived from this software without specific prior
+ written permission of Yahoo! Inc.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+This software also requires access to software from the following sources:
+
+The Jarg Library v 1.0 ( http://jargs.sourceforge.net/ ) is available
+under a BSD License � Copyright (c) 2001-2003 Steve Purcell,
+Copyright (c) 2002 Vidar Holen, Copyright (c) 2002 Michal Ceresna and
+Copyright (c) 2005 Ewan Mellor.
+
+The Rhino Library ( http://www.mozilla.org/rhino/ ) is dually available
+under an MPL 1.1/GPL 2.0 license, with portions subject to a BSD license.
+
+Additionally, this software contains modified versions of the following
+component files from the Rhino Library:
+
+[org/mozilla/javascript/Decompiler.java]
+[org/mozilla/javascript/Parser.java]
+[org/mozilla/javascript/Token.java]
+[org/mozilla/javascript/TokenStream.java]
+
+The modified versions of these files are distributed under the MPL v 1.1
+( http://www.mozilla.org/MPL/MPL-1.1.html )
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/CC-BY-2.5-LightboxJS.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/CC-BY-2.5-LightboxJS.txt
new file mode 100644
index 00000000000..a0b87e5a8b3
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/CC-BY-2.5-LightboxJS.txt
@@ -0,0 +1,8 @@
+ Lightbox JS: Fullsize Image Overlays
+ by Lokesh Dhakar - http://www.huddletogether.com
+
+ For more information on this script, visit:
+ http://huddletogether.com/projects/lightbox/
+
+ Licensed under the Creative Commons Attribution 2.5 License - http://creativecommons.org/licenses/by/2.5/
+ (basically, do anything you want, just leave my name and link)
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/CC-BY-3.0-jsTextReader.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/CC-BY-3.0-jsTextReader.txt
new file mode 100644
index 00000000000..29ab3915372
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/CC-BY-3.0-jsTextReader.txt
@@ -0,0 +1,10 @@
+JSTextReader - Workaround for wmode=transparent text input bug
+
+Modifications and conversion to AS3:
+Mike Almond, MadeByPi
+
+Original author:
+astgtciv@analogcode.com - http://analogcode.com/p/JSTextReader/
+
+This work is licenced under a Creative Commons Attribution 3.0 License
+http://creativecommons.org/licenses/by/3.0/
\ No newline at end of file
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/CDDL-1.0.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/CDDL-1.0.txt
new file mode 100644
index 00000000000..8671089cb07
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/CDDL-1.0.txt
@@ -0,0 +1,183 @@
+COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
+
+ *
+
+ 1. Definitions.
+ o
+
+ 1.1. "Contributor" means each individual or entity that creates or contributes to the creation of Modifications.
+ o
+
+ 1.2. "Contributor Version" means the combination of the Original Software, prior Modifications used by a Contributor (if any), and the Modifications made by that particular Contributor.
+ o
+
+ 1.3. "Covered Software" means (a) the Original Software, or (b) Modifications, or (c) the combination of files containing Original Software with files containing Modifications, in each case including portions thereof.
+ o
+
+ 1.4. "Executable" means the Covered Software in any form other than Source Code.
+ o
+
+ 1.5. "Initial Developer" means the individual or entity that first makes Original Software available under this License.
+ o
+
+ 1.6. "Larger Work" means a work which combines Covered Software or portions thereof with code not governed by the terms of this License.
+ o
+
+ 1.7. "License" means this document.
+ o
+
+ 1.8. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein.
+ o
+
+ 1.9. "Modifications" means the Source Code and Executable form of any of the following:
+ +
+
+ A. Any file that results from an addition to, deletion from or modification of the contents of a file containing Original Software or previous Modifications;
+ +
+
+ B. Any new file that contains any part of the Original Software or previous Modification; or
+ +
+
+ C. Any new file that is contributed or otherwise made available under the terms of this License.
+ o
+
+ 1.10. "Original Software" means the Source Code and Executable form of computer software code that is originally released under this License.
+ o
+
+ 1.11. "Patent Claims" means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor.
+ o
+
+ 1.12. "Source Code" means (a) the common form of computer software code in which modifications are made and (b) associated documentation included in or with such code.
+ o
+
+ 1.13. "You" (or "Your") means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity.
+ *
+
+ 2. License Grants.
+ o
+
+ 2.1. The Initial Developer Grant.
+
+ Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, the Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license:
+ +
+
+ (a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer, to use, reproduce, modify, display, perform, sublicense and distribute the Original Software (or portions thereof), with or without Modifications, and/or as part of a Larger Work; and
+ +
+
+ (b) under Patent Claims infringed by the making, using or selling of Original Software, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Software (or portions thereof).
+ +
+
+ (c) The licenses granted in Sections 2.1(a) and (b) are effective on the date Initial Developer first distributes or otherwise makes the Original Software available to a third party under the terms of this License.
+ +
+
+ (d) Notwithstanding Section 2.1(b) above, no patent license is granted: (1) for code that You delete from the Original Software, or (2) for infringements caused by: (i) the modification of the Original Software, or (ii) the combination of the Original Software with other software or devices.
+ o
+
+ 2.2. Contributor Grant.
+
+ Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license:
+ +
+
+ (a) under intellectual property rights (other than patent or trademark) Licensable by Contributor to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof), either on an unmodified basis, with other Modifications, as Covered Software and/or as part of a Larger Work; and
+ +
+
+ (b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: (1) Modifications made by that Contributor (or portions thereof); and (2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination).
+ +
+
+ (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first distributes or otherwise makes the Modifications available to a third party.
+ +
+
+ (d) Notwithstanding Section 2.2(b) above, no patent license is granted: (1) for any code that Contributor has deleted from the Contributor Version; (2) for infringements caused by: (i) third party modifications of Contributor Version, or (ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or (3) under Patent Claims infringed by Covered Software in the absence of Modifications made by that Contributor.
+ *
+
+ 3. Distribution Obligations.
+ o
+
+ 3.1. Availability of Source Code.
+
+ Any Covered Software that You distribute or otherwise make available in Executable form must also be made available in Source Code form and that Source Code form must be distributed only under the terms of this License. You must include a copy of this License with every copy of the Source Code form of the Covered Software You distribute or otherwise make available. You must inform recipients of any such Covered Software in Executable form as to how they can obtain such Covered Software in Source Code form in a reasonable manner on or through a medium customarily used for software exchange.
+ o
+
+ 3.2. Modifications.
+
+ The Modifications that You create or to which You contribute are governed by the terms of this License. You represent that You believe Your Modifications are Your original creation(s) and/or You have sufficient rights to grant the rights conveyed by this License.
+ o
+
+ 3.3. Required Notices.
+
+ You must include a notice in each of Your Modifications that identifies You as the Contributor of the Modification. You may not remove or alter any copyright, patent or trademark notices contained within the Covered Software, or any notices of licensing or any descriptive text giving attribution to any Contributor or the Initial Developer.
+ o
+
+ 3.4. Application of Additional Terms.
+
+ You may not offer or impose any terms on any Covered Software in Source Code form that alters or restricts the applicable version of this License or the recipients rights hereunder. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, you may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear that any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer.
+ o
+
+ 3.5. Distribution of Executable Versions.
+
+ You may distribute the Executable form of the Covered Software under the terms of this License or under the terms of a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable form does not attempt to limit or alter the recipients rights in the Source Code form from the rights set forth in this License. If You distribute the Covered Software in Executable form under a different license, You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer.
+ o
+
+ 3.6. Larger Works.
+
+ You may create a Larger Work by combining Covered Software with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Software.
+ *
+
+ 4. Versions of the License.
+ o
+
+ 4.1. New Versions.
+
+ Sun Microsystems, Inc. is the initial license steward and may publish revised and/or new versions of this License from time to time. Each version will be given a distinguishing version number. Except as provided in Section 4.3, no one other than the license steward has the right to modify this License.
+ o
+
+ 4.2. Effect of New Versions.
+
+ You may always continue to use, distribute or otherwise make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. If the Initial Developer includes a notice in the Original Software prohibiting it from being distributed or otherwise made available under any subsequent version of the License, You must distribute and make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. Otherwise, You may also choose to use, distribute or otherwise make the Covered Software available under the terms of any subsequent version of the License published by the license steward.
+ o
+
+ 4.3. Modified Versions.
+
+ When You are an Initial Developer and You want to create a new license for Your Original Software, You may create and use a modified version of this License if You: (a) rename the license and remove any references to the name of the license steward (except to note that the license differs from this License); and (b) otherwise make it clear that the license contains terms which differ from this License.
+ *
+
+ 5. DISCLAIMER OF WARRANTY.
+
+ COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+ *
+
+ 6. TERMINATION.
+ o
+
+ 6.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive.
+ o
+
+ 6.2. If You assert a patent infringement claim (excluding declaratory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You assert such claim is referred to as "Participant") alleging that the Participant Software (meaning the Contributor Version where the Participant is a Contributor or the Original Software where the Participant is the Initial Developer) directly or indirectly infringes any patent, then any and all rights granted directly or indirectly to You by such Participant, the Initial Developer (if the Initial Developer is not the Participant) and all Contributors under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively and automatically at the expiration of such 60 day notice period, unless if within such 60 day period You withdraw Your claim with respect to the Participant Software against such Participant either unilaterally or pursuant to a written agreement with Participant.
+ o
+
+ 6.3. In the event of termination under Sections 6.1 or 6.2 above, all end user licenses that have been validly granted by You or any distributor hereunder prior to termination (excluding licenses granted to You by any distributor) shall survive termination.
+ *
+
+ 7. LIMITATION OF LIABILITY.
+
+ UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTYS NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+ *
+
+ 8. U.S. GOVERNMENT END USERS.
+
+ The Covered Software is a "commercial item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer software" (as that term is defined at 48 C.F.R. 252.227-7014(a)(1)) and "commercial computer software documentation" as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Software with only those rights set forth herein. This U.S. Government Rights clause is in lieu of, and supersedes, any other FAR, DFAR, or other clause or provision that addresses Government rights in computer software under this License.
+ *
+
+ 9. MISCELLANEOUS.
+
+ This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by the law of the jurisdiction specified in a notice contained within the Original Software (except to the extent applicable law, if any, provides otherwise), excluding such jurisdictions conflict-of-law provisions. Any litigation relating to this License shall be subject to the jurisdiction of the courts located in the jurisdiction and venue specified in a notice contained within the Original Software, with the losing party responsible for costs, including, without limitation, court costs and reasonable attorneys fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. You agree that You alone are responsible for compliance with the United States export administration regulations (and the export control laws and regulation of any other countries) when You use, distribute or otherwise make available any Covered Software.
+ *
+
+ 10. RESPONSIBILITY FOR CLAIMS.
+
+ As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability.
+ *
+
+ NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL)
+
+ The code released under the CDDL shall be governed by the laws of the State of California (excluding conflict-of-law provisions). Any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California and the state courts of the State of California, with venue lying in Santa Clara County, California.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/CDDL-1.1.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/CDDL-1.1.txt
new file mode 100644
index 00000000000..88deb3dd071
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/CDDL-1.1.txt
@@ -0,0 +1,107 @@
+COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL)Version 1.1
+
+1. Definitions.
+
+1.1. “Contributor” means each individual or entity that creates or contributes to the creation of Modifications.
+
+1.2. “Contributor Version” means the combination of the Original Software, prior Modifications used by a Contributor (if any), and the Modifications made by that particular Contributor.
+
+1.3. “Covered Software” means (a) the Original Software, or (b) Modifications, or (c) the combination of files containing Original Software with files containing Modifications, in each case including portions thereof.
+
+1.4. “Executable” means the Covered Software in any form other than Source Code.
+
+1.5. “Initial Developer” means the individual or entity that first makes Original Software available under this License.
+
+1.6. “Larger Work” means a work which combines Covered Software or portions thereof with code not governed by the terms of this License.
+
+1.7. “License” means this document.
+
+1.8. “Licensable” means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein.
+
+1.9. “Modifications” means the Source Code and Executable form of any of the following:
+A. Any file that results from an addition to, deletion from or modification of the contents of a file containing Original Software or previous Modifications;
+B. Any new file that contains any part of the Original Software or previous Modification; or
+C. Any new file that is contributed or otherwise made available under the terms of this License.
+
+1.10. “Original Software” means the Source Code and Executable form of computer software code that is originally released under this License.
+
+1.11. “Patent Claims” means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor.
+
+1.12. “Source Code” means (a) the common form of computer software code in which modifications are made and (b) associated documentation included in or with such code.
+
+1.13. “You” (or “Your”) means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, “You” includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, “control” means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity.
+
+2. License Grants.
+
+2.1. The Initial Developer Grant.
+Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, the Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license:
+(a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer, to use, reproduce, modify, display, perform, sublicense and distribute the Original Software (or portions thereof), with or without Modifications, and/or as part of a Larger Work; and
+(b) under Patent Claims infringed by the making, using or selling of Original Software, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Software (or portions thereof).
+(c) The licenses granted in Sections 2.1(a) and (b) are effective on the date Initial Developer first distributes or otherwise makes the Original Software available to a third party under the terms of this License.
+(d) Notwithstanding Section 2.1(b) above, no patent license is granted: (1) for code that You delete from the Original Software, or (2) for infringements caused by: (i) the modification of the Original Software, or (ii) the combination of the Original Software with other software or devices.
+
+2.2. Contributor Grant.
+Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license:
+(a) under intellectual property rights (other than patent or trademark) Licensable by Contributor to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof), either on an unmodified basis, with other Modifications, as Covered Software and/or as part of a Larger Work; and
+(b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: (1) Modifications made by that Contributor (or portions thereof); and (2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination).
+(c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first distributes or otherwise makes the Modifications available to a third party.
+(d) Notwithstanding Section 2.2(b) above, no patent license is granted: (1) for any code that Contributor has deleted from the Contributor Version; (2) for infringements caused by: (i) third party modifications of Contributor Version, or (ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or (3) under Patent Claims infringed by Covered Software in the absence of Modifications made by that Contributor.
+
+3. Distribution Obligations.
+
+3.1. Availability of Source Code.
+Any Covered Software that You distribute or otherwise make available in Executable form must also be made available in Source Code form and that Source Code form must be distributed only under the terms of this License. You must include a copy of this License with every copy of the Source Code form of the Covered Software You distribute or otherwise make available. You must inform recipients of any such Covered Software in Executable form as to how they can obtain such Covered Software in Source Code form in a reasonable manner on or through a medium customarily used for software exchange.
+
+3.2. Modifications.
+The Modifications that You create or to which You contribute are governed by the terms of this License. You represent that You believe Your Modifications are Your original creation(s) and/or You have sufficient rights to grant the rights conveyed by this License.
+
+3.3. Required Notices.
+You must include a notice in each of Your Modifications that identifies You as the Contributor of the Modification. You may not remove or alter any copyright, patent or trademark notices contained within the Covered Software, or any notices of licensing or any descriptive text giving attribution to any Contributor or the Initial Developer.
+
+3.4. Application of Additional Terms.
+You may not offer or impose any terms on any Covered Software in Source Code form that alters or restricts the applicable version of this License or the recipients' rights hereunder. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, you may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear that any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer.
+
+3.5. Distribution of Executable Versions.
+You may distribute the Executable form of the Covered Software under the terms of this License or under the terms of a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable form does not attempt to limit or alter the recipient's rights in the Source Code form from the rights set forth in this License. If You distribute the Covered Software in Executable form under a different license, You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer.
+
+3.6. Larger Works.
+You may create a Larger Work by combining Covered Software with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Software.
+
+4. Versions of the License.
+
+4.1. New Versions.
+Oracle is the initial license steward and may publish revised and/or new versions of this License from time to time. Each version will be given a distinguishing version number. Except as provided in Section 4.3, no one other than the license steward has the right to modify this License.
+
+4.2. Effect of New Versions.
+You may always continue to use, distribute or otherwise make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. If the Initial Developer includes a notice in the Original Software prohibiting it from being distributed or otherwise made available under any subsequent version of the License, You must distribute and make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. Otherwise, You may also choose to use, distribute or otherwise make the Covered Software available under the terms of any subsequent version of the License published by the license steward.
+
+4.3. Modified Versions.
+When You are an Initial Developer and You want to create a new license for Your Original Software, You may create and use a modified version of this License if You: (a) rename the license and remove any references to the name of the license steward (except to note that the license differs from this License); and (b) otherwise make it clear that the license contains terms which differ from this License.
+
+5. DISCLAIMER OF WARRANTY.
+COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN “AS IS” BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+6. TERMINATION.
+
+6.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive.
+
+6.2. If You assert a patent infringement claim (excluding declaratory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You assert such claim is referred to as “Participant”) alleging that the Participant Software (meaning the Contributor Version where the Participant is a Contributor or the Original Software where the Participant is the Initial Developer) directly or indirectly infringes any patent, then any and all rights granted directly or indirectly to You by such Participant, the Initial Developer (if the Initial Developer is not the Participant) and all Contributors under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively and automatically at the expiration of such 60 day notice period, unless if within such 60 day period You withdraw Your claim with respect to the Participant Software against such Participant either unilaterally or pursuant to a written agreement with Participant.
+
+6.3. If You assert a patent infringement claim against Participant alleging that the Participant Software directly or indirectly infringes any patent where such claim is resolved (such as by license or settlement) prior to the initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license.
+
+6.4. In the event of termination under Sections 6.1 or 6.2 above, all end user licenses that have been validly granted by You or any distributor hereunder prior to termination (excluding licenses granted to You by any distributor) shall survive termination.
+
+7. LIMITATION OF LIABILITY.
+UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+8. U.S. GOVERNMENT END USERS.
+The Covered Software is a “commercial item,” as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of “commercial computer software” (as that term is defined at 48 C.F.R. § 252.227-7014(a)(1)) and “commercial computer software documentation” as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Software with only those rights set forth herein. This U.S. Government Rights clause is in lieu of, and supersedes, any other FAR, DFAR, or other clause or provision that addresses Government rights in computer software under this License.
+
+9. MISCELLANEOUS.
+This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by the law of the jurisdiction specified in a notice contained within the Original Software (except to the extent applicable law, if any, provides otherwise), excluding such jurisdiction's conflict-of-law provisions. Any litigation relating to this License shall be subject to the jurisdiction of the courts located in the jurisdiction and venue specified in a notice contained within the Original Software, with the losing party responsible for costs, including, without limitation, court costs and reasonable attorneys' fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. You agree that You alone are responsible for compliance with the United States export administration regulations (and the export control laws and regulation of any other countries) when You use, distribute or otherwise make available any Covered Software.
+
+10. RESPONSIBILITY FOR CLAIMS.
+As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability.
+
+NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL)
+The code released under the CDDL shall be governed by the laws of the State of California (excluding conflict-of-law provisions). Any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California and the state courts of the State of California, with venue lying in Santa Clara County, California.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/CPL 1.0.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/CPL 1.0.txt
new file mode 100644
index 00000000000..e6435e8c6f6
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/CPL 1.0.txt
@@ -0,0 +1,85 @@
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+ a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and
+
+ b) in the case of each subsequent Contributor:
+
+ i) changes to the Program, and
+
+ ii) additions to the Program;
+
+ where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
+
+"Contributor" means any person or entity that distributes the Program.
+
+"Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
+
+"Program" means the Contributions distributed in accordance with this Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.
+
+2. GRANT OF RIGHTS
+
+ a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
+
+ b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
+
+ c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program.
+
+ d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
+
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
+
+ a) it complies with the terms and conditions of this Agreement; and
+
+ b) its license agreement:
+
+ i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
+
+ ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
+
+ iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
+
+ iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
+
+When the Program is made available in source code form:
+
+ a) it must be made available under this Agreement; and
+
+ b) a copy of this Agreement must be included with each copy of the Program.
+
+Contributors may not remove or alter any copyright notices contained within the Program.
+
+Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, if Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/Eclipse Public License.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/Eclipse Public License.txt
new file mode 100644
index 00000000000..d6b3020fc7e
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/Eclipse Public License.txt
@@ -0,0 +1,87 @@
+Eclipse Public License -v 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and
+
+b) in the case of each subsequent Contributor:
+
+i) changes to the Program, and
+
+ii) additions to the Program;
+
+where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
+
+"Contributor" means any person or entity that distributes the Program.
+
+"Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
+
+"Program" means the Contributions distributed in accordance with this Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.
+
+2. GRANT OF RIGHTS
+
+a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
+
+b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
+
+c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program.
+
+d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
+
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
+
+a) it complies with the terms and conditions of this Agreement; and
+
+b) its license agreement:
+
+i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
+
+ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
+
+iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
+
+iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
+
+When the Program is made available in source code form:
+
+a) it must be made available under this Agreement; and
+
+b) a copy of this Agreement must be included with each copy of the Program.
+
+Contributors may not remove or alter any copyright notices contained within the Program.
+
+Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/ICU License.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/ICU License.txt
new file mode 100644
index 00000000000..f700b9d8702
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/ICU License.txt
@@ -0,0 +1,11 @@
+ICU License - ICU 1.8.1 and later
+
+COPYRIGHT AND PERMISSION NOTICE
+
+Copyright (c) 1995-2010 International Business Machines Corporation and others
+
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, provided that the above copyright notice(s) and this permission notice appear in all copies of the Software and that both the above copyright notice(s) and this permission notice appear in supporting documentation.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
\ No newline at end of file
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/ImageMagick-license.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/ImageMagick-license.txt
new file mode 100644
index 00000000000..fac88bf9ef5
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/ImageMagick-license.txt
@@ -0,0 +1,110 @@
+The authoritative ImageMagick license can be found at
+http://www.imagemagick.org/script/license.php and ImageMagick notices at
+http://www.imagemagick.org/www/Notice.html.
+
+Before we get to the text of the license, lets just review what the license says in simple terms:
+
+It allows you to:
+
+ * freely download and use ImageMagick software, in whole or in part, for personal, company internal, or commercial purposes;
+ * use ImageMagick software in packages or distributions that you create;
+ * link against a library under a different license;
+ * link code under a different license against a library under this license;
+ * merge code into a work under a different license;
+ * extend patent grants to any code using code under this license;
+ *and extend patent protection.
+
+It forbids you to:
+
+ * redistribute any piece of ImageMagick-originated software without proper attribution;
+ * use any marks owned by ImageMagick Studio LLC in any way that might state or imply that ImageMagick Studio LLC endorses your distribution;
+ * use any marks owned by ImageMagick Studio LLC in any way that might state or imply that you created the ImageMagick software in question.
+
+It requires you to:
+
+ * include a copy of the license in any redistribution you may make that includes ImageMagick software;
+ * provide clear attribution to ImageMagick Studio LLC for any distributions that include ImageMagick software.
+
+It does not require you to:
+
+ * include the source of the ImageMagick software itself, or of any modifications you may have made to it, in any redistribution you may assemble that includes it;
+ * submit changes that you make to the software back to the ImageMagick Studio LLC (though such feedback is encouraged).
+
+A few other clarifications include:
+ * ImageMagick is freely available without charge;
+ * you may include ImageMagick on any digital media as long as you comply with the terms of the license;
+ * you can give modified code away for free or sell it under the terms of the ImageMagick license or distribute the result under a different license, but you need to acknowledge the use of the ImageMagick software;
+ * the license is compatible with the GPL V3.
+ * when exporting the ImageMagick software, review its export classification.
+
+Terms and Conditions for Use, Reproduction, and Distribution
+
+The legally binding and authoritative terms and conditions for use, reproduction, and distribution of ImageMagick follow:
+
+Copyright © 1999-2018 ImageMagick Studio LLC, a non-profit organization dedicated to making software imaging solutions freely available.
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ a. You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ b. You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ c. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+ d. If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
+
+How to Apply the License to your Work
+
+To apply the ImageMagick License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information (don't include the brackets). The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the ImageMagick License (the "License"); you may not use
+ this file except in compliance with the License. You may obtain a copy
+ of the License at
+
+ https://www.imagemagick.org/script/license.php
+
+ 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.
\ No newline at end of file
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/JSON.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/JSON.txt
new file mode 100644
index 00000000000..e29500b0e23
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/JSON.txt
@@ -0,0 +1,11 @@
+JSON License
+
+Copyright (c) 2002 JSON.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+The Software shall be used for Good, not Evil.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/LGPL 2.1.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/LGPL 2.1.txt
new file mode 100644
index 00000000000..07ef01307ef
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/LGPL 2.1.txt
@@ -0,0 +1,168 @@
+GNU Lesser General Public License
+
+Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
+
+ [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.]
+
+Preamble
+
+The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users.
+
+This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below.
+
+When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things.
+
+To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it.
+
+For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights.
+
+We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library.
+
+To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others.
+
+Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license.
+
+Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs.
+
+When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library.
+
+We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances.
+
+For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License.
+
+In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system.
+
+Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library.
+
+The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run.
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you".
+
+A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables.
+
+The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".)
+
+"Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library.
+
+Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does.
+
+1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library.
+
+You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.)
+
+ These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.
+
+ Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library.
+
+ In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
+
+3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices.
+
+Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy.
+
+This option is useful when you wish to copy part of the code of the Library into a program that is not a library.
+
+4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange.
+
+If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code.
+
+5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License.
+
+However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables.
+
+When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law.
+
+If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.)
+
+Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself.
+
+6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications.
+
+You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things:
+
+ a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy.
+
+For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.
+
+It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute.
+
+7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above.
+
+ b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.
+
+8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
+
+9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it.
+
+10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License.
+
+11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.
+
+This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
+
+12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.
+
+13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation.
+
+14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.
+
+NO WARRANTY
+
+15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+END OF TERMS AND CONDITIONS
+How to Apply These Terms to Your New Libraries
+If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License).
+
+To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.
+
+ Copyright (C)
+
+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ signature of Ty Coon, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
\ No newline at end of file
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/LGPL 3.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/LGPL 3.txt
new file mode 100644
index 00000000000..ae30c46bfcb
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/LGPL 3.txt
@@ -0,0 +1,63 @@
+Version 3, 29 June 2007
+
+Copyright (C) 2007 Free Software Foundation, Inc.
+
+Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
+
+This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below.
+0. Additional Definitions.
+
+As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License.
+
+"The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below.
+
+An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library.
+
+A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version".
+
+The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version.
+
+The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work.
+1. Exception to Section 3 of the GNU GPL.
+
+You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL.
+2. Conveying Modified Versions.
+
+If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version:
+
+ * a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or
+ * b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy.
+
+3. Object Code Incorporating Material from Library Header Files.
+
+The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following:
+
+ * a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License.
+ * b) Accompany the object code with a copy of the GNU GPL and this license document.
+
+4. Combined Works.
+
+You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following:
+
+ * a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License.
+ * b) Accompany the Combined Work with a copy of the GNU GPL and this license document.
+ * c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document.
+ * d) Do one of the following:
+ o 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.
+ o 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version.
+ * e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.)
+
+5. Combined Libraries.
+
+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 that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following:
+
+ * a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License.
+ * b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.
+
+6. Revised Versions of the GNU Lesser General Public License.
+
+The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation.
+
+If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library.
\ No newline at end of file
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/LGPL-2.0.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/LGPL-2.0.txt
new file mode 100644
index 00000000000..5ee3eaed056
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/LGPL-2.0.txt
@@ -0,0 +1,174 @@
+GNU LIBRARY GENERAL PUBLIC LICENSE
+
+Version 2, June 1991
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+
+Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+Preamble
+
+The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users.
+
+This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, too.
+
+When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.
+
+To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library, or if you modify it.
+
+For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights.
+
+Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library.
+
+Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations.
+
+Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.
+
+Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license.
+
+The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such.
+
+Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better.
+
+However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries.
+
+The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library.
+
+Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you".
+
+A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables.
+
+The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".)
+
+"Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library.
+
+Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does.
+
+1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library.
+
+You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
+
+a) The modified work must itself be a software library.
+b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change.
+c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License.
+d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful.
+
+(For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
+
+3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices.
+
+Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy.
+
+This option is useful when you wish to copy part of the code of the Library into a program that is not a library.
+
+4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange.
+
+If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code.
+
+5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License.
+
+However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables.
+
+When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law.
+
+If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.)
+
+Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself.
+
+6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications.
+
+You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things:
+
+a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.)
+b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution.
+c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place.
+d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy.
+
+For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.
+
+It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute.
+
+7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things:
+
+a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above.
+b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.
+8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
+
+9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it.
+
+10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.
+
+11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.
+
+This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
+
+12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.
+
+13. The Free Software Foundation may publish revised and/or new versions of the Library General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation.
+
+14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.
+
+NO WARRANTY
+
+15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Libraries
+
+If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License).
+
+To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.
+
+one line to give the library's name and an idea of what it does.
+Copyright (C) year name of author
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the
+Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+Boston, MA 02110-1301, USA.
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names:
+
+Yoyodyne, Inc., hereby disclaims all copyright interest in
+the library `Frob' (a library for tweaking knobs) written
+by James Random Hacker.
+
+signature of Ty Coon, 1 April 1990
+Ty Coon, President of Vice
+That's all there is to it!
\ No newline at end of file
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/MIT-CodeMirror.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/MIT-CodeMirror.txt
new file mode 100644
index 00000000000..d21bbea5a63
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/MIT-CodeMirror.txt
@@ -0,0 +1,19 @@
+Copyright (C) 2014 by Marijn Haverbeke and others
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/MIT-DateFormatJS.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/MIT-DateFormatJS.txt
new file mode 100644
index 00000000000..c7f5f75b98e
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/MIT-DateFormatJS.txt
@@ -0,0 +1,4 @@
+Date Format 1.1
+(c) 2007 Steven Levithan
+MIT license
+With code by Scott Trenda (Z and o flags, and enhanced brevity)
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/MIT-EnumJS.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/MIT-EnumJS.txt
new file mode 100644
index 00000000000..49e0b3af495
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/MIT-EnumJS.txt
@@ -0,0 +1,19 @@
+Copyright (c) 2013 Adriano Raiano
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/MIT-FullCalendar.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/MIT-FullCalendar.txt
new file mode 100644
index 00000000000..46d47544964
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/MIT-FullCalendar.txt
@@ -0,0 +1,20 @@
+Copyright (c) 2009 Adam Shaw
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/MIT-extMouseWheel.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/MIT-extMouseWheel.txt
new file mode 100644
index 00000000000..b7684dd5286
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/MIT-extMouseWheel.txt
@@ -0,0 +1,22 @@
+The MIT License
+
+Copyright (c) Ali Rantakari
+http://hasseg.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/MIT-jquery.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/MIT-jquery.txt
new file mode 100644
index 00000000000..5bf4f5e6898
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/MIT-jquery.txt
@@ -0,0 +1,37 @@
+Copyright 2005, 2014 jQuery Foundation and other contributors,
+https://jquery.org/
+
+This software consists of voluntary contributions made by many
+individuals. For exact contribution history, see the revision history
+available at https://github.com/jquery/jquery
+
+The following license applies to all parts of this software except as
+documented below:
+
+====
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+====
+
+All files located in the node_modules and external directories are
+externally maintained libraries used by this software which have their
+own licenses; we recommend you read them, as their terms may differ from
+the terms above.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/MIT-jqueryui.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/MIT-jqueryui.txt
new file mode 100644
index 00000000000..156f8d5caaf
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/MIT-jqueryui.txt
@@ -0,0 +1,44 @@
+Copyright 2007, 2014 jQuery Foundation and other contributors,
+https://jquery.org/
+
+This software consists of voluntary contributions made by many
+individuals. For exact contribution history, see the revision history
+available at https://github.com/jquery/jquery-ui
+
+The following license applies to all parts of this software except as
+documented below:
+
+====
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+====
+
+Copyright and related rights for sample code are waived via CC0. Sample
+code is defined as all source code contained within the demos directory.
+
+CC0: http://creativecommons.org/publicdomain/zero/1.0/
+
+====
+
+All files located in the node_modules and external directories are
+externally maintained libraries used by this software which have their
+own licenses; we recommend you read them, as their terms may differ from
+the terms above.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/MIT-jutf7.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/MIT-jutf7.txt
new file mode 100644
index 00000000000..2183ec98c48
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/MIT-jutf7.txt
@@ -0,0 +1,20 @@
+Copyright (c) 2006,2008 J.T. Beetstra
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/MIT-slf4j.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/MIT-slf4j.txt
new file mode 100644
index 00000000000..43112bc7e0a
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/MIT-slf4j.txt
@@ -0,0 +1,24 @@
+Copyright (c) 2004-2014 QOS.ch
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/MPL-1.1.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/MPL-1.1.txt
new file mode 100644
index 00000000000..6ed1e046a84
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/MPL-1.1.txt
@@ -0,0 +1,165 @@
+Mozilla Public License Version 1.1
+1. Definitions.
+
+1.0.1. "Commercial Use"
+ means distribution or otherwise making the Covered Code available to a third party.
+1.1. "Contributor"
+ means each entity that creates or contributes to the creation of Modifications.
+1.2. "Contributor Version"
+ means the combination of the Original Code, prior Modifications used by a Contributor, and the Modifications made by that particular Contributor.
+1.3. "Covered Code"
+ means the Original Code or Modifications or the combination of the Original Code and Modifications, in each case including portions thereof.
+1.4. "Electronic Distribution Mechanism"
+ means a mechanism generally accepted in the software development community for the electronic transfer of data.
+1.5. "Executable"
+ means Covered Code in any form other than Source Code.
+1.6. "Initial Developer"
+ means the individual or entity identified as the Initial Developer in the Source Code notice required by Exhibit A.
+1.7. "Larger Work"
+ means a work which combines Covered Code or portions thereof with code not governed by the terms of this License.
+1.8. "License"
+ means this document.
+1.8.1. "Licensable"
+ means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein.
+1.9. "Modifications"
+
+ means any addition to or deletion from the substance or structure of either the Original Code or any previous Modifications. When Covered Code is released as a series of files, a Modification is:
+
+ 1. Any addition to or deletion from the contents of a file containing Original Code or previous Modifications.
+ 2. Any new file that contains any part of the Original Code or previous Modifications.
+
+1.10. "Original Code"
+ means Source Code of computer software code which is described in the Source Code notice required by Exhibit A as Original Code, and which, at the time of its release under this License is not already Covered Code governed by this License.
+1.10.1. "Patent Claims"
+ means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor.
+1.11. "Source Code"
+ means the preferred form of the Covered Code for making modifications to it, including all modules it contains, plus any associated interface definition files, scripts used to control compilation and installation of an Executable, or source code differential comparisons against either the Original Code or another well known, available Covered Code of the Contributor's choice. The Source Code can be in a compressed or archival form, provided the appropriate decompression or de-archiving software is widely available for no charge.
+1.12. "You" (or "Your")
+ means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License or a future version of this License issued under Section 6.1. For legal entities, "You" includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity.
+
+2. Source Code License.
+2.1. The Initial Developer Grant.
+
+The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license, subject to third party intellectual property claims:
+
+ 1. under intellectual property rights (other than patent or trademark) Licensable by Initial Developer to use, reproduce, modify, display, perform, sublicense and distribute the Original Code (or portions thereof) with or without Modifications, and/or as part of a Larger Work; and
+ 2. under Patents Claims infringed by the making, using or selling of Original Code, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Code (or portions thereof).
+ 3. the licenses granted in this Section 2.1 (a) and (b) are effective on the date Initial Developer first distributes Original Code under the terms of this License.
+ 4. Notwithstanding Section 2.1 (b) above, no patent license is granted: 1) for code that You delete from the Original Code; 2) separate from the Original Code; or 3) for infringements caused by: i) the modification of the Original Code or ii) the combination of the Original Code with other software or devices.
+
+2.2. Contributor Grant.
+
+Subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license
+
+ 1. under intellectual property rights (other than patent or trademark) Licensable by Contributor, to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof) either on an unmodified basis, with other Modifications, as Covered Code and/or as part of a Larger Work; and
+ 2. under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: 1) Modifications made by that Contributor (or portions thereof); and 2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination).
+ 3. the licenses granted in Sections 2.2 (a) and 2.2 (b) are effective on the date Contributor first makes Commercial Use of the Covered Code.
+ 4. Notwithstanding Section 2.2 (b) above, no patent license is granted: 1) for any code that Contributor has deleted from the Contributor Version; 2) separate from the Contributor Version; 3) for infringements caused by: i) third party modifications of Contributor Version or ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or 4) under Patent Claims infringed by Covered Code in the absence of Modifications made by that Contributor.
+
+3. Distribution Obligations.
+3.1. Application of License.
+
+The Modifications which You create or to which You contribute are governed by the terms of this License, including without limitation Section 2.2. The Source Code version of Covered Code may be distributed only under the terms of this License or a future version of this License released under Section 6.1, and You must include a copy of this License with every copy of the Source Code You distribute. You may not offer or impose any terms on any Source Code version that alters or restricts the applicable version of this License or the recipients' rights hereunder. However, You may include an additional document offering the additional rights described in Section 3.5.
+3.2. Availability of Source Code.
+
+Any Modification which You create or to which You contribute must be made available in Source Code form under the terms of this License either on the same media as an Executable version or via an accepted Electronic Distribution Mechanism to anyone to whom you made an Executable version available; and if made available via Electronic Distribution Mechanism, must remain available for at least twelve (12) months after the date it initially became available, or at least six (6) months after a subsequent version of that particular Modification has been made available to such recipients. You are responsible for ensuring that the Source Code version remains available even if the Electronic Distribution Mechanism is maintained by a third party.
+3.3. Description of Modifications.
+
+You must cause all Covered Code to which You contribute to contain a file documenting the changes You made to create that Covered Code and the date of any change. You must include a prominent statement that the Modification is derived, directly or indirectly, from Original Code provided by the Initial Developer and including the name of the Initial Developer in (a) the Source Code, and (b) in any notice in an Executable version or related documentation in which You describe the origin or ownership of the Covered Code.
+3.4. Intellectual Property Matters
+(a) Third Party Claims
+
+If Contributor has knowledge that a license under a third party's intellectual property rights is required to exercise the rights granted by such Contributor under Sections 2.1 or 2.2, Contributor must include a text file with the Source Code distribution titled "LEGAL" which describes the claim and the party making the claim in sufficient detail that a recipient will know whom to contact. If Contributor obtains such knowledge after the Modification is made available as described in Section 3.2, Contributor shall promptly modify the LEGAL file in all copies Contributor makes available thereafter and shall take other steps (such as notifying appropriate mailing lists or newsgroups) reasonably calculated to inform those who received the Covered Code that new knowledge has been obtained.
+(b) Contributor APIs
+
+If Contributor's Modifications include an application programming interface and Contributor has knowledge of patent licenses which are reasonably necessary to implement that API, Contributor must also include this information in the legal file.
+(c) Representations.
+
+Contributor represents that, except as disclosed pursuant to Section 3.4 (a) above, Contributor believes that Contributor's Modifications are Contributor's original creation(s) and/or Contributor has sufficient rights to grant the rights conveyed by this License.
+3.5. Required Notices.
+
+You must duplicate the notice in Exhibit A in each file of the Source Code. If it is not possible to put such notice in a particular Source Code file due to its structure, then You must include such notice in a location (such as a relevant directory) where a user would be likely to look for such a notice. If You created one or more Modification(s) You may add your name as a Contributor to the notice described in Exhibit A. You must also duplicate this License in any documentation for the Source Code where You describe recipients' rights or ownership rights relating to Covered Code. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Code. However, You may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear than any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer.
+3.6. Distribution of Executable Versions.
+
+You may distribute Covered Code in Executable form only if the requirements of Sections 3.1, 3.2, 3.3, 3.4 and 3.5 have been met for that Covered Code, and if You include a notice stating that the Source Code version of the Covered Code is available under the terms of this License, including a description of how and where You have fulfilled the obligations of Section 3.2. The notice must be conspicuously included in any notice in an Executable version, related documentation or collateral in which You describe recipients' rights relating to the Covered Code. You may distribute the Executable version of Covered Code or ownership rights under a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable version does not attempt to limit or alter the recipient's rights in the Source Code version from the rights set forth in this License. If You distribute the Executable version under a different license You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or any Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer.
+3.7. Larger Works.
+
+You may create a Larger Work by combining Covered Code with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Code.
+4. Inability to Comply Due to Statute or Regulation.
+
+If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Code due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be included in the legal file described in Section 3.4 and must be included with all distributions of the Source Code. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it.
+5. Application of this License.
+
+This License applies to code to which the Initial Developer has attached the notice in Exhibit A and to related Covered Code.
+6. Versions of the License.
+6.1. New Versions
+
+Netscape Communications Corporation ("Netscape") may publish revised and/or new versions of the License from time to time. Each version will be given a distinguishing version number.
+6.2. Effect of New Versions
+
+Once Covered Code has been published under a particular version of the License, You may always continue to use it under the terms of that version. You may also choose to use such Covered Code under the terms of any subsequent version of the License published by Netscape. No one other than Netscape has the right to modify the terms applicable to Covered Code created under this License.
+6.3. Derivative Works
+
+If You create or use a modified version of this License (which you may only do in order to apply it to code which is not already Covered Code governed by this License), You must (a) rename Your license so that the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", "MPL", "NPL" or any confusingly similar phrase do not appear in your license (except to note that your license differs from this License) and (b) otherwise make it clear that Your version of the license contains terms which differ from the Mozilla Public License and Netscape Public License. (Filling in the name of the Initial Developer, Original Code or Contributor in the notice described in Exhibit A shall not of themselves be deemed to be modifications of this License.)
+7. Disclaimer of warranty
+
+Covered code is provided under this license on an "as is" basis, without warranty of any kind, either expressed or implied, including, without limitation, warranties that the covered code is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire risk as to the quality and performance of the covered code is with you. Should any covered code prove defective in any respect, you (not the initial developer or any other contributor) assume the cost of any necessary servicing, repair or correction. This disclaimer of warranty constitutes an essential part of this license. No use of any covered code is authorized hereunder except under this disclaimer.
+8. Termination
+
+8.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. All sublicenses to the Covered Code which are properly granted shall survive any termination of this License. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive.
+
+8.2. If You initiate litigation by asserting a patent infringement claim (excluding declatory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You file such action is referred to as "Participant") alleging that:
+
+ 1. such Participant's Contributor Version directly or indirectly infringes any patent, then any and all rights granted by such Participant to You under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively, unless if within 60 days after receipt of notice You either: (i) agree in writing to pay Participant a mutually agreeable reasonable royalty for Your past and future use of Modifications made by such Participant, or (ii) withdraw Your litigation claim with respect to the Contributor Version against such Participant. If within 60 days of notice, a reasonable royalty and payment arrangement are not mutually agreed upon in writing by the parties or the litigation claim is not withdrawn, the rights granted by Participant to You under Sections 2.1 and/or 2.2 automatically terminate at the expiration of the 60 day notice period specified above.
+ 2. any software, hardware, or device, other than such Participant's Contributor Version, directly or indirectly infringes any patent, then any rights granted to You by such Participant under Sections 2.1(b) and 2.2(b) are revoked effective as of the date You first made, used, sold, distributed, or had made, Modifications made by that Participant.
+
+8.3. If You assert a patent infringement claim against Participant alleging that such Participant's Contributor Version directly or indirectly infringes any patent where such claim is resolved (such as by license or settlement) prior to the initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license.
+
+8.4. In the event of termination under Sections 8.1 or 8.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or any distributor hereunder prior to termination shall survive termination.
+9. Limitation of liability
+
+Under no circumstances and under no legal theory, whether tort (including negligence), contract, or otherwise, shall you, the initial developer, any other contributor, or any distributor of covered code, or any supplier of any of such parties, be liable to any person for any indirect, special, incidental, or consequential damages of any character including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses, even if such party shall have been informed of the possibility of such damages. This limitation of liability shall not apply to liability for death or personal injury resulting from such party's negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to you.
+10. U.S. government end users
+
+The Covered Code is a "commercial item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer software" and "commercial computer software documentation," as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Code with only those rights set forth herein.
+11. Miscellaneous
+
+This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by California law provisions (except to the extent applicable law, if any, provides otherwise), excluding its conflict-of-law provisions. With respect to disputes in which at least one party is a citizen of, or an entity chartered or registered to do business in the United States of America, any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California, with venue lying in Santa Clara County, California, with the losing party responsible for costs, including without limitation, court costs and reasonable attorneys' fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License.
+12. Responsibility for claims
+
+As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability.
+13. Multiple-licensed code
+
+Initial Developer may designate portions of the Covered Code as "Multiple-Licensed". "Multiple-Licensed" means that the Initial Developer permits you to utilize portions of the Covered Code under Your choice of the MPL or the alternative licenses, if any, specified by the Initial Developer in the file described in Exhibit A.
+Exhibit A - Mozilla Public License.
+
+"The contents of this file are subject to the Mozilla Public License
+Version 1.1 (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.mozilla.org/MPL/
+
+Software distributed under the License is distributed on an "AS IS"
+basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+License for the specific language governing rights and limitations
+under the License.
+
+The Original Code is ______________________________________.
+
+The Initial Developer of the Original Code is ________________________.
+Portions created by ______________________ are Copyright (C) ______
+_______________________. All Rights Reserved.
+
+Contributor(s): ______________________________________.
+
+Alternatively, the contents of this file may be used under the terms
+of the _____ license (the "[___] License"), in which case the
+provisions of [______] License are applicable instead of those
+above. If you wish to allow use of your version of this file only
+under the terms of the [____] License and not to allow others to use
+your version of this file under the MPL, indicate your decision by
+deleting the provisions above and replace them with the notice and
+other provisions required by the [___] License. If you do not delete
+the provisions above, a recipient may use your version of this file
+under either the MPL or the [___] License."
+
+NOTE: The text of this Exhibit A may differ slightly from the text of the notices in the Source Code files of the Original Code. You should use the text of this Exhibit A rather than the text found in the Original Code Source Code for Your Modifications.
\ No newline at end of file
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/MPL-2.0.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/MPL-2.0.txt
new file mode 100644
index 00000000000..f4bbcd200ad
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/MPL-2.0.txt
@@ -0,0 +1,373 @@
+Mozilla Public License Version 2.0
+==================================
+
+1. Definitions
+--------------
+
+1.1. "Contributor"
+ means each individual or legal entity that creates, contributes to
+ the creation of, or owns Covered Software.
+
+1.2. "Contributor Version"
+ means the combination of the Contributions of others (if any) used
+ by a Contributor and that particular Contributor's Contribution.
+
+1.3. "Contribution"
+ means Covered Software of a particular Contributor.
+
+1.4. "Covered Software"
+ means Source Code Form to which the initial Contributor has attached
+ the notice in Exhibit A, the Executable Form of such Source Code
+ Form, and Modifications of such Source Code Form, in each case
+ including portions thereof.
+
+1.5. "Incompatible With Secondary Licenses"
+ means
+
+ (a) that the initial Contributor has attached the notice described
+ in Exhibit B to the Covered Software; or
+
+ (b) that the Covered Software was made available under the terms of
+ version 1.1 or earlier of the License, but not also under the
+ terms of a Secondary License.
+
+1.6. "Executable Form"
+ means any form of the work other than Source Code Form.
+
+1.7. "Larger Work"
+ means a work that combines Covered Software with other material, in
+ a separate file or files, that is not Covered Software.
+
+1.8. "License"
+ means this document.
+
+1.9. "Licensable"
+ means having the right to grant, to the maximum extent possible,
+ whether at the time of the initial grant or subsequently, any and
+ all of the rights conveyed by this License.
+
+1.10. "Modifications"
+ means any of the following:
+
+ (a) any file in Source Code Form that results from an addition to,
+ deletion from, or modification of the contents of Covered
+ Software; or
+
+ (b) any new file in Source Code Form that contains any Covered
+ Software.
+
+1.11. "Patent Claims" of a Contributor
+ means any patent claim(s), including without limitation, method,
+ process, and apparatus claims, in any patent Licensable by such
+ Contributor that would be infringed, but for the grant of the
+ License, by the making, using, selling, offering for sale, having
+ made, import, or transfer of either its Contributions or its
+ Contributor Version.
+
+1.12. "Secondary License"
+ means either the GNU General Public License, Version 2.0, the GNU
+ Lesser General Public License, Version 2.1, the GNU Affero General
+ Public License, Version 3.0, or any later versions of those
+ licenses.
+
+1.13. "Source Code Form"
+ means the form of the work preferred for making modifications.
+
+1.14. "You" (or "Your")
+ means an individual or a legal entity exercising rights under this
+ License. For legal entities, "You" includes any entity that
+ controls, is controlled by, or is under common control with You. For
+ purposes of this definition, "control" means (a) the power, direct
+ or indirect, to cause the direction or management of such entity,
+ whether by contract or otherwise, or (b) ownership of more than
+ fifty percent (50%) of the outstanding shares or beneficial
+ ownership of such entity.
+
+2. License Grants and Conditions
+--------------------------------
+
+2.1. Grants
+
+Each Contributor hereby grants You a world-wide, royalty-free,
+non-exclusive license:
+
+(a) under intellectual property rights (other than patent or trademark)
+ Licensable by such Contributor to use, reproduce, make available,
+ modify, display, perform, distribute, and otherwise exploit its
+ Contributions, either on an unmodified basis, with Modifications, or
+ as part of a Larger Work; and
+
+(b) under Patent Claims of such Contributor to make, use, sell, offer
+ for sale, have made, import, and otherwise transfer either its
+ Contributions or its Contributor Version.
+
+2.2. Effective Date
+
+The licenses granted in Section 2.1 with respect to any Contribution
+become effective for each Contribution on the date the Contributor first
+distributes such Contribution.
+
+2.3. Limitations on Grant Scope
+
+The licenses granted in this Section 2 are the only rights granted under
+this License. No additional rights or licenses will be implied from the
+distribution or licensing of Covered Software under this License.
+Notwithstanding Section 2.1(b) above, no patent license is granted by a
+Contributor:
+
+(a) for any code that a Contributor has removed from Covered Software;
+ or
+
+(b) for infringements caused by: (i) Your and any other third party's
+ modifications of Covered Software, or (ii) the combination of its
+ Contributions with other software (except as part of its Contributor
+ Version); or
+
+(c) under Patent Claims infringed by Covered Software in the absence of
+ its Contributions.
+
+This License does not grant any rights in the trademarks, service marks,
+or logos of any Contributor (except as may be necessary to comply with
+the notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+No Contributor makes additional grants as a result of Your choice to
+distribute the Covered Software under a subsequent version of this
+License (see Section 10.2) or under the terms of a Secondary License (if
+permitted under the terms of Section 3.3).
+
+2.5. Representation
+
+Each Contributor represents that the Contributor believes its
+Contributions are its original creation(s) or it has sufficient rights
+to grant the rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+This License is not intended to limit any rights You have under
+applicable copyright doctrines of fair use, fair dealing, or other
+equivalents.
+
+2.7. Conditions
+
+Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
+in Section 2.1.
+
+3. Responsibilities
+-------------------
+
+3.1. Distribution of Source Form
+
+All distribution of Covered Software in Source Code Form, including any
+Modifications that You create or to which You contribute, must be under
+the terms of this License. You must inform recipients that the Source
+Code Form of the Covered Software is governed by the terms of this
+License, and how they can obtain a copy of this License. You may not
+attempt to alter or restrict the recipients' rights in the Source Code
+Form.
+
+3.2. Distribution of Executable Form
+
+If You distribute Covered Software in Executable Form then:
+
+(a) such Covered Software must also be made available in Source Code
+ Form, as described in Section 3.1, and You must inform recipients of
+ the Executable Form how they can obtain a copy of such Source Code
+ Form by reasonable means in a timely manner, at a charge no more
+ than the cost of distribution to the recipient; and
+
+(b) You may distribute such Executable Form under the terms of this
+ License, or sublicense it under different terms, provided that the
+ license for the Executable Form does not attempt to limit or alter
+ the recipients' rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+You may create and distribute a Larger Work under terms of Your choice,
+provided that You also comply with the requirements of this License for
+the Covered Software. If the Larger Work is a combination of Covered
+Software with a work governed by one or more Secondary Licenses, and the
+Covered Software is not Incompatible With Secondary Licenses, this
+License permits You to additionally distribute such Covered Software
+under the terms of such Secondary License(s), so that the recipient of
+the Larger Work may, at their option, further distribute the Covered
+Software under the terms of either this License or such Secondary
+License(s).
+
+3.4. Notices
+
+You may not remove or alter the substance of any license notices
+(including copyright notices, patent notices, disclaimers of warranty,
+or limitations of liability) contained within the Source Code Form of
+the Covered Software, except that You may alter any license notices to
+the extent required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+You may choose to offer, and to charge a fee for, warranty, support,
+indemnity or liability obligations to one or more recipients of Covered
+Software. However, You may do so only on Your own behalf, and not on
+behalf of any Contributor. You must make it absolutely clear that any
+such warranty, support, indemnity, or liability obligation is offered by
+You alone, and You hereby agree to indemnify every Contributor for any
+liability incurred by such Contributor as a result of warranty, support,
+indemnity or liability terms You offer. You may include additional
+disclaimers of warranty and limitations of liability specific to any
+jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+---------------------------------------------------
+
+If it is impossible for You to comply with any of the terms of this
+License with respect to some or all of the Covered Software due to
+statute, judicial order, or regulation then You must: (a) comply with
+the terms of this License to the maximum extent possible; and (b)
+describe the limitations and the code they affect. Such description must
+be placed in a text file included with all distributions of the Covered
+Software under this License. Except to the extent prohibited by statute
+or regulation, such description must be sufficiently detailed for a
+recipient of ordinary skill to be able to understand it.
+
+5. Termination
+--------------
+
+5.1. The rights granted under this License will terminate automatically
+if You fail to comply with any of its terms. However, if You become
+compliant, then the rights granted under this License from a particular
+Contributor are reinstated (a) provisionally, unless and until such
+Contributor explicitly and finally terminates Your grants, and (b) on an
+ongoing basis, if such Contributor fails to notify You of the
+non-compliance by some reasonable means prior to 60 days after You have
+come back into compliance. Moreover, Your grants from a particular
+Contributor are reinstated on an ongoing basis if such Contributor
+notifies You of the non-compliance by some reasonable means, this is the
+first time You have received notice of non-compliance with this License
+from such Contributor, and You become compliant prior to 30 days after
+Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+infringement claim (excluding declaratory judgment actions,
+counter-claims, and cross-claims) alleging that a Contributor Version
+directly or indirectly infringes any patent, then the rights granted to
+You by any and all Contributors for the Covered Software under Section
+2.1 of this License shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all
+end user license agreements (excluding distributors and resellers) which
+have been validly granted by You or Your distributors under this License
+prior to termination shall survive termination.
+
+************************************************************************
+* *
+* 6. Disclaimer of Warranty *
+* ------------------------- *
+* *
+* Covered Software is provided under this License on an "as is" *
+* basis, without warranty of any kind, either expressed, implied, or *
+* statutory, including, without limitation, warranties that the *
+* Covered Software is free of defects, merchantable, fit for a *
+* particular purpose or non-infringing. The entire risk as to the *
+* quality and performance of the Covered Software is with You. *
+* Should any Covered Software prove defective in any respect, You *
+* (not any Contributor) assume the cost of any necessary servicing, *
+* repair, or correction. This disclaimer of warranty constitutes an *
+* essential part of this License. No use of any Covered Software is *
+* authorized under this License except under this disclaimer. *
+* *
+************************************************************************
+
+************************************************************************
+* *
+* 7. Limitation of Liability *
+* -------------------------- *
+* *
+* Under no circumstances and under no legal theory, whether tort *
+* (including negligence), contract, or otherwise, shall any *
+* Contributor, or anyone who distributes Covered Software as *
+* permitted above, be liable to You for any direct, indirect, *
+* special, incidental, or consequential damages of any character *
+* including, without limitation, damages for lost profits, loss of *
+* goodwill, work stoppage, computer failure or malfunction, or any *
+* and all other commercial damages or losses, even if such party *
+* shall have been informed of the possibility of such damages. This *
+* limitation of liability shall not apply to liability for death or *
+* personal injury resulting from such party's negligence to the *
+* extent applicable law prohibits such limitation. Some *
+* jurisdictions do not allow the exclusion or limitation of *
+* incidental or consequential damages, so this exclusion and *
+* limitation may not apply to You. *
+* *
+************************************************************************
+
+8. Litigation
+-------------
+
+Any litigation relating to this License may be brought only in the
+courts of a jurisdiction where the defendant maintains its principal
+place of business and such litigation shall be governed by laws of that
+jurisdiction, without reference to its conflict-of-law provisions.
+Nothing in this Section shall prevent a party's ability to bring
+cross-claims or counter-claims.
+
+9. Miscellaneous
+----------------
+
+This License represents the complete agreement concerning the subject
+matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent
+necessary to make it enforceable. Any law or regulation which provides
+that the language of a contract shall be construed against the drafter
+shall not be used to construe this License against a Contributor.
+
+10. Versions of the License
+---------------------------
+
+10.1. New Versions
+
+Mozilla Foundation is the license steward. Except as provided in Section
+10.3, no one other than the license steward has the right to modify or
+publish new versions of this License. Each version will be given a
+distinguishing version number.
+
+10.2. Effect of New Versions
+
+You may distribute the Covered Software under the terms of the version
+of the License under which You originally received the Covered Software,
+or under the terms of any subsequent version published by the license
+steward.
+
+10.3. Modified Versions
+
+If you create software not governed by this License, and you want to
+create a new license for such software, you may create and use a
+modified version of this License if you rename the license and remove
+any references to the name of the license steward (except to note that
+such modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary
+Licenses
+
+If You choose to distribute Source Code Form that is Incompatible With
+Secondary Licenses under the terms of this version of the License, the
+notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+-------------------------------------------
+
+ This Source Code Form is subject to the terms of the Mozilla Public
+ License, v. 2.0. If a copy of the MPL was not distributed with this
+ file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular
+file, then You may include the notice in a location (such as a LICENSE
+file in a relevant directory) where a recipient would be likely to look
+for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - "Incompatible With Secondary Licenses" Notice
+---------------------------------------------------------
+
+ This Source Code Form is "Incompatible With Secondary Licenses", as
+ defined by the Mozilla Public License, v. 2.0.
\ No newline at end of file
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/OracleBinaryCode-Java.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/OracleBinaryCode-Java.txt
new file mode 100644
index 00000000000..4a7dbef4575
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/OracleBinaryCode-Java.txt
@@ -0,0 +1,69 @@
+Oracle Binary Code License Agreement for the Java SE Platform Products and JavaFX
+
+ORACLE AMERICA, INC. ("ORACLE"), FOR AND ON BEHALF OF ITSELF AND ITS SUBSIDIARIES AND AFFILIATES UNDER COMMON CONTROL, IS WILLING TO LICENSE THE SOFTWARE TO YOU ONLY UPON THE CONDITION THAT YOU ACCEPT ALL OF THE TERMS CONTAINED IN THIS BINARY CODE LICENSE AGREEMENT AND SUPPLEMENTAL LICENSE TERMS (COLLECTIVELY "AGREEMENT"). PLEASE READ THE AGREEMENT CAREFULLY. BY SELECTING THE "ACCEPT LICENSE AGREEMENT" (OR THE EQUIVALENT) BUTTON AND/OR BY USING THE SOFTWARE YOU ACKNOWLEDGE THAT YOU HAVE READ THE TERMS AND AGREE TO THEM. IF YOU ARE AGREEING TO THESE TERMS ON BEHALF OF A COMPANY OR OTHER LEGAL ENTITY, YOU REPRESENT THAT YOU HAVE THE LEGAL AUTHORITY TO BIND THE LEGAL ENTITY TO THESE TERMS. IF YOU DO NOT HAVE SUCH AUTHORITY, OR IF YOU DO NOT WISH TO BE BOUND BY THE TERMS, THEN SELECT THE "DECLINE LICENSE AGREEMENT" (OR THE EQUIVALENT) BUTTON AND YOU MUST NOT USE THE SOFTWARE ON THIS SITE OR ANY OTHER MEDIA ON WHICH THE SOFTWARE IS CONTAINED.
+
+1. DEFINITIONS. "Software" means the software identified above in binary form that you selected for download, install or use (in the version You selected for download, install or use) from Oracle or its authorized licensees, any other machine readable materials (including, but not limited to, libraries, source files, header files, and data files), any updates or error corrections provided by Oracle, and any user manuals, programming guides and other documentation provided to you by Oracle under this Agreement. "General Purpose Desktop Computers and Servers" means computers, including desktop and laptop computers, or servers, used for general computing functions under end user control (such as but not specifically limited to email, general purpose Internet browsing, and office suite productivity tools). The use of Software in systems and solutions that provide dedicated functionality (other than as mentioned above) or designed for use in embedded or function-specific software applications, for example but not limited to: Software embedded in or bundled with industrial control systems, wireless mobile telephones, wireless handheld devices, kiosks, TV/STB, Blu-ray Disc devices, telematics and network control switching equipment, printers and storage management systems, and other related systems are excluded from this definition and not licensed under this Agreement. "Programs" means (a) Java technology applets and applications intended to run on the Java Platform, Standard Edition platform on Java-enabled General Purpose Desktop Computers and Servers; and (b) JavaFX technology applications intended to run on the JavaFX Runtime on JavaFX-enabled General Purpose Desktop Computers and Servers. Commercial Features means those features identified in Table 1-1 (Commercial Features In Java SE Product Editions) of the Java SE documentation accessible at http://www.oracle.com/technetwork/java/javase/documentation/index.html. README File means the README file for the Software accessible at http://www.oracle.com/technetwork/java/javase/documentation/index.html.
+
+2. LICENSE TO USE. Subject to the terms and conditions of this Agreement including, but not limited to, the Java Technology Restrictions of the Supplemental License Terms, Oracle grants you a non-exclusive, non-transferable, limited license without license fees to reproduce and use internally the Software complete and unmodified for the sole purpose of running Programs. THE LICENSE SET FORTH IN THIS SECTION 2 DOES NOT EXTEND TO THE COMMERCIAL FEATURES. YOUR RIGHTS AND OBLIGATIONS RELATED TO THE COMMERCIAL FEATURES ARE AS SET FORTH IN THE SUPPLEMENTAL TERMS ALONG WITH ADDITIONAL LICENSES FOR DEVELOPERS AND PUBLISHERS.
+
+3. RESTRICTIONS. Software is copyrighted. Title to Software and all associated intellectual property rights is retained by Oracle and/or its licensors. Unless enforcement is prohibited by applicable law, you may not modify, decompile, or reverse engineer Software. You acknowledge that the Software is developed for general use in a variety of information management applications; it is not developed or intended for use in any inherently dangerous applications, including applications that may create a risk of personal injury. If you use the Software in dangerous applications, then you shall be responsible to take all appropriate fail-safe, backup, redundancy, and other measures to ensure its safe use. Oracle disclaims any express or implied warranty of fitness for such uses. No right, title or interest in or to any trademark, service mark, logo or trade name of Oracle or its licensors is granted under this Agreement. Additional restrictions for developers and/or publishers licenses are set forth in the Supplemental License Terms.
+
+4. DISCLAIMER OF WARRANTY. THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. ORACLE FURTHER DISCLAIMS ALL WARRANTIES, EXPRESS AND IMPLIED, INCLUDING WITHOUT LIMITATION, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+
+5. LIMITATION OF LIABILITY. IN NO EVENT SHALL ORACLE BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, PUNITIVE OR CONSEQUENTIAL DAMAGES, OR DAMAGES FOR LOSS OF PROFITS, REVENUE, DATA OR DATA USE, INCURRED BY YOU OR ANY THIRD PARTY, WHETHER IN AN ACTION IN CONTRACT OR TORT, EVEN IF ORACLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. ORACLE'S ENTIRE LIABILITY FOR DAMAGES HEREUNDER SHALL IN NO EVENT EXCEED ONE THOUSAND DOLLARS (U.S. $1,000).
+
+6. TERMINATION. This Agreement is effective until terminated. You may terminate this Agreement at any time by destroying all copies of Software. This Agreement will terminate immediately without notice from Oracle if you fail to comply with any provision of this Agreement. Either party may terminate this Agreement immediately should any Software become, or in either party's opinion be likely to become, the subject of a claim of infringement of any intellectual property right. Upon termination, you must destroy all copies of Software.
+
+7. EXPORT REGULATIONS. You agree that U.S. export control laws and other applicable export and import laws govern your use of the Software, including technical data; additional information can be found on Oracle's Global Trade Compliance web site (http://www.oracle.com/us/products/export). You agree that neither the Software nor any direct product thereof will be exported, directly, or indirectly, in violation of these laws, or will be used for any purpose prohibited by these laws including, without limitation, nuclear, chemical, or biological weapons proliferation.
+
+8. TRADEMARKS AND LOGOS. You acknowledge and agree as between you
+and Oracle that Oracle owns the ORACLE and JAVA trademarks and all ORACLE- and JAVA-related trademarks, service marks, logos and other brand
+designations ("Oracle Marks"), and you agree to comply with the Third
+Party Usage Guidelines for Oracle Trademarks currently located at
+http://www.oracle.com/us/legal/third-party-trademarks/index.html . Any use you make of the Oracle Marks inures to Oracle's benefit.
+
+9. U.S. GOVERNMENT LICENSE RIGHTS. If Software is being acquired by or on behalf of the U.S. Government or by a U.S. Government prime contractor or subcontractor (at any tier), then the Government's rights in Software and accompanying documentation shall be only those set forth in this Agreement.
+
+10. GOVERNING LAW. This agreement is governed by the substantive and procedural laws of California. You and Oracle agree to submit to the exclusive jurisdiction of, and venue in, the courts of San Francisco, or Santa Clara counties in California in any dispute arising out of or relating to this agreement.
+
+11. SEVERABILITY. If any provision of this Agreement is held to be unenforceable, this Agreement will remain in effect with the provision omitted, unless omission would frustrate the intent of the parties, in which case this Agreement will immediately terminate.
+
+12. INTEGRATION. This Agreement is the entire agreement between you and Oracle relating to its subject matter. It supersedes all prior or contemporaneous oral or written communications, proposals, representations and warranties and prevails over any conflicting or additional terms of any quote, order, acknowledgment, or other communication between the parties relating to its subject matter during the term of this Agreement. No modification of this Agreement will be binding, unless in writing and signed by an authorized representative of each party.
+
+SUPPLEMENTAL LICENSE TERMS
+
+These Supplemental License Terms add to or modify the terms of the Binary Code License Agreement. Capitalized terms not defined in these Supplemental Terms shall have the same meanings ascribed to them in the Binary Code License Agreement. These Supplemental Terms shall supersede any inconsistent or conflicting terms in the Binary Code License Agreement, or in any license contained within the Software.
+
+A. COMMERCIAL FEATURES. You may not use the Commercial Features for running Programs, Java applets or applications in your internal business operations or for any commercial or production purpose, or for any purpose other than as set forth in Sections B, C, D and E of these Supplemental Terms. If You want to use the Commercial Features for any purpose other than as permitted in this Agreement, You must obtain a separate license from Oracle.
+
+B. SOFTWARE INTERNAL USE FOR DEVELOPMENT LICENSE GRANT. Subject to the terms and conditions of this Agreement and restrictions and exceptions set forth in the README File incorporated herein by reference, including, but not limited to the Java Technology Restrictions of these Supplemental Terms, Oracle grants you a non-exclusive, non-transferable, limited license without fees to reproduce internally and use internally the Software complete and unmodified for the purpose of designing, developing, and testing your Programs.
+
+C. LICENSE TO DISTRIBUTE SOFTWARE. Subject to the terms and conditions of this Agreement and restrictions and exceptions set forth in the README File, including, but not limited to the Java Technology Restrictions and Limitations on Redistribution of these Supplemental Terms, Oracle grants you a non-exclusive, non-transferable, limited license without fees to reproduce and distribute the Software, provided that (i) you distribute the Software complete and unmodified and only bundled as part of, and for the sole purpose of running, your Programs, (ii) the Programs add significant and primary functionality to the Software, (iii) you do not distribute additional software intended to replace any component(s) of the Software, (iv) you do not remove or alter any proprietary legends or notices contained in the Software, (v) you only distribute the Software subject to a license agreement that: (a) is a complete, unmodified reproduction of this Agreement; or (b) protects Oracle's interests consistent with the terms contained in this Agreement and that includes the notice set forth in Section H, and (vi) you agree to defend and indemnify Oracle and its licensors from and against any damages, costs, liabilities, settlement amounts and/or expenses (including attorneys' fees) incurred in connection with any claim, lawsuit or action by any third party that arises or results from the use or distribution of any and all Programs and/or Software. The license set forth in this Section C does not extend to the Software identified in Section G.
+
+D. LICENSE TO DISTRIBUTE REDISTRIBUTABLES. Subject to the terms and conditions of this Agreement and restrictions and exceptions set forth in the README File, including but not limited to the Java Technology Restrictions and Limitations on Redistribution of these Supplemental Terms, Oracle grants you a non-exclusive, non-transferable, limited license without fees to reproduce and distribute those files specifically identified as redistributable in the README File ("Redistributables") provided that: (i) you distribute the Redistributables complete and unmodified, and only bundled as part of Programs, (ii) the Programs add significant and primary functionality to the Redistributables, (iii) you do not distribute additional software intended to supersede any component(s) of the Redistributables (unless otherwise specified in the applicable README File), (iv) you do not remove or alter any proprietary legends or notices contained in or on the Redistributables, (v) you only distribute the Redistributables pursuant to a license agreement that: (a) is a complete, unmodified reproduction of this Agreement; or (b) protects Oracle's interests consistent with the terms contained in the Agreement and includes the notice set forth in Section H, (vi) you agree to defend and indemnify Oracle and its licensors from and against any damages, costs, liabilities, settlement amounts and/or expenses (including attorneys' fees) incurred in connection with any claim, lawsuit or action by any third party that arises or results from the use or distribution of any and all Programs and/or Software. The license set forth in this Section D does not extend to the Software identified in Section G.
+
+E. DISTRIBUTION BY PUBLISHERS. This section pertains to your distribution of the JavaTM SE Development Kit Software (JDK) with your printed book or magazine (as those terms are commonly used in the industry) relating to Java technology ("Publication"). Subject to and conditioned upon your compliance with the restrictions and obligations contained in the Agreement, Oracle hereby grants to you a non-exclusive, nontransferable limited right to reproduce complete and unmodified copies of the JDK on electronic media (the "Media") for the sole purpose of inclusion and distribution with your Publication(s), subject to the following terms: (i) You may not distribute the JDK on a stand-alone basis; it must be distributed with your Publication(s); (ii) You are responsible for downloading the JDK from the applicable Oracle web site; (iii) You must refer to the JDK as JavaTM SE Development Kit; (iv) The JDK must be reproduced in its entirety and without any modification whatsoever (including with respect to all proprietary notices) and distributed with your Publication subject to a license agreement that is a complete, unmodified reproduction of this Agreement; (v) The Media label shall include the following information: Copyright [YEAR], Oracle America, Inc. All rights reserved. Use is subject to license terms. ORACLE and JAVA trademarks and all ORACLE- and JAVA-related trademarks, service marks, logos and other brand designations are trademarks or registered trademarks of Oracle in the U.S. and other countries. [YEAR] is the year of Oracle's release of the Software; the year information can typically be found in the Softwares About box or screen. This information must be placed on the Media label in such a manner as to only apply to the JDK; (vi) You must clearly identify the JDK as Oracle's product on the Media holder or Media label, and you may not state or imply that Oracle is responsible for any third-party software contained on the Media; (vii) You may not include any third party software on the Media which is intended to be a replacement or substitute for the JDK; (viii) You agree to defend and indemnify Oracle and its licensors from and against any damages, costs, liabilities, settlement amounts and/or expenses (including attorneys' fees) incurred in connection with any claim, lawsuit or action by any third party that arises or results from the use or distribution of the JDK and/or the Publication; ; and (ix) You shall provide Oracle with a written notice for each Publication; such notice shall include the following information: (1) title of Publication, (2) author(s), (3) date of Publication, and (4) ISBN or ISSN numbers. Such notice shall be sent to Oracle America, Inc., 500 Oracle Parkway, Redwood Shores, California 94065 U.S.A , Attention: General Counsel.
+
+F. JAVA TECHNOLOGY RESTRICTIONS. You may not create, modify, or change the behavior of, or authorize your licensees to create, modify, or change the behavior of, classes, interfaces, or subpackages that are in any way identified as "java", "javax", "sun", oracle or similar convention as specified by Oracle in any naming convention designation.
+
+G. LIMITATIONS ON REDISTRIBUTION. You may not redistribute or otherwise transfer patches, bug fixes or updates made available by Oracle through Oracle Premier Support, including those made available under Oracle's Java SE Support program.
+
+H. COMMERCIAL FEATURES NOTICE. For purpose of complying with Supplemental Term Section C.(v)(b) and D.(v)(b), your license agreement shall include the following notice, where the notice is displayed in a manner that anyone using the Software will see the notice:
+
+Use of the Commercial Features for any commercial or production purpose requires a separate license from Oracle. Commercial Features means those features identified Table 1-1 (Commercial Features In Java SE Product Editions) of the Java SE documentation accessible at http://www.oracle.com/technetwork/java/javase/documentation/index.html
+
+
+
+I. SOURCE CODE. Software may contain source code that, unless expressly licensed for other purposes, is provided solely for reference purposes pursuant to the terms of this Agreement. Source code may not be redistributed unless expressly provided for in this Agreement.
+
+J. THIRD PARTY CODE. Additional copyright notices and license terms applicable to portions of the Software are set forth in the THIRDPARTYLICENSEREADME file accessible at http://www.oracle.com/technetwork/java/javase/documentation/index.html. In addition to any terms and conditions of any third party opensource/freeware license identified in the THIRDPARTYLICENSEREADME file, the disclaimer of warranty and limitation of liability provisions in paragraphs 4 and 5 of the Binary Code License Agreement shall apply to all Software in this distribution.
+
+K. TERMINATION FOR INFRINGEMENT. Either party may terminate this Agreement immediately should any Software become, or in either party's opinion be likely to become, the subject of a claim of infringement of any intellectual property right.
+
+L. INSTALLATION AND AUTO-UPDATE. The Software's installation and auto-update processes transmit a limited amount of data to Oracle (or its service provider) about those specific processes to help Oracle understand and optimize them. Oracle does not associate the data with personally identifiable information. You can find more information about the data Oracle collects as a result of your Software download at http://www.oracle.com/technetwork/java/javase/documentation/index.html.
+
+For inquiries please contact: Oracle America, Inc., 500 Oracle Parkway,
+
+Redwood Shores, California 94065, USA.
+
+Last updated 02 April 2013
\ No newline at end of file
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/Sun Public License.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/Sun Public License.txt
new file mode 100644
index 00000000000..f7668c8f0fa
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/Sun Public License.txt
@@ -0,0 +1,504 @@
+1. Definitions.
+
+ 1.0.1. "Commercial Use" means distribution or otherwise making the
+ Covered Code available to a third party.
+
+ 1.1. "Contributor" means each entity that creates or contributes to
+ the creation of Modifications.
+
+ 1.2. "Contributor Version" means the combination of the Original Code,
+ prior Modifications used by a Contributor, and the Modifications made
+ by that particular Contributor.
+
+ 1.3. "Covered Code" means the Original Code or Modifications or the
+ combination of the Original Code and Modifications, in each case
+ including portions thereof and corresponding documentation released
+ with the source code.
+
+ 1.4. "Electronic Distribution Mechanism" means a mechanism generally
+ accepted in the software development community for the electronic
+ transfer of data.
+
+ 1.5. "Executable" means Covered Code in any form other than Source
+ Code.
+
+ 1.6. "Initial Developer" means the individual or entity identified as
+ the Initial Developer in the Source Code notice required by Exhibit
+ A.
+
+ 1.7. "Larger Work" means a work which combines Covered Code or
+ portions thereof with code not governed by the terms of this
+ License.
+
+ 1.8. "License" means this document.
+
+ 1.8.1. "Licensable" means having the right to grant, to the maximum
+ extent possible, whether at the time of the initial grant or
+ subsequently acquired, any and all of the rights conveyed herein.
+
+ 1.9. "Modifications" means any addition to or deletion from the
+ substance or structure of either the Original Code or any previous
+ Modifications. When Covered Code is released as a series of files, a
+ Modification is:
+
+ A. Any addition to or deletion from the contents of a file containing
+ Original Code or previous Modifications.
+
+ B. Any new file that contains any part of the Original Code or
+ previous Modifications.
+
+ 1.10. "Original Code"../ means Source Code of computer software code
+ which is described in the Source Code notice required by Exhibit A as
+ Original Code, and which, at the time of its release under this
+ License is not already Covered Code governed by this License.
+
+ 1.10.1. "Patent Claims" means any patent claim(s), now owned or
+ hereafter acquired, including without limitation, method, process, and
+ apparatus claims, in any patent Licensable by grantor.
+
+ 1.11. "Source Code"../ means the preferred form of the Covered Code
+ for
+ making modifications to it, including all modules it contains, plus
+ any associated documentation, interface definition files, scripts used
+ to control compilation and installation of an Executable, or source
+ code differential comparisons against either the Original Code or
+ another well known, available Covered Code of the Contributor's
+ choice. The Source Code can be in a compressed or archival form,
+ provided the appropriate decompression or de-archiving software is
+ widely available for no charge.
+
+ 1.12. "You" (or "Your") means an individual or a legal entity
+ exercising rights under, and complying with all of the terms of, this
+ License or a future version of this License issued under Section 6.1.
+ For legal entities, "You" includes any entity which controls, is
+ controlled by, or is under common control with You. For purposes of
+ this definition, "control"../ means (a) the power, direct or indirect,
+ to
+ cause the direction or management of such entity, whether by contract
+ or otherwise, or (b) ownership of more than fifty percent (50%) of the
+ outstanding shares or beneficial ownership of such entity.
+
+2. Source Code License.
+
+ 2.1 The Initial Developer Grant.
+
+ The Initial Developer hereby grants You a world-wide, royalty-free,
+ non-exclusive license, subject to third party intellectual property
+ claims:
+
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Initial Developer to use, reproduce, modify,
+ display, perform, sublicense and distribute the Original Code (or
+ portions thereof) with or without Modifications, and/or as part of a
+ Larger Work; and
+
+ (b) under Patent Claims infringed by the making, using or selling of
+ Original Code, to make, have made, use, practice, sell, and offer for
+ sale, and/or otherwise dispose of the Original Code (or portions
+ thereof).
+
+ (c) the licenses granted in this Section 2.1(a) and (b) are effective
+ on the date Initial Developer first distributes Original Code under
+ the terms of this License.
+
+ (d) Notwithstanding Section 2.1(b) above, no patent license is
+ granted: 1) for code that You delete from the Original Code; 2)
+ separate from the Original Code; or 3) for infringements caused
+ by:
+
+ i) the modification of the Original Code or ii) the combination of the
+ Original Code with other software or devices.
+
+ 2.2. Contributor Grant.
+
+ Subject to third party intellectual property claims, each Contributor
+ hereby grants You a world-wide, royalty-free, non-exclusive license
+
+ (a) under intellectual property rights (other than patent
+ or
+ trademark) Licensable by Contributor, to use, reproduce, modify,
+ display, perform, sublicense and distribute the Modifications created
+ by such Contributor (or portions thereof) either on an unmodified
+ basis, with other Modifications, as Covered Code and/or as part of a
+ Larger Work; and
+
+ b) under Patent Claims infringed by the making, using, or selling of
+ Modifications made by that Contributor either alone and/or in
+ combination with its Contributor Version (or portions of such
+ combination), to make, use, sell, offer for sale, have made, and/or
+ otherwise dispose of: 1) Modifications made by that Contributor (or
+ portions thereof); and 2) the combination of Modifications made by
+ that Contributor with its Contributor Version (or portions of such
+ combination).
+
+ (c) the licenses granted in Sections 2.2(a) and 2.2(b) are effective
+ on the date Contributor first makes Commercial Use of the Covered
+ Code.
+
+ (d) notwithstanding Section 2.2(b) above, no patent license is
+ granted: 1) for any code that Contributor has deleted from the
+ Contributor Version; 2) separate from the Contributor Version; 3) for
+ infringements caused by: i) third party modifications of Contributor
+ Version or ii) the combination of Modifications made by that
+ Contributor with other software (except as part of the Contributor
+ Version) or other devices; or 4) under Patent Claims infringed by
+ Covered Code in the absence of Modifications made by that
+ Contributor.
+
+ 3. Distribution Obligations.
+
+ 3.1. Application of License.
+
+ The Modifications which You create or to which You contribute are
+ governed by the terms of this License, including without limitation
+ Section 2.2. The Source Code version of Covered Code may be
+ distributed only under the terms of this License or a future version
+ of this License released under Section 6.1, and You must include a
+ copy of this License with every copy of the Source Code You
+ distribute. You may not offer or impose any terms on any Source Code
+ version that alters or restricts the applicable version of this
+ License or the recipients' rights hereunder. However, You may include
+ an additional document offering the additional rights described in
+ Section 3.5.
+
+ 3.2. Availability of Source Code.
+
+ Any Modification which You create or to which You contribute must be
+ made available in Source Code form under the terms of this License
+ either on the same media as an Executable version or via an accepted
+ Electronic Distribution Mechanism to anyone to whom you made an
+ Executable version available; and if made available via Electronic
+ Distribution Mechanism, must remain available for at least twelve (12)
+ months after the date it initially became available, or at least six
+ (6) months after a subsequent version of that particular Modification
+ has been made available to such recipients. You are responsible for
+ ensuring that the Source Code version remains available even if the
+ Electronic Distribution Mechanism is maintained by a third party.
+
+ 3.3. Description of Modifications.
+
+ You must cause all Covered Code to which You contribute to contain a
+ file documenting the changes You made to create that Covered Code and
+ the date of any change. You must include a prominent statement that
+ the Modification is derived, directly or indirectly, from Original
+ Code provided by the Initial Developer and including the name of the
+ Initial Developer in (a) the Source Code, and (b) in any notice in an
+ Executable version or related documentation in which You describe the
+ origin or ownership of the Covered Code.
+
+ 3.4. Intellectual Property Matters.
+
+ (a) Third Party Claims.
+
+ If Contributor has knowledge that a license under a third party's
+ intellectual property rights is required to exercise the rights
+ granted by such Contributor under Sections 2.1 or 2.2, Contributor
+ must include a text file with the Source Code distribution titled
+ "../LEGAL'' which describes the claim and the party making the claim in
+ sufficient detail that a recipient will know whom to contact. If
+ Contributor obtains such knowledge after the Modification is made
+ available as described in Section 3.2, Contributor shall promptly
+ modify the LEGAL file in all copies Contributor makes available
+ thereafter and shall take other steps (such as notifying appropriate
+ mailing lists or newsgroups) reasonably calculated to inform those who
+ received the Covered Code that new knowledge has been obtained.
+
+ (b) Contributor APIs.
+
+ If Contributor's Modifications include an application programming
+ interface ("API"../) and Contributor has knowledge of patent licenses
+ which are reasonably necessary to implement that API, Contributor must
+ also include this information in the LEGAL file.
+
+ (c) Representations.
+
+ Contributor represents that, except as disclosed pursuant to Section
+ 3.4(a) above, Contributor believes that Contributor's Modifications
+ are Contributor's original creation(s) and/or Contributor has
+ sufficient rights to grant the rights conveyed by this
+ License
+
+ .
+
+ 3.5. Required Notices.
+
+ You must duplicate the notice in Exhibit A in each file of the Source
+ Code. If it is not possible to put such notice in a particular Source
+ Code file due to its structure, then You must include such notice in a
+ location (such as a relevant directory) where a user would be likely
+ to look for such a notice. If You created one or more Modification(s)
+ You may add your name as a Contributor to the notice described in
+ Exhibit A. You must also duplicate this License in any documentation
+ for the Source Code where You describe recipients' rights or ownership
+ rights relating to Covered Code. You may choose to offer, and to
+ charge a fee for, warranty, support, indemnity or liability
+ obligations to one or more recipients of Covered Code. However, You
+ may do so only on Your own behalf, and not on behalf of the Initial
+ Developer or any Contributor. You must make it absolutely clear than
+ any such warranty, support, indemnity or liability obligation is
+ offered by You alone, and You hereby agree to indemnify the Initial
+ Developer and every Contributor for any liability incurred by the
+ Initial Developer or such Contributor as a result of warranty,
+ support, indemnity or liability terms You offer.
+
+ 3.6. Distribution of Executable Versions.
+
+ You may distribute Covered Code in Executable form only if the
+ requirements of Section 3.1-3.5 have been met for that Covered Code,
+ and if You include a notice stating that the Source Code version of
+ the Covered Code is available under the terms of this License,
+ including a description of how and where You have fulfilled the
+ obligations of Section 3.2. The notice must be conspicuously included
+ in any notice in an Executable version, related documentation or
+ collateral in which You describe recipients' rights relating to the
+ Covered Code. You may distribute the Executable version of Covered
+ Code or ownership rights under a license of Your choice, which may
+ contain terms different from this License, provided that You are in
+ compliance with the terms of this License and that the license for the
+ Executable version does not attempt to limit or alter the recipient's
+ rights in the Source Code version from the rights set forth in this
+ License. If You distribute the Executable version under a different
+ license You must make it absolutely clear that any terms which differ
+ from this License are offered by You alone, not by the Initial
+ Developer or any Contributor. You hereby agree to indemnify the
+ Initial Developer and every Contributor for any liability incurred by
+ the Initial Developer or such Contributor as a result of any such
+ terms You offer.
+
+ 3.7. Larger Works.
+
+ You may create a Larger Work by combining Covered Code with other
+ code
+ not governed by the terms of this License and distribute the Larger
+ Work as a single product. In such a case, You must make sure the
+ requirements of this License are fulfilled for the Covered Code.
+
+ 4. Inability to Comply Due to Statute or Regulation.
+
+ If it is impossible for You to comply with any of the terms of this
+ License with respect to some or all of the Covered Code due to
+ statute, judicial order, or regulation then You must: (a) comply with
+ the terms of this License to the maximum extent possible; and (b)
+ describe the limitations and the code they affect. Such description
+ must be included in the LEGAL file described in Section 3.4 and must
+ be included with all distributions of the Source Code. Except to the
+ extent prohibited by statute or regulation, such description must be
+ sufficiently detailed for a recipient of ordinary skill to be able to
+ understand it.
+
+ 5. Application of this License.
+
+ This License applies to code to which the Initial Developer has
+ attached the notice in Exhibit A and to related Covered Code.
+
+ 6. Versions of the License.
+
+ 6.1. New Versions.
+
+ Sun Microsystems, Inc. ("Sun") may publish revised and/or new versions
+ of the License from time to time. Each version will be given a
+ distinguishing version number.
+
+ 6.2. Effect of New Versions.
+
+ Once Covered Code has been published under a particular version of
+ the
+ License, You may always continue to use it under the terms of that
+ version. You may also choose to use such Covered Code under the terms
+ of any subsequent version of the License published by Sun. No one
+ other than Sun has the right to modify the terms applicable to Covered
+ Code created under this License.
+
+ 6.3. Derivative Works.
+
+ If You create or use a modified version of this License (which you
+ may
+ only do in order to apply it to code which is not already Covered Code
+ governed by this License), You must: (a) rename Your license so that
+ the phrases "Sun," "Sun Public License," or "SPL"../ or any confusingly
+ similar phrase do not appear in your license (except to note that your
+ license differs from this License) and (b) otherwise make it clear
+ that Your version of the license contains terms which differ from the
+ Sun Public License. (Filling in the name of the Initial Developer,
+ Original Code or Contributor in the notice described in Exhibit A
+ shall not of themselves be deemed to be modifications of this
+ License.)
+
+ 7. DISCLAIMER OF WARRANTY.
+
+ COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "../AS IS'' BASIS,
+ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
+ DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
+ THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
+ IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
+ YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
+ COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
+ OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
+ ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS
+ DISCLAIMER.
+
+ 8. TERMINATION.
+
+ 8.1. This License and the rights granted hereunder will terminate
+ automatically if You fail to comply with terms herein and fail to cure
+ such breach within 30 days of becoming aware of the breach. All
+ sublicenses to the Covered Code which are properly granted shall
+ survive any termination of this License. Provisions which, by their
+ nature, must remain in effect beyond the termination of this License
+ shall survive.
+
+ 8.2. If You initiate litigation by asserting a patent infringement
+ claim (excluding declaratory judgment actions) against Initial Developer
+ or a Contributor (the Initial Developer or Contributor against whom
+ You file such action is referred to as "Participant") alleging
+ that:
+
+ (a) such Participant's Contributor Version directly or indirectly
+ infringes any patent, then any and all rights granted by such
+ Participant to You under Sections 2.1 and/or 2.2 of this License
+ shall, upon 60 days notice from Participant terminate prospectively,
+ unless if within 60 days after receipt of notice You either: (i)
+ agree in writing to pay Participant a mutually agreeable reasonable
+ royalty for Your past and future use of Modifications made by such
+ Participant, or (ii) withdraw Your litigation claim with respect to
+ the Contributor Version against such Participant. If within 60 days
+ of notice, a reasonable royalty and payment arrangement are not
+ mutually agreed upon in writing by the parties or the litigation claim
+ is not withdrawn, the rights granted by Participant to You under
+ Sections 2.1 and/or 2.2 automatically terminate at the expiration of
+ the 60 day notice period specified above.
+
+ (b) any software, hardware, or device, other than such Participant's
+ Contributor Version, directly or indirectly infringes any patent, then
+ any rights granted to You by such Participant under Sections 2.1(b)
+ and 2.2(b) are revoked effective as of the date You first made, used,
+ sold, distributed, or had made, Modifications made by that
+ Participant.
+
+ 8.3. If You assert a patent infringement claim against Participant
+ alleging that such Participant's Contributor Version directly or
+ indirectly infringes any patent where such claim is resolved (such as
+ by license or settlement) prior to the initiation of patent
+ infringement litigation, then the reasonable value of the licenses
+ granted by such Participant under Sections 2.1 or 2.2 shall be taken
+ into account in determining the amount or value of any payment or
+ license.
+
+ 8.4. In the event of termination under Sections 8.1 or 8.2 above,
+ all
+ end user license agreements (excluding distributors and resellers)
+ which have been validly granted by You or any distributor hereunder
+ prior to termination shall survive termination.
+
+ 9. LIMITATION OF LIABILITY.
+
+ UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+ (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
+ DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
+ OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
+ ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
+ CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
+ WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+ COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+ INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
+ LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
+ RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
+ PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
+ EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
+ THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+ 10. U.S. GOVERNMENT END USERS.
+
+ The Covered Code is a "commercial item," as that term is defined in
+ 48
+ C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer software"
+ and "commercial computer software documentation,"../ as such terms are
+ used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R.
+ 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all
+ U.S. Government End Users acquire Covered Code with only those rights
+ set forth herein.
+
+ 11. MISCELLANEOUS.
+
+ This License represents the complete agreement concerning subject
+ matter hereof. If any provision of this License is held to be
+ unenforceable, such provision shall be reformed only to the extent
+ necessary to make it enforceable. This License shall be governed by
+ California law provisions (except to the extent applicable law, if
+ any, provides otherwise), excluding its conflict-of-law provisions.
+ With respect to disputes in which at least one party is a citizen of,
+ or an entity chartered or registered to do business in the United
+ States of America, any litigation relating to this License shall be
+ subject to the jurisdiction of the Federal Courts of the Northern
+ District of California, with venue lying in Santa Clara County,
+ California, with the losing party responsible for costs, including
+ without limitation, court costs and reasonable attorneys' fees and
+ expenses. The application of the United Nations Convention on
+ Contracts for the International Sale of Goods is expressly excluded.
+ Any law or regulation which provides that the language of a contract
+ shall be construed against the drafter shall not apply to this
+ License.
+
+ 12. RESPONSIBILITY FOR CLAIMS.
+
+ As between Initial Developer and the Contributors, each party is
+ responsible for claims and damages arising, directly or indirectly,
+ out of its utilization of rights under this License and You agree to
+ work with Initial Developer and Contributors to distribute such
+ responsibility on an equitable basis. Nothing herein is intended or
+ shall be deemed to constitute any admission of liability.
+
+ 13. MULTIPLE-LICENSED CODE.
+
+ Initial Developer may designate portions of the Covered Code as
+ ?Multiple-Licensed?. ?Multiple-Licensed? means that the Initial
+ Developer permits you to utilize portions of the Covered Code under
+ Your choice of the alternative licenses, if any, specified by the
+ Initial Developer in the file described in Exhibit A.
+
+ Exhibit A -Sun Public License Notice.
+
+ The contents of this file are subject to the Sun Public License
+
+ Version 1.0 (the License); you may not use this file except in
+
+ compliance with the License. A copy of the License is available at
+
+ http://www.sun.com/
+
+ The Original Code is _________________. The Initial Developer of the
+
+ Original Code is ___________. Portions created by ______ are Copyright
+
+ (C)_________. All Rights Reserved.
+
+ Contributor(s): ______________________________________.
+
+ Alternatively, the contents of this file may be used under the terms
+
+ of the _____ license (the ?[___] License?), in which case the
+
+ provisions of [______] License are applicable instead of those above.
+
+ If you wish to allow use of your version of this file only under the
+
+ terms of the [____] License and not to allow others to use your
+
+ version of this file under the SPL, indicate your decision by deleting
+
+ the provisions above and replace them with the notice and other
+
+ provisions required by the [___] License. If you do not delete the
+
+ provisions above, a recipient may use your version of this file under
+
+ either the SPL or the [___] License.
+
+ [NOTE: The text of this Exhibit A may differ slightly from the text of
+
+ the notices in the Source Code files of the Original Code. You should
+
+ use the text of this Exhibit A rather than the text found in the
+
+ Original Code Source Code for Your Modifications.]
\ No newline at end of file
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/Sun-JSR250-CommonsAnnotations.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/Sun-JSR250-CommonsAnnotations.txt
new file mode 100644
index 00000000000..430f758f3db
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/Sun-JSR250-CommonsAnnotations.txt
@@ -0,0 +1,400 @@
+SUN MICROSYSTEMS, INC. ("SUN") IS WILLING TO LICENSE
+THIS SPECIFICATION
+TO YOU ONLY UPON THE CONDITION THAT YOU ACCEPT ALL OF
+THE TERMS
+CONTAINED IN THIS AGREEMENT. PLEASE READ THE TERMS AND
+CONDITIONS OF
+THIS AGREEMENT CAREFULLY.
+BY DOWNLOADING THIS
+SPECIFICATION, YOU ACCEPT
+THE TERMS AND CONDITIONS OF THE AGREEMENT. IF YOU ARE
+NOT WILLING TO BE
+BOUND BY IT, SELECT THE "DECLINE" BUTTON AT THE BOTTOM
+OF THIS PAGE.
+
+
+Specification: JSR-000250 Common Annotations for the
+Java(tm) Platform ("Specification")
+
+
+Version: 1.0
+
+
+Status: Final Release
+
+
+Release: 19 April 2006
+
+
+Copyright 2006 SUN MICROSYSTEMS, INC.
+
+4150 Network Circle, Santa Clara, California 95054, U.S.A
+
+All rights reserved.
+
+
+LIMITED LICENSE GRANTS
+
+
+1. _License for Evaluation Purposes_. Sun hereby
+grants you a
+fully-paid, non-exclusive, non-transferable,
+worldwide, limited license
+(without the right to sub
+license), under Sun's
+applicable intellectual
+property rights to view, download, use and reproduce
+the Specification
+only for the purpose of internal evaluation. This
+includes (i)
+developing applications intended to run on an
+impl
+ementation of the
+Specification, provided that such applications do not
+themselves
+implement any portion(s) of the Specification, and
+(ii) discussing the
+Specification with any third party; and (iii)
+excerpting brief portions
+of th
+e Specification in oral or written communications
+which discuss the
+Specification provided that such excerpts do not in
+the aggregate
+constitute a significant portion of the Specification.
+
+
+2. _License for the Distribution of Compl
+iant
+Implementations_. Sun also
+grants you a perpetual, non-exclusive,
+non-transferable, worldwide,
+fully paid-up, royalty free, limited license (without
+the right to
+sublicense) under any applicable copyrights or,
+subject to the
+provisions of subsection 4 below, patent rights it may
+have covering the
+Specification to create and/or distribute an
+Independent Implementation
+of the Specification that: (a) fully implements the
+Specification
+including all its re
+quired interfaces and
+functionality; (b) does not
+modify, subset, superset or otherwise extend the
+Licensor Name Space, or
+include any public or protected packages, classes,
+Java interfaces,
+fields or methods within the Licensor Name
+Space other
+than those
+required/authorized by the Specification or
+Specifications being
+implemented; and (c) passes the Technology
+Compatibility Kit (including
+satisfying the requirements of the applicable TCK
+Users Guide) for suc
+h
+Specification ("Compliant Implementation"). In
+addition, the foregoing
+license is expressly conditioned on your not acting
+outside its scope.
+No license is granted hereunder for any other purpose
+(including, for
+example, modifyin
+g the Specification, other than to
+the extent of your
+fair use rights, or distributing the Specification to
+third parties).
+Also, no right, title, or interest in or to any
+trademarks, service
+marks, or trade names of Sun or Sun's lice
+nsors is
+granted hereunder.
+Java, and Java-related logos, marks and names are
+trademarks or
+registered trademarks of Sun Microsystems, Inc. in the
+U.S. and other
+countries.
+
+
+3. _Pass-through Conditions_. You need not include
+
+limitations (a)-(c)
+from the previous paragraph or any other particular
+"pass through"
+requirements in any license You grant concerning the
+use of your
+Independent Implementation or products derived from
+it. However, except
+wi
+th respect to Independent Implementations (and
+products derived from
+them) that satisfy limitations (a)-(c) from the
+previous paragraph, You
+may neither: (a) grant or otherwise pass through to
+your licensees any
+licenses under Sun's a
+pplicable intellectual property
+rights; nor (b)
+authorize your licensees to make any claims concerning
+their
+implementation's compliance with the Specification in
+question.
+
+
+4. _Reciprocity Concerning Patent Licenses_.
+
+
+a. With respect to any patent claims covered by the
+license granted
+under subparagraph 2 above that would be infringed by
+all technically
+feasible implementations of the Specification, such
+license is
+conditioned upon your offering
+on fair, reasonable and
+non-discriminatory terms, to any party seeking it from
+You, a perpetual,
+non-exclusive, non-transferable, worldwide license
+under Your patent
+rights which are or would be infringed by all
+technically feasible
+implementations of the Specification to develop,
+distribute and use a
+Compliant Implementation.
+
+
+b With respect to any patent claims owned by Sun and
+covered by the
+license granted under subparagraph 2, whether or not
+their
+infringement
+can be avoided in a technically feasible manner when
+implementing the
+Specification, such license shall terminate with
+respect to such claims
+if You initiate a claim against Sun that it has, in
+the course of
+performing
+its responsibilities as the Specification
+Lead, induced any
+other entity to infringe Your patent rights.
+
+
+c Also with respect to any patent claims owned by Sun
+and covered by the
+license granted under subparagraph 2 above, where t
+he
+infringement of
+such claims can be avoided in a technically feasible
+manner when
+implementing the Specification such license, with
+respect to such
+claims, shall terminate if You initiate a claim
+against Sun that its
+making,
+having made, using, offering to sell, selling
+or importing a
+Compliant Implementation infringes Your patent rights.
+
+
+5. _Definitions_. For the purposes of this Agreement:
+"Independent
+Implementation" shall mean an implementation of
+the
+Specification that
+neither derives from any of Sun's source code or
+binary code materials
+nor, except with an appropriate and separate license
+from Sun, includes
+any of Sun's source code or binary code materials;
+"Licensor Na
+me Space"
+shall mean the public class or interface declarations
+whose names begin
+with "java", "javax", "com.sun" or their equivalents
+in any subsequent
+naming convention adopted by Sun through the Java
+Community Process, or
+any re
+cognized successors or replacements thereof; and
+"Technology
+Compatibility Kit" or "TCK" shall mean the test suite
+and accompanying
+TCK User's Guide provided by Sun which corresponds to
+the Specification
+and that was available either
+(i) from Sun's 120 days
+before the first
+release of Your Independent Implementation that allows
+its use for
+commercial purposes, or (ii) more recently than 120
+days from such
+release but against which You elect to test Your
+implem
+entation of the
+Specification.
+
+
+This Agreement will terminate immediately without
+notice from Sun if you
+breach the Agreement or act outside the scope of the
+licenses granted above.
+
+
+DISCLAIMER OF WARRANTIES
+
+
+TH
+E SPECIFICATION IS PROVIDED "AS IS". SUN MAKES NO
+REPRESENTATIONS OR
+WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO,
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE,
+NON-INFRINGEMENT (INCLUDING AS
+A CONSEQUENCE OF ANY
+PRACTICE OR
+IMPLEMENTATION OF THE SPECIFICATION), OR THAT THE
+CONTENTS OF THE
+SPECIFICATION ARE SUITABLE FOR ANY PURPOSE. This
+document does not
+represent any commitment to release or implement any
+portion of
+the
+Specification in any product. In addition, the
+Specification could
+include technical inaccuracies or typographical errors.
+
+
+LIMITATION OF LIABILITY
+
+
+TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT WILL
+SUN OR ITS
+
+LICENSORS BE LIABLE FOR ANY DAMAGES, INCLUDING WITHOUT
+LIMITATION, LOST
+REVENUE, PROFITS OR DATA, OR FOR SPECIAL, INDIRECT,
+CONSEQUENTIAL,
+INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+REGARDLESS OF THE
+THEORY OF LIABILITY, ARISI
+NG OUT OF OR RELATED IN ANY
+WAY TO YOUR
+HAVING, IMPLEMENTING OR OTHERWISE USING THE
+SPECIFICATION, EVEN
+IF SUN AND/OR ITS LICENSORS HAVE BEEN ADVISED OF THE
+POSSIBILITY OF SUCH
+DAMAGES.
+
+You will indemnify, hold harmless, and de
+fend Sun and
+its licensors from
+any claims arising or resulting from: (i) your use of
+the Specification;
+(ii) the use or distribution of your Java application,
+applet and/or
+implementation; and/or (iii) any claims that later
+versi
+ons or releases
+of any Specification furnished to you are incompatible
+with the
+Specification provided to you under this license.
+
+
+RESTRICTED RIGHTS LEGEND
+
+
+U.S. Government: If this Specification is being
+acquired by or o
+n behalf
+of the U.S. Government or by a U.S. Government prime
+contractor or
+subcontractor (at any tier), then the Government's
+rights in the
+Software and accompanying documentation shall be only
+as set forth in
+this license; this i
+s in accordance with 48 C.F.R.
+227.7201 through
+227.7202-4 (for Department of Defense (DoD)
+acquisitions) and with 48
+C.F.R. 2.101 and 12.212 (for non-DoD acquisitions).
+
+
+REPORT
+
+
+If you provide Sun with any comments or su
+ggestions
+concerning the
+Specification ("Feedback"), you hereby: (i) agree that
+such Feedback is
+provided on a non-proprietary and non-confidential
+basis, and (ii) grant
+Sun a perpetual, non-exclusive, worldwide, fully
+paid-up, ir
+revocable
+license, with the right to sublicense through multiple
+levels of
+sublicensees, to incorporate, disclose, and use
+without limitation the
+Feedback for any purpose.
+
+
+GENERAL TERMS
+
+
+Any action related to this Agr
+eement will be governed
+by California law
+and controlling U.S. federal law. The U.N. Convention
+for the
+International Sale of Goods and the choice of law
+rules of any
+jurisdiction will not apply.
+
+
+The Specification is subjec
+t to U.S. export control
+laws and may be
+subject to export or import regulations in other
+countries. Licensee
+agrees to comply strictly with all such laws and
+regulations and
+acknowledges that it has the responsibility to obtain
+s
+uch licenses to
+export, re-export or import as may be required after
+delivery to Licensee.
+
+
+This Agreement is the parties' entire agreement
+relating to its subject
+matter. It supersedes all prior or contemporaneous
+oral or writ
+ten
+communications, proposals, conditions, representations
+and warranties
+and prevails over any conflicting or additional terms
+of any quote,
+order, acknowledgment, or other communication between
+the parties
+relating to its subject
+matter during the term of this
+Agreement. No
+modification to this Agreement will be binding, unless
+in writing and
+signed by an authorized representative of each party.
+
+
+
+
+Rev. April, 2006
+
+Sun/Final/Full
+
+
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/Sun-JSR907-TransactionAPI.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/Sun-JSR907-TransactionAPI.txt
new file mode 100644
index 00000000000..ec960801e6f
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/Sun-JSR907-TransactionAPI.txt
@@ -0,0 +1,288 @@
+
+SUN MICROSYSTEMS, INC. ("SUN") IS WILLING TO LICENSE
+THIS SPECIFICATION TO YOU ONLY UPON THE CONDITION THAT
+YOU ACCEPT ALL OF THE TERMS CONTAINED IN THIS
+AGREEMENT. PLEASE READ THE TERMS AND CONDITIONS OF
+THIS AGREEMENT CAREFULLY. BY D
+OWNLOADING THIS
+SPECIFICATION, YOU ACCEPT THE TERMS AND CONDITIONS OF
+THE AGREEMENT. IF YOU ARE NOT WILLING TO BE BOUND BY
+IT, SELECT THE "DECLINE" BUTTON AT THE BOTTOM OF THIS
+PAGE.
+
+Specification: JSR-000907 Java(tm) Transaction API
+(JTA) Specification ("Specification")
+
+Version: 1.1
+
+Status: Maintenance Release
+
+Release: 14 February 2007
+
+Copyright 2007 SUN MICROSYSTEMS, INC.
+4150 Network Circle, Santa Clara, California 95054,
+U.S.A
+All
+rights reserved.
+
+LIMITED LICENSE GRANTS
+
+1. License for Evaluation Purposes. Sun hereby grants
+you a fully-paid, non-exclusive, non-transferable,
+worldwide, limited license (without the right to
+sublicense), under Sun's applicab
+le intellectual
+property rights to view, download, use and reproduce
+the Specification only for the purpose of internal
+evaluation. This includes (i) developing applications
+intended to run on an implementation of the
+Specification, p
+rovided that such applications do not
+themselves implement any portion(s) of the
+Specification, and (ii) discussing the Specification
+with any third party; and (iii) excerpting brief
+portions of the Specification in oral or written
+com
+munications which discuss the Specification
+provided that such excerpts do not in the aggregate
+constitute a significant portion of the Specification.
+
+2. License for the Distribution of Compliant
+Implementations. Sun also grants you a
+perpetual,
+non-exclusive, non-transferable, worldwide, fully
+paid-up, royalty free, limited license (without the
+right to sublicense) under any applicable copyrights
+or, subject to the provisions of subsection 4 below,
+patent rights it
+may have covering the Specification
+to create and/or distribute an Independent
+Implementation of the Specification that: (a) fully
+implements the Specification including all its
+required interfaces and functionality; (b) does not
+modi
+fy, subset, superset or otherwise extend the
+Licensor Name Space, or include any public or
+protected packages, classes, Java interfaces, fields
+or methods within the Licensor Name Space other than
+those required/authorized by the Specifica
+tion or
+Specifications being implemented; and (c) passes the
+Technology Compatibility Kit (including satisfying the
+requirements of the applicable TCK Users Guide) for
+such Specification ("Compliant Implementation"). In
+addition, the
+foregoing license is expressly
+conditioned on your not acting outside its scope. No
+license is granted hereunder for any other purpose
+(including, for example, modifying the Specification,
+other than to the extent of your fair use rights,
+or
+distributing the Specification to third parties).
+Also, no right, title, or interest in or to any
+trademarks, service marks, or trade names of Sun or
+Sun's licensors is granted hereunder. Java, and
+Java-related logos, marks and n
+ames are trademarks or
+registered trademarks of Sun Microsystems, Inc. in the
+U.S. and other countries.
+
+3. Pass-through Conditions. You need not include
+limitations (a)-(c) from the previous paragraph or any
+other particular "pass t
+hrough" requirements in any
+license You grant concerning the use of your
+Independent Implementation or products derived from
+it. However, except with respect to Independent
+Implementations (and products derived from them) that
+satisfy
+limitations (a)-(c) from the previous
+paragraph, You may neither: (a) grant or otherwise
+pass through to your licensees any licenses under
+Sun's applicable intellectual property rights; nor
+(b) authorize your licensees to make any claim
+s
+concerning their implementation's compliance with the
+Specification in question.
+
+4. Reciprocity Concerning Patent Licenses.
+
+ a. With respect to any patent claims covered
+by the license granted under subparagraph 2 above that
+
+would be infringed by all technically feasible
+implementations of the Specification, such license is
+conditioned upon your offering on fair, reasonable and
+non-discriminatory terms, to any party seeking it from
+You, a perpetual, non-e
+xclusive, non-transferable,
+worldwide license under Your patent rights which are
+or would be infringed by all technically feasible
+implementations of the Specification to develop,
+distribute and use a Compliant Implementation.
+
+ b W
+ith respect to any patent claims owned by
+Sun and covered by the license granted under
+subparagraph 2, whether or not their infringement can
+be avoided in a technically feasible manner when
+implementing the Specification, such license shal
+l
+terminate with respect to such claims if You initiate
+a claim against Sun that it has, in the course of
+performing its responsibilities as the Specification
+Lead, induced any other entity to infringe Your patent
+rights.
+
+ c Al
+so with respect to any patent claims
+owned by Sun and covered by the license granted under
+subparagraph 2 above, where the infringement of such
+claims can be avoided in a technically feasible manner
+when implementing the Specification such
+license, with
+respect to such claims, shall terminate if You
+initiate a claim against Sun that its making, having
+made, using, offering to sell, selling or importing a
+Compliant Implementation infringes Your patent rights.
+
+5. Defi
+nitions. For the purposes of this Agreement:
+"Independent Implementation" shall mean an
+implementation of the Specification that neither
+derives from any of Sun's source code or binary code
+materials nor, except with an appropriate and s
+eparate
+license from Sun, includes any of Sun's source code
+or binary code materials; "Licensor Name Space" shall
+mean the public class or interface declarations whose
+names begin with "java", "javax", "com.sun" or their
+equivalents
+in any subsequent naming convention
+adopted by Sun through the Java Community Process, or
+any recognized successors or replacements thereof; and
+"Technology Compatibility Kit" or "TCK" shall mean the
+test suite and accompanying TCK User's
+Guide provided
+by Sun which corresponds to the Specification and
+that was available either (i) from Sun's 120 days
+before the first release of Your Independent
+Implementation that allows its use for commercial
+purposes, or (ii) more
+recently than 120 days from
+such release but against which You elect to test Your
+implementation of the Specification.
+
+This Agreement will terminate immediately without
+notice from Sun if you breach the Agreement or act
+outside the
+scope of the licenses granted above.
+
+DISCLAIMER OF WARRANTIES
+
+THE SPECIFICATION IS PROVIDED "AS IS". SUN MAKES NO
+REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF
+MERCHANTABIL
+ITY, FITNESS FOR A PARTICULAR PURPOSE,
+NON-INFRINGEMENT (INCLUDING AS A CONSEQUENCE OF ANY
+PRACTICE OR IMPLEMENTATION OF THE SPECIFICATION), OR
+THAT THE CONTENTS OF THE SPECIFICATION ARE SUITABLE
+FOR ANY PURPOSE. This document does not re
+present any
+commitment to release or implement any portion of the
+Specification in any product. In addition, the
+Specification could include technical inaccuracies or
+typographical errors.
+
+LIMITATION OF LIABILITY
+
+TO THE EXTE
+NT NOT PROHIBITED BY LAW, IN NO EVENT WILL
+SUN OR ITS LICENSORS BE LIABLE FOR ANY DAMAGES,
+INCLUDING WITHOUT LIMITATION, LOST REVENUE, PROFITS OR
+DATA, OR FOR SPECIAL, INDIRECT, CONSEQUENTIAL,
+INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED
+AND
+REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
+OR RELATED IN ANY WAY TO YOUR HAVING, IMPELEMENTING OR
+OTHERWISE USING USING THE SPECIFICATION, EVEN IF SUN
+AND/OR ITS LICENSORS HAVE BEEN ADVISED OF THE
+POSSIBILITY OF SUCH D
+AMAGES.
+You will indemnify, hold harmless, and defend Sun and
+its licensors from any claims arising or resulting
+from: (i) your use of the Specification; (ii) the use
+or distribution of your Java application, applet
+and/or implementati
+on; and/or (iii) any claims that
+later versions or releases of any Specification
+furnished to you are incompatible with the
+Specification provided to you under this license.
+
+RESTRICTED RIGHTS LEGEND
+
+U.S. Government: If this Spe
+cification is being
+acquired by or on behalf of the U.S. Government or by
+a U.S. Government prime contractor or subcontractor
+(at any tier), then the Government's rights in the
+Software and accompanying documentation shall be only
+as s
+et forth in this license; this is in accordance
+with 48 C.F.R. 227.7201 through 227.7202-4 (for
+Department of Defense (DoD) acquisitions) and with 48
+C.F.R. 2.101 and 12.212 (for non-DoD acquisitions).
+
+REPORT
+
+If you provide Sun
+with any comments or suggestions
+concerning the Specification ("Feedback"), you hereby:
+(i) agree that such Feedback is provided on a
+non-proprietary and non-confidential basis, and (ii)
+grant Sun a perpetual, non-exclusive, worldwide, ful
+ly
+paid-up, irrevocable license, with the right to
+sublicense through multiple levels of sublicensees, to
+incorporate, disclose, and use without limitation the
+Feedback for any purpose.
+
+GENERAL TERMS
+
+Any action related to thi
+s Agreement will be governed
+by California law and controlling U.S. federal law.
+The U.N. Convention for the International Sale of
+Goods and the choice of law rules of any jurisdiction
+will not apply.
+
+The Specification is subject to
+U.S. export control
+laws and may be subject to export or import
+regulations in other countries. Licensee agrees to
+comply strictly with all such laws and regulations and
+acknowledges that it has the responsibility to obtain
+such licen
+ses to export, re-export or import as may be
+required after delivery to Licensee.
+
+This Agreement is the parties' entire agreement
+relating to its subject matter. It supersedes all
+prior or contemporaneous oral or written
+communicati
+ons, proposals, conditions, representations
+and warranties and prevails over any conflicting or
+additional terms of any quote, order, acknowledgment,
+or other communication between the parties relating to
+its subject matter during the ter
+m of this Agreement.
+No modification to this Agreement will be binding,
+unless in writing and signed by an authorized
+representative of each party.
+
+
+
+Rev. April, 2006
+
+
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/Unidata Free Software.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/Unidata Free Software.txt
new file mode 100644
index 00000000000..938c73812f4
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/Unidata Free Software.txt
@@ -0,0 +1,7 @@
+Copyright 1993-2010 University Corporation for Atmospheric Research/Unidata
+
+Portions of this software were developed by the Unidata Program at the University Corporation for Atmospheric Research.
+
+Access and use of this software shall impose the following obligations and understandings on the user. The user is granted the right, without any fee or cost, to use, copy, modify, alter, enhance and distribute this software, and any derivative works thereof, and its supporting documentation for any purpose whatsoever, provided that this entire notice appears in all copies of the software, derivative works and supporting documentation. Further, UCAR requests that the user credit UCAR/Unidata in any publications that result from the use of this software or in any product that includes this software, although this is not an obligation. The names UCAR and/or Unidata, however, may not be used in any advertising or publicity to endorse or promote any products or commercial entity unless specific written permission is obtained from UCAR/Unidata. The user also understands that UCAR/Unidata is not obligated to provide the user with any support, consulting, training or assistance of any kind with regard to the use, operation and performance of this software nor to provide the user with any updates, revisions, new versions or "bug fixes."
+
+THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
\ No newline at end of file
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/bouncycastle-license.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/bouncycastle-license.txt
new file mode 100644
index 00000000000..cbef4fc8677
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/bouncycastle-license.txt
@@ -0,0 +1,7 @@
+Copyright (c) 2000 The Legion Of The Bouncy Castle (http://www.bouncycastle.org)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/gpl-2.0.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/gpl-2.0.txt
new file mode 100644
index 00000000000..d159169d105
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/gpl-2.0.txt
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+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 Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program 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 to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ , 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/libreoffice.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/libreoffice.txt
new file mode 100644
index 00000000000..a82e6b6292a
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/libreoffice.txt
@@ -0,0 +1,9428 @@
+
+ Licensing and Legal information
+
+ This product is made available subject to the terms of the Mozilla
+ Public License, v. 2.0. A copy of the MPL Version 2 license can be
+ found below.
+
+ See MPL Version 2 below
+
+ Third Party Code Additional copyright notices and license terms
+ applicable to portions of the Software can be found below in this
+ document.
+
+ All trademarks and registered trademarks mentioned herein are the
+ property of their respective owners.
+
+ Copyright © 2000, 2014 LibreOffice contributors. All rights reserved.
+
+ This product is based on OpenOffice.org. Portions of this software are
+ copyright © 2000-2011, Oracle and/or its affiliates.
+
+ This product has been created by The Document Foundation, incorporating
+ many modifications from different contributors, see
+ http://www.libreoffice.org/ for more details.
+
+ Note: Do not translate or localize this document. Only English version
+ is legally binding.
+
+ Contents
+
+ Libraries
+
+ Extensions
+
+ Fonts
+
+ Dictionaries
+
+ Artwork
+
+ Miscellaneous
+
+ GNU Lesser General Public License Version 3
+
+ GNU Lesser General Public License Version 2.1
+
+ GNU Library General Public License Version 2
+
+ GNU General Public License Version 3
+
+ GNU General Public License Version 2
+
+ Mozilla Public License Version 1.1
+
+ Mozilla Public License Version 2.0
+
+ SIL Open Font License Version 1.1 – 26 February 2007
+
+ Apache License
+
+ The LaTeX Project Public License
+
+ Creative Commons Attribution-ShareAlike 3.0 Unported
+
+ Third Party Code Additional Copyright Notices and License Terms
+
+ Libraries
+
+Apache Commons
+
+ The following software may be included in this product: Apache Commons
+ (codec, httpclient, lang, logging). Use of any of this software is
+ governed by the terms of the license below:
+
+ See Apache License Version 2.0 below
+
+beanshell
+
+ The following software may be included in this product: beanshell. Use
+ of any of this software is governed by the terms of the license below:
+
+ This file is part of the BeanShell Java Scripting distribution.
+ Documentation and updates may be found at http://www.beanshell.org/
+
+ Sun Public License Notice:
+
+ The contents of this file are subject to the Sun Public License Version
+ 1.0 (the "License"); you may not use this file except in compliance
+ with the License. A copy of the License is available at
+ http://www.sun.com
+
+ The Original Code is BeanShell. The Initial Developer of the Original
+ Code is Pat Niemeyer. Portions created by Pat Niemeyer are Copyright
+ (C) 2000. All Rights Reserved.
+
+ GNU Public License Notice:
+
+ Alternatively, the contents of this file may be used under the terms of
+ the GNU Lesser General Public License (the "LGPL"), in which case the
+ provisions of LGPL are applicable instead of those above. If you wish
+ to allow use of your version of this file only under the terms of the
+ LGPL and not to allow others to use your version of this file under the
+ SPL, indicate your decision by deleting the provisions above and
+ replace them with the notice and other provisions required by the LGPL.
+ If you do not delete the provisions above, a recipient may use your
+ version of this file under either the SPL or the LGPL.
+
+ Patrick Niemeyer (pat@pat.net) Author of Learning Java, O'Reilly &
+ Associates http://www.pat.net/~pat/
+
+ See LGPL Version 3 below
+
+C++ Boost Library
+
+ The following software may be included in this product: C++ Boost
+ Library. Use of any of this software is governed by the terms of the
+ license below:
+
+ Boost Software License - Version 1.0 - August 17th, 2003
+
+ Permission is hereby granted, free of charge, to any person or
+ organization obtaining a copy of the software and accompanying
+ documentation covered by this license (the "Software") to use,
+ reproduce, display, distribute, execute, and transmit the Software, and
+ to prepare derivative works of the Software, and to permit
+ third-parties to whom the Software is furnished to do so, all subject
+ to the following:
+
+ The copyright notices in the Software and this entire statement,
+ including the above license grant, this restriction and the following
+ disclaimer, must be included in all copies of the Software, in whole or
+ in part, and all derivative works of the Software, unless such copies
+ or derivative works are solely in the form of machine-executable object
+ code generated by a source language processor.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
+ NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE
+ DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY,
+ WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+
+Cairo
+
+ The following software may be included in this product: Cairo. Use of
+ any of this software is governed by the terms of the license below:
+
+ Cairo is free software.
+
+ Every source file in the implementation[*] of cairo is available to be
+ redistributed and/or modified under the terms of either the GNU Lesser
+ General Public License (LGPL) version 2.1 or the Mozilla Public License
+ (MPL) version 1.1. Some files are available under more liberal terms,
+ but we believe that in all cases, each file may be used under either
+ the LGPL or the MPL.
+
+ See the following files in this directory for the precise terms and
+ conditions of either license:
+
+ See LGPL Version 2.1 below
+
+ See MPL Version 1.1 below
+
+ Please see each file in the implementation for copyright and licensing
+ information, (in the opening comment of each file).
+
+ [*] The implementation of cairo is contained entirely within the "src"
+ and "pixman" directories of the cairo source distribution. There are
+ other components of the cairo source distribution (such as the "test"
+ and "perf") that are auxiliary to the library itself. None of the
+ source code in these directories contributes to a build of the cairo
+ library itself, (libcairo.so or cairo.dll or similar).
+
+ These auxilary components are also free software, but may be under
+ different license terms than cairo itself. For example, most of the
+ test cases in the perf and test directories are made available under a
+ MIT license to simplify any use of this code for reference purposes in
+ using cairo itself. Other files might be available under the GNU
+ General Public License (GPL), for example. Again, please see the
+ opening comment of each file for copyright and licensing information.
+
+CLucene
+
+ The following software may be included in this product: CLucene. Use of
+ any of this software is governed by the terms of the license below:
+
+ CLucene is distributed under the GNU Lesser General Public License
+ (LGPL) or the Apache License, Version 2.0
+
+ See LGPL Version 2.1 below
+
+ See Apache License Version 2.0 below
+
+expat XML Parser Toolkit
+
+ The following software may be included in this product: expat XML
+ Parser Toolkit. Use of any of this software is governed by the terms of
+ the license below:
+
+ Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd and
+ Clark Cooper
+
+ Copyright (c) 2001, 2002, 2003 Expat maintainers.
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Flute
+
+ The following software may be included in this product: Flute. Use of
+ any of this software is governed by the terms of the license below:
+
+ W3C IPR SOFTWARE NOTICE
+
+ Copyright © 2002 World Wide Web Consortium, (Massachusetts Institute of
+ Technology, Institut National de Recherche en Informatique et en
+ Automatique, Keio University). All Rights Reserved.
+
+ Note: The original version of the W3C Software Copyright Notice and
+ License could be found at
+ http://www.w3.org/Consortium/Legal/copyright-software-19980720
+
+ Copyright © 1994-2000 World Wide Web Consortium, (Massachusetts
+ Institute of Technology, Institut National de Recherche en
+ Informatique et en Automatique, Keio University). All Rights
+ Reserved. http://www.w3.org/Consortium/Legal/
+
+ This W3C work (including software, documents, or other related items)
+ is being provided by the copyright holders under the following license.
+ By obtaining, using and/or copying this work, you (the licensee) agree
+ that you have read, understood, and will comply with the following
+ terms and conditions:
+
+ Permission to use, copy, and modify this software and its
+ documentation, with or without modification, for any purpose and
+ without fee or royalty is hereby granted, provided that you include the
+ following on ALL copies of the software and documentation or portions
+ thereof, including modifications, that you make:
+ 1. The full text of this NOTICE in a location viewable to users of the
+ redistributed or derivative work.
+ 2. Any pre-existing intellectual property disclaimers, notices, or
+ terms and conditions. If none exist, a short notice of the
+ following form (hypertext is preferred, text is permitted) should
+ be used within the body of any redistributed or derivative code:
+ "Copyright © 2002 World Wide Web Consortium, (Massachusetts
+ Institute of Technology, Institut National de Recherche en
+ Informatique et en Automatique, Keio University). All Rights
+ Reserved. http://www.w3.org/Consortium/Legal/"
+ 3. Notice of any changes or modifications to the W3C files, including
+ the date changes were made. (We recommend you provide URIs to the
+ location from which the code is derived.)
+
+ THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT
+ HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED,
+ INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS
+ FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR
+ DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS,
+ TRADEMARKS OR OTHER RIGHTS.
+
+ COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR
+ DOCUMENTATION.
+
+ The name and trademarks of copyright holders may NOT be used in
+ advertising or publicity pertaining to the software without specific,
+ written prior permission. Title to copyright in this software and any
+ associated documentation will at all times remain with copyright
+ holders.
+
+ Freetype Library
+
+ The following software may be included in this product: Freetype. Use
+ of any of this software is governed by the terms of the license below:
+
+ 0. Definitions
+
+ Throughout this license, the terms `package', `FreeType Project', and
+ `FreeType archive' refer to the set of files originally distributed by
+ the authors (David Turner, Robert Wilhelm, and Werner Lemberg) as the
+ `FreeType Project', be they named as alpha, beta or final release.
+
+ `You' refers to the licensee, or person using the project, where
+ `using' is a generic term including compiling the project's source code
+ as well as linking it to form a `program' or `executable'. This program
+ is referred to as `a program using the FreeType engine'.
+
+ This license applies to all files distributed in the original FreeType
+ Project, including all source code, binaries and documentation, unless
+ otherwise stated in the file in its original, unmodified form as
+ distributed in the original archive. If you are unsure whether or not a
+ particular file is covered by this license, you must contact us to
+ verify this.
+
+ The FreeType Project is copyright (C) 1996-2000 by David Turner, Robert
+ Wilhelm, and Werner Lemberg. All rights reserved except as specified
+ below.
+
+ 1. No Warranty
+
+ THE FREETYPE PROJECT IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY KIND,
+ EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL
+ ANY OF THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES
+ CAUSED BY THE USE OR THE INABILITY TO USE, OF THE FREETYPE PROJECT.
+
+ 2. Redistribution
+
+ This license grants a worldwide, royalty-free, perpetual and
+ irrevocable right and license to use, execute, perform, compile,
+ display, copy, create derivative works of, distribute and sublicense
+ the FreeType Project (in both source and object code forms) and
+ derivative works thereof for any purpose; and to authorize others to
+ exercise some or all of the rights granted herein, subject to the
+ following conditions:
+ * Redistribution of source code must retain this license file
+ ('FTL.TXT') unaltered; any additions, deletions or changes to the
+ original files must be clearly indicated in accompanying
+ documentation. The copyright notices of the unaltered, original
+ files must be preserved in all copies of source files.
+ * Redistribution in binary form must provide a disclaimer that states
+ that the software is based in part of the work of the FreeType
+ Team, in the distribution documentation. We also encourage you to
+ put an URL to the FreeType web page in your documentation, though
+ this isn't mandatory.
+
+ These conditions apply to any software derived from or based on the
+ FreeType Project, not just the unmodified files. If you use our work,
+ you must acknowledge us. However, no fee need be paid to us.
+
+ 3. Advertising
+
+ Neither the FreeType authors and contributors nor you shall use the
+ name of the other for commercial, advertising, or promotional purposes
+ without specific prior written permission.
+
+ We suggest, but do not require, that you use one or more of the
+ following phrases to refer to this software in your documentation or
+ advertising materials: `FreeType Project', `FreeType Engine', `FreeType
+ library', or `FreeType Distribution'.
+
+ As you have not signed this license, you are not required to accept it.
+ However, as the FreeType Project is copyrighted material, only this
+ license, or another one contracted with the authors, grants you the
+ right to use, distribute, and modify it. Therefore, by using,
+ distributing, or modifying the FreeType Project, you indicate that you
+ understand and accept all the terms of this license.
+
+ 4. Contacts
+
+ There are two mailing lists related to FreeType:
+ * freetype@freetype.org
+
+ Discusses general use and applications of FreeType, as well as future
+ and wanted additions to the library and distribution. If you are
+ looking for support, start in this list if you haven't found anything
+ to help you in the documentation.
+ * devel@freetype.org
+
+ Discusses bugs, as well as engine internals, design issues, specific
+ licenses, porting, etc.
+ * http://www.freetype.org
+
+ Holds the current FreeType web page, which will allow you to download
+ our latest development version and read online documentation.
+
+ You can also contact us individually at:
+
+ David Turner
+ Robert Wilhelm
+ Werner Lemberg
+
+GNU ISO C++ Library
+
+ The following software may be included in this product: GNU ISO C++
+ Library. Use of any of this software is governed by the terms of the
+ license below:
+
+ © Free Software Foundation, Inc.
+
+ See GPL Version 2 below
+
+ Additional License(s)
+
+libstdc++:
+// Explicit instantiation file.
+
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
+// Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, 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 General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free
+software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you
+compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be
+covered by
+// the GNU General Public License.
+
+libgcc:
+//
+// ISO C++ 14882:
+//
+
+/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Contributed by Jakub Jelinek .
+
+ This file is part of GNU CC.
+
+ GNU CC is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GNU CC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU CC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public
+License. */
+
+/* Locate the FDE entry for a given address, using PT_GNU_EH_FRAME ELF
+ segment and dl_iterate_phdr to avoid register/deregister calls at
+ DSO load/unload. */
+
+Firebird
+
+ The applicable and approved licenses for the source files of the
+ Firebird RDBMS project are:
+
+ 1) InterBase Public License (IPL), version 1.0
+
+ 2) Initial Developer's Public License (IDPL), version 1.0
+
+ The IPL is copyright of Borland Corp., the other licenses are copyright
+ by the source code authors and contributors. Both are variants of the
+ Mozilla Public License V.1.1 (MPL). See
+ http://www.firebirdsql.org/en/licensing/
+
+fontconfig
+
+ The following software may be included in this product: fontconfig. Use
+ of any of this software is governed by the terms of the license below:
+
+ Copyright © 2002 Keith Packard
+
+ Permission to use, copy, modify, distribute, and sell this software and
+ its documentation for any purpose is hereby granted without fee,
+ provided that the above copyright notice appear in all copies and that
+ both that copyright notice and this permission notice appear in
+ supporting documentation, and that the name of the author(s) not be
+ used in advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission. The authors make
+ no representations about the suitability of this software for any
+ purpose. It is provided "as is" without express or implied warranty.
+
+ THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ PERFORMANCE OF THIS SOFTWARE.
+
+Graphite2
+
+ The following software may be included in this product: Graphite2. Use
+ of any of this software is governed by the terms of the license below:
+
+ Copyright 2010, SIL International All rights reserved.
+
+ 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 License, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+ General Public License for more details.
+
+ You should also have received a copy of the GNU Lesser General Public
+ License along with this library in the file named "LICENSE". If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place, Suite
+ 330, Boston, MA 02111-1307, USA or visit their web page on the internet
+ at http://www.fsf.org/licenses/lgpl.html.
+
+ Alternatively, you may use this library under the terms of the Mozilla
+ Public License (http://mozilla.org/MPL) or under the GNU General
+ Public License, as published by the Free Sofware Foundation; either
+ version 2 of the license or (at your option) any later version.
+
+ See LGPL Version 2.1 below
+
+ See MPL Version 1.1 below
+
+HarfBuzz
+
+ HarfBuzz is licensed under the so-called "Old MIT" license. Details
+ follow. For parts of HarfBuzz that are licensed under different
+ licenses see individual files names COPYING in subdirectories where
+ applicable.
+
+ Copyright © 2010,2011,2012 Google, Inc.
+ Copyright © 2012 Mozilla Foundation
+ Copyright © 2011 Codethink Limited
+ Copyright © 2008,2010 Nokia Corporation and/or its subsidiary(-ies)
+ Copyright © 2009 Keith Stribley
+ Copyright © 2009 Martin Hosken and SIL International
+ Copyright © 2007 Chris Wilson
+ Copyright © 2006 Behdad Esfahbod
+ Copyright © 2005 David Turner
+ Copyright © 2004,2007,2008,2009,2010 Red Hat, Inc.
+ Copyright © 1998-2004 David Turner and Werner Lemberg
+
+ For full copyright notices consult the individual files in the package.
+
+ Permission is hereby granted, without written agreement and without
+ license or royalty fees, to use, copy, modify, and distribute this
+ software and its documentation for any purpose, provided that the above
+ copyright notice and the following two paragraphs appear in all copies
+ of this software.
+
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING
+ OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE
+ COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON
+ AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO PROVIDE
+ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+
+HSQLDB
+
+ The following software may be included in this product: HSQLDB. Use of
+ any of this software is governed by the terms of the license below:
+
+ ORIGINAL LICENSE (a.k.a. "hypersonic_lic.txt")
+
+ For content, code, and products originally developed by Thomas Mueller
+ and the Hypersonic SQL Group:
+
+ Copyright (c) 1995-2000 by the Hypersonic SQL Group. All rights
+ reserved. Redistribution and use in source and binary forms, with or
+ without modification, are permitted provided that the following
+ conditions are met:
+
+ Redistribution of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ Redistribution in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ Neither the name of the Hypersonic SQL Group nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL
+ GROUP, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the Hypersonic SQL Group.
+
+ For work added by the HSQL Development Group (a.k.a. hsqldb_lic.txt)
+
+ Copyright (c) 2001-2004, The HSQL Development Group All rights
+ reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ Redistribution of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ Redistribution in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ Neither the name of the HSQL Development Group nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT
+ GROUP, HSQLDB.ORG, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGE.
+
+Hunspell
+
+ The following software may be included in this product: Hunspell. Use
+ of any of this software is governed by the terms of the license below:
+
+ GPL 2.0/LGPL 2.1/MPL 1.1 tri-license
+
+ The contents of this software may be used under the terms of the GNU
+ General Public License Version 2 or later (the "GPL"), or the GNU
+ Lesser General Public License Version 2.1 or later (the "LGPL") or
+ (excepting the LGPLed GNU gettext library in the intl/ directory) the
+ Mozilla Public License Version 1.1 or later (the "MPL").
+
+ Software distributed under these licenses is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ licenses for the specific language governing rights and limitations
+ under the licenses.
+
+ See GPL Version 2 below
+
+ See LGPL Version 2.1 below
+
+ See MPL Version 1.1 below
+
+Hyphen
+
+ The following software may be included in this product: Hyphen. Use of
+ any of this software is governed by the terms of the license below:
+
+ GPL 2.0/LGPL 2.1/MPL 1.1 tri-license
+
+ The contents of this software may be used under the terms of the GNU
+ General Public License Version 2 or later (the "GPL"), or the GNU
+ Lesser General Public License Version 2.1 or later (the "LGPL") or
+ (excepting the LGPLed GNU gettext library in the intl/ directory) the
+ Mozilla Public License Version 1.1 or later (the "MPL").
+
+ The Plain TeX hyphenation tables "hyphen.tex" by Donald E. Knuth has a
+ non MPL/LGPL compatible license, but freely redistributable: "Unlimited
+ copying and redistribution of this file are permitted as long as this
+ file is not modified. Modifications are permitted, but only if the
+ resulting file is not named hyphen.tex."
+
+ Software distributed under these licenses is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ licenses for the specific language governing rights and limitations
+ under the licenses.
+
+ See GPL Version 2 below
+
+ See LGPL Version 2.1 below
+
+ See MPL Version 1.1 below
+
+IAccessible2
+
+ The following software may be included in this product: IAccessible2
+ API.
+
+ IAccessible2 IDL Specification
+
+ Copyright (c) 2007, 2013 Linux Foundation
+ Copyright (c) 2006 IBM Corporation
+ Copyright (c) 2000, 2006 Sun Microsystems, Inc.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 1. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the
+ distribution.
+
+ 1. Neither the name of the Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ This BSD License conforms to the Open Source Initiative "Simplified BSD
+ License" as published at:
+ http://www.opensource.org/licenses/bsd-license.php
+
+ IAccessible2 is a trademark of the Linux Foundation. The IAccessible2
+ mark may be used in accordance with the Linux Foundation Trademark
+ Policy to indicate compliance with the IAccessible2 specification.
+
+ Find out more about IAccessible2 at
+ http://accessibility.linuxfoundation.org/.
+
+ICU
+
+ The following software may be included in this product: ICU. Use of any
+ of this software is governed by the terms of the license below:
+
+ ICU License - ICU 1.8.1 and later
+
+ COPYRIGHT AND PERMISSION NOTICE
+
+ Copyright (c) 1995-2002 International Business Machines Corporation and
+ others All rights reserved.
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, and/or sell copies of the Software, and to permit persons
+ to whom the Software is furnished to do so, provided that the above
+ copyright notice(s) and this permission notice appear in all copies of
+ the Software and that both the above copyright notice(s) and this
+ permission notice appear in supporting documentation.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+ OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
+ INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
+ FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ Except as contained in this notice, the name of a copyright holder
+ shall not be used in advertising or otherwise to promote the sale, use
+ or other dealings in this Software without prior written authorization
+ of the copyright holder.
+
+ All trademarks and registered trademarks mentioned herein are the
+ property of their respective owners.
+
+IJG JPEG Library
+
+ The following software may be included in this product: IJG JPEG
+ Library. Use of any of this software is governed by the terms of the
+ license below:
+
+ In plain English:
+ 1. We don't promise that this software works. (But if you find any
+ bugs, please let us know!)
+ 2. You can use this software for whatever you want. You don't have to
+ pay us.
+ 3. You may not pretend that you wrote this software. If you use it in
+ a program, you must acknowledge somewhere in your documentation
+ that you've used the IJG code.
+
+ In legalese:
+
+ The authors make NO WARRANTY or representation, either express or
+ implied, with respect to this software, its quality, accuracy,
+ merchantability, or fitness for a particular purpose. This software is
+ provided "AS IS", and you, its user, assume the entire risk as to its
+ quality and accuracy.
+
+ This software is copyright (C) 1991-1998, Thomas G. Lane. All Rights
+ Reserved except as specified below.
+
+ Permission is hereby granted to use, copy, modify, and distribute this
+ software (or portions thereof) for any purpose, without fee, subject to
+ these conditions: (1) If any part of the source code for this software
+ is distributed, then this README file must be included, with this
+ copyright and no-warranty notice unaltered; and any additions,
+ deletions, or changes to the original files must be clearly indicated
+ in accompanying documentation. (2) If only executable code is
+ distributed, then the accompanying documentation must state that "this
+ software is based in part on the work of the Independent JPEG Group".
+ (3) Permission for use of this software is granted only if the user
+ accepts full responsibility for any undesirable consequences; the
+ authors accept NO LIABILITY for damages of any kind.
+
+ These conditions apply to any software derived from or based on the IJG
+ code, not just to the unmodified library. If you use our work, you
+ ought to acknowledge us.
+
+ Permission is NOT granted for the use of any IJG author's name or
+ company name in advertising or publicity relating to this software or
+ products derived from it. This software may be referred to only as "the
+ Independent JPEG Group's software".
+
+ We specifically permit and encourage the use of this software as the
+ basis of commercial products, provided that all warranty or liability
+ claims are assumed by the product vendor.
+
+ ansi2knr.c is included in this distribution by permission of L. Peter
+ Deutsch, sole proprietor of its copyright holder, Aladdin Enterprises
+ of Menlo Park, CA. ansi2knr.c is NOT covered by the above copyright and
+ conditions, but instead by the usual distribution terms of the Free
+ Software Foundation; principally, that you must include source code if
+ you redistribute it. (See the file ansi2knr.c for full details.)
+ However, since ansi2knr.c is not needed as part of any program
+ generated from the IJG code, this does not limit you more than the
+ foregoing paragraphs do.
+
+ The Unix configuration script "configure" was produced with GNU
+ Autoconf. It is copyright by the Free Software Foundation but is freely
+ distributable. The same holds for its supporting scripts (config.guess,
+ config.sub, ltconfig, ltmain.sh). Another support script, install-sh,
+ is copyright by M.I.T. but is also freely distributable.
+
+ It appears that the arithmetic coding option of the JPEG spec is
+ covered by patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic
+ coding cannot legally be used without obtaining one or more licenses.
+ For this reason, support for arithmetic coding has been removed from
+ the free JPEG software. (Since arithmetic coding provides only a
+ marginal gain over the unpatented Huffman mode, it is unlikely that
+ very many implementations will support it.) So far as we are aware,
+ there are no patent restrictions on the remaining code.
+
+ The IJG distribution formerly included code to read and write GIF
+ files. To avoid entanglement with the Unisys LZW patent, GIF reading
+ support has been removed altogether, and the GIF writer has been
+ simplified to produce "uncompressed GIFs". This technique does not use
+ the LZW algorithm; the resulting GIF files are larger than usual, but
+ are readable by all standard GIF decoders.
+
+ We are required to state that
+
+ "The Graphics Interchange Format(c) is the Copyright property of
+ CompuServe Incorporated. GIF(sm) is a Service Mark property of
+ CompuServe Incorporated."
+
+JDOM
+
+ The following software may be included in this product: JDOM. Use of
+ any of this software is governed by the terms of the license below:
+
+ Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin. All rights
+ reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ 1. Redistribution of source code must retain the above copyright
+ notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistribution in binary form must reproduce the above copyright
+ notice, this list of conditions, and the disclaimer that follows these
+ conditions in the documentation and/or other materials provided with
+ the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+ derived from this software without prior written permission. For
+ written permission, please contact .
+
+ 4. Products derived from this software may not be called "JDOM", nor
+ may "JDOM" appear in their name, without prior written permission from
+ the JDOM Project Management .
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+
+ "This product includes software developed by the JDOM Project
+ (http://www.jdom.org/)."
+
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally created by
+ Jason Hunter and Brett McLaughlin
+ . For more information on the JDOM Project,
+ please see http://www.jdom.org/.
+
+libatomic-ops
+
+ The following software may be included in this product: libatomic-ops.
+ Use of any of this software is governed by the terms of the license
+ below:
+
+ See GPL Version 2 below
+
+libcdr
+
+ The following software may be included in this product: libcdr. Use of
+ any of this software is governed by the terms of the license below:
+
+ MPL 1.1 / LGPL v2+ / GPL v2+
+
+ See GPL Version 2 below
+
+ See LGPL Version 2 below
+
+ See MPL Version 1.1 below
+
+libcmis
+
+ The following software may be included in this product: libcmis. Use of
+ any of this software is governed by the terms of the license below:
+
+ MPL 1.1 / LGPL v2+ / GPL v2+
+
+ See GPL Version 2 below
+
+ See LGPL Version 2 below
+
+ See MPL Version 1.1 below
+
+libcurl
+
+ The following software may be included in this product: libcurl. Use of
+ any of this software is governed by the terms of the license below:
+
+ Copyright (c) 1996 - 2009, Daniel Stenberg, .
+
+ All rights reserved.
+
+ Permission to use, copy, modify, and distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+ OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+
+ Except as contained in this notice, the name of a copyright holder
+ shall not be used in advertising or otherwise to promote the sale, use
+ or other dealings in this Software without prior written authorization
+ of the copyright holder.
+
+libeot
+
+ The following software may be included in this product: libeot. Use of
+ any of this software is governed by the terms of the license below:
+
+ See MPL Version 2 below
+
+libe-book
+
+ The following software may be included in this product: libe-book. Use
+ of any of this software is governed by the terms of the license below:
+
+ LGPL v2.1+ / MPL 2+
+
+ See LGPL Version 2.1 below
+
+ See MPL Version 2 below
+
+libetonyek
+
+ The following software may be included in this product: libetonyek. Use
+ of any of this software is governed by the terms of the license below:
+
+ See MPL Version 2 below
+
+libexttextcat
+
+ The following software may be included in this product: libexttextcat.
+ Use of any of this software is governed by the terms of the license
+ below:
+
+ Copyright (c) 2003, WiseGuys Internet B.V.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ - Redistribution of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ - Redistribution in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of the WiseGuys Internet B.V. nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+libfreehand
+
+ The following software may be included in this product: libfreehand.
+ Use of any of this software is governed by the terms of the license
+ below:
+
+ See MPL Version 2 below
+
+liblangtag
+
+ The following software may be included in this product: liblangtag. Use
+ of any of this software is governed by the terms of the license below:
+
+ See LGPL Version 3 below
+
+libmspub
+
+ The following software may be included in this product: libmspub. Use
+ of any of this software is governed by the terms of the license below:
+
+ MPL 1.1 / LGPL v2+ / GPL v2+
+
+ See GPL Version 2 below
+
+ See LGPL Version 2 below
+
+ See MPL Version 1.1 below
+
+libmwaw
+
+ The following software may be included in this product: libmwaw. Use of
+ any of this software is governed by the terms of the license below:
+
+ LGPL v2.1+ / MPL 2
+
+ See LGPL Version 2.1 below
+
+ See MPL Version 2 below
+
+libodfgen
+
+ The following software may be included in this product: libodfgen. Use
+ of any of this software is governed by the terms of the license below:
+
+ LGPL v2.1+ / MPL 2
+
+ See LGPL Version 2.1 below
+
+ See MPL Version 2 below
+
+liborcus
+
+ The following software may be included in this product: liborcus. Use
+ of any of this software is governed by the terms of the license below:
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+libpng
+
+ The following software may be included in this product: libpng. Use of
+ any of this software is governed by the terms of the license below:
+
+ This copy of the libpng notices is provided for your convenience. In
+ case of
+ any discrepancy between this copy and the notices in the file png.h
+ that is
+ included in the libpng distribution, the latter shall prevail.
+ COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+ If you modify libpng you may insert additional notices immediately
+ following
+ this sentence.
+ This code is released under the libpng license.
+ libpng versions 1.2.6, August 15, 2004, through 1.5.1, February 3,
+ 2011, are
+ Copyright (c) 2004, 2006-2011 Glenn Randers-Pehrson, and are
+ distributed according to the same disclaimer and license as
+ libpng-1.2.5
+ with the following individual added to the list of Contributing Authors
+ Cosmin Truta
+ libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002,
+ are
+ Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
+ distributed according to the same disclaimer and license as
+ libpng-1.0.6
+ with the following individuals added to the list of Contributing
+ Authors
+ Simon-Pierre Cadieux
+ Eric S. Raymond
+ Gilles Vollant
+ and with the following additions to the disclaimer:
+ There is no warranty against interference with your enjoyment of the
+ library or against infringement. There is no warranty that our
+ efforts or the library will fulfill any of your particular purposes
+ or needs. This library is provided with all faults, and the entire
+ risk of satisfactory quality, performance, accuracy, and effort is with
+ the user.
+ libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
+ Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are
+ distributed according to the same disclaimer and license as
+ libpng-0.96,
+ with the following individuals added to the list of Contributing
+ Authors:
+ Tom Lane
+ Glenn Randers-Pehrson
+ Willem van Schaik
+ libpng versions 0.89, June 1996, through 0.96, May 1997, are
+ Copyright (c) 1996, 1997 Andreas Dilger
+ Distributed according to the same disclaimer and license as
+ libpng-0.88,
+ with the following individuals added to the list of Contributing
+ Authors:
+ John Bowler
+ Kevin Bracey
+ Sam Bushell
+ Magnus Holmgren
+ Greg Roelofs
+ Tom Tanner
+ libpng versions 0.5, May 1995, through 0.88, January 1996, are
+ Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ For the purposes of this copyright and license, "Contributing Authors"
+ is defined as the following set of individuals:
+ Andreas Dilger
+ Dave Martindale
+ Guy Eric Schalnat
+ Paul Schmidt
+ Tim Wegner
+ The PNG Reference Library is supplied "AS IS". The Contributing Authors
+ and Group 42, Inc. disclaim all warranties, expressed or implied,
+ including, without limitation, the warranties of merchantability and of
+ fitness for any purpose. The Contributing Authors and Group 42, Inc.
+ assume no liability for direct, indirect, incidental, special,
+ exemplary,
+ or consequential damages, which may result from the use of the PNG
+ Reference Library, even if advised of the possibility of such damage.
+ Permission is hereby granted to use, copy, modify, and distribute this
+ source code, or portions hereof, for any purpose, without fee, subject
+ to the following restrictions:
+ 1. The origin of this source code must not be misrepresented.
+ 2. Altered versions must be plainly marked as such and must not
+ be misrepresented as being the original source.
+ 3. This Copyright notice may not be removed or altered from any
+ source or altered source distribution.
+ The Contributing Authors and Group 42, Inc. specifically permit,
+ without
+ fee, and encourage the use of this source code as a component to
+ supporting the PNG file format in commercial products. If you use this
+ source code in a product, acknowledgment is not required but would be
+ appreciated.
+ A "png_get_copyright" function is available, for convenient use in
+ "about"
+ boxes and the like:
+ printf("%s",png_get_copyright(NULL));
+ Also, the PNG logo (in PNG format, of course) is supplied in the
+ files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+ Libpng is OSI Certified Open Source Software. OSI Certified Open Source
+ is a
+ certification mark of the Open Source Initiative.
+ Glenn Randers-Pehrson
+ glennrp at users.sourceforge.net
+ February 3, 2011
+
+libvisio
+
+ The following software may be included in this product: libvisio. Use
+ of any of this software is governed by the terms of the license below:
+
+ MPL 1.1+ / LGPL v2.1+ / GPL v2+
+
+ See GPL Version 2 below
+
+ See LGPL Version 2.1 below
+
+ See MPL Version 1.1 below
+
+libwpd
+
+ The following software may be included in this product: libwpd. Use of
+ any of this software is governed by the terms of the license below:
+
+ LGPL v2.1+ / MPL 2
+
+ See LGPL Version 2.1 below
+
+ See MPL Version 2 below
+
+libwpg
+
+ The following software may be included in this product: libwpg. Use of
+ any of this software is governed by the terms of the license below:
+
+ LGPL v2.1+ / MPL 2
+
+ See LGPL Version 2.1 below
+
+ See MPL Version 2 below
+
+libwps
+
+ The following software may be included in this product: libwps. Use of
+ any of this software is governed by the terms of the license below:
+
+ LGPL v2.1+ / MPL 2
+
+ See LGPL Version 2.1 below
+
+ See MPL Version 2 below
+
+libxml2
+
+ The following software may be included in this product: libxml2. Use of
+ any of this software is governed by the terms of the license below:
+
+ Except where otherwise noted in the source code (e.g. the files hash.c,
+ list.c and the trio files, which are covered by a similar license but
+ with different Copyright notices) all the files are:
+
+ Copyright (C) 1998-2003 Daniel Veillard. All Rights Reserved.
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FIT- NESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE DANIEL VEILLARD BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- NECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ Except as contained in this notice, the name of Daniel Veillard shall
+ not be used in advertising or otherwise to promote the sale, use or
+ other dealings in this Software without prior written authorization
+ from him.
+
+libxslt
+
+ The following software may be included in this product: libxslt. Use of
+ any of this software is governed by the terms of the license below:
+
+ License for libxslt except libexslt
+
+ Copyright (C) 2001-2002 Daniel Veillard. All Rights Reserved.
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FIT- NESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE DANIEL VEILLARD BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- NECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ Except as contained in this notice, the name of Daniel Veillard shall
+ not be used in advertising or otherwise to promote the sale, use or
+ other dealings in this Software without prior written authorization
+ from him.
+
+ License for libexslt
+
+ Copyright (C) 2001-2002 Thomas Broyer, Charlie Bozeman and Daniel
+ Veillard. All Rights Reserved.
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FIT- NESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CON- NECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ Except as contained in this notice, the name of the authors shall not
+ be used in advertising or otherwise to promote the sale, use or other
+ dealings in this Software without prior written authorization from him.
+
+Little CMS (lcms2)
+
+ The following software may be included in this product: Little CMS
+ (lcms2). Use of any of this software is governed by the terms of the
+ license below:
+
+ Copyright (c) 1998-2011 Marti Maria Saguer
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+lpsolve
+
+ The following software may be included in this product: lpsolve. Use of
+ any of this software is governed by the terms of the license below:
+
+ See LGPL Version 2.1 below
+
+mdds
+
+ The following software may be included in this product: mdds. Use of
+ any of this software is governed by the terms of the license below:
+
+ Copyright (c) 2010 Kohei Yoshida
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Mesa
+
+ The following software may be included in this product: The Mesa 3D
+ Graphics Library. The default Mesa license is as follows:
+
+ Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+
+ Ext headers
+
+ Copyright (c) 2007 The Khronos Group Inc.
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and/or associated documentation files (the
+ "Materials"), to deal in the Materials without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Materials, and to
+ permit persons to whom the Materials are furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Materials.
+
+ THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+
+Microsoft Visual C++ 2010 Runtime Libraries
+
+ The following software may be included in this product: Microsoft
+ Visual C++ 2010 Runtime Libraries. Use of any of this software is
+ governed by the terms of the license below:
+
+ MICROSOFT SOFTWARE LICENSE TERMS
+
+ MICROSOFT VISUAL C++ 2010 RUNTIME LIBRARIES WITH SERVICE PACK 1
+
+ These license terms are an agreement between Microsoft Corporation (or
+ based on where you live, one of its affiliates) and you. Please read
+ them. They apply to the software named above, which includes the media
+ on which you received it, if any. The terms also apply to any Microsoft
+ * updates,
+ * supplements,
+ * Internet-based services, and
+ * support services
+
+ for this software, unless other terms accompany those items. If so,
+ those terms apply.
+
+ BY USING THE SOFTWARE, YOU ACCEPT THESE TERMS. IF YOU DO NOT ACCEPT
+ THEM, DO NOT USE THE SOFTWARE.
+
+ If you comply with these license terms, you have the rights below.
+ 1. INSTALLATION AND USE RIGHTS. You may install and use any number of
+ copies of the software on your devices.
+ 2. SCOPE OF LICENSE. The software is licensed, not sold. This
+ agreement only gives you some rights to use the software. Microsoft
+ reserves all other rights. Unless applicable law gives you more
+ rights despite this limitation, you may use the software only as
+ expressly permitted in this agreement. In doing so, you must comply
+ with any technical limitations in the software that only allow you
+ to use it in certain ways. You may not
+
+ * disclose the results of any benchmark tests of the software to any
+ third party without Microsoft’s prior written approval;
+ * work around any technical limitations in the software;
+ * reverse engineer, decompile or disassemble the software, except and
+ only to the extent that applicable law expressly permits, despite
+ this limitation;
+ * make more copies of the software than specified in this agreement
+ or allowed by applicable law, despite this limitation;
+ * publish the software for others to copy;
+ * rent, lease or lend the software;
+ * transfer the software or this agreement to any third party; or
+ * use the software for commercial software hosting services.
+
+ 3. BACKUP COPY. You may make one backup copy of the software. You may
+ use it only to reinstall the software.
+ 4. DOCUMENTATION. Any person that has valid access to your computer or
+ internal network may copy and use the documentation for your
+ internal, reference purposes.
+ 5. EXPORT RESTRICTIONS. The software is subject to United States
+ export laws and regulations. You must comply with all domestic and
+ international export laws and regulations that apply to the
+ software. These laws include restrictions on destinations, end
+ users and end use. For additional information, see
+ www.microsoft.com/exporting.
+ 6. SUPPORT SERVICES. Because this software is “as is,” we may not
+ provide support services for it.
+ 7. ENTIRE AGREEMENT. This agreement, and the terms for supplements,
+ updates, Internet-based services and support services that you use,
+ are the entire agreement for the software and support services.
+ 8. APPLICABLE LAW.
+
+ a. United States. If you acquired the software in the United States,
+ Washington state law governs the interpretation of this agreement
+ and applies to claims for breach of it, regardless of conflict of
+ laws principles. The laws of the state where you live govern all
+ other claims, including claims under state consumer protection
+ laws, unfair competition laws, and in tort.
+ b. Outside the United States. If you acquired the software in any
+ other country, the laws of that country apply.
+
+ 9. LEGAL EFFECT. This agreement describes certain legal rights. You
+ may have other rights under the laws of your country. You may also
+ have rights with respect to the party from whom you acquired the
+ software. This agreement does not change your rights under the laws
+ of your country if the laws of your country do not permit it to do
+ so.
+ 10. DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED “AS-IS.” YOU BEAR
+ THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES,
+ GUARANTEES OR CONDITIONS. YOU MAY HAVE ADDITIONAL CONSUMER RIGHTS
+ UNDER YOUR LOCAL LAWS WHICH THIS AGREEMENT CANNOT CHANGE. TO THE
+ EXTENT PERMITTED UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ PURPOSE AND NON-INFRINGEMENT.
+ 11. LIMITATION ON AND EXCLUSION OF REMEDIES AND DAMAGES. YOU CAN
+ RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO
+ U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING
+ CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL
+ DAMAGES.
+
+ This limitation applies to
+ * anything related to the software, services, content (including
+ code) on third party Internet sites, or third party programs; and
+ * claims for breach of contract, breach of warranty, guarantee or
+ condition, strict liability, negligence, or other tort to the
+ extent permitted by applicable law.
+
+ It also applies even if Microsoft knew or should have known about the
+ possibility of the damages. The above limitation or exclusion may not
+ apply to you because your country may not allow the exclusion or
+ limitation of incidental, consequential or other damages.
+
+Mozilla
+
+ The following software may be included in this product: Mozilla,
+ Mozilla Address Book, NP SDK. Use of any of this software is governed
+ by the terms of the license below:
+
+ See MPL 1.1 below
+
+MySQL Connector/C++
+
+ The following software may be included in this product:
+ MySQL Connector/C++. Use of any of this software is governed by the
+ terms of the license below:
+
+ Copyright 2007-2008 MySQL AB, 2008-2009 Sun Microsystems Inc.
+
+ See GPL Version 2 below
+
+MyThes
+
+ The following software may be included in this product: MyThes. Use of
+ any of this software is governed by the terms of the license below:
+
+ Copyright 2003 Kevin B. Hendricks, Stratford, Ontario, Canada And
+ Contributors. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ 1. Redistribution of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistribution in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. All modifications to the source code must be clearly marked as such.
+ Binary redistribution based on modified source code must be clearly
+ marked as modified versions in the documentation and/or other materials
+ provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS ``AS
+ IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KEVIN B. HENDRICKS
+ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+neon
+
+ The following software may be included in this product: neon. Use of
+ any of this software is governed by the terms of the license below:
+
+ neon is Copyright (C) 1999-2007 Joe Orton
+ Portions are:
+ Copyright (C) 1999-2000 Tommi Komulainen
+ Copyright (C) 1999-2000 Peter Boos
+ Copyright (C) 1991, 1995, 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 2004 Aleix Conchillo Flaque
+ Copyright (C) 2004 Jiang Lei
+ Copyright (C) 2004-2005 Vladimir Berezniker @
+ http://public.xdi.org/=vmpn
+
+ See LGPL Version 2.1 below
+
+Network Security Services (NSS)
+
+ The following software may be included in this product: Network
+ Security Services (NSS). Use of any of this software is governed by the
+ terms of the license below:
+
+ See MPL 1.1 below
+
+OpenLDAP
+
+ The following software may be included in this product: OpenLDAP. Use
+ of any of this software is governed by the terms of the license below:
+
+ The OpenLDAP Public License
+
+ Version 2.8, 17 August 2003
+
+ Redistribution and use of this software and associated documentation
+ ("Software"), with or without modification, are permitted provided that
+ the following conditions are met:
+ 1. Redistributions in source form must retain copyright statements and
+ notices,
+ 2. Redistributions in binary form must reproduce applicable copyright
+ statements and notices, this list of conditions, and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution, and
+ 3. Redistributions must contain a verbatim copy of this document.
+
+ The OpenLDAP Foundation may revise this license from time to time. Each
+ revision is distinguished by a version number. You may use this
+ Software under terms of this license revision or under the terms of any
+ subsequent revision of the license.
+
+ THIS SOFTWARE IS PROVIDED BY THE OPENLDAP FOUNDATION AND ITS
+ CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ NO EVENT SHALL THE OPENLDAP FOUNDATION, ITS CONTRIBUTORS, OR THE
+ AUTHOR(S) OR OWNER(S) OF THE SOFTWARE BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ The names of the authors and copyright holders must not be used in
+ advertising or otherwise to promote the sale, use or other dealing in
+ this Software without specific, written prior permission. Title to
+ copyright in this Software shall at all times remain with copyright
+ holders.
+
+ OpenLDAP is a registered trademark of the OpenLDAP Foundation.
+
+ Copyright 1999-2003 The OpenLDAP Foundation, Redwood City, California,
+ USA. All Rights Reserved. Permission to copy and distribute verbatim
+ copies of this document is granted.
+
+OpenSSL
+
+ The following software may be included in this product: OpenSSL. Use of
+ any of this software is governed by the terms of the license below:
+
+ The OpenSSL toolkit stays under a dual license, i.e. both the
+ conditions of the OpenSSL License and the original SSLeay license apply
+ to the toolkit.
+
+ See below for the actual license texts. Actually both licenses are
+ BSD-style Open Source licenses. In case of any license issues related
+ to OpenSSL please contact openssl-core@openssl.org.
+
+ OpenSSL License
+
+ Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ 1. Redistribution of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistribution in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the
+ distribution.
+ 3. All advertising materials mentioning features or use of this
+ software must display the following acknowledgment: "This product
+ includes software developed by the OpenSSL Project for use in the
+ OpenSSL Toolkit. (http://www.openssl.org/)"
+ 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used
+ to endorse or promote products derived from this software without
+ prior written permission. For written permission, please contact
+ openssl-core@openssl.org.
+ 5. Products derived from this software may not be called "OpenSSL" nor
+ may "OpenSSL" appear in their names without prior written
+ permission of the OpenSSL Project.
+ 6. Redistribution of any form whatsoever must retain the following
+ acknowledgment: "This product includes software developed by the
+ OpenSSL Project for use in the OpenSSL Toolkit
+ (http://www.openssl.org/)"
+
+ THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ITS
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ This product includes cryptographic software written by Eric Young
+ (eay@cryptsoft.com). This product includes software written by Tim
+ Hudson (tjh@cryptsoft.com).
+
+ Original SSLeay License
+
+ Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) All rights
+ reserved.
+
+ This package is an SSL implementation written by Eric Young
+ (eay@cryptsoft.com).
+ The implementation was written so as to conform with Netscapes SSL.
+
+ This library is free for commercial and non-commercial use as long as
+ the following conditions are aheared to. The following conditions apply
+ to all code found in this distribution, be it the RC4, RSA, lhash, DES,
+ etc., code; not just the SSL code. The SSL documentation included with
+ this distribution is covered by the same copyright terms except that
+ the holder is Tim Hudson (tjh@cryptsoft.com).
+
+ Copyright remains Eric Young's, and as such any Copyright notices in
+ the code are not to be removed. If this package is used in a product,
+ Eric Young should be given attribution as the author of the parts of
+ the library used. This can be in the form of a textual message at
+ program startup or in documentation (online or textual) provided with
+ the package.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ 1. Redistribution of source code must retain the copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistribution in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the
+ distribution.
+ 3. All advertising materials mentioning features or use of this
+ software must display the following acknowledgment: "This product
+ includes cryptographic software written by Eric Young
+ (eay@cryptsoft.com)" The word 'cryptographic' can be left out if
+ the routines from the library being used are not cryptographic
+ related :-).
+ 4. If you include any Windows specific code (or a derivative thereof)
+ from the apps directory (application code) you must include an
+ acknowledgment: "This product includes software written by Tim
+ Hudson (tjh@cryptsoft.com)"
+
+ THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ The license and distribution terms for any publicly available version
+ or derivative of this code cannot be changed. i.e. this code cannot
+ simply be copied and put under another distribution license [including
+ the GNU Public License.]
+
+Pentaho Reporting Flow Engine
+
+ The following software may be included in this product: Pentaho
+ Reporting Flow Engine (including core, flow-engine, libbase, libfonts,
+ libformula, liblayout, libloader, librepository, libserializer, and
+ libxml). Use of any of this software is governed by the terms of the
+ license below:
+
+ See LGPL Version 2.1 below
+
+Pixman
+
+ The following software may be included in this product: Pixman
+ (libpixman). Use of any of this software is governed by the terms of
+ the license below:
+
+ The following is the MIT license, agreed upon by most contributors.
+
+ Copyright holders of new code should use this license statement where
+ possible. They may also add themselves to the list below.
+
+ Copyright 1987, 1988, 1989, 1998 The Open Group
+ Copyright 1987, 1988, 1989 Digital Equipment Corporation
+ Copyright 1999, 2004, 2008 Keith Packard
+ Copyright 2000 SuSE, Inc.
+ Copyright 2000 Keith Packard, member of The XFree86 Project, Inc.
+ Copyright 2004, 2005, 2007, 2008, 2009, 2010 Red Hat, Inc.
+ Copyright 2004 Nicholas Miell
+ Copyright 2005 Lars Knoll & Zack Rusin, Trolltech
+ Copyright 2005 Trolltech AS
+ Copyright 2007 Luca Barbato
+ Copyright 2008 Aaron Plattner, NVIDIA Corporation
+ Copyright 2008 Rodrigo Kumpera
+ Copyright 2008 André Tupinambá
+ Copyright 2008 Mozilla Corporation
+ Copyright 2008 Frederic Plourde
+ Copyright 2009, Oracle and/or its affiliates. All rights reserved.
+ Copyright 2009, 2010 Nokia Corporation
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions: The above copyright notice and this
+ permission notice (including the next paragraph) shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+poppler
+
+ The following software may be included in this product: poppler. Use of
+ any of this software is governed by the terms of the license below:
+
+ See GPL Version 2 below
+
+PostgreSQL
+
+ The following software may be included in this product: PostgreSQL. Use
+ of any of this software is governed by the terms of the license below:
+
+ PostgreSQL is released under the PostgreSQL License, a liberal Open
+ Source license, similar to the BSD or MIT licenses.
+
+ PostgreSQL Database Management System
+ (formerly known as Postgres, then as Postgres95)
+
+ Portions Copyright (c) 1996-2012, The PostgreSQL Global Development
+ Group
+
+ Portions Copyright (c) 1994, The Regents of the University of
+ California
+
+ Permission to use, copy, modify, and distribute this software and its
+ documentation for any purpose, without fee, and without a written
+ agreement is hereby granted, provided that the above copyright notice
+ and this paragraph and the following two paragraphs appear in all
+ copies.
+
+ IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
+ FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
+ INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
+ DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF
+ THE POSSIBILITY OF SUCH DAMAGE.
+
+ THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
+ PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
+ CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ ENHANCEMENTS, OR MODIFICATIONS.
+
+Python
+
+ The following software may be included in this product: Python. Use of
+ any of this software is governed by the terms of the license below:
+
+ PSF LICENSE AGREEMENT FOR PYTHON 2.3
+
+ 1. This LICENSE AGREEMENT is between the Python Software Foundation
+ ("PSF"), and the Individual or Organization ("Licensee") accessing and
+ otherwise using Python 2.3 software in source or binary form and its
+ associated documentation.
+
+ 2. Subject to the terms and conditions of this License Agreement, PSF
+ hereby grants Licensee a nonexclusive, royalty-free, world-wide license
+ to reproduce, analyze, test, perform and/or display publicly, prepare
+ derivative works, distribute, and otherwise use Python 2.3 alone or in
+ any derivative version, provided, however, that PSF's License Agreement
+ and PSF's notice of copyright, i.e., "Copyright (c) 2001, 2002, 2003,
+ 2004 Python Software Foundation; All Rights Reserved" are retained in
+ Python 2.3 alone or in any derivative version prepared by Licensee.
+
+ 3. In the event Licensee prepares a derivative work that is based on or
+ incorporates Python 2.3 or any part thereof, and wants to make the
+ derivative work available to others as provided herein, then Licensee
+ hereby agrees to include in any such work a brief summary of the
+ changes made to Python 2.3.
+
+ 4. PSF is making Python 2.3 available to Licensee on an "AS IS" basis.
+ PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY
+ OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY
+ REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY
+ PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 2.3 WILL NOT INFRINGE ANY
+ THIRD PARTY RIGHTS.
+
+ 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 2.3
+ FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A
+ RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.3, OR
+ ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+ 6. This License Agreement will automatically terminate upon a material
+ breach of its terms and conditions.
+
+ 7. Nothing in this License Agreement shall be deemed to create any
+ relationship of agency, partnership, or joint venture between PSF and
+ Licensee. This License Agreement does not grant permission to use PSF
+ trademarks or trade name in a trademark sense to endorse or promote
+ products or services of Licensee, or any third party.
+
+ 8. By copying, installing or otherwise using Python 2.3, Licensee
+ agrees to be bound by the terms and conditions of this License
+ Agreement.
+
+ BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
+
+ BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
+
+ 1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
+ office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
+ Individual or Organization ("Licensee") accessing and otherwise using
+ this software in source or binary form and its associated documentation
+ ("the Software").
+
+ 2. Subject to the terms and conditions of this BeOpen Python License
+ Agreement, BeOpen hereby grants Licensee a non-exclusive, royalty-free,
+ world-wide license to reproduce, analyze, test, perform and/or display
+ publicly, prepare derivative works, distribute, and otherwise use the
+ Software alone or in any derivative version, provided, however, that
+ the BeOpen Python License is retained in the Software, alone or in any
+ derivative version prepared by Licensee.
+
+ 3. BeOpen is making the Software available to Licensee on an "AS IS"
+ basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+ IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
+ DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+ FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
+ INFRINGE ANY THIRD PARTY RIGHTS.
+
+ 4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
+ SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
+ AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
+ DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+ 5. This License Agreement will automatically terminate upon a material
+ breach of its terms and conditions.
+
+ 6. This License Agreement shall be governed by and interpreted in all
+ respects by the law of the State of California, excluding conflict of
+ law provisions. Nothing in this License Agreement shall be deemed to
+ create any relationship of agency, partnership, or joint venture
+ between BeOpen and Licensee. This License Agreement does not grant
+ permission to use BeOpen trademarks or trade names in a trademark sense
+ to endorse or promote products or services of Licensee, or any third
+ party. As an exception, the "BeOpen Python" logos available at
+ http://www.pythonlabs.com/logos.html may be used according to the
+ permissions granted on that web page.
+
+ 7. By copying, installing or otherwise using the software, Licensee
+ agrees to be bound by the terms and conditions of this License
+ Agreement.
+
+ CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
+
+ 1. This LICENSE AGREEMENT is between the Corporation for National
+ Research Initiatives, having an office at 1895 Preston White Drive,
+ Reston, VA 20191 ("CNRI"), and the Individual or Organization
+ ("Licensee") accessing and otherwise using Python 1.6.1 software in
+ source or binary form and its associated documentation.
+
+ 2. Subject to the terms and conditions of this License Agreement, CNRI
+ hereby grants Licensee a nonexclusive, royalty-free, world-wide license
+ to reproduce, analyze, test, perform and/or display publicly, prepare
+ derivative works, distribute, and otherwise use Python 1.6.1 alone or
+ in any derivative version, provided, however, that CNRI's License
+ Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
+ 1995-2001 Corporation for National Research Initiatives; All Rights
+ Reserved" are retained in Python 1.6.1 alone or in any derivative
+ version prepared by Licensee. Alternately, in lieu of CNRI's License
+ Agreement, Licensee may substitute the following text (omitting the
+ quotes): "Python 1.6.1 is made available subject to the terms and
+ conditions in CNRI's License Agreement. This Agreement together with
+ Python 1.6.1 may be located on the Internet using the following unique,
+ persistent identifier (known as a handle): 1895.22/1013. This Agreement
+ may also be obtained from a proxy server on the Internet using the
+ following URL: http://hdl.handle.net/1895.22/1013".
+
+ 3. In the event Licensee prepares a derivative work that is based on or
+ incorporates Python 1.6.1 or any part thereof, and wants to make the
+ derivative work available to others as provided herein, then Licensee
+ hereby agrees to include in any such work a brief summary of the
+ changes made to Python 1.6.1.
+
+ 4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
+ basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
+ BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND DISCLAIMS ANY
+ REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY
+ PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT INFRINGE
+ ANY THIRD PARTY RIGHTS.
+
+ 5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+ 1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+ A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
+ OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+ 6. This License Agreement will automatically terminate upon a material
+ breach of its terms and conditions.
+
+ 7. This License Agreement shall be governed by the federal intellectual
+ property law of the United States, including without limitation the
+ federal copyright law, and, to the extent such U.S. federal law does
+ not apply, by the law of the Commonwealth of Virginia, excluding
+ Virginia's conflict of law provisions. Notwithstanding the foregoing,
+ with regard to derivative works based on Python 1.6.1 that incorporate
+ non-separable material that was previously distributed under the GNU
+ General Public License (GPL), the law of the Commonwealth of Virginia
+ shall govern this License Agreement only as to issues arising under or
+ with respect to Paragraphs 4, 5, and 7 of this License Agreement.
+ Nothing in this License Agreement shall be deemed to create any
+ relationship of agency, partnership, or joint venture between CNRI and
+ Licensee. This License Agreement does not grant permission to use CNRI
+ trademarks or trade name in a trademark sense to endorse or promote
+ products or services of Licensee, or any third party.
+
+ 8. By clicking on the "ACCEPT" button where indicated, or by copying,
+ installing or otherwise using Python 1.6.1, Licensee agrees to be bound
+ by the terms and conditions of this License Agreement.
+
+ ACCEPT
+
+ CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
+
+ Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
+ The Netherlands. All rights reserved.
+
+ Permission to use, copy, modify, and distribute this software and its
+ documentation for any purpose and without fee is hereby granted,
+ provided that the above copyright notice appear in all copies and that
+ both that copyright notice and this permission notice appear in
+ supporting documentation, and that the name of Stichting Mathematisch
+ Centrum or CWI not be used in advertising or publicity pertaining to
+ distribution of the software without specific, written prior
+ permission.
+
+ STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE FOR
+ ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+Raptor RDF Parser Library
+
+ The following software may be included in this product: Raptor RDF
+ Parser Library. Use of any of this software is governed by the terms of
+ the license below:
+
+ Copyright (C) 2000-2008 David Beckett
+ Copyright (C) 2000-2005 University of Bristol. All Rights
+ Reserved.
+
+ All the licenses below are alternatives and if you select one license,
+ that one alone applies.
+
+ See LGPL Version 2.1 below
+
+ See Apache License Version 2.0 below
+
+Rasqal RDF Query Library
+
+ The following software may be included in this product: Rasqal RDF
+ Query Library. Use of any of this software is governed by the terms of
+ the license below:
+
+ Copyright (C) 2000-2008 David Beckett
+ Copyright (C) 2000-2005 University of Bristol. All Rights
+ Reserved.
+
+ All the licenses below are alternatives and if you select one license,
+ that one alone applies.
+
+ See LGPL Version 2.1 below
+
+ See Apache License Version 2.0 below
+
+Redland RDF Application Framework
+
+ The following software may be included in this product: Redland RDF
+ Application Framework. Use of any of this software is governed by the
+ terms of the license below:
+
+ Copyright (C) 2000-2008 David Beckett
+ Copyright (C) 2000-2005 University of Bristol. All Rights
+ Reserved.
+
+ All the licenses below are alternatives and if you select one license,
+ that one alone applies.
+
+ See LGPL Version 2.1 below
+
+ See Apache License Version 2.0 below
+
+Remote Control Wrapper
+
+ The following software may be included in this product: Remote Control
+ Wrapper. Use of any of this software is governed by the terms of the
+ license below:
+
+ Created by Martin Kahr under a MIT-style license. Copyright (c)
+ 2006/2007 martinkahr.com. All rights reserved.
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Rhino
+
+ The following software may be included in this product: Rhino. Use of
+ any of this software is governed by the terms of the license below:
+
+ See MPL Version 1.1 below
+
+SANE
+
+ The following software may be included in this product: SANE. Use of
+ any of this software is governed by the terms of the license below:
+
+ sane - Scanner Access Now Easy. Copyright (C) 1997-1999 David
+ Mosberger-Tang and Andreas Beck
+
+ This file is part of the SANE package.
+
+ This file is in the public domain. You may use and modify it as you see
+ fit, as long as this copyright message is included and that there is an
+ indication as to what modifications have been made (if any).
+
+ SANE 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.
+
+ This file declares SANE application interface. See the SANE standard
+ for a detailed explanation of the interface.
+
+STLPort
+
+ The following software may be included in this product:STLport. Use of
+ any of this software is governed by the terms of the license below:
+
+ License Agreement
+
+ Boris Fomitchev grants Licensee a non-exclusive, non-transferable,
+ royalty-free license to use STLport and its documentation without fee.
+
+ By downloading, using, or copying STLport or any portion thereof,
+ Licensee agrees to abide by the intellectual property laws and all
+ other applicable laws of the United States of America, and to all of
+ the terms and conditions of this Agreement.
+
+ Licensee shall maintain the following copyright and permission notices
+ on STLport sources and its documentation unchanged:
+
+ Copyright 1999,2000 Boris Fomitchev
+
+ This material is provided "as is", with absolutely no warranty
+ expressed or implied. Any use is at your own risk.
+
+ Permission to use or copy this software for any purpose is hereby
+ granted without fee, provided the above notices are retained on all
+ copies. Permission to modify the code and to distribute modified code
+ is granted, provided the above notices are retained, and a notice that
+ the code was modified is included with the above copyright notice.
+
+ The Licensee may distribute binaries compiled with STLport (whether
+ original or modified) without any royalties or restrictions.
+
+ The Licensee may distribute original or modified STLport sources,
+ provided that:
+ * The conditions indicated in the above permission notice are met;
+ * The following copyright notices are retained when present, and
+ conditions provided in accompanying permission notices are met:
+
+ Copyright 1994 Hewlett-Packard Company
+
+ Copyright 1996,97 Silicon Graphics Computer Systems, Inc.
+
+ Copyright 1997 Moscow Center for SPARC Technology.
+
+ Permission to use, copy, modify, distribute and sell this software
+ and its documentation for any purpose is hereby granted without fee,
+ provided that the above copyright notice appear in all copies and
+ that both that copyright notice and this permission notice appear in
+ supporting documentation. Hewlett-Packard Company makes no
+ representations about the suitability of this software for any
+ purpose. It is provided "as is" without express or implied warranty.
+
+ Permission to use, copy, modify, distribute and sell this software
+ and its documentation for any purpose is hereby granted without fee,
+ provided that the above copyright notice appear in all copies and
+ that both that copyright notice and this permission notice appear in
+ supporting documentation. Silicon Graphics makes no representations
+ about the suitability of this software for any purpose. It is
+ provided "as is" without express or implied warranty.
+
+ Permission to use, copy, modify, distribute and sell this software
+ and its documentation for any purpose is hereby granted without fee,
+ provided that the above copyright notice appear in all copies and
+ that both that copyright notice and this permission notice appear in
+ supporting documentation. Moscow Center for SPARC Technology makes
+ no representations about the suitability of this software for any
+ purpose. It is provided "as is" without express or implied warranty.
+
+TWAIN
+
+ The following software may be included in this product: TWAIN. Use of
+ any of this software is governed by the terms of the license below:
+
+ The TWAIN License
+
+ The TWAIN Working Group grants customer ("Customer") the worldwide,
+ royalty-free, non-exclusive license to reproduce and distribute the
+ software and documentation of the TWAIN toolkit ("TWAIN Toolkit"). The
+ TWAIN Toolkit was designed to be used by third parties to assist them
+ in becoming compliant with the TWAIN standard, but it has not been
+ developed to the standards of a commercial product. Consequently, the
+ TWAIN toolkit is provided AS IS without any warranty. THE TWAIN Working
+ Group disclaims all warranties in the TWAIN toolkit whether implied,
+ express or statutory, including, without limitation, the implied
+ warranties of merchantability, non infringement of third party rights
+ and fitness for a particular purpose. The TWAIN Working Group disclaims
+ all liability for damages, whether direct, indirect, special,
+ incidental, or consequential, arising from the reproduction,
+ distribution, modification, or other use of the TWAIN Toolkit.
+
+ As a condition of this license, Customer agrees to include in software
+ programs based in whole or in part on the TWAIN Toolkit the following
+ provisions in (i) the header or similar file in such software and (ii)
+ prominently in its documentation and to require its sublicensees to
+ include these provisions in similar locations: The TWAIN Toolkit is
+ distributed as is. The developer and distributors of the TWAIN Toolkit
+ expressly disclaim all implied, express or statutory warranties
+ including, without limitation, the implied warranties of
+ merchantability, non infringement of third party rights and fitness for
+ a particular purpose. Neither the developers nor the distributors will
+ be liable for damages, whether direct, indirect, special, incidental,
+ or consequential, as a result of the reproduction, modification,
+ distribution or other use of the TWAIN Toolkit.
+
+Unicode CLDR data repository
+
+ The following software may be included in this product: Unicode's CLDR
+ data repository. Use of any of this software is governed by the terms
+ of the license below:
+
+ Copyright 1991-2005 Unicode, Inc. All rights reserved. Distributed
+ under the Terms of Use in http://www.unicode.org/copyright.html.
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of the Unicode data files and any associated documentation (the
+ "Data Files") or Unicode software and any associated documentation (the
+ "Software") to deal in the Data Files or Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, and/or sell copies of the Data Files or Software,
+ and to permit persons to whom the Data Files or Software are furnished
+ to do so, provided that (a) the above copyright notice(s) and this
+ permission notice appear with all copies of the Data Files or Software,
+ (b) both the above copyright notice(s) and this permission notice
+ appear in associated documentation, and (c) there is clear notice in
+ each modified Data File or in the Software as well as in the
+ documentation associated with the Data File(s) or Software that the
+ data or software has been modified.
+
+ THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF
+ ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT
+ HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR
+ ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR
+ SOFTWARE.
+
+ Except as contained in this notice, the name of a copyright holder
+ shall not be used in advertising or otherwise to promote the sale, use
+ or other dealings in these Data Files or Software without prior written
+ authorization of the copyright holder.
+
+UnixODBC
+
+ The following software may be included in this product: unixODBC. Use
+ of any of this software is governed by the terms of the license below:
+
+ See LGPL Version 2.1 below
+
+vigra
+
+ The following software may be included in this product: vigra. Use of
+ any of this software is governed by the terms of the license below:
+
+ The VIGRA Artistic License
+
+ (modeled after the Perl Artistic License)
+
+ Preamble
+
+ The intent of this document is to state the conditions under which
+ VIGRA may be copied, such that the author maintains some semblance of
+ artistic control over the development of the library, while giving the
+ users of the library the right to use and distribute VIGRA in a
+ more-or-less customary fashion, plus the right to make reasonable
+ modifications.
+
+ Definitions
+
+ "Copyright Holder" of the VIGRA library is Ullrich Koethe, Cognitive
+ Systems Group, University of Hamburg, Germany.
+
+ "Library" refers to the collection of files distributed by the
+ Copyright Holder under the name "VIGRA" (including this LICENSE file
+ and all accompanying documentation), and derivatives of that collection
+ of files created through textual modification.
+
+ "Standard Version" refers to the Library if it has not been modified,
+ or has been modified in accordance with the wishes of the Copyright
+ Holder as specified below.
+
+ "You" is you, if you're thinking about using, copying, modifying or
+ distributing this Library.
+
+ "Freely Available" means that no fee is charged for the item. It also
+ means that recipients of the item may redistribute it under the same
+ conditions they received it.
+
+ "Reasonable copying fee" is whatever you can justify on the basis of
+ media cost, duplication charges, time of people involved, and so on.
+ (You will not be required to justify it to the Copyright Holder, but
+ only to the computing community at large as a market that must bear the
+ fee.)
+
+ License terms
+
+ 1. You may make and give away verbatim copies of the Standard Version
+ of this Library without restriction, provided that you duplicate all of
+ the original copyright notices, this license, and associated
+ disclaimers.
+
+ 2. The Standard Version of the Library may be distributed as part of a
+ collection of software, provided no more than a reasonable copying fee
+ is charged for the software collection.
+
+ 3. You may apply bug fixes and portability fixes derived from the
+ Public Domain or from the Copyright Holder. A Library modified in such
+ a way shall still be considered the Standard Version.
+
+ 4. You may otherwise modify your copy of this Library in any way,
+ provided that you insert a prominent notice in each changed file
+ stating how and when you changed that file, and provided that you do at
+ least ONE of the following:
+
+ a. place your modifications in the Public Domain or otherwise make them
+ Freely Available, for example by allowing the Copyright Holder to
+ include your modifications in the Standard Version of the Library.
+
+ b. use the modified Library only within your corporation or
+ organization.
+
+ c. make other distribution arrangements with the Copyright Holder.
+
+ 5. You may distribute programs which use this Library in object code or
+ executable form without restriction.
+
+ 6. Any object code generated as a result of using this Library does not
+ fall under the copyright of this Library, but belongs to whomever
+ generated it, and may be sold commercially.
+
+ 7. The name of the Copyright Holder or the Library may not be used to
+ endorse or promote products derived from this software without specific
+ prior written permission.
+
+ 8. THIS LIBRARY IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL,
+ INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND OR ANY
+ DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ OR NOT ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR ON ANY THEORY OF
+ LIABILITY ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ OF THIS LIBRARY.
+
+W3C Simple API for CSS (SAC)
+
+ The following software may be included in this product: W3C Simple API
+ for CSS (SAC). Use of any of this software is governed by the terms of
+ the license below:
+
+ W3C IPR SOFTWARE NOTICE
+
+ Copyright © 2002 World Wide Web Consortium, (Massachusetts Institute of
+ Technology, Institut National de Recherche en Informatique et en
+ Automatique, Keio University). All Rights Reserved.
+
+ Note: The original version of the W3C Software Copyright Notice and
+ License could be found at
+ http://www.w3.org/Consortium/Legal/copyright-software-19980720
+
+ Copyright © 1994-2002 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University). All
+ Rights Reserved. http://www.w3.org/Consortium/Legal/
+
+ This W3C work (including software, documents, or other related items)
+ is being provided by the copyright holders under the following license.
+ By obtaining, using and/or copying this work, you (the licensee) agree
+ that you have read, understood, and will comply with the following
+ terms and conditions:
+
+ Permission to use, copy, and modify this software and its
+ documentation, with or without modification, for any purpose and
+ without fee or royalty is hereby granted, provided that you include the
+ following on ALL copies of the software and documentation or portions
+ thereof, including modifications, that you make:
+ 1. The full text of this NOTICE in a location viewable to users of the
+ redistributed or derivative work.
+ 2. Any pre-existing intellectual property disclaimers, notices, or
+ terms and conditions. If none exist, a short notice of the
+ following form (hypertext is preferred, text is permitted) should
+ be used within the body of any redistributed or derivative code:
+ "Copyright © 2002 World Wide Web Consortium,
+ (Massachusetts Institute of Technology, Institut National
+ de Recherche en Informatique et en Automatique, Keio
+ University). All Rights Reserved.
+ http://www.w3.org/Consortium/Legal/"
+ 3. Notice of any changes or modifications to the W3C files, including
+ the date changes were made. (We recommend you provide URIs to the
+ location from which the code is derived.)
+
+ THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT
+ HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED,
+ INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS
+ FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR
+ DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS,
+ TRADEMARKS OR OTHER RIGHTS.
+
+ COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR
+ DOCUMENTATION.
+
+ The name and trademarks of copyright holders may NOT be used in
+ advertising or publicity pertaining to the software without specific,
+ written prior permission. Title to copyright in this software and any
+ associated documentation will at all times remain with copyright
+ holders.
+
+ X11 XRender Extension
+
+ The following software may be included in this product: X11 XRender
+ Extension. Use of any of this software is governed by the terms of the
+ license below:
+
+ Copyright © 2000 SuSE, Inc.
+
+ Permission to use, copy, modify, distribute, and sell this software and
+ its documentation for any purpose is hereby granted without fee,
+ provided that the above copyright notice appear in all copies and that
+ both that copyright notice and this permission notice appear in
+ supporting documentation, and that the name of SuSE not be used in
+ advertising or publicity pertaining to distribution of the software
+ without specific, written prior permission. SuSE makes no
+ representations about the suitability of this software for any purpose.
+ It is provided "as is" without express or implied warranty.
+
+ SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+ SHALL SuSE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES
+ OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ SOFTWARE.
+
+Xalan
+
+ The following software may be included in this product: Xalan. Use of
+ any of this software is governed by the terms of the license below:
+
+ See Apache License Version 2.0 below
+
+XML Security Library (xmlsec)
+
+ The following software may be included in this product: XML Security
+ Library (xmlsec). Use of any of this software is governed by the terms
+ of the license below:
+
+ xmlsec, xmlsec-openssl, xmlsec-gnutls libraries
+
+ Copyright (C) 2002-2003 Aleksey Sanin. All Rights Reserved.
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FIT- NESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE ALEKSEY SANIN BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- NECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ Except as contained in this notice, the name of Aleksey Sanin shall not
+ be used in advertising or otherwise to promote the sale, use or other
+ dealings in this Software without prior written authorization from him.
+
+ xmlsec-nss library
+
+ Copyright (C) 2002-2003 Aleksey Sanin. All Rights Reserved.
+
+ Copyright (c) 2003 America Online, Inc. All rights reserved.
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ Portions of the Software were created using source code and/or APIs
+ governed by the Mozilla Public License (MPL). The MPL is available at
+ http://www.mozilla.org/MPL/MPL-1.1.html. The MPL permits such
+ portions to be distributed with code not governed by MPL, as long as
+ the requirements of MPL are fulfilled for such portions.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FIT- NESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE ALEKSEY SANIN BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- NECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ Except as contained in this notice, the name of Aleksey Sanin shall not
+ be used in advertising or otherwise to promote the sale, use or other
+ dealings in this Software without prior written authorization from him.
+
+XSLT MathML Library
+
+ The following software may be included in this product: XSLT MathML
+ Library. Use of any of this software is governed by the terms of the
+ license below:
+
+ Copyright
+
+ Copyright (C) 2001-2003 Vasil Yaroshevich
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ Except as contained in this notice, the names of individuals credited
+ with contribution to this software shall not be used in advertising or
+ otherwise to promote the sale, use or other dealings in this Software
+ without prior written authorization from the individuals in question.
+
+ Any stylesheet derived from this Software that is publicly distributed
+ will be identified with a different name and the version strings in any
+ derived Software will be changed so that no possibility of confusion
+ between the derived package and this Software will exist.
+
+ Warranty
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL NORMAN WALSH OR ANY OTHER CONTRIBUTOR BE LIABLE FOR
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+ THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+zlib
+
+ The following software may be included in this product: zlib. Use of
+ any of this software is governed by the terms of the license below:
+
+ (C) 1995-2002 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software in
+ a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not
+ be misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source
+ distribution.
+
+ Extensions
+
+ Only third party extensions are listed here whose source code is not in
+ the LibreOffice tree.
+
+Barcode
+
+ The following software may be included in this product: Barcode. Use of
+ any of this software is governed by the terms of the license below:
+
+ Copyright (C) Dániel Darabos and Kálmán Szalai
+
+ This program is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ See GPL Version 3 below
+
+Convert Text to Number
+
+ The following software may be included in this product: Convert Text to
+ Number. Use of any of this software is governed by the terms of the
+ license below:
+
+ Copyright (C) 2008/2009 - Cor Nouws
+
+ See LGPL Version 3 below
+
+OpenOffice.org2GoogleDocs - export & import to Google Docs, Zoho, WebDAV
+
+ The following software may be included in this product:
+ OpenOffice.org2GoogleDocs - export & import to Google Docs, Zoho,
+ WebDAV. Use of any of this software is governed by the terms of the
+ license below:
+
+ Copyright © Przemyslaw Rumik
+
+ See LGPL Version 3 below
+
+Hungarian cross-reference toolbar
+
+ The following software may be included in this product: Hungarian
+ cross-reference toolbar. Use of any of this software is governed by the
+ terms of the license below:
+
+ 2009-2010 (c) László Németh, license: GNU LGPL
+
+ See LGPL Version 3 below
+
+LanguageTool Grammar Checker
+
+ The following software may be included in this product: LanguageTool
+ Grammar Checker. Use of any of this software is governed by the terms
+ of the license below:
+
+ See LGPL Version 3 below
+
+Numbertext
+
+ The following software may be included in this product: Numbertext. Use
+ of any of this software is governed by the terms of the license below:
+
+ License: LGPL/BSD dual-license, 2009-2010 (C) László Németh (nemeth at
+ openoffice dot org)
+
+ Numbertext language data (Soros programs):
+
+ LGPL/BSD dual-license, 2009-2010 (C) László Németh et al. (see AUTHORS)
+
+ Serbian modules:
+
+ CC/LGPL/BSD tri-license, 2009 (C) Goran Rakić (grakic at devbase dot
+ net)
+
+ Note: for full distribution with specifications, IDE and JavaScript
+ implementation, see http://NUMBERTEXT.org
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
+
+ See LGPL Version 3 below
+
+SmART Gallery (Diagram)
+
+ The following software may be included in this product: SmART Gallery
+ (Diagram). Use of any of this software is governed by the terms of the
+ license below:
+
+ Copyright © Tibor Hornyák and OxygenOffice Professional Team -
+ http://ooop.sf.net/
+
+ See LGPL Version 3 below
+
+Solver for Nonlinear Programming
+
+ The following software may be included in this product: Solver for
+ Nonlinear Programming. Use of any of this software is governed by the
+ terms of the license below:
+
+ Copyright 2009 by Sun Microsystems, Inc.
+
+ See LGPL Version 3 below
+
+Typography Toolbar
+
+ The following software may be included in this product: Typography
+ Toolbar. Use of any of this software is governed by the terms of the
+ license below:
+
+ 2009-2010 (c) László Németh, license: GNU LGPL
+
+ See LGPL Version 3 below
+
+Validator
+
+ The following software may be included in this product: Validator. Use
+ of any of this software is governed by the terms of the license below:
+
+ Copyright © Tibor Hornyák and OxygenOffice Professional Team -
+ http://ooop.sf.net/
+
+ See LGPL Version 3 below
+
+WatchWindow
+
+ The following software may be included in this product: WatchWindow.
+ Use of any of this software is governed by the terms of the license
+ below:
+
+ Copyright © Tibor Hornyák and OxygenOffice Professional Team -
+ http://ooop.sf.net/
+
+ See LGPL Version 3 below
+
+ Fonts
+
+Adobe PostScript® AFM files
+
+ The following software may be included in this product: PostScript® AFM
+ Files. Use of any of this software is governed by the terms of the
+ license below:
+
+ Adobe Core 35 AFM Files with 314 Glyph Entries
+
+ This file and the 35 PostScript® AFM files it accompanies may be used,
+ copied, and distributed for any purpose and without charge, with or
+ without modification, provided that all copyright notices are retained;
+ that the AFM files are not distributed without this file; that all
+ modifications to this file or any of the AFM files are prominently
+ noted in the modified file(s); and that this paragraph is not modified.
+ Adobe Systems has no responsibility or obligation to support the use of
+ the AFM files.
+
+Caladea
+
+ Copyright (c) 2012 Huerta Tipografia
+
+ This Font Software is licensed under the Apache License, Version 2.0 as
+ shown below.
+
+ See Apache License Version 2.0 below
+
+Carlito
+
+ Copyright (c) 2010-2013 by tyPoland Lukasz Dziedzic with Reserved Font
+ Name "Carlito".
+
+ This Font Software is licensed under the SIL Open Font License, Version
+ 1.1 as shown below.
+
+ See SIL Open Font License, Version 1.1 below
+
+Deja Vu
+
+ The following software may be included in this product: Deja Vu fonts.
+ Use of any of this software is governed by the terms of the license
+ below:
+
+ Fonts are (c) Bitstream (see below). DejaVu changes are in public
+ domain. Glyphs imported from Arev fonts are (c) Tavmjong Bah (see
+ below)
+
+ Bitstream Vera Fonts Copyright
+
+ Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream
+ Vera is a trademark of Bitstream, Inc.
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of the fonts accompanying this license ("Fonts") and associated
+ documentation files (the "Font Software"), to reproduce and distribute
+ the Font Software, including without limitation the rights to use,
+ copy, merge, publish, distribute, and/or sell copies of the Font
+ Software, and to permit persons to whom the Font Software is furnished
+ to do so, subject to the following conditions:
+
+ The above copyright and trademark notices and this permission notice
+ shall be included in all copies of one or more of the Font Software
+ typefaces.
+
+ The Font Software may be modified, altered, or added to, and in
+ particular the designs of glyphs or characters in the Fonts may be
+ modified and additional glyphs or characters may be added to the Fonts,
+ only if the fonts are renamed to names not containing either the words
+ "Bitstream" or the word "Vera".
+
+ This License becomes null and void to the extent applicable to Fonts or
+ Font Software that has been modified and is distributed under the
+ "Bitstream Vera" names.
+
+ The Font Software may be sold as part of a larger software package but
+ no copy of one or more of the Font Software typefaces may be sold by
+ itself.
+
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL
+ BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL,
+ OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT
+ SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
+
+ Except as contained in this notice, the names of Gnome, the Gnome
+ Foundation, and Bitstream Inc., shall not be used in advertising or
+ otherwise to promote the sale, use or other dealings in this Font
+ Software without prior written authorization from the Gnome Foundation
+ or Bitstream Inc., respectively. For further information, contact:
+ fonts at gnome dot org.
+
+ Arev Fonts Copyright
+
+ Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved.
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of the fonts accompanying this license ("Fonts") and associated
+ documentation files (the "Font Software"), to reproduce and distribute
+ the modifications to the Bitstream Vera Font Software, including
+ without limitation the rights to use, copy, merge, publish, distribute,
+ and/or sell copies of the Font Software, and to permit persons to whom
+ the Font Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright and trademark notices and this permission notice
+ shall be included in all copies of one or more of the Font Software
+ typefaces.
+
+ The Font Software may be modified, altered, or added to, and in
+ particular the designs of glyphs or characters in the Fonts may be
+ modified and additional glyphs or characters may be added to the Fonts,
+ only if the fonts are renamed to names not containing either the words
+ "Tavmjong Bah" or the word "Arev".
+
+ This License becomes null and void to the extent applicable to Fonts or
+ Font Software that has been modified and is distributed under the
+ "Tavmjong Bah Arev" names.
+
+ The Font Software may be sold as part of a larger software package but
+ no copy of one or more of the Font Software typefaces may be sold by
+ itself.
+
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL
+ TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+ OTHER DEALINGS IN THE FONT SOFTWARE.
+
+ Except as contained in this notice, the name of Tavmjong Bah shall not
+ be used in advertising or otherwise to promote the sale, use or other
+ dealings in this Font Software without prior written authorization from
+ Tavmjong Bah. For further information, contact: tavmjong @ free . fr.
+
+Gentium
+
+ The following software may be included in this product: Gentium fonts.
+ Use of any of this software is governed by the terms of the license
+ below:
+
+ Copyright (c) 2003-2008 SIL International (http://www.sil.org/),
+ with Reserved Font Names "Gentium" and "SIL".
+
+ This Font Software is licensed under the SIL Open Font License, Version
+ 1.1. This license is copied below, and is also available with a
+ FAQ at: http://scripts.sil.org/OFL
+
+ See SIL Open Font License, Version 1.1 below
+
+Liberation
+
+ The following software may be included in this product: Liberation
+ fonts. Use of any of this software is governed by the terms of the
+ license below:
+
+ This Font Software is licensed under the SIL Open Font License, Version
+ 1.1. This license is copied below, and is also available with a
+ FAQ at: http://scripts.sil.org/OFL
+
+ See SIL Open Font License, Version 1.1 below
+
+ LICENSE AGREEMENT AND LIMITED PRODUCT WARRANTY
+ LIBERATION FONT SOFTWARE
+
+ This agreement governs the use of the Software and any updates to the
+ Software, regardless of the delivery mechanism. Subject to the
+ following terms, Red Hat, Inc. ("Red Hat") grants to the user
+ ("Client") a license to this work pursuant to the GNU General Public
+ License v.2 with the exceptions set forth below and such other terms as
+ are set forth in this End User License Agreement.
+
+ 1. The Software and License Exception. LIBERATION font software (the
+ "Software") consists of TrueType-OpenType formatted font software for
+ rendering LIBERATION typefaces in sans-serif, serif, and monospaced
+ character styles. You are licensed to use, modify, copy, and distribute
+ the Software pursuant to the GNU General Public License v.2 with the
+ following exceptions:
+
+ (a) As a special exception, if you create a document which uses this
+ font, and embed this font or unaltered portions of this font into the
+ document, this font does not by itself cause the resulting document to
+ be covered by the GNU General Public License. This exception does not
+ however invalidate any other reasons why the document might be covered
+ by the GNU General Public License. If you modify this font, you may
+ extend this exception to your version of the font, but you are not
+ obligated to do so. If you do not wish to do so, delete this exception
+ statement from your version.
+
+ (b) As a further exception, any distribution of the object code of the
+ Software in a physical product must provide you the right to access and
+ modify the source code for the Software and to reinstall that modified
+ version of the Software in object code form on the same physical
+ product on which you received it.
+
+ 2. Intellectual Property Rights. The Software and each of its
+ components, including the source code, documentation, appearance,
+ structure and organization are owned by Red Hat and others and are
+ protected under copyright and other laws. Title to the Software and any
+ component, or to any copy, modification, or merged portion shall remain
+ with the aforementioned, subject to the applicable license. The
+ "LIBERATION" trademark is a trademark of Red Hat, Inc. in the U.S. and
+ other countries. This agreement does not permit Client to distribute
+ modified versions of the Software using Red Hat's trademarks. If Client
+ makes a redistribution of a modified version of the Software, then
+ Client must modify the files names to remove any reference to the Red
+ Hat trademarks and must not use the Red Hat trademarks in any way to
+ reference or promote the modified Software.
+
+ 3. Limited Warranty. To the maximum extent permitted under applicable
+ law, the Software is provided and licensed "as is" without warranty of
+ any kind, expressed or implied, including the implied warranties of
+ merchantability, non-infringement or fitness for a particular purpose.
+ Red Hat does not warrant that the functions contained in the Software
+ will meet Client's requirements or that the operation of the Software
+ will be entirely error free or appear precisely as described in the
+ accompanying documentation.
+
+ 4. Limitation of Remedies and Liability. To the maximum extent
+ permitted by applicable law, Red Hat or any Red Hat authorized dealer
+ will not be liable to Client for any incidental or consequential
+ damages, including lost profits or lost savings arising out of the use
+ or inability to use the Software, even if Red Hat or such dealer has
+ been advised of the possibility of such damages.
+
+ 5. General. If any provision of this agreement is held to be
+ unenforceable, that shall not affect the enforceability of the
+ remaining provisions. This agreement shall be governed by the laws of
+ the State of North Carolina and of the United States, without regard to
+ any conflict of laws provisions, except that the United Nations
+ Convention on the International Sale of Goods shall not apply.
+
+ Copyright © 2007 Red Hat, Inc. All rights reserved. LIBERATION is a
+ trademark of Red Hat, Inc.
+
+Linux Libertine G and Linux Biolinum G
+
+ This Font Software is Copyright (c) 2003-2006, Philipp H. Poll
+ (http://linuxlibertine.sf.net/).
+ All Rights Reserved.
+ "Linux Libertine" is a Reserved Font Name for this Font Software.
+
+ Graphite extension of the original Linux Libertine font was made by
+ Laszlo Nemeth under the same license.
+ Our fonts are free in the sense of the GPL. In short: Changing the font
+ is allowed as long as the derivative work is published under the same
+ license again. Pedantics keep claiming that the embedded use of
+ GPL-fonts in i.e. PDFs requires the free publication of the PDF as
+ well. This is why our GPL contains the so called "font exception".
+
+ See GPL version 2 below
+
+ As a special exception, if you create a document which uses this font,
+ and embed this font or unaltered portions of this font into the
+ document, this font does not by itself cause the resulting document to
+ be covered by the GNU General Public License. This exception does not
+ however invalidate any other reasons why the document might be covered
+ by the GNU General Public License. If you modify this font, you may
+ extend this exception to your version of the font, but you are not
+ obligated to do so. If you do not wish to do so, delete this exception
+ statement from your version.
+
+ Additionally our fonts are licensed under the Open Fonts License (see
+ below).
+
+ This Font Software is licensed under the SIL Open Font License, Version
+ 1.0. No modification of the license is permitted, only verbatim copy is
+ allowed. This license is copied below, and is also available with a FAQ
+ at: http://scripts.sil.org/OFL
+
+ SIL OPEN FONT LICENSE Version 1.0 - 22 November 2005
+
+ PREAMBLE The goals of the Open Font License (OFL) are to stimulate
+ worldwide development of cooperative font projects, to support the font
+ creation efforts of academic and linguistic communities, and to provide
+ an open framework in which fonts may be shared and improved in
+ partnership with others.
+
+ The OFL allows the licensed fonts to be used, studied, modified and
+ redistributed freely as long as they are not sold by themselves. The
+ fonts, including any derivative works, can be bundled, embedded,
+ redistributed and sold with any software provided that the font names
+ of derivative works are changed. The fonts and derivatives, however,
+ cannot be released under any other type of license.
+
+ DEFINITIONS "Font Software" refers to any and all of the following: -
+ font files - data files - source code - build scripts - documentation
+
+ "Reserved Font Name" refers to the Font Software name as seen by users
+ and any other names as specified after the copyright statement.
+
+ "Standard Version" refers to the collection of Font Software components
+ as distributed by the Copyright Holder.
+
+ "Modified Version" refers to any derivative font software made by
+ adding to, deleting, or substituting -- in part or in whole -- any of
+ the components of the Standard Version, by changing formats or by
+ porting the Font Software to a new environment.
+
+ "Author" refers to any designer, engineer, programmer, technical writer
+ or other person who contributed to the Font Software.
+
+ PERMISSION & CONDITIONS Permission is hereby granted, free of charge,
+ to any person obtaining a copy of the Font Software, to use, study,
+ copy, merge, embed, modify, redistribute, and sell modified and
+ unmodified copies of the Font Software, subject to the following
+ conditions:
+
+ 1) Neither the Font Software nor any of its individual components, in
+ Standard or Modified Versions, may be sold by itself.
+
+ 2) Standard or Modified Versions of the Font Software may be bundled,
+ redistributed and sold with any software, provided that each copy
+ contains the above copyright notice and this license. These can be
+ included either as stand-alone text files, human-readable headers or in
+ the appropriate machine-readable metadata fields within text or binary
+ files as long as those fields can be easily viewed by the user.
+
+ 3) No Modified Version of the Font Software may use the Reserved Font
+ Name(s), in part or in whole, unless explicit written permission is
+ granted by the Copyright Holder. This restriction applies to all
+ references stored in the Font Software, such as the font menu name and
+ other font description fields, which are used to differentiate the font
+ from others.
+
+ 4) The name(s) of the Copyright Holder or the Author(s) of the Font
+ Software shall not be used to promote, endorse or advertise any
+ Modified Version, except to acknowledge the contribution(s) of the
+ Copyright Holder and the Author(s) or with their explicit written
+ permission.
+
+ 5) The Font Software, modified or unmodified, in part or in whole, must
+ be distributed using this license, and may not be distributed under any
+ other license.
+
+ TERMINATION This license becomes null and void if any of the above
+ conditions are not met.
+
+ DISCLAIMER THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO
+ EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL,
+ OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT
+ SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
+
+Open Sans
+
+ The following software may be included in this product: Open Sans
+ fonts. Use of any of this software is governed by the terms of the
+ license below:
+
+ See Apache License Version 2.0 below
+
+PT Serif
+
+ The following software may be included in this product: PT Serif fonts.
+ Use of any of this software is governed by the terms of the license
+ below:
+
+ Copyright (c) 2010, ParaType Ltd.
+ (http://www.paratype.com/public), with Reserved Font Names "PT
+ Sans", "PT Serif" and "ParaType".
+
+ This Font Software is licensed under the SIL Open Font License, Version
+ 1.1. This license is copied below, and is also available with a
+ FAQ at: http://scripts.sil.org/OFL
+
+ See SIL Open Font License, Version 1.1 below
+
+Source Code Pro
+
+ The following software may be included in this product: Source Code Pro
+ fonts. Use of any of this software is governed by the terms of the
+ license below:
+
+ Copyright 2010, 2012 Adobe Systems Incorporated
+ (http://www.adobe.com/), with Reserved Font Name 'Source'. All
+ Rights Reserved. Source is a trademark of Adobe Systems Incorporated in
+ the United States and/or other countries.
+
+ This Font Software is licensed under the SIL Open Font License, Version
+ 1.1. This license is copied below, and is also available with a
+ FAQ at: http://scripts.sil.org/OFL
+
+ See SIL Open Font License, Version 1.1 below
+
+Source Sans Pro
+
+ The following software may be included in this product: Source Sans Pro
+ fonts. Use of any of this software is governed by the terms of the
+ license below:
+
+ Copyright 2010, 2012 Adobe Systems Incorporated
+ (http://www.adobe.com/), with Reserved Font Name 'Source'. All
+ Rights Reserved. Source is a trademark of Adobe Systems Incorporated in
+ the United States and/or other countries.
+
+ This Font Software is licensed under the SIL Open Font License, Version
+ 1.1. This license is copied below, and is also available with a
+ FAQ at: http://scripts.sil.org/OFL
+
+ See SIL Open Font License, Version 1.1 below
+
+ Dictionaries
+
+Afrikaans
+
+ Spelling dictionary
+
+ The following software may be included in this product: Afrikaans
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ Afrikaans Wordlist
+
+ The Afrikaans wordlist used by MySpell is made up of multiple
+ wordlists. These are wither in the public domain, are used with the
+ authors permission or are licensed under the LGPL. The majority of
+ the words are derived from the Nieuwoudt and Viljoen list.
+
+ The Nieuwoudt list was first published in this form in 1993 by Bernard
+ A Nieuwoudt. Contact details: origen at icon co za or bnieuwoudt at acm
+ org
+
+ Copyright (C) 1993, 2003 Bernard A Nieuwoudt relicensed under the
+ LGPL.
+
+ The Viljoen list is derived from the original Nieuwoudt list and is
+ used with permission of the author and relicensed under the LGPL.
+
+ Copyright (C) 1998 Danie Viljoen
+
+ MySpell Affix File
+
+ Copyright (C) 2003 Dwayne Bailey under the LGPL based on the
+ original ispell list by Renier de Vos which was released under the BSD
+ license.
+
+ Hyphenation patterns
+
+ The following software may be included in this product: Afrikaans
+ hyphenation patterns. Use of any of this software is governed by the
+ terms of the license below:
+
+ Copyright (C) 2005 Friedel Wolff
+
+ 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.
+
+Arabic
+
+ Spelling dictionary
+
+ The following software may be included in this product: Arabic spelling
+ dictionary. Use of any of this software is governed by the terms of the
+ license below:
+
+ Author of Hunspell-ar, the arabic dictionary for Hunspell
+ (spellchecker): 2006-2008, Mohamed Kebdani, med.kebdani (at) gmail.com
+
+ GPL 2.0/LGPL 2.1/MPL 1.1 tri-license
+
+ The contents of this software may be used under the terms of the GNU
+ General Public License Version 2 or later (the "GPL"), or the GNU
+ Lesser General Public License Version 2.1 or later (the "LGPL") the
+ Mozilla Public License Version 1.1 or later (the "MPL").
+
+ Software distributed under these licenses is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ licenses for the specific language governing rights and limitations
+ under the licenses.
+
+ Thesaurus
+
+ The following software may be included in this product: Arabic
+ thesaurus. Use of any of this software is governed by the terms of the
+ license below:
+
+ 2006-2009, Taha Zerrouki, taha_zerrouki at gawab.com
+
+ GPL 2.0/LGPL 2.1/MPL 1.1 tri-license
+
+ The contents of this software may be used under the terms of the GNU
+ General Public License Version 2 or later (the "GPL"), or the GNU
+ Lesser General Public License Version 2.1 or later (the "LGPL") the
+ Mozilla Public License Version 1.1 or later (the "MPL").
+
+ Software distributed under these licenses is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ licenses for the specific language governing rights and limitations
+ under the licenses.
+
+Aragonese
+
+ Spelling dictionary
+
+ The following software may be included in this product: Aragonese
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ Copyright (c) 2011 Santiago Paricio (spariciogmailcom)
+ Copyright (c) 2011 Juan Pablo Martínez (jpmartunizares)
+
+ MPL1.1/GPLv3+/LGPLv3+ Tri-licence
+
+ Version 0.2 of the wordlist (an_ES.dic) has been built using free
+ corpuses have been used as Wikipedia in Aragonese
+ (http://an.wikipedia.org) and wordlists obtained from Apertium
+ dictionaries
+ (http://apertium.svn.sourceforge.net/viewvc/apertium/tags/apertium
+ -es-an/release-2.0/).
+
+Belarusian
+
+ Spelling dictionary
+
+ The following software may be included in this product: Belarusian
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ Creative Commons CC-BY-SA
+
+ Author: Mikalai Udodau
+ Origin: Словазбор аўтарскі; арфаграфія паводле ТСБМ-2005
+
+Bengali
+
+ Spelling dictionary
+
+ The following software may be included in this product: Bengali
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ See GNU GPL version 2.0 below
+
+Breton
+
+ Spelling dictionary
+
+ The following software may be included in this product: Breton spelling
+ dictionary. Use of any of this software is governed by the terms of the
+ license below:
+
+ LICENSE: "An Drouizig" spelling dictionary: LGPL
+
+Bulgarian
+
+ Spelling dictionary
+
+ The following software may be included in this product: Bulgarian
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ See GNU GPL version 2.0 below
+
+ Hyphenation patterns
+
+ The following software may be included in this product: Bulgarian
+ hyphenation patterns. Use of any of this software is governed by the
+ terms of the license below:
+
+ Copyright (C) 2001 Anton Zinoviev and Borislav Mitev
+ Maintained by Radostin Radnev
+
+ See GNU GPL version 2.0 below
+
+ Thesaurus
+
+ The following software may be included in this product: Bulgarian
+ thesaurus. Use of any of this software is governed by the terms of the
+ license below:
+
+ Copyright (C) 2001 Radostin Radnev
+
+ See GNU GPL version 2.0 below
+
+Catalan
+
+ Spelling dictionary
+
+ The following software may be included in this product: Catalan
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ Copyright (C) 2002-2008 Joan Moratinos
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version. This program is distributed in the hope that
+ it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ See the GNU General Public License for more details. You should have
+ received a copy of the GNU General Public License along with this
+ program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ See GPL version 3 below
+
+ Hyphenation patterns
+
+ The following software may be included in this product: Catalan
+ hyphenation patterns. Use of any of this software is governed by the
+ terms of the license below:
+
+ See GPL version 3 below
+
+ Thesaurus
+
+ The following software may be included in this product: Catalan
+ thesaurus. Use of any of this software is governed by the terms of the
+ license below:
+
+ Copyright (C) 2009 Joan Montané --- Softcatalà
+
+ License: GPL/LGPL
+
+ See GPL version 3 below
+
+ See LGPL version 3 below
+
+Czech
+
+ Thesaurus
+
+ The following software may be included in this product: Czech
+ thesaurus. Use of any of this software is governed by the terms of the
+ license below:
+
+ Copyright (c) 2002 Pavel Rychly, Pavel Smrz, {pary,smrz}@fi.muni.cz,
+ NLPlab, Faculty of Informatics, Masaryk University
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this data (the "Data"), to deal in the Data without
+ restriction, including without limitation the rights to use, copy,
+ modify, merge, publish, distribute, sublicense, and/or sell copies of
+ the Data, and to permit persons to whom the Data is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Data.
+
+ THE DATA ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE DATA
+ OR THE USE OR OTHER DEALINGS IN THE DATA.
+
+Croatian
+
+ Spelling dictionary
+
+ The following software may be included in this product: Croatian
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ See LGPL Version 2.1 below
+
+ Hyphenation patterns
+
+ The following software may be included in this product: Croatian
+ hyphenation patterns. Use of any of this software is governed by the
+ terms of the license below:
+
+ These patterns were manually converted from TeX hyphenation patterns
+ using the guide at
+ http://wiki.services.openoffice.org/wiki/Documentation/SL/Using_Te
+ X_hyphenation_patterns_in_OpenOffice.org
+
+ Original version:
+ http://tug.org/svn/texhyphen/trunk/hyph-utf8/tex/generic/hyph-utf8
+ /patterns/txt/hyph-hr.pat.txt?revision=416
+
+ License: OpenOffice.org adaption of this file is licensed under the GNU
+ LGPL license.
+
+ See LGPL Version 2.1 below
+
+ Original license text: This file is part of hyph-utf8 package and
+ resulted from semi-manual conversions of hyphenation patterns into
+ UTF-8 in June 2008.
+
+ Source: hrhyph.tex (1996-04-10) Author: Marinović Igor
+
+ The above mentioned file should become obsolete, and the author of the
+ original file should preferably modify this file instead.
+
+ Modifications were needed in order to support native UTF-8 engines, but
+ functionality (hopefully) didn't change in any way, at least not
+ intentionally. This file is no longer stand-alone; at least for 8-bit
+ engines you probably want to use loadhyph-foo.tex (which will load this
+ file) instead.
+
+ Modifications were done by Jonathan Kew, Mojca Miklavec & Arthur
+ Reutenauer with help & support from: - Karl Berry, who gave us free
+ hands and all resources - Taco Hoekwater, with useful macros - Hans
+ Hagen, who did the unicodifisation of patterns already long before and
+ helped with testing, suggestions and bug reports - Norbert Preining,
+ who tested & integrated patterns into TeX Live
+
+ However, the "copyright/copyleft" owner of patterns remains the
+ original author.
+
+ The copyright statement of this file is thus:
+
+ Do with this file whatever needs to be done in future for the sake of
+ "a better world" as long as you respect the copyright of original file.
+ If you're the original author of patterns or taking over a new
+ revolution, please remove all of the TUG comments & credits that we
+ added here - you are the Queen / the King, we are only the servants.
+
+ If you want to change this file, rather than uploading directly to
+ CTAN, we would be grateful if you could send it to us
+ (http://tug.org/tex-hyphen) or ask for credentials for SVN
+ repository and commit it yourself; we will then upload the whole
+ "package" to CTAN.
+
+ Before a new "pattern-revolution" starts, please try to follow some
+ guidelines if possible:
+
+ - \lccode is *forbidden*, and I really mean it - all the patterns
+ should be in UTF-8 - the only "allowed" TeX commands in this file are:
+ \patterns, \hyphenation, and if you really cannot do without, also
+ \input and \message - in particular, please no \catcode or \lccode
+ changes, they belong to loadhyph-foo.tex, and no \lefthyphenmin and
+ \righthyphenmin, they have no influence here and belong elsewhere -
+ \begingroup and/or \endinput is not needed - feel free to do whatever
+ you want inside comments
+
+ We know that TeX is extremely powerful, but give a stupid parser at
+ least a chance to read your patterns.
+
+ For more information see http://tug.org/tex-hyphen
+
+Danish
+
+ Spelling dictionary
+
+ The following software may be included in this product: Danish spelling
+ dictionary. Use of any of this software is governed by the terms of the
+ license below:
+
+ Stavekontrolden - Danish dictionary files for Hunspell
+
+ Version 1.6 - 2010-09-19
+
+ da_DK.dic, da_DK.aff: © 2010 Foreningen for frit tilgængelige
+ sprogværktøjer
+
+ http://www.stavekontrolden.dk
+
+ These files are published under the following open source licenses:
+ * GNU GPL version 2.0
+ * GNU LGPL version 2.1
+ * Mozilla MPL version 1.1
+
+ This dictionary is based on data from Det Danske Sprog- og
+ Litteraturselskab
+
+ (The Danish Society for Language and Literature),
+ http://www.dsl.dk.
+
+ Hyphenation patterns
+
+ The following software may be included in this product: Danish
+ hyphenation patterns. Use of any of this software is governed by the
+ terms of the license below:
+
+ Thesaurus
+
+ The following software may be included in this product: Danish
+ thesaurus. Use of any of this software is governed by the terms of the
+ license below:
+ * GNU GPL version 2.0
+ * GNU LGPL version 2.1
+ * Mozilla MPL version 1.1
+
+ Stavekontrolden - Danish thesaurus files for OpenOffice.org 3.0.
+
+ Den Danske Ordbog - Synonymer
+
+ DanNet - leksikalsk-semantisk ordnet fra Det Danske Sprog- og
+ Litteraturselskab og Center for Sprogteknologi, Københavns Universitet
+
+ © 2007 Foreningen for frit tilgængelige sprogværktøjer
+
+Dutch
+
+ Spelling dictionary and hyphenation patterns
+
+ The following software may be included in this product: Dutch spelling
+ dictionary and hyphenation patterns. Use of any of this software is
+ governed by the terms of the license below:
+
+ 1. Name: Dutch word list for spell checking - OpenTaal
+
+ 2. Version of words list: 2.10G; version of spell checking: 2.10G.
+
+ 3. Requirements: Hunspell 1.2.8 and higher
+
+ 4. Spelling Seal of Dutch Language Union: The OpenTaal list of lemmas
+ has received the Spelling Seal of Approval from the Dutch Language
+ Union, the formal Dutch language institute. For more information please
+ see: http://www.taalunieversum.org/keurmerk/
+
+ 5. Copyrights: © 2006-2010 OpenTaal, © 2001-2005 Simon Brouwer e.a., ©
+ 1996 Nederlandstalige Tex Gebruikersgroep
+
+ 6. Licenses: OpenTaal aims to create and publish free Dutch language
+ files. To enable the broadest (re)use the language files are freely
+ available under the below, liberal licenses at the discretion of the
+ user. We strongly recommend to read the applicable license before
+ usage.
+
+ A. BSD (revised version):
+
+ - Full license text:
+ http://creativecommons.org/licenses/BSD/legalcode
+
+ - Summary: http://creativecommons.org/licenses/BSD/deed.en
+
+ B. Creative Commons, Attribution 3.0 (unported)
+
+ - Full license text:
+ http://creativecommons.org/licenses/by/3.0/legalcode
+
+ - Summary: http://creativecommons.org/licenses/by/3.0/deed.en
+
+ 7. Support OpenTaal: OpenTaal is a non-profit volunteer project. With
+ your (small) financial support OpenTaal will further expand its
+ activities and enhance its professionalism. Your donation is welcome at
+ account number: 15.62.32.782, BIC: RABONL2U, IBAN: NL88RABO0156232782
+ of Stichting OpenTaal / OpenTaal Foundation. In the Netherlands your
+ donations are tax deductible. OpenTaal Foundation has been designated
+ by the Dutch Tax Administration as an Institution for General Benefit
+ (algemeen nut beogende instelling or ANBI). Please see:
+ http://belastingdienst.nl/anbi/
+
+ 8. Participate: Everyone is welcome to participate. Please give
+ feedback, discuss on the mailing list or run Harvester. By contributing
+ to the project you agree that your contribution is available under free
+ or/open source licenses. In case you wish, your name will be mentioned
+ on the website. Your are invited to send us your written request.
+
+ 9. Rights of third parties: OpenTaal respects the rights of third
+ parties and aims to keep its data freely available. Therefore you may
+ no use protected sources of third parties, i.e. dictionaries, without
+ their permission when you contribute to the project. It is permitted to
+ use the materials of the Dutch Language Union, i.e. their spelling
+ instruction and word list. In case you believe OpenTaal is violating
+ your rights, we ask you to send us a written notice as soon as
+ possible.
+
+ 10.Contact: OpenTaal Foundation, http://www.opentaal.org,
+ bestuur@opentaal.org
+
+German
+
+ Spelling dictionary
+
+ The following software may be included in this product: German spelling
+ dictionary. Use of any of this software is governed by the terms of the
+ license below:
+
+ Author: Franz Michael Baumann
+
+ License: GNU GPL Version 2 or GPL Version 3 or OASIS 0.1
+
+ The "frami"-dictionary contains the complete word list of Björn Jacke's
+ "igerman98"
+
+ (Version: 2011-03-21) and numerous supplements by Franz Michael Baumann
+ according to the reform of 2006-08-01.
+
+ OASIS distribution license agreement 0.1 from 2005-11-10
+
+ Without any modifications this dictionary may be distributed with
+ programs that support the OASIS Open Document Format for Office
+ Applications and whose PRIMARY format for saving documents is the Open
+ Document Format.
+
+ This requires that all licenses and copyright files are also
+ distributed together with the package the dictionary is shipped with.
+
+ Any modifications of the dictionary files are not allowed for this
+ agreement, modifications require the use of the GNU GENERAL PUBLIC
+ LICENSE.
+
+ If you have questions or don't get along with this, send me your
+ comments/questions/ideas to Bjoern Jacke
+
+ See GPL version 3 below
+
+ See GPL version 2 below
+
+ Hyphenation patterns
+
+ The following software may be included in this product: German
+ hyphenation patterns. Use of any of this software is governed by the
+ terms of the license below:
+
+ Authors: Marco Huggenberger / Daniel Naber
+
+ Version: 2011-05-05 (author and license information in source file
+ added)
+
+ License: GNU LGPL
+
+ See LGPL Version 2.1 below
+
+ Thesaurus
+
+ The following software may be included in this product: German
+ thesaurus. Use of any of this software is governed by the terms of the
+ license below:
+
+ OpenThesaurus - Deutscher Thesaurus - Synonyme und Assoziationen
+
+ Version: 2011-05-04 AT
+
+ License: GNU LGPL
+
+ See LGPL Version 2.1 below
+
+Greek
+
+ Spelling dictionary
+
+ The following software may be included in this product: Greek spelling
+ dictionary. Use of any of this software is governed by the terms of the
+ license below:
+
+ GPL 2.0/LGPL 2.1/MPL 1.1 tri-license
+
+ Hyphenation patterns
+
+ The following software may be included in this product: Greek
+ hyphenation patterns. Use of any of this software is governed by the
+ terms of the license below:
+
+ See LGPL Version 2.1 below
+
+English (Australia)
+
+ Spelling dictionary
+
+ The following software may be included in this product: English
+ (Australia) spelling dictionary. Use of any of this software is
+ governed by the terms of the license below:
+
+ Copyright (C) 2006 Cameron Roy
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ See GPL version 2 below
+
+English (Canada)
+
+ Spelling dictionary
+
+ The following software may be included in this product: English
+ (Canada) spelling dictionary. Use of any of this software is governed
+ by the terms of the license below:
+Wordlist en_CA spelling and morphological dictionary for OpenOffice.org
+Version 2008-12-18
+
+Based on Wordlist Hunspell dictionaries version 2008-12-05
+and Wordlist POS and AGID data created by Kevin Atkinson
+and released on http://wordlist.sourceforge.net.
+
+Other fixes:
+
+OOo Issue 48060 - add numbers with affixes by COMPOUNDRULE (1st, 111th, 1990s et
+c.)
+New REP items (better suggestions for accented words and a few mistakes)
+OOo Issue 63541 - remove *dessicated, *dessication
+
+László Németh
+
+Original license:
+
+2008-12-05 Release
+
+README file for en_US and en_CA Hunspell dictionaries
+
+These dictionaries are created using the speller/make-hunspell-dict
+dictionary in SCOWL, SVN revision 74.
+
+The NOSUGGEST flag was added to certain taboo words. While I made an
+honest attempt to flag the strongest taboo words with the NOSUGGEST
+flag, I MAKE NO GUARANTEE THAT I FLAGGED EVERY POSSIBLE TABOO WORD.
+The list was originally derived from Németh László, however I removed
+some words which, while being considered taboo by some dictionaries,
+are not really considered swear words in today's society.
+
+You can find SCOWL and friend at http://wordlist.sourceforge.net/.
+Bug reports should go to the Issue Tracker found on the previously
+mentioned web site. General discussion should go to the
+wordlist-devel at sourceforge net mailing list.
+
+COPYRIGHT, SOURCES, and CREDITS:
+
+The en_US and en_CA dictionaries come directly from SCOWL (up to level
+60) and is thus under the same copyright of SCOWL. The affix file is
+a heavily modified version of the original english.aff file which was
+released as part of Geoff Kuenning's Ispell and as such is covered by
+his BSD license. Part of SCOWL is also based on Ispell thus the
+Ispell copyright is included with the SCOWL copyright.
+
+The collective work is Copyright 2000-2007 by Kevin Atkinson as well
+as any of the copyrights mentioned below:
+
+ Copyright 2000-2007 by Kevin Atkinson
+
+ Permission to use, copy, modify, distribute and sell these word
+ lists, the associated scripts, the output created from the scripts,
+ and its documentation for any purpose is hereby granted without fee,
+ provided that the above copyright notice appears in all copies and
+ that both that copyright notice and this permission notice appear in
+ supporting documentation. Kevin Atkinson makes no representations
+ about the suitability of this array for any purpose. It is provided
+ "as is" without express or implied warranty.
+
+Alan Beale also deserves special credit as he has,
+in addition to providing the 12Dicts package and being a major
+contributor to the ENABLE word list, given me an incredible amount of
+feedback and created a number of special lists (those found in the
+Supplement) in order to help improve the overall quality of SCOWL.
+
+The 10 level includes the 1000 most common English words (according to
+the Moby (TM) Words II [MWords] package), a subset of the 1000 most
+common words on the Internet (again, according to Moby Words II), and
+frequently class 16 from Brian Kelk's "UK English Wordlist
+with Frequency Classification".
+
+The MWords package was explicitly placed in the public domain:
+
+ The Moby lexicon project is complete and has
+ been place into the public domain. Use, sell,
+ rework, excerpt and use in any way on any platform.
+
+ Placing this material on internal or public servers is
+ also encouraged. The compiler is not aware of any
+ export restrictions so freely distribute world-wide.
+
+ You can verify the public domain status by contacting
+
+ Grady Ward
+ 3449 Martha Ct.
+ Arcata, CA 95521-4884
+
+ grady@netcom.com
+ grady@northcoast.com
+
+The "UK English Wordlist With Frequency Classification" is also in the
+Public Domain:
+
+ Date: Sat, 08 Jul 2000 20:27:21 +0100
+ From: Brian Kelk
+
+ > I was wondering what the copyright status of your "UK English
+ > Wordlist With Frequency Classification" word list as it seems to
+ > be lacking any copyright notice.
+
+ There were many many sources in total, but any text marked
+ "copyright" was avoided. Locally-written documentation was one
+ source. An earlier version of the list resided in a filespace called
+ PUBLIC on the University mainframe, because it was considered public
+ domain.
+
+ Date: Tue, 11 Jul 2000 19:31:34 +0100
+
+ > So are you saying your word list is also in the public domain?
+
+ That is the intention.
+
+The 20 level includes frequency classes 7-15 from Brian's word list.
+
+The 35 level includes frequency classes 2-6 and words appearing in at
+least 11 of 12 dictionaries as indicated in the 12Dicts package. All
+words from the 12Dicts package have had likely inflections added via
+my inflection database.
+
+The 12Dicts package and Supplement is in the Public Domain.
+
+The WordNet database, which was used in the creation of the
+Inflections database, is under the following copyright:
+
+ This software and database is being provided to you, the LICENSEE,
+ by Princeton University under the following license. By obtaining,
+ using and/or copying this software and database, you agree that you
+ have read, understood, and will comply with these terms and
+ conditions.:
+
+ Permission to use, copy, modify and distribute this software and
+ database and its documentation for any purpose and without fee or
+ royalty is hereby granted, provided that you agree to comply with
+ the following copyright notice and statements, including the
+ disclaimer, and that the same appear on ALL copies of the software,
+ database and documentation, including modifications that you make
+ for internal use or for distribution.
+
+ WordNet 1.6 Copyright 1997 by Princeton University. All rights
+ reserved.
+
+ THIS SOFTWARE AND DATABASE IS PROVIDED "AS IS" AND PRINCETON
+ UNIVERSITY MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+ IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PRINCETON
+ UNIVERSITY MAKES NO REPRESENTATIONS OR WARRANTIES OF MERCHANT-
+ ABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE
+ LICENSED SOFTWARE, DATABASE OR DOCUMENTATION WILL NOT INFRINGE ANY
+ THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+
+ The name of Princeton University or Princeton may not be used in
+ advertising or publicity pertaining to distribution of the software
+ and/or database. Title to copyright in this software, database and
+ any associated documentation shall at all times remain with
+ Princeton University and LICENSEE agrees to preserve same.
+
+The 40 level includes words from Alan's 3esl list found in version 4.0
+of his 12dicts package. Like his other stuff the 3esl list is also in the
+public domain.
+
+The 50 level includes Brian's frequency class 1, words words appearing
+in at least 5 of 12 of the dictionaries as indicated in the 12Dicts
+package, and uppercase words in at least 4 of the previous 12
+dictionaries. A decent number of proper names is also included: The
+top 1000 male, female, and Last names from the 1990 Census report; a
+list of names sent to me by Alan Beale; and a few names that I added
+myself. Finally a small list of abbreviations not commonly found in
+other word lists is included.
+
+The name files form the Census report is a government document which I
+don't think can be copyrighted.
+
+The file special-jargon.50 uses common.lst and word.lst from the
+"Unofficial Jargon File Word Lists" which is derived from "The Jargon
+File". All of which is in the Public Domain. This file also contain
+a few extra UNIX terms which are found in the file "unix-terms" in the
+special/ directory.
+
+The 55 level includes words from Alan's 2of4brif list found in version
+4.0 of his 12dicts package. Like his other stuff the 2of4brif is also
+in the public domain.
+
+The 60 level includes Brian's frequency class 0 and all words
+appearing in at least 2 of the 12 dictionaries as indicated by the
+12Dicts package. A large number of names are also included: The 4,946
+female names and the 3,897 male names from the MWords package.
+
+The 70 level includes the 74,550 common dictionary words and the
+21,986 names list from the MWords package The common dictionary words,
+like those from the 12Dicts package, have had all likely inflections
+added. The 70 level also included the 5desk list from version 4.0 of
+the 12Dics package which is the public domain
+
+The 80 level includes the ENABLE word list, all the lists in the
+ENABLE supplement package (except for ABLE), the "UK Advanced Cryptics
+Dictionary" (UKACD), the list of signature words in from YAWL package,
+and the 10,196 places list from the MWords package.
+
+The ENABLE package, mainted by M\Cooper ,
+is in the Public Domain:
+
+ The ENABLE master word list, WORD.LST, is herewith formally released
+ into the Public Domain. Anyone is free to use it or distribute it in
+ any manner they see fit. No fee or registration is required for its
+ use nor are "contributions" solicited (if you feel you absolutely
+ must contribute something for your own peace of mind, the authors of
+ the ENABLE list ask that you make a donation on their behalf to your
+ favorite charity). This word list is our gift to the Scrabble
+ community, as an alternate to "official" word lists. Game designers
+ may feel free to incorporate the WORD.LST into their games. Please
+ mention the source and credit us as originators of the list. Note
+ that if you, as a game designer, use the WORD.LST in your product,
+ you may still copyright and protect your product, but you may *not*
+ legally copyright or in any way restrict redistribution of the
+ WORD.LST portion of your product. This *may* under law restrict your
+ rights to restrict your users' rights, but that is only fair.
+
+UKACD, by J Ross Beresford , is under the
+following copyright:
+
+ Copyright (c) J Ross Beresford 1993-1999. All Rights Reserved.
+
+ The following restriction is placed on the use of this publication:
+ if The UK Advanced Cryptics Dictionary is used in a software package
+ or redistributed in any form, the copyright notice must be
+ prominently displayed and the text of this document must be included
+ verbatim.
+
+ There are no other restrictions: I would like to see the list
+ distributed as widely as possible.
+
+The 95 level includes the 354,984 single words and 256,772 compound
+words from the MWords package, ABLE.LST from the ENABLE Supplement,
+and some additional words found in my part-of-speech database that
+were not found anywhere else.
+
+Accent information was taken from UKACD.
+
+My VARCON package was used to create the American, British, and
+Canadian word list.
+
+Since the original word lists used used in the VARCON package came
+from the Ispell distribution they are under the Ispell copyright:
+
+ Copyright 1993, Geoff Kuenning, Granada Hills, CA
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistribution of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistribution in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. All modifications to the source code must be clearly marked as
+ such. Binary redistribution based on modified source code
+ must be clearly marked as modified versions in the documentation
+ and/or other materials provided with the distribution.
+ (clause 4 removed with permission from Geoff Kuenning)
+ 5. The name of Geoff Kuenning may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY GEOFF KUENNING AND CONTRIBUTORS ``AS
+ IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GEOFF
+ KUENNING OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+English (South Africa)
+
+ Spelling dictionary
+
+ The following software may be included in this product: English (South
+ Africa) spelling dictionary. Use of any of this software is governed by
+ the terms of the license below:
+
+ See LGPL Version 2.1 below
+
+English (United Kingdom)
+
+ Spelling dictionary
+
+ The following software may be included in this product: English (United
+ Kingdom) spelling dictionary. Use of any of this software is governed
+ by the terms of the license below:
+
+ See LGPL Version 2.1 below
+
+ Hyphenation patterns
+
+ The following software may be included in this product: English (United
+ Kingdom) hyphenation patterns. Use of any of this software is governed
+ by the terms of the license below:
+
+ BSD-style. Unlimited copying, redistribution and modification of this
+ file is permitted with this copyright and license information.
+
+English (USA)
+
+ Spelling dictionary
+
+ The following software may be included in this product: English (USA)
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ See English (Canada).
+
+ Hyphenation patterns
+
+ The following software may be included in this product: English (USA)
+ hyphenation patterns. Use of any of this software is governed by the
+ terms of the license below:
+
+ BSD-style. Unlimited copying, redistribution and modification of this
+ file
+ is permitted with this copyright and license information.
+
+ Thesaurus
+
+ The following software may be included in this product: English (USA)
+ thesaurus. Use of any of this software is governed by the terms of the
+ license below:
+
+ WordNet Release 2.1
+
+ This software and database is being provided to you, the LICENSEE, by
+ Princeton University under the following license. By obtaining, using
+ and/or copying this software and database, you agree that you have
+ read, understood, and will comply with these terms and conditions.:
+
+ Permission to use, copy, modify and distribute this software and
+ database and its documentation for any purpose and without fee or
+ royalty is hereby granted, provided that you agree to comply with the
+ following copyright notice and statements, including the disclaimer,
+ and that the same appear on ALL copies of the software, database and
+ documentation, including modifications that you make for internal use
+ or for distribution.
+
+ WordNet 2.1 Copyright 2005 by Princeton University. All rights
+ reserved.
+
+ THIS SOFTWARE AND DATABASE IS PROVIDED "AS IS" AND PRINCETON UNIVERSITY
+ MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF
+ EXAMPLE, BUT NOT LIMITATION, PRINCETON UNIVERSITY MAKES NO
+ REPRESENTATIONS OR WARRANTIES OF MERCHANT- ABILITY OR FITNESS FOR ANY
+ PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE, DATABASE
+ OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS,
+ TRADEMARKS OR OTHER RIGHTS.
+
+ The name of Princeton University or Princeton may not be used in
+ advertising or publicity pertaining to distribution of the software
+ and/or database. Title to copyright in this software, database and any
+ associated documentation shall at all times remain with Princeton
+ University and LICENSEE agrees to preserve same.
+
+ English sentence checker for LibreOffice
+
+ The following software may be included in this product: English
+ sentence checker. Use of any of this software is governed by the terms
+ of the license below:
+
+ 2011-2012 (c) László Németh, license: MPL 1.1 / GPLv3+ / LGPLv3+
+
+ See GPL Version 3 below
+
+ See LGPL Version 3 below
+
+ See MPL Version 1.1 below
+
+Estonian
+
+ Spelling dictionary
+
+ The following software may be included in this product: Estonian
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ Dictionary is adapted to myspell by Jaak Pruulmann (jjpp@meso.ee,
+ http://www.meso.ee/~jjpp/speller/ ) on the base of word list
+ created and shared by IEL (Institute of the Estonian Language,
+ tarkvara@eki.ee). The original of EKI software license is available at
+ http://www.eki.ee/eki/licence.html. The work of Jaak Pruulmann is
+ licensed under LGPL (GNU Lesser General Public License). The copies of
+ licenses are added to current file. IEL is informed about the use of
+ this word list.
+
+ Software License Agreement
+
+ Institute of the Estonian Language
+
+ Copyright © Institute of the Estonian Language
+
+ E-mail: tarkvara@eki.ee
+
+ URL: http://www.eki.ee/tarkvara/
+
+ The present License Agreement gives the user of this Software Product
+ (hereinafter: Product) the right to use the Product for whatever
+ purpose (incl. distribution, copying, altering, inclusion in other
+ software, and selling) on the following conditions:
+
+ The present License Agreement should belong unaltered to each copy ever
+ made of this Product;
+
+ Neither the Institute of the Estonian Language (hereinafter: IEL) nor
+ the author(s) of the Product will take responsibility for any
+ detriment, direct or indirect, possibly ensuing from the application of
+ the Product;
+
+ The IEL is ready to share the Product with other users as we wish to
+ advance research on the Estonian language and to promote the use of
+ Estonian in IT-technology now rapidly developing, yet we refuse to bind
+ ourselves to any further obligation, which means that the IEL is not
+ obliged either to warrant the suitability of the Product for a concrete
+ use, to improve the program, or to provide a more detailed description
+ of the underlying algorithms. (Which does not mean, though, that we may
+ not do it.)
+
+ Whenever you use the Product, we request that you inform us by writing
+ to the e-mail address tarkvara@eki.ee or to street address listed
+ below.
+
+ Institute of the Estonian Language
+
+ Roosikrantsi 6
+ EE-10119 Tallinn
+ ESTONIA
+
+ E-mail: eki@eki.ee
+ Phone & Fax: +372-6411443
+
+ See LGPL Version 2.1 below
+
+ Hyphenation patterns
+
+ The following software may be included in this product: Estonian
+ hyphenation patterns. Use of any of this software is governed by the
+ terms of the license below:
+
+ Hyphenation file is adapted to OpenOffice.org by Jaak Pruulmann
+ (jjpp@meso.ee, http://www.meso.ee/~jjpp/speller/) on the base of
+ the LaTeX hyphenation file created by Enn Saar (saar@aai.ee), who has
+ signed the JCA (Joint Copyright Agreement) allowing to use his work for
+ OpenOffice.org. The original file is available at address
+ http://www.cs.ut.ee/~tqnu/eehyph.tex and in the heading of the
+ file it is written that this file is licensed under LPPL. The work of
+ Jaak Pruulmann is licensed under LGPL (GNU Lesser General Public
+ License).
+
+ See LPPL below
+
+ See LGPL Version 2.1 below
+
+French
+
+ Spelling dictionary
+
+ The following software may be included in this product: French spelling
+ dictionary. Use of any of this software is governed by the terms of the
+ license below:
+
+ Olivier R. - dicollectefreefr
+
+ Dicollecte: http://www.dicollecte.org/
+
+ Licenses:
+ * MPL: Mozilla Public License version 1.1 or higher
+ * GPL: GNU General Public License version 2.0 or higher
+ * LGPL: GNU Lesser General Public License version 2.1 or higher
+
+ Hyphenation patterns
+
+ The following software may be included in this product: French
+ hyphenation patterns. Use of any of this software is governed by the
+ terms of the license below:
+
+ Origin: Based on the TeX hyphenation tables frhyph.tex (V2.12)
+ <2002/12/11>
+ http://mirror.ctan.org/language/hyphenation/frhyph.tex
+
+ The TeX hyphenation tables are released under the LaTeX Project Public
+ License (LPPL)
+
+ See LPPL below
+
+ License: OpenOffice.org adaptions of this package are licensed under
+ the GNU Lesser General Public License (LGPL) version 2.1 or higher.
+
+ See LGPL Version 2.1 below
+
+ Author: Conversion author is Paul Pichaureau
+
+
+ Based on a previous conversion by Blaise Drayer
+
+ Thesaurus
+
+ The following software may be included in this product: French
+ thesaurus. Use of any of this software is governed by the terms of the
+ license below:
+
+ Licence: LGPL: GNU Lesser General Public License version 2.1 or higher.
+
+ See LGPL Version 2.1 below
+
+Galician
+
+ Spelling dictionary
+
+ The following software may be included in this product: Galician
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ This extension was made by Frco. Javier Rial Rodríguez for Mancomún,
+ Centro de Referencia e Servizos de Software Libre 2008
+
+ Spellchecker files (gl_ES.aff, gl_ES.dic) from Mar Castro Pereiro also
+ developed for Mancomún.
+
+ Distributed under the GPL License.
+
+ See GPL Version 3 below
+
+Gujarati
+
+ Spelling dictionary
+
+ The following software may be included in this product: Gujarati
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ See GPL Version 3 below
+
+Hebrew
+
+ Spelling dictionary
+
+ The following software may be included in this product: Hebrew spelling
+ dictionary. Use of any of this software is governed by the terms of the
+ license below:
+
+ This dictionary is Copyright (C) 2000-2009, Nadav Har'El
+ (nyh@math.technion.ac.il) and Dan Kenigsberg
+ (danken@cs.technion.ac.il).
+
+ It is licensed under the GNU General Public License (GPL).
+
+ See GPL Version 3 below
+
+Hindi
+
+ The following software may be included in this product: Hindi spelling
+ dictionary. Use of any of this software is governed by the terms of the
+ license below:
+
+ GNU Aspell Hindi Word List Package
+ Copyright © 2005 Swapnil {Hajare, Sant}
+
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ Conversion made by Laszlo Nemeth, for demonstration of Hunspell Unicode
+ support.
+
+ See GPL Version 2 below
+
+Hungarian
+
+ Spelling dictionary
+
+ The following software may be included in this product: Hungarian
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ GPL 2.0/LGPL 2.1/MPL 1.1 tri-license
+
+ The contents of this software may be used under the terms of the GNU
+ General Public License Version 2 or later (the "GPL"), or the GNU
+ Lesser General Public License Version 2.1 or later (the "LGPL", see
+ COPYING.LGPL) or (excepting the LGPLed GNU gettext library in the intl/
+ directory) the Mozilla Public License Version 1.1 or later (the "MPL",
+ see COPYING.MPL).
+
+ Software distributed under these licenses is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ licences for the specific language governing rights and limitations
+ under the licenses.
+
+ 2010 (c) László Németh & Ferenc Godó
+
+ See GPL Version 2 below
+
+ See LGPL Version 2.1 below
+
+ See MPL Version 1.1 below
+
+ Hyphenation patterns
+
+ The following software may be included in this product: Hungarian
+ hyphenation patterns. Use of any of this software is governed by the
+ terms of the license below:
+
+ Copyright © Bence Nagy , 2006
+
+ Original license: GPL v2
+
+ Patch author: László Németh
+
+ Patch license: MPL/GPL/LGPL
+
+ See GPL Version 2 below
+
+ See LGPL Version 2.1 below
+
+ See MPL Version 1.1 below
+
+ Thesaurus
+
+ The following software may be included in this product: Hungarian
+ thesaurus. Use of any of this software is governed by the terms of the
+ license below:
+
+ Copyright (C) 2009, László Németh
+
+ See GPL Version 2 below
+
+ Hungarian sentence checker for LibreOffice
+
+ The following software may be included in this product: Hungarian
+ sentence checker. Use of any of this software is governed by the terms
+ of the license below:
+
+ 2009-2012 (c) László Németh, license: MPL 1.1 / GPLv3+ / LGPLv3+
+
+ See GPL Version 3 below
+
+ See LGPL Version 3 below
+
+ See MPL Version 1.1 below
+
+Icelandic
+
+ Spelling dictionary and thesaurus
+
+ The wordlist was developed by Orðabók Háskólans in cooperation with
+ Reiknistofnun Háskóla Íslands in the early nineties and was released
+ into the public domain. Further modifications to the wordlist are also
+ released into the public domain.
+ The thesaurus and words in the spell checker with additional
+ morphological information are from the Icelandic Wiktionary Project,
+ http://is.wiktionary.org. Works released by the Wiktionary project are
+ under the Creative Commons Attribution-ShareAlike 3.0 Unported license.
+ You are free:
+ to Share — to copy, distribute and transmit the work
+ to Remix — to adapt the work
+ to make commercial use of the work
+ Under the following conditions:
+ Attribution — You must attribute the work in the manner specified by
+ the author or licensor (but not in any way that suggests that they
+ endorse you or your use of the work).
+ Share Alike — If you alter, transform, or build upon this work, you may
+ distribute the resulting work only under the same or similar license to
+ this one.
+
+ See CC-BY-SA 3.0 below
+
+Italian
+
+ Spelling dictionary
+
+ The following software may be included in this product: Italian
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ Copyright (C) 2001, 2002 Gianluca Turconi
+ Copyright (C) 2002, 2003, 2004 Gianluca Turconi and Davide Prina
+ Copyright (C) 2004, 2005, 2006, 2007 Davide Prina
+ Copyright (C) 2010 Andrea Pescetti
+
+ See GPL Version 3 below
+
+ Hyphenation patterns
+
+ The following software may be included in this product: Italian
+ hyphenation patterns. Use of any of this software is governed by the
+ terms of the license below:
+
+ Origin: Based on the TeX hyphenation tables by Claudio Beccari
+
+ Author: conversion author is Giuseppe Bilotta
+
+
+ See LGPL Version 3 below
+
+ Thesaurus
+
+ The following software may be included in this product: Italian
+ thesaurus. Use of any of this software is governed by the terms of the
+ license below:
+
+ Copyright (C) 2004,2005,2006,2007,2008 Daniela Volta
+ Copyright (C) 2008 Giovanni Zuliani
+ Copyright (C) 2006,2007,2008 Davide Prina
+ Copyright (C) 2010 Andrea Pescetti
+
+ See GPL Version 3 below
+
+Kurdish
+
+ Spelling dictionary
+
+ The following software may be included in this product: Kurdish
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ (C) Copyright Reimar Heider
+
+ With contributions from Kevin P. Scannell and Rêzan
+ Tovjîn
+
+ The original word list used for this package was augmented using Kevin
+ Scannell's web crawling software "An Crúbadán" and then hand-checked by
+ Ronahi and Tovjîn.
+
+ Originally GPL, relicensed on 04-07-2007 to GPLv3, LGPLv3, MPL 1.1
+
+ See GPL Version 3 below
+
+ See LGPL Version 3 below
+
+ See MPL Version 1.1 below
+
+Lao
+
+ Spelling dictionary
+
+ The following software may be included in this product: Lao spelling
+ dictionary. Use of any of this software is governed by the terms of the
+ license below:
+
+ Copyright (C) 2013 by Brian Eugene Wilson, Robert Martin Campbell
+
+ See LGPL Version 2.1 below
+
+Latvian
+
+ Spelling dictionary
+
+ The following software may be included in this product: Latvian
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ Copyright (C) 2002-2010 Janis Eisaks, jancs@dv.lv,
+ http://dict.dv.lv
+
+ See LGPL Version 2.1 below
+
+ Hyphenation patterns
+
+ The following software may be included in this product: Latvian
+ hyphenation patterns. Use of any of this software is governed by the
+ terms of the license below:
+
+ Copyright (C) 2004-2005 Jânis Vilims, jvilims@apollo.lv
+
+ See LGPL Version 2.1 below
+
+ Thesaurus
+
+ The following software may be included in this product: Latvian
+ thesaurus. Use of any of this software is governed by the terms of the
+ license below:
+
+ Copyright (C) 2002-2010 Janis Eisaks, jancs@dv.lv,
+ http://dict.dv.lv
+
+ See LGPL Version 2.1 below
+
+Lithuanian
+
+ Spelling dictionary
+
+ The following software may be included in this product: Lithuanian
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ Copyright (c) Albertas Agejevas , 2000, 2001. All
+ rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ 1. Redistribution of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistribution in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the
+ distribution.
+ 3. Neither the name of the Albertas Agejevas nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY ALBERTAS AGEJEVAS AND CONTRIBUTORS ``AS
+ IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALBERTAS AGEJEVAS
+ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ Hyphenation patterns
+
+ The following software may be included in this product: Lithuanian
+ hyphenation patterns. Use of any of this software is governed by the
+ terms of the license below:
+
+ Origin: TeX hyphenation tables by Sigitas Tolusis and Vytas
+ Statulevicius. The original tables can be found at
+ http://www.vtex.lt/tex/download/zip/texmf.zip as lthyphen.tex.
+
+ Author: Converted to OOo format by Albertas Agejevas
+
+ License: LaTeX Project Public Licence
+
+ See LPPL below
+
+Nepali
+
+ Spelling dictionary
+
+ The following software may be included in this product: Nepali spelling
+ dictionary. Use of any of this software is governed by the terms of the
+ license below:
+
+ Compiled by Madan Puraskar Pustakalaya
+
+ See LGPL Version 2.1 below
+
+ Thesaurus
+
+ The following software may be included in this product: Nepali
+ thesaurus. Use of any of this software is governed by the terms of the
+ license below:
+
+ Compiled by Madan Puraskar Pustakalaya
+
+ See LGPL Version 2.1 below
+
+Norwegian
+
+ Spelling dictionary
+
+ The following software may be included in this product: Norwegian
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ See GPL Version 2 below
+
+ Hyphenation patterns
+
+ The following software may be included in this product: Norwegian
+ hyphenation patterns. Use of any of this software is governed by the
+ terms of the license below:
+
+ See GPL Version 2 below
+
+ Thesaurus
+
+ The following software may be included in this product: Norwegian
+ thesaurus. Use of any of this software is governed by the terms of the
+ license below:
+
+ See GPL Version 2 below
+
+Occitan
+
+ Spelling dictionary
+
+ The following software may be included in this product: Occitan
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ Copyright (C) 2006 Bruno GALLART
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ See GPL Version 2 below
+
+Polish
+
+ Spelling dictionary
+
+ The following software may be included in this product: Polish spelling
+ dictionary. Use of any of this software is governed by the terms of the
+ license below:
+
+ This dictionary for spell-checking Polish texts is licensed under GPL,
+ LGPL, MPL (Mozilla Public License) and Creative Commons ShareAlike
+ licenses (see http://creativecommons.org/licenses/sa/1.0).
+
+ Hyphenation patterns
+
+ The following software may be included in this product: Polish
+ hyphenation patterns. Use of any of this software is governed by the
+ terms of the license below:
+
+ Origin: Based on the TeX hyphenation patterns plhyph.tex, version 3.0a,
+ Wednesday, May 17th, 1995. The original file is in CTAN archives, for
+ example
+ here:http://ctan.binkerton.com/ctan.readme.php?filename=language/p
+ olish/plhyph.tex and is licensed under LPPL.
+
+ License: OpenOffice.org Adaptions of this package are licensed under
+ the GNU LGPL license.
+
+ Author: conversion and corrects author is Artur Polaczyński
+
+
+ See LGPL Version 3 below
+
+ Thesaurus
+
+ The following software may be included in this product: Polish
+ thesaurus. Use of any of this software is governed by the terms of the
+ license below:
+
+ Copyright (C) 2004-2008 Marcin Miłkowski
+
+
+ This product is made available subject to the terms of GNU Lesser
+ General Public License Version 2.1.
+
+ See LGPL Version 2.1 below
+
+Portuguese
+
+ Spelling dictionary
+
+ The following software may be included in this product: Portuguese
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ Copyright (C) 2006 Jose Joao de Almeida, Rui Vilela, Alberto Simões
+
+ Dep. Informatica, Universidade do Minho, Portugal
+
+ GPL 2.0/LGPL 2.1/MPL 1.1 tri-license
+
+ See GPL Version 2 below
+
+ See LGPL Version 2.1 below
+
+ See MPL Version 1.1 below
+
+ Hyphenation patterns
+
+ The following software may be included in this product: Portuguese
+ hyphenation patterns. Use of any of this software is governed by the
+ terms of the license below:
+
+ Based on the TeX hyphenation tables by Pedro J. de Rezende (Brazilian)
+ and tuned up by J.Joao Dias Almeida
+
+ Author: conversion author is Paulo Morgado
+
+ See GPL Version 2 below
+
+ Thesaurus
+
+ The following software may be included in this product: Portuguese
+ thesaurus. Use of any of this software is governed by the terms of the
+ license below:
+
+ See GPL Version 2 below
+
+Portuguese (Brazilian)
+
+ Spelling dictionary
+
+ The following software may be included in this product: Portuguese
+ (Brazilian) spelling dictionary. Use of any of this software is
+ governed by the terms of the license below:
+
+ This dictionary is under continuous development by Raimundo Moura and
+ his team. It is icensed under the terms of the GNU Lesser General
+ Public License version 3 (LGPLv3), as published by the Free Software
+ Foundation, and Mozilla Public License as published by The Mozilla
+ Foundation. The credits are available at
+ http://pt-br.libreoffice.org/projetos/projeto-vero-verificador-ort
+ ografico/ and you can find new releases at
+ http://extensions.libreoffice.org
+
+ Copyright (C) 2006 - 2013 by Raimundo Santos Moura
+
+
+ See LGPL Version 3 below
+
+ See MPL Version 1.1 below
+
+ Hyphenation patterns
+
+ The following software may be included in this product: Portuguese
+ (Brazilian) hyphenation patterns. Use of any of this software is
+ governed by the terms of the license below:
+
+ These hyphenation patterns are under continuous development by Raimundo
+ Moura and his team. It is icensed under the terms of the GNU Lesser
+ General Public License version 3 (LGPLv3), as published by the Free
+ Software Foundation, and Mozilla Public License as published by The
+ Mozilla Foundation. The credits are available at
+ http://pt-br.libreoffice.org/projetos/projeto-vero-verificador-ort
+ ografico/ and you can find new releases at
+ http://extensions.libreoffice.org
+
+ Copyright (C) 2006 - 2013 by Raimundo Santos Moura
+
+
+ See LGPL Version 3 below
+
+ See MPL Version 1.1 below
+
+ Portuguese Brazilian sentence checker for LibreOffice
+
+ The following software may be included in this product: Portuguese
+ (Brazilian) sentence checker. Use of any of this software is governed
+ by the terms of the license below:
+
+ MPL 1.1 / GPLv3+ / LGPLv3+
+
+ 2013 © Raimundo Santos Moura
+
+ See GPL Version 3 below
+
+ See LGPL Version 3 below
+
+ See MPL Version 1.1 below
+
+Romanian
+
+ Spelling dictionary
+
+ The following software may be included in this product: Romanian
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ GPL 2.0/LGPL 2.1/MPL 1.1 tri-license.
+
+ See GPL Version 2 below
+
+ See LGPL Version 2.1 below
+
+ See MPL Version 1.1 below
+
+ Hyphenation patterns
+
+ The following software may be included in this product: Romanian
+ hyphenation patterns. Use of any of this software is governed by the
+ terms of the license below:
+
+ GNU General Public License Version 2
+
+ See GPL Version 2 below
+
+ Thesaurus
+
+ The following software may be included in this product: Romanian
+ thesaurus. Use of any of this software is governed by the terms of the
+ license below:
+
+ GNU General Public License Version 2 or later
+
+ See GPL Version 2 below
+
+Russian
+
+ Spelling dictionary
+
+ The following software may be included in this product: Russian
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ Copyright (c) 1997-2008, Alexander I. Lebedev
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistribution of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistribution in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the
+ distribution.
+ * Modified versions must be clearly marked as such.
+ * The name of Alexander I. Lebedev may not be used to endorse or
+ promote products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ Hyphenation patterns
+
+ The following software may be included in this product: Russian
+ hyphenation patterns. Use of any of this software is governed by the
+ terms of the license below:
+
+ unknown
+
+ Thesaurus
+
+ The following software may be included in this product: Russian
+ thesaurus. Use of any of this software is governed by the terms of the
+ license below:
+
+ License: GNU LGPL
+
+ Author: Mikhail Korolyov
+
+ Origin: Абрамовъ, Н. Словарь русскихъ синонимовъ и сходныхъ по смыслу
+ выраженiй. Изд. 3-е, доп., Пг., 1911
+
+ Russian grammar checker
+
+ The following software may be included in this product: Russian grammar
+ checker. Use of any of this software is governed by the terms of the
+ license below:
+
+ 2009, 2011, 2012 (c) Yakov Reztsov , license: MPL
+ 1.1 / GPL / LGPL
+
+Scottish Gaelic
+
+ Spelling dictionary
+
+ The following software may be included in this product: Scottish Gaelic
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ See GPL Version 3 below
+
+Serbian
+
+ Spelling dictionary
+
+ The following software may be included in this product: Serbian
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ Serbian spellcheck dictionary (files sr.dic, sr.aff, sh.dic, sh.aff) is
+ released under disjunctive tri-licence GNU LGPL version 2.1 or later /
+ MPL version 1.1 or later / GNU GPL version 2 or later giving you the
+ choice of one of the three sets of free software licensing terms. You
+ can also use the dictionary under the terms of the Creative Commons
+ BY-SA 3.0 Unpored licence.
+
+ Hyphenation patterns
+
+ The following software may be included in this product: Serbian
+ hyphenation patterns. Use of any of this software is governed by the
+ terms of the license below:
+
+ Serbian hyphenation patterns (files hyph_sr.dic and hyph_sh.dic) are
+ derived from the official TeX patterns for Serbocroatian language
+ (Cyrillic and Latin) created by Dejan Muhamedagić
+ version 2.02 released on 22 June 2008. The
+ format is adopted for usage with Hyphen hyphenation library and is
+ released again as hyphen-sr under the compatible GNU LGPL version 2.1
+ or later.
+
+ See LGPL Version 2.1 below
+
+Sinhala
+
+ Spelling dictionary
+
+ The following software may be included in this product: Sinhala
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ Copyright (C) <2010> Laknath Semage
+
+ See GPL Version 3 below
+
+Slovak
+
+ Spelling dictionary
+
+ The following software may be included in this product: Slovak spelling
+ dictionary. Use of any of this software is governed by the terms of the
+ license below:
+
+ Data are released under these licenses (you can select one):
+ * The GNU General Public License (GPL) Version 2, June 1991
+ * GNU Lesser General Public License Version 2.1, February 1999
+ * Mozilla Public License 1.1 (MPL 1.1)
+
+ See GPL Version 2 below
+
+ See LGPL Version 2.1 below
+
+ See MPL Version 1.1 below
+
+ Hyphenation patterns
+
+ The following software may be included in this product: Slovak
+ hyphenation patterns. Use of any of this software is governed by the
+ terms of the license below:
+
+ Dictionary is created by converting TeX hyphenation patterns for Slovak
+ (Author: Jana Chlebíková) with lingucomponent-tools
+ (http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/oo-cs/lingucompone
+ nt-tools/).
+
+ Original license: LPPL
+
+ See LPPL below
+
+ Thesaurus
+
+ The following software may be included in this product: Slovak
+ thesaurus. Use of any of this software is governed by the terms of the
+ license below:
+
+ Copyright (c) 2004-2010 Tibor Bako, yorik (at) szm.sk, Zdenko Podobný,
+ zposter (at) gmail.com
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this data (the "Data"), to deal in the Data without
+ restriction, including without limitation the rights to use, copy,
+ modify, merge, publish, distribute, sublicense, and/or sell copies of
+ the Data, and to permit persons to whom the Data is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Data.
+
+ THE DATA ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE DATA
+ OR THE USE OR OTHER DEALINGS IN THE DATA.
+
+Slovenian
+
+ Spelling dictionary
+
+ The following software may be included in this product: Slovenian
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ See GPL Version 2 below
+
+ See LGPL Version 2.1 below
+
+ Hyphenation patterns
+
+ The following software may be included in this product: Slovenian
+ hyphenation patterns. Use of any of this software is governed by the
+ terms of the license below:
+
+ See GPL Version 2 below
+
+ See LGPL Version 2.1 below
+
+ Thesaurus
+
+ The following software may be included in this product: Slovenian
+ thesaurus. Use of any of this software is governed by the terms of the
+ license below:
+
+ See LGPL Version 2.1 below
+
+Spanish
+
+ Spelling dictionary
+
+ The following software may be included in this product: Spanish
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the licenses (or any later versions) below:
+
+ See GPL version 3 below
+
+ See LGPL Version 3 below
+
+ See MPL Version 1.1 below
+
+ Hyphenation patterns
+
+ The following software may be included in this product: Spanish
+ hyphenation patterns. Use of any of this software is governed by the
+ terms of the licenses (or any later versions) below:
+
+ See GPL version 3 below
+
+ See LGPL Version 3 below
+
+ See MPL Version 1.1 below
+
+ Thesaurus
+
+ The following software may be included in this product: Spanish
+ thesaurus. Use of any of this software is governed by the terms of the
+ license below:
+
+ See LGPL Version 2.1 below
+
+Swahili
+
+ Spelling dictionary
+
+ The following software may be included in this product: Swahili
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ Copyright (C) 2004 Jason M Githeko
+
+ See LGPL Version 2.1 below
+
+Swedish
+
+ Spelling dictionary
+
+ The following software may be included in this product: Swedish
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ Copyright © 2003-12 Göran Andersson .
+
+ This dictionary is made available subject to the terms of GNU Lesser
+ General Public License Version 3.
+
+ See LGPL Version 3 below
+
+ Thesaurus
+
+ The following software may be included in this product: Swedish
+ thesaurus. Use of any of this software is governed by the terms of the
+ license below:
+
+ This thesaurus was directly converted from Synlex. The synonyms will be
+ displayed sorted by their voted synonym level.
+
+ The synlex file license, You are free to use this file
+ with the same license
+
+ Copyright (c) Viggo Kann KTH 2009
+
+ THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
+ OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
+
+ Permission is hereby granted to use or copy this program for any
+ purpose, provided the above notices are retained on all copies.
+ Permission to modify the code and to distribute modified code is
+ granted, provided the above notices are retained, and a notice that the
+ code was modified is included with the above copyright notice.
+
+Telugu
+
+ Spelling dictionary
+
+ The following software may be included in this product: Telugu spelling
+ dictionary. Use of any of this software is governed by the terms of the
+ license below:
+
+ GNU Hunspell Telugu Word List Package adaptation
+
+ Copyright © 2010 adaptation to Hunspell, Arjuna Rao Chavala
+ Copyright © 2005 Aspell Telugu word list released by IndLinux, Khadir
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ See GPL Version 2 below
+
+ Hyphenation patterns
+
+ The following software may be included in this product: Telugu
+ hyphenation patterns. Use of any of this software is governed by the
+ terms of the license below:
+
+ Copyright © 2009 Santhosh Thottingal
+
+ The Telugu Hyphenation Dictionary may be used under the terms of either
+ the GNU General Public License Version 3 or later (the "GPL"), or the
+ GNU Lesser General Public License Version 3 or later (the "LGPL")
+
+ See GPL Version 3 below
+
+ See LGPL Version 3 below
+
+Thai
+
+ Spelling dictionary
+
+ The following software may be included in this product: Thai spelling
+ dictionary. Use of any of this software is governed by the terms of the
+ license below:
+
+ See LGPL Version 2.1 below
+
+Ukrainian
+
+ Spelling dictionary
+
+ The following software may be included in this product: Ukrainian
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ Copyright (C) 1999 Vladimir Yakovchuk, Oleg Podgurniy
+ Copyright (C) 2001 Dmytro Kovalyov, Maksym Polyakov, Andriy Rysin
+ Copyright (C) 2002 Valentyn Solomko, Volodymyr M. Lisivka
+ Copyright (C) 2005 Andriy Rysin, Eugeniy Meshcheryakov, Dmytro Kovalyov
+ Copyright (C) 2006-2009 Andriy Rysin
+
+ This dictionary is licensed under GPL 2.0 or above, LGPL 2.1 or above
+ and MPL (Mozilla Public License) 1.1 licenses.
+
+ See GPL Version 2 below
+
+ See LGPL Version 2.1 below
+
+ See MPL Version 1.1 below
+
+ Hyphenation patterns
+
+ The following software may be included in this product: Ukrainian
+ hyphenation patterns. Use of any of this software is governed by the
+ terms of the license below:
+
+ Copyright 1998-2002 Maksym Polyakov.
+
+ License: GNU General Public License version 2 or any later version
+
+ See GPL Version 2 below
+
+ Thesaurus
+
+ The following software may be included in this product: Ukrainian
+ thesaurus. Use of any of this software is governed by the terms of the
+ license below:
+
+ This thesaurus is based on: П. М. Деркач, Короткий словник синонімів
+ української мови, Радянська школа, Київ, 1960 С. Караванський, Пошук
+ українського слова
+
+ Copyright (C) 2009 Andriy Rysin
+
+ This thesaurus is licensed under GPL, LGPL and MPL (Mozilla Public
+ License) licenses.
+
+ See GPL Version 2 below
+
+ See LGPL Version 2.1 below
+
+ See MPL Version 1.1 below
+
+Vietnamese
+
+ Spelling dictionary
+
+ The following software may be included in this product: Vietnamese
+ spelling dictionary. Use of any of this software is governed by the
+ terms of the license below:
+
+ Authors:
+ Ivan Garcia
+ Nguyễn Xuân Minh
+
+ This spellchecker for OpenOffice was based on the Vietnamese Dictionary
+ list from Proffessor Hồ Ngọc Đức
+
+ This spellchecker is released with GPLv2 license.
+
+ See GPL Version 2 below
+
+Zulu
+
+ Hyphenation patterns
+
+ The following software may be included in this product: Zulu
+ hyphenation patterns. Use of any of this software is governed by the
+ terms of the license below:
+
+ Copyright (C) 2005, 2007 Friedel Wolff
+
+ See LGPL Version 2.1 below
+
+ Artwork
+
+KDE Crystal theme icons
+
+ The following software may be included in this product: KDE Crystal
+ theme icons. Use of any of this software is governed by the terms of
+ the license below:
+
+ KDE Crystal theme icons.
+ Copyright (C) 2002 and following years KDE Artists 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 of the License.
+
+ See LGPL Version 2.1 below
+
+Tango theme
+
+ Portions of the Tango theme contain work licenced under the Creative
+ Commons Attribution-Share Alike 3.0 United States License. To view a
+ copy of this licence, visit
+ http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to
+ Creative Commons, 171 Second Street, Suite 300, San Francisco,
+ California 94105, USA.
+
+ This artwork is attributed to the "GNOME Project":
+ http://www.gnome.org
+
+ See CC-BY-SA 3.0 below
+
+ Miscellaneous
+
+Adobe Printer Description Files
+
+ The following software may be included in this product: Adobe Printer
+ Description Files. Use of any of this software is governed by the terms
+ of the license below:
+
+ Copyright 1987-1995 Adobe Systems Incorporated.
+
+ All Rights Reserved.
+
+ Permission is granted for redistribution of this file as long as this
+ copyright notice is intact and the contents of the file is not altered
+ in any way from its original form.
+
+ End of Copyright statement
+
+International Color Consortium sRGB Profiles
+
+ The following software may be included in this product: ICC sRGB
+ Profiles. Use of any of this software is governed by the terms of the
+ license below:
+
+ To anyone who acknowledges that the files "sRGB_IEC61966-2-1_noBPC.icc"
+ and "sRGB_IEC61966-2-1_withBPC.icc" are provided "AS IS" WITH NO
+ EXPRESS OR IMPLIED WARRANTY, permission to use, copy and distribute
+ these file for any purpose is hereby granted without fee, provided that
+ the files are not changed including the HP copyright notice tag, and
+ that the name of Hewlett-Packard Company shall not be used in
+ advertising or publicity pertaining to distribution of the software
+ without specific, written prior permission. Hewlett-Packard Company
+ makes no representations about the suitability of this software for any
+ purpose.
+
+ GNU Lesser General Public License Version 3
+
+ Copyright © 2007 Free Software Foundation, Inc.
+
+ Everyone is permitted to copy and distribute verbatim copies of this
+ license document, but changing it is not allowed.
+
+ This version of the GNU Lesser General Public License incorporates the
+ terms and conditions of version 3 of the GNU General Public License,
+ supplemented by the additional permissions listed below.
+
+0. Additional Definitions.
+
+ As used herein, “this License” refers to version 3 of the GNU Lesser
+ General Public License, and the “GNU GPL” refers to version 3 of the
+ GNU General Public License.
+
+ “The Library” refers to a covered work governed by this License, other
+ than an Application or a Combined Work as defined below.
+
+ An “Application” is any work that makes use of an interface provided by
+ the Library, but which is not otherwise based on the Library. Defining
+ a subclass of a class defined by the Library is deemed a mode of using
+ an interface provided by the Library.
+
+ A “Combined Work” is a work produced by combining or linking an
+ Application with the Library. The particular version of the Library
+ with which the Combined Work was made is also called the “Linked
+ Version”.
+
+ The “Minimal Corresponding Source” for a Combined Work means the
+ Corresponding Source for the Combined Work, excluding any source code
+ for portions of the Combined Work that, considered in isolation, are
+ based on the Application, and not on the Linked Version.
+
+ The “Corresponding Application Code” for a Combined Work means the
+ object code and/or source code for the Application, including any data
+ and utility programs needed for reproducing the Combined Work from the
+ Application, but excluding the System Libraries of the Combined Work.
+
+1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+ without being bound by section 3 of the GNU GPL.
+
+2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+ facility refers to a function or data to be supplied by an Application
+ that uses the facility (other than as an argument passed when the
+ facility is invoked), then you may convey a copy of the modified
+ version:
+ * a) under this License, provided that you make a good faith effort
+ to ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+ * b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from a
+ header file that is part of the Library. You may convey such object
+ code under terms of your choice, provided that, if the incorporated
+ material is not limited to numerical parameters, data structure layouts
+ and accessors, or small macros, inline functions and templates (ten or
+ fewer lines in length), you do both of the following:
+ * a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are covered
+ by this License.
+ * b) Accompany the object code with a copy of the GNU GPL and this
+ license document.
+
+4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that, taken
+ together, effectively do not restrict modification of the portions of
+ the Library contained in the Combined Work and reverse engineering for
+ debugging such modifications, if you also do each of the following:
+ * a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+ * b) Accompany the Combined Work with a copy of the GNU GPL and this
+ license document.
+ * c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among these
+ notices, as well as a reference directing the user to the copies of
+ the GNU GPL and this license document.
+ * d) Do one of the following:
+ + 0) Convey the Minimal Corresponding Source under the terms of
+ this License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+ + 1) Use a suitable shared library mechanism for linking with
+ the Library. A suitable mechanism is one that (a) uses at run
+ time a copy of the Library already present on the user's
+ computer system, and (b) will operate properly with a modified
+ version of the Library that is interface-compatible with the
+ Linked Version.
+ * e) Provide Installation Information, but only if you would
+ otherwise be required to provide such information under section 6
+ of the GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the Combined
+ Work produced by recombining or relinking the Application with a
+ modified version of the Linked Version. (If you use option 4d0, the
+ Installation Information must accompany the Minimal Corresponding
+ Source and Corresponding Application Code. If you use option 4d1,
+ you must provide the Installation Information in the manner
+ specified by section 6 of the GNU GPL for conveying Corresponding
+ Source.)
+
+5. Combined Libraries.
+
+ 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
+ that are not Applications and are not covered by this License, and
+ convey such a combined library under terms of your choice, if you do
+ both of the following:
+ * a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+ * b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+ the GNU Lesser General Public License from time to time. Such new
+ versions will be similar in spirit to the present version, but may
+ differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the Library
+ as you received it specifies that a certain numbered version of the GNU
+ Lesser General Public License “or any later version” applies to it, you
+ have the option of following the terms and conditions either of that
+ published version or of any later version published by the Free
+ Software Foundation. If the Library as you received it does not specify
+ a version number of the GNU Lesser General Public License, you may
+ choose any version of the GNU Lesser General Public License ever
+ published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+ whether future versions of the GNU Lesser General Public License shall
+ apply, that proxy's public statement of acceptance of any version is
+ permanent authorization for you to choose that version for the Library.
+
+ GNU Lesser General Public License Version 2.1
+
+Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts as the suc
+cessor of the GNU Library Public License, version 2, hence the version number 2.
+1.]
+
+Preamble
+
+ The licenses for most software are designed to take away your freedom
+ to share and change it. By contrast, the GNU General Public Licenses
+ are intended to guarantee your freedom to share and change free
+ software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+ specially designated software packages--typically libraries--of the
+ Free Software Foundation and other authors who decide to use it. You
+ can use it too, but we suggest you first think carefully about whether
+ this license or the ordinary General Public License is the better
+ strategy to use in any particular case, based on the explanations
+ below.
+
+ When we speak of free software, we are referring to freedom of use, not
+ price. Our General Public Licenses are designed to make sure that you
+ have the freedom to distribute copies of free software (and charge for
+ this service if you wish); that you receive source code or can get it
+ if you want it; that you can change the software and use pieces of it
+ in new free programs; and that you are informed that you can do these
+ things.
+
+ To protect your rights, we need to make restrictions that forbid
+ distributors to deny you these rights or to ask you to surrender these
+ rights. These restrictions translate to certain responsibilities for
+ you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis or
+ for a fee, you must give the recipients all the rights that we gave
+ you. You must make sure that they, too, receive or can get the source
+ code. If you link other code with the library, you must provide
+ complete object files to the recipients, so that they can relink them
+ with the library after making changes to the library and recompiling
+ it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+ library, and (2) we offer you this license, which gives you legal
+ permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that there
+ is no warranty for the free library. Also, if the library is modified
+ by someone else and passed on, the recipients should know that what
+ they have is not the original version, so that the original author's
+ reputation will not be affected by problems that might be introduced by
+ others.
+
+ Finally, software patents pose a constant threat to the existence of
+ any free program. We wish to make sure that a company cannot
+ effectively restrict the users of a free program by obtaining a
+ restrictive license from a patent holder. Therefore, we insist that any
+ patent license obtained for a version of the library must be consistent
+ with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the ordinary
+ GNU General Public License. This license, the GNU Lesser General Public
+ License, applies to certain designated libraries, and is quite
+ different from the ordinary General Public License. We use this license
+ for certain libraries in order to permit linking those libraries into
+ non-free programs.
+
+ When a program is linked with a library, whether statically or using a
+ shared library, the combination of the two is legally speaking a
+ combined work, a derivative of the original library. The ordinary
+ General Public License therefore permits such linking only if the
+ entire combination fits its criteria of freedom. The Lesser General
+ Public License permits more lax criteria for linking other code with
+ the library.
+
+ We call this license the "Lesser" General Public License because it
+ does Less to protect the user's freedom than the ordinary General
+ Public License. It also provides other free software developers Less of
+ an advantage over competing non-free programs. These disadvantages are
+ the reason we use the ordinary General Public License for many
+ libraries. However, the Lesser license provides advantages in certain
+ special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+ encourage the widest possible use of a certain library, so that it
+ becomes a de-facto standard. To achieve this, non-free programs must be
+ allowed to use the library. A more frequent case is that a free library
+ does the same job as widely used non-free libraries. In this case,
+ there is little to gain by limiting the free library to free software
+ only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+ programs enables a greater number of people to use a large body of free
+ software. For example, permission to use the GNU C Library in non-free
+ programs enables many more people to use the whole GNU operating
+ system, as well as its variant, the GNU/Linux operating system.
+
+ Although the Lesser General Public License is Less protective of the
+ users' freedom, it does ensure that the user of a program that is
+ linked with the Library has the freedom and the wherewithal to run that
+ program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+ modification follow. Pay close attention to the difference between a
+ "work based on the library" and a "work that uses the library". The
+ former contains code derived from the library, whereas the latter must
+ be combined with the library in order to run.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+ program which contains a notice placed by the copyright holder or other
+ authorized party saying it may be distributed under the terms of this
+ Lesser General Public License (also called "this License"). Each
+ licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+ prepared so as to be conveniently linked with application programs
+ (which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work which
+ has been distributed under these terms. A "work based on the Library"
+ means either the Library or any derivative work under copyright law:
+ that is to say, a work containing the Library or a portion of it,
+ either verbatim or with modifications and/or translated
+ straightforwardly into another language. (Hereinafter, translation is
+ included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+ making modifications to it. For a library, complete source code means
+ all the source code for all modules it contains, plus any associated
+ interface definition files, plus the scripts used to control
+ compilation and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+ covered by this License; they are outside its scope. The act of running
+ a program using the Library is not restricted, and output from such a
+ program is covered only if its contents constitute a work based on the
+ Library (independent of the use of the Library in a tool for writing
+ it). Whether that is true depends on what the Library does and what the
+ program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+ complete source code as you receive it, in any medium, provided that
+ you conspicuously and appropriately publish on each copy an appropriate
+ copyright notice and disclaimer of warranty; keep intact all the
+ notices that refer to this License and to the absence of any warranty;
+ and distribute a copy of this License along with the Library.
+
+ You may charge a fee for the physical act of transferring a copy, and
+ you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Library or any portion of
+ it, thus forming a work based on the Library, and copy and distribute
+ such modifications or work under the terms of Section 1 above, provided
+ that you also meet all of these conditions:
+ * a) The modified work must itself be a software library.
+ * b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+ * c) You must cause the whole of the work to be licensed at no charge
+ to all third parties under the terms of this License.
+ * d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility is
+ invoked, then you must make a good faith effort to ensure that, in
+ the event an application does not supply such function or table,
+ the facility still operates, and performs whatever part of its
+ purpose remains meaningful.
+ (For example, a function in a library to compute square roots has a
+ purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square root
+ function must still compute square roots.)
+
+ These requirements apply to the modified work as a whole. If
+ identifiable sections of that work are not derived from the Library,
+ and can be reasonably considered independent and separate works in
+ themselves, then this License, and its terms, do not apply to those
+ sections when you distribute them as separate works. But when you
+ distribute the same sections as part of a whole which is a work based
+ on the Library, the distribution of the whole must be on the terms of
+ this License, whose permissions for other licensees extend to the
+ entire whole, and thus to each and every part regardless of who wrote
+ it.
+
+ Thus, it is not the intent of this section to claim rights or contest
+ your rights to work written entirely by you; rather, the intent is to
+ exercise the right to control the distribution of derivative or
+ collective works based on the Library.
+
+ In addition, mere aggregation of another work not based on the Library
+ with the Library (or with a work based on the Library) on a volume of a
+ storage or distribution medium does not bring the other work under the
+ scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+ License instead of this License to a given copy of the Library. To do
+ this, you must alter all the notices that refer to this License, so
+ that they refer to the ordinary GNU General Public License, version 2,
+ instead of to this License. (If a newer version than version 2 of the
+ ordinary GNU General Public License has appeared, then you can specify
+ that version instead if you wish.) Do not make any other change in
+ these notices.
+
+ Once this change is made in a given copy, it is irreversible for that
+ copy, so the ordinary GNU General Public License applies to all
+ subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of the
+ Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or derivative
+ of it, under Section 2) in object code or executable form under the
+ terms of Sections 1 and 2 above provided that you accompany it with the
+ complete corresponding machine-readable source code, which must be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy from
+ a designated place, then offering equivalent access to copy the source
+ code from the same place satisfies the requirement to distribute the
+ source code, even though third parties are not compelled to copy the
+ source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the Library,
+ but is designed to work with the Library by being compiled or linked
+ with it, is called a "work that uses the Library". Such a work, in
+ isolation, is not a derivative work of the Library, and therefore falls
+ outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+ creates an executable that is a derivative of the Library (because it
+ contains portions of the Library), rather than a "work that uses the
+ library". The executable is therefore covered by this License. Section
+ 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+ that is part of the Library, the object code for the work may be a
+ derivative work of the Library even though the source code is not.
+ Whether this is true is especially significant if the work can be
+ linked without the Library, or if the work is itself a library. The
+ threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data structure
+ layouts and accessors, and small macros and small inline functions (ten
+ lines or less in length), then the use of the object file is
+ unrestricted, regardless of whether it is legally a derivative work.
+ (Executables containing this object code plus portions of the Library
+ will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+ distribute the object code for the work under the terms of Section 6.
+ Any executables containing that work also fall under Section 6, whether
+ or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or link
+ a "work that uses the Library" with the Library to produce a work
+ containing portions of the Library, and distribute that work under
+ terms of your choice, provided that the terms permit modification of
+ the work for the customer's own use and reverse engineering for
+ debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+ Library is used in it and that the Library and its use are covered by
+ this License. You must supply a copy of this License. If the work
+ during execution displays copyright notices, you must include the
+ copyright notice for the Library among them, as well as a reference
+ directing the user to the copy of this License. Also, you must do one
+ of these things:
+ * a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood that
+ the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+ * b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+ * c) Accompany the work with a written offer, valid for at least
+ three years, to give the same user the materials specified in
+ Subsection 6a, above, for a charge no more than the cost of
+ performing this distribution.
+ * d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+ * e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+ Library" must include any data and utility programs needed for
+ reproducing the executable from it. However, as a special exception,
+ the materials to be distributed need not include anything that is
+ normally distributed (in either source or binary form) with the major
+ components (compiler, kernel, and so on) of the operating system on
+ which the executable runs, unless that component itself accompanies the
+ executable.
+
+ It may happen that this requirement contradicts the license
+ restrictions of other proprietary libraries that do not normally
+ accompany the operating system. Such a contradiction means you cannot
+ use both them and the Library together in an executable that you
+ distribute.
+
+ 7. You may place library facilities that are a work based on the
+ Library side-by-side in a single library together with other library
+ facilities not covered by this License, and distribute such a combined
+ library, provided that the separate distribution of the work based on
+ the Library and of the other library facilities is otherwise permitted,
+ and provided that you do these two things:
+ * a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library facilities.
+ This must be distributed under the terms of the Sections above.
+ * b) Give prominent notice with the combined library of the fact that
+ part of it is a work based on the Library, and explaining where to
+ find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute the
+ Library except as expressly provided under this License. Any attempt
+ otherwise to copy, modify, sublicense, link with, or distribute the
+ Library is void, and will automatically terminate your rights under
+ this License. However, parties who have received copies, or rights,
+ from you under this License will not have their licenses terminated so
+ long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+ signed it. However, nothing else grants you permission to modify or
+ distribute the Library or its derivative works. These actions are
+ prohibited by law if you do not accept this License. Therefore, by
+ modifying or distributing the Library (or any work based on the
+ Library), you indicate your acceptance of this License to do so, and
+ all its terms and conditions for copying, distributing or modifying the
+ Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+ Library), the recipient automatically receives a license from the
+ original licensor to copy, distribute, link with or modify the Library
+ subject to these terms and conditions. You may not impose any further
+ restrictions on the recipients' exercise of the rights granted herein.
+ You are not responsible for enforcing compliance by third parties with
+ this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+ infringement or for any other reason (not limited to patent issues),
+ conditions are imposed on you (whether by court order, agreement or
+ otherwise) that contradict the conditions of this License, they do not
+ excuse you from the conditions of this License. If you cannot
+ distribute so as to satisfy simultaneously your obligations under this
+ License and any other pertinent obligations, then as a consequence you
+ may not distribute the Library at all. For example, if a patent license
+ would not permit royalty-free redistribution of the Library by all
+ those who receive copies directly or indirectly through you, then the
+ only way you could satisfy both it and this License would be to refrain
+ entirely from distribution of the Library.
+
+ If any portion of this section is held invalid or unenforceable under
+ any particular circumstance, the balance of the section is intended to
+ apply, and the section as a whole is intended to apply in other
+ circumstances.
+
+ It is not the purpose of this section to induce you to infringe any
+ patents or other property right claims or to contest validity of any
+ such claims; this section has the sole purpose of protecting the
+ integrity of the free software distribution system which is implemented
+ by public license practices. Many people have made generous
+ contributions to the wide range of software distributed through that
+ system in reliance on consistent application of that system; it is up
+ to the author/donor to decide if he or she is willing to distribute
+ software through any other system and a licensee cannot impose that
+ choice.
+
+ This section is intended to make thoroughly clear what is believed to
+ be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+ certain countries either by patents or by copyrighted interfaces, the
+ original copyright holder who places the Library under this License may
+ add an explicit geographical distribution limitation excluding those
+ countries, so that distribution is permitted only in or among countries
+ not thus excluded. In such case, this License incorporates the
+ limitation as if written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+ versions of the Lesser General Public License from time to time. Such
+ new versions will be similar in spirit to the present version, but may
+ differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the Library
+ specifies a version number of this License which applies to it and "any
+ later version", you have the option of following the terms and
+ conditions either of that version or of any later version published by
+ the Free Software Foundation. If the Library does not specify a license
+ version number, you may choose any version ever published by the Free
+ Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+ programs whose distribution conditions are incompatible with these,
+ write to the author to ask for permission. For software which is
+ copyrighted by the Free Software Foundation, write to the Free Software
+ Foundation; we sometimes make exceptions for this. Our decision will be
+ guided by the two goals of preserving the free status of all
+ derivatives of our free software and of promoting the sharing and reuse
+ of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+ WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+ EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+ OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND,
+ EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH
+ YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
+ NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+ WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+ AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+ FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+ LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+ RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+ FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+ possible use to the public, we recommend making it free software that
+ everyone can redistribute and change. You can do so by permitting
+ redistribution under these terms (or, alternatively, under the terms of
+ the ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It
+ is safest to attach them to the start of each source file to most
+ effectively convey the exclusion of warranty; and each file should have
+ at least the "copyright" line and a pointer to where the full notice is
+ found.
+one line to give the library's name and an idea of what it does.
+Copyright (C) year name of author
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Also add information on how to contact you by electronic and paper
+ mail.
+
+ You should also get your employer (if you work as a programmer) or your
+ school, if any, to sign a "copyright disclaimer" for the library, if
+ necessary. Here is a sample; alter the names:
+Yoyodyne, Inc., hereby disclaims all copyright interest in
+the library `Frob' (a library for tweaking knobs) written
+by James Random Hacker.
+
+signature of Ty Coon, 1 April 1990
+Ty Coon, President of Vice
+
+ That's all there is to it!
+
+ GNU Library General Public License Version 2
+
+ Version 2, June 1991
+Copyright (C) 1991 Free Software Foundation, Inc.
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is
+numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+Preamble
+
+ The licenses for most software are designed to take away your freedom
+ to share and change it. By contrast, the GNU General Public Licenses
+ are intended to guarantee your freedom to share and change free
+ software--to make sure the software is free for all its users.
+
+ This license, the Library General Public License, applies to some
+ specially designated Free Software Foundation software, and to any
+ other libraries whose authors decide to use it. You can use it for your
+ libraries, too.
+
+ When we speak of free software, we are referring to freedom, not price.
+ Our General Public Licenses are designed to make sure that you have the
+ freedom to distribute copies of free software (and charge for this
+ service if you wish), that you receive source code or can get it if you
+ want it, that you can change the software or use pieces of it in new
+ free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid anyone
+ to deny you these rights or to ask you to surrender the rights. These
+ restrictions translate to certain responsibilities for you if you
+ distribute copies of the library, or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis or
+ for a fee, you must give the recipients all the rights that we gave
+ you. You must make sure that they, too, receive or can get the source
+ code. If you link a program with the library, you must provide complete
+ object files to the recipients so that they can relink them with the
+ library, after making changes to the library and recompiling it. And
+ you must show them these terms so they know their rights.
+
+ Our method of protecting your rights has two steps: (1) copyright the
+ library, and (2) offer you this license which gives you legal
+ permission to copy, distribute and/or modify the library.
+
+ Also, for each distributor's protection, we want to make certain that
+ everyone understands that there is no warranty for this free library.
+ If the library is modified by someone else and passed on, we want its
+ recipients to know that what they have is not the original version, so
+ that any problems introduced by others will not reflect on the original
+ authors' reputations.
+
+ Finally, any free program is threatened constantly by software patents.
+ We wish to avoid the danger that companies distributing free software
+ will individually obtain patent licenses, thus in effect transforming
+ the program into proprietary software. To prevent this, we have made it
+ clear that any patent must be licensed for everyone's free use or not
+ licensed at all.
+
+ Most GNU software, including some libraries, is covered by the ordinary
+ GNU General Public License, which was designed for utility programs.
+ This license, the GNU Library General Public License, applies to
+ certain designated libraries. This license is quite different from the
+ ordinary one; be sure to read it in full, and don't assume that
+ anything in it is the same as in the ordinary license.
+
+ The reason we have a separate public license for some libraries is that
+ they blur the distinction we usually make between modifying or adding
+ to a program and simply using it. Linking a program with a library,
+ without changing the library, is in some sense simply using the
+ library, and is analogous to running a utility program or application
+ program. However, in a textual and legal sense, the linked executable
+ is a combined work, a derivative of the original library, and the
+ ordinary General Public License treats it as such.
+
+ Because of this blurred distinction, using the ordinary General Public
+ License for libraries did not effectively promote software sharing,
+ because most developers did not use the libraries. We concluded that
+ weaker conditions might promote sharing better.
+
+ However, unrestricted linking of non-free programs would deprive the
+ users of those programs of all benefit from the free status of the
+ libraries themselves. This Library General Public License is intended
+ to permit developers of non-free programs to use free libraries, while
+ preserving your freedom as a user of such programs to change the free
+ libraries that are incorporated in them. (We have not seen how to
+ achieve this as regards changes in header files, but we have achieved
+ it as regards changes in the actual functions of the Library.) The hope
+ is that this will lead to faster development of free libraries.
+
+ The precise terms and conditions for copying, distribution and
+ modification follow. Pay close attention to the difference between a
+ "work based on the library" and a "work that uses the library". The
+ former contains code derived from the library, while the latter only
+ works together with the library.
+
+ Note that it is possible for a library to be covered by the ordinary
+ General Public License rather than by this special one.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library which
+ contains a notice placed by the copyright holder or other authorized
+ party saying it may be distributed under the terms of this Library
+ General Public License (also called "this License"). Each licensee is
+ addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+ prepared so as to be conveniently linked with application programs
+ (which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work which
+ has been distributed under these terms. A "work based on the Library"
+ means either the Library or any derivative work under copyright law:
+ that is to say, a work containing the Library or a portion of it,
+ either verbatim or with modifications and/or translated
+ straightforwardly into another language. (Hereinafter, translation is
+ included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+ making modifications to it. For a library, complete source code means
+ all the source code for all modules it contains, plus any associated
+ interface definition files, plus the scripts used to control
+ compilation and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+ covered by this License; they are outside its scope. The act of running
+ a program using the Library is not restricted, and output from such a
+ program is covered only if its contents constitute a work based on the
+ Library (independent of the use of the Library in a tool for writing
+ it). Whether that is true depends on what the Library does and what the
+ program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+ complete source code as you receive it, in any medium, provided that
+ you conspicuously and appropriately publish on each copy an appropriate
+ copyright notice and disclaimer of warranty; keep intact all the
+ notices that refer to this License and to the absence of any warranty;
+ and distribute a copy of this License along with the Library.
+
+ You may charge a fee for the physical act of transferring a copy, and
+ you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Library or any portion of
+ it, thus forming a work based on the Library, and copy and distribute
+ such modifications or work under the terms of Section 1 above, provided
+ that you also meet all of these conditions:
+ * a) The modified work must itself be a software library.
+ * b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+ * c) You must cause the whole of the work to be licensed at no charge
+ to all third parties under the terms of this License.
+ * d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility is
+ invoked, then you must make a good faith effort to ensure that, in
+ the event an application does not supply such function or table,
+ the facility still operates, and performs whatever part of its
+ purpose remains meaningful.
+ (For example, a function in a library to compute square roots has a
+ purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square root
+ function must still compute square roots.)
+
+ These requirements apply to the modified work as a whole. If
+ identifiable sections of that work are not derived from the Library,
+ and can be reasonably considered independent and separate works in
+ themselves, then this License, and its terms, do not apply to those
+ sections when you distribute them as separate works. But when you
+ distribute the same sections as part of a whole which is a work based
+ on the Library, the distribution of the whole must be on the terms of
+ this License, whose permissions for other licensees extend to the
+ entire whole, and thus to each and every part regardless of who wrote
+ it.
+
+ Thus, it is not the intent of this section to claim rights or contest
+ your rights to work written entirely by you; rather, the intent is to
+ exercise the right to control the distribution of derivative or
+ collective works based on the Library.
+
+ In addition, mere aggregation of another work not based on the Library
+ with the Library (or with a work based on the Library) on a volume of a
+ storage or distribution medium does not bring the other work under the
+ scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+ License instead of this License to a given copy of the Library. To do
+ this, you must alter all the notices that refer to this License, so
+ that they refer to the ordinary GNU General Public License, version 2,
+ instead of to this License. (If a newer version than version 2 of the
+ ordinary GNU General Public License has appeared, then you can specify
+ that version instead if you wish.) Do not make any other change in
+ these notices.
+
+ Once this change is made in a given copy, it is irreversible for that
+ copy, so the ordinary GNU General Public License applies to all
+ subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of the
+ Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or derivative
+ of it, under Section 2) in object code or executable form under the
+ terms of Sections 1 and 2 above provided that you accompany it with the
+ complete corresponding machine-readable source code, which must be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy from
+ a designated place, then offering equivalent access to copy the source
+ code from the same place satisfies the requirement to distribute the
+ source code, even though third parties are not compelled to copy the
+ source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the Library,
+ but is designed to work with the Library by being compiled or linked
+ with it, is called a "work that uses the Library". Such a work, in
+ isolation, is not a derivative work of the Library, and therefore falls
+ outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+ creates an executable that is a derivative of the Library (because it
+ contains portions of the Library), rather than a "work that uses the
+ library". The executable is therefore covered by this License. Section
+ 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+ that is part of the Library, the object code for the work may be a
+ derivative work of the Library even though the source code is not.
+ Whether this is true is especially significant if the work can be
+ linked without the Library, or if the work is itself a library. The
+ threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data structure
+ layouts and accessors, and small macros and small inline functions (ten
+ lines or less in length), then the use of the object file is
+ unrestricted, regardless of whether it is legally a derivative work.
+ (Executables containing this object code plus portions of the Library
+ will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+ distribute the object code for the work under the terms of Section 6.
+ Any executables containing that work also fall under Section 6, whether
+ or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also compile or link
+ a "work that uses the Library" with the Library to produce a work
+ containing portions of the Library, and distribute that work under
+ terms of your choice, provided that the terms permit modification of
+ the work for the customer's own use and reverse engineering for
+ debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+ Library is used in it and that the Library and its use are covered by
+ this License. You must supply a copy of this License. If the work
+ during execution displays copyright notices, you must include the
+ copyright notice for the Library among them, as well as a reference
+ directing the user to the copy of this License. Also, you must do one
+ of these things:
+ * a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood that
+ the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+ * b) Accompany the work with a written offer, valid for at least
+ three years, to give the same user the materials specified in
+ Subsection 6a, above, for a charge no more than the cost of
+ performing this distribution.
+ * c) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+ * d) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+ Library" must include any data and utility programs needed for
+ reproducing the executable from it. However, as a special exception,
+ the source code distributed need not include anything that is normally
+ distributed (in either source or binary form) with the major components
+ (compiler, kernel, and so on) of the operating system on which the
+ executable runs, unless that component itself accompanies the
+ executable.
+
+ It may happen that this requirement contradicts the license
+ restrictions of other proprietary libraries that do not normally
+ accompany the operating system. Such a contradiction means you cannot
+ use both them and the Library together in an executable that you
+ distribute.
+
+ 7. You may place library facilities that are a work based on the
+ Library side-by-side in a single library together with other library
+ facilities not covered by this License, and distribute such a combined
+ library, provided that the separate distribution of the work based on
+ the Library and of the other library facilities is otherwise permitted,
+ and provided that you do these two things:
+ * a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library facilities.
+ This must be distributed under the terms of the Sections above.
+ * b) Give prominent notice with the combined library of the fact that
+ part of it is a work based on the Library, and explaining where to
+ find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute the
+ Library except as expressly provided under this License. Any attempt
+ otherwise to copy, modify, sublicense, link with, or distribute the
+ Library is void, and will automatically terminate your rights under
+ this License. However, parties who have received copies, or rights,
+ from you under this License will not have their licenses terminated so
+ long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+ signed it. However, nothing else grants you permission to modify or
+ distribute the Library or its derivative works. These actions are
+ prohibited by law if you do not accept this License. Therefore, by
+ modifying or distributing the Library (or any work based on the
+ Library), you indicate your acceptance of this License to do so, and
+ all its terms and conditions for copying, distributing or modifying the
+ Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+ Library), the recipient automatically receives a license from the
+ original licensor to copy, distribute, link with or modify the Library
+ subject to these terms and conditions. You may not impose any further
+ restrictions on the recipients' exercise of the rights granted herein.
+ You are not responsible for enforcing compliance by third parties to
+ this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+ infringement or for any other reason (not limited to patent issues),
+ conditions are imposed on you (whether by court order, agreement or
+ otherwise) that contradict the conditions of this License, they do not
+ excuse you from the conditions of this License. If you cannot
+ distribute so as to satisfy simultaneously your obligations under this
+ License and any other pertinent obligations, then as a consequence you
+ may not distribute the Library at all. For example, if a patent license
+ would not permit royalty-free redistribution of the Library by all
+ those who receive copies directly or indirectly through you, then the
+ only way you could satisfy both it and this License would be to refrain
+ entirely from distribution of the Library.
+
+ If any portion of this section is held invalid or unenforceable under
+ any particular circumstance, the balance of the section is intended to
+ apply, and the section as a whole is intended to apply in other
+ circumstances.
+
+ It is not the purpose of this section to induce you to infringe any
+ patents or other property right claims or to contest validity of any
+ such claims; this section has the sole purpose of protecting the
+ integrity of the free software distribution system which is implemented
+ by public license practices. Many people have made generous
+ contributions to the wide range of software distributed through that
+ system in reliance on consistent application of that system; it is up
+ to the author/donor to decide if he or she is willing to distribute
+ software through any other system and a licensee cannot impose that
+ choice.
+
+ This section is intended to make thoroughly clear what is believed to
+ be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+ certain countries either by patents or by copyrighted interfaces, the
+ original copyright holder who places the Library under this License may
+ add an explicit geographical distribution limitation excluding those
+ countries, so that distribution is permitted only in or among countries
+ not thus excluded. In such case, this License incorporates the
+ limitation as if written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+ versions of the Library General Public License from time to time. Such
+ new versions will be similar in spirit to the present version, but may
+ differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the Library
+ specifies a version number of this License which applies to it and "any
+ later version", you have the option of following the terms and
+ conditions either of that version or of any later version published by
+ the Free Software Foundation. If the Library does not specify a license
+ version number, you may choose any version ever published by the Free
+ Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+ programs whose distribution conditions are incompatible with these,
+ write to the author to ask for permission. For software which is
+ copyrighted by the Free Software Foundation, write to the Free Software
+ Foundation; we sometimes make exceptions for this. Our decision will be
+ guided by the two goals of preserving the free status of all
+ derivatives of our free software and of promoting the sharing and reuse
+ of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+ WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+ EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+ OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND,
+ EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH
+ YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
+ NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+ WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+ AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+ FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+ LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+ RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+ FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+ possible use to the public, we recommend making it free software that
+ everyone can redistribute and change. You can do so by permitting
+ redistribution under these terms (or, alternatively, under the terms of
+ the ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It
+ is safest to attach them to the start of each source file to most
+ effectively convey the exclusion of warranty; and each file should have
+ at least the "copyright" line and a pointer to where the full notice is
+ found.
+one line to give the library's name and an idea of what it does.
+Copyright (C) year name of author
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the
+Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+Boston, MA 02110-1301, USA.
+
+ Also add information on how to contact you by electronic and paper
+ mail.
+
+ You should also get your employer (if you work as a programmer) or your
+ school, if any, to sign a "copyright disclaimer" for the library, if
+ necessary. Here is a sample; alter the names:
+Yoyodyne, Inc., hereby disclaims all copyright interest in
+the library `Frob' (a library for tweaking knobs) written
+by James Random Hacker.
+
+signature of Ty Coon, 1 April 1990
+Ty Coon, President of Vice
+
+ That's all there is to it!
+
+ GNU General Public License Version 3
+
+ Copyright © 2007 Free Software Foundation, Inc.
+
+ Everyone is permitted to copy and distribute verbatim copies of this
+ license document, but changing it is not allowed.
+
+Preamble
+
+ The GNU General Public License is a free, copyleft license for software
+ and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+ to take away your freedom to share and change the works. By contrast,
+ the GNU General Public License is intended to guarantee your freedom to
+ share and change all versions of a program--to make sure it remains
+ free software for all its users. We, the Free Software Foundation, use
+ the GNU General Public License for most of our software; it applies
+ also to any other work released this way by its authors. You can apply
+ it to your programs, too.
+
+ When we speak of free software, we are referring to freedom, not price.
+ Our General Public Licenses are designed to make sure that you have the
+ freedom to distribute copies of free software (and charge for them if
+ you wish), that you receive source code or can get it if you want it,
+ that you can change the software or use pieces of it in new free
+ programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+ these rights or asking you to surrender the rights. Therefore, you have
+ certain responsibilities if you distribute copies of the software, or
+ if you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether gratis
+ or for a fee, you must pass on to the recipients the same freedoms that
+ you received. You must make sure that they, too, receive or can get the
+ source code. And you must show them these terms so they know their
+ rights.
+
+ Developers that use the GNU GPL protect your rights with two steps: (1)
+ assert copyright on the software, and (2) offer you this License giving
+ you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+ that there is no warranty for this free software. For both users' and
+ authors' sake, the GPL requires that modified versions be marked as
+ changed, so that their problems will not be attributed erroneously to
+ authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+ modified versions of the software inside them, although the
+ manufacturer can do so. This is fundamentally incompatible with the aim
+ of protecting users' freedom to change the software. The systematic
+ pattern of such abuse occurs in the area of products for individuals to
+ use, which is precisely where it is most unacceptable. Therefore, we
+ have designed this version of the GPL to prohibit the practice for
+ those products. If such problems arise substantially in other domains,
+ we stand ready to extend this provision to those domains in future
+ versions of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+ States should not allow patents to restrict development and use of
+ software on general-purpose computers, but in those that do, we wish to
+ avoid the special danger that patents applied to a free program could
+ make it effectively proprietary. To prevent this, the GPL assures that
+ patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+ modification follow.
+
+TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ “This License” refers to version 3 of the GNU General Public License.
+
+ “Copyright” also means copyright-like laws that apply to other kinds of
+ works, such as semiconductor masks.
+
+ “The Program” refers to any copyrightable work licensed under this
+ License. Each licensee is addressed as “you”. “Licensees” and
+ “recipients” may be individuals or organizations.
+
+ To “modify” a work means to copy from or adapt all or part of the work
+ in a fashion requiring copyright permission, other than the making of
+ an exact copy. The resulting work is called a “modified version” of the
+ earlier work or a work “based on” the earlier work.
+
+ A “covered work” means either the unmodified Program or a work based on
+ the Program.
+
+ To “propagate” a work means to do anything with it that, without
+ permission, would make you directly or secondarily liable for
+ infringement under applicable copyright law, except executing it on a
+ computer or modifying a private copy. Propagation includes copying,
+ distribution (with or without modification), making available to the
+ public, and in some countries other activities as well.
+
+ To “convey” a work means any kind of propagation that enables other
+ parties to make or receive copies. Mere interaction with a user through
+ a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays “Appropriate Legal Notices” to
+ the extent that it includes a convenient and prominently visible
+ feature that (1) displays an appropriate copyright notice, and (2)
+ tells the user that there is no warranty for the work (except to the
+ extent that warranties are provided), that licensees may convey the
+ work under this License, and how to view a copy of this License. If the
+ interface presents a list of user commands or options, such as a menu,
+ a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The “source code” for a work means the preferred form of the work for
+ making modifications to it. “Object code” means any non-source form of
+ a work.
+
+ A “Standard Interface” means an interface that either is an official
+ standard defined by a recognized standards body, or, in the case of
+ interfaces specified for a particular programming language, one that is
+ widely used among developers working in that language.
+
+ The “System Libraries” of an executable work include anything, other
+ than the work as a whole, that (a) is included in the normal form of
+ packaging a Major Component, but which is not part of that Major
+ Component, and (b) serves only to enable use of the work with that
+ Major Component, or to implement a Standard Interface for which an
+ implementation is available to the public in source code form. A “Major
+ Component”, in this context, means a major essential component (kernel,
+ window system, and so on) of the specific operating system (if any) on
+ which the executable work runs, or a compiler used to produce the work,
+ or an object code interpreter used to run it.
+
+ The “Corresponding Source” for a work in object code form means all the
+ source code needed to generate, install, and (for an executable work)
+ run the object code and to modify the work, including scripts to
+ control those activities. However, it does not include the work's
+ System Libraries, or general-purpose tools or generally available free
+ programs which are used unmodified in performing those activities but
+ which are not part of the work. For example, Corresponding Source
+ includes interface definition files associated with source files for
+ the work, and the source code for shared libraries and dynamically
+ linked subprograms that the work is specifically designed to require,
+ such as by intimate data communication or control flow between those
+ subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users can
+ regenerate automatically from other parts of the Corresponding Source.
+
+ The Corresponding Source for a work in source code form is that same
+ work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+ copyright on the Program, and are irrevocable provided the stated
+ conditions are met. This License explicitly affirms your unlimited
+ permission to run the unmodified Program. The output from running a
+ covered work is covered by this License only if the output, given its
+ content, constitutes a covered work. This License acknowledges your
+ rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not convey,
+ without conditions so long as your license otherwise remains in force.
+ You may convey covered works to others for the sole purpose of having
+ them make modifications exclusively for you, or provide you with
+ facilities for running those works, provided that you comply with the
+ terms of this License in conveying all material for which you do not
+ control copyright. Those thus making or running the covered works for
+ you must do so exclusively on your behalf, under your direction and
+ control, on terms that prohibit them from making any copies of your
+ copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under the
+ conditions stated below. Sublicensing is not allowed; section 10 makes
+ it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+ measure under any applicable law fulfilling obligations under article
+ 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar
+ laws prohibiting or restricting circumvention of such measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+ circumvention of technological measures to the extent such
+ circumvention is effected by exercising rights under this License with
+ respect to the covered work, and you disclaim any intention to limit
+ operation or modification of the work as a means of enforcing, against
+ the work's users, your or third parties' legal rights to forbid
+ circumvention of technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+ receive it, in any medium, provided that you conspicuously and
+ appropriately publish on each copy an appropriate copyright notice;
+ keep intact all notices stating that this License and any
+ non-permissive terms added in accord with section 7 apply to the code;
+ keep intact all notices of the absence of any warranty; and give all
+ recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey, and
+ you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+ produce it from the Program, in the form of source code under the terms
+ of section 4, provided that you also meet all of these conditions:
+ * a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+ * b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to “keep
+ intact all notices”.
+ * c) You must license the entire work, as a whole, under this License
+ to anyone who comes into possession of a copy. This License will
+ therefore apply, along with any applicable section 7 additional
+ terms, to the whole of the work, and all its parts, regardless of
+ how they are packaged. This License gives no permission to license
+ the work in any other way, but it does not invalidate such
+ permission if you have separately received it.
+ * d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your work
+ need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+ works, which are not by their nature extensions of the covered work,
+ and which are not combined with it such as to form a larger program, in
+ or on a volume of a storage or distribution medium, is called an
+ “aggregate” if the compilation and its resulting copyright are not used
+ to limit the access or legal rights of the compilation's users beyond
+ what the individual works permit. Inclusion of a covered work in an
+ aggregate does not cause this License to apply to the other parts of
+ the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms of
+ sections 4 and 5, provided that you also convey the machine-readable
+ Corresponding Source under the terms of this License, in one of these
+ ways:
+ * a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium customarily
+ used for software interchange.
+ * b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as long
+ as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the Corresponding Source
+ from a network server at no charge.
+ * c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This alternative
+ is allowed only occasionally and noncommercially, and only if you
+ received the object code with such an offer, in accord with
+ subsection 6b.
+ * d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+ * e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+ from the Corresponding Source as a System Library, need not be included
+ in conveying the object code work.
+
+ A “User Product” is either (1) a “consumer product”, which means any
+ tangible personal property which is normally used for personal, family,
+ or household purposes, or (2) anything designed or sold for
+ incorporation into a dwelling. In determining whether a product is a
+ consumer product, doubtful cases shall be resolved in favor of
+ coverage. For a particular product received by a particular user,
+ “normally used” refers to a typical or common use of that class of
+ product, regardless of the status of the particular user or of the way
+ in which the particular user actually uses, or expects or is expected
+ to use, the product. A product is a consumer product regardless of
+ whether the product has substantial commercial, industrial or
+ non-consumer uses, unless such uses represent the only significant mode
+ of use of the product.
+
+ “Installation Information” for a User Product means any methods,
+ procedures, authorization keys, or other information required to
+ install and execute modified versions of a covered work in that User
+ Product from a modified version of its Corresponding Source. The
+ information must suffice to ensure that the continued functioning of
+ the modified object code is in no case prevented or interfered with
+ solely because modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+ specifically for use in, a User Product, and the conveying occurs as
+ part of a transaction in which the right of possession and use of the
+ User Product is transferred to the recipient in perpetuity or for a
+ fixed term (regardless of how the transaction is characterized), the
+ Corresponding Source conveyed under this section must be accompanied by
+ the Installation Information. But this requirement does not apply if
+ neither you nor any third party retains the ability to install modified
+ object code on the User Product (for example, the work has been
+ installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+ requirement to continue to provide support service, warranty, or
+ updates for a work that has been modified or installed by the
+ recipient, or for the User Product in which it has been modified or
+ installed. Access to a network may be denied when the modification
+ itself materially and adversely affects the operation of the network or
+ violates the rules and protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+ in accord with this section must be in a format that is publicly
+ documented (and with an implementation available to the public in
+ source code form), and must require no special password or key for
+ unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ “Additional permissions” are terms that supplement the terms of this
+ License by making exceptions from one or more of its conditions.
+ Additional permissions that are applicable to the entire Program shall
+ be treated as though they were included in this License, to the extent
+ that they are valid under applicable law. If additional permissions
+ apply only to part of the Program, that part may be used separately
+ under those permissions, but the entire Program remains governed by
+ this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option remove
+ any additional permissions from that copy, or from any part of it.
+ (Additional permissions may be written to require their own removal in
+ certain cases when you modify the work.) You may place additional
+ permissions on material, added by you to a covered work, for which you
+ have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+ add to a covered work, you may (if authorized by the copyright holders
+ of that material) supplement the terms of this License with terms:
+ * a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+ * b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+ * c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+ * d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+ * e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+ * f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions
+ of it) with contractual assumptions of liability to the recipient,
+ for any liability that these contractual assumptions directly
+ impose on those licensors and authors.
+
+ All other non-permissive additional terms are considered “further
+ restrictions” within the meaning of section 10. If the Program as you
+ received it, or any part of it, contains a notice stating that it is
+ governed by this License along with a term that is a further
+ restriction, you may remove that term. If a license document contains a
+ further restriction but permits relicensing or conveying under this
+ License, you may add to a covered work material governed by the terms
+ of that license document, provided that the further restriction does
+ not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+ must place, in the relevant source files, a statement of the additional
+ terms that apply to those files, or a notice indicating where to find
+ the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+ form of a separately written license, or stated as exceptions; the
+ above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+ provided under this License. Any attempt otherwise to propagate or
+ modify it is void, and will automatically terminate your rights under
+ this License (including any patent licenses granted under the third
+ paragraph of section 11).
+
+ However, if you cease all violation of this License, then your license
+ from a particular copyright holder is reinstated (a) provisionally,
+ unless and until the copyright holder explicitly and finally terminates
+ your license, and (b) permanently, if the copyright holder fails to
+ notify you of the violation by some reasonable means prior to 60 days
+ after the cessation.
+
+ Moreover, your license from a particular copyright holder is reinstated
+ permanently if the copyright holder notifies you of the violation by
+ some reasonable means, this is the first time you have received notice
+ of violation of this License (for any work) from that copyright holder,
+ and you cure the violation prior to 30 days after your receipt of the
+ notice.
+
+ Termination of your rights under this section does not terminate the
+ licenses of parties who have received copies or rights from you under
+ this License. If your rights have been terminated and not permanently
+ reinstated, you do not qualify to receive new licenses for the same
+ material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or run
+ a copy of the Program. Ancillary propagation of a covered work
+ occurring solely as a consequence of using peer-to-peer transmission to
+ receive a copy likewise does not require acceptance. However, nothing
+ other than this License grants you permission to propagate or modify
+ any covered work. These actions infringe copyright if you do not accept
+ this License. Therefore, by modifying or propagating a covered work,
+ you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+ receives a license from the original licensors, to run, modify and
+ propagate that work, subject to this License. You are not responsible
+ for enforcing compliance by third parties with this License.
+
+ An “entity transaction” is a transaction transferring control of an
+ organization, or substantially all assets of one, or subdividing an
+ organization, or merging organizations. If propagation of a covered
+ work results from an entity transaction, each party to that transaction
+ who receives a copy of the work also receives whatever licenses to the
+ work the party's predecessor in interest had or could give under the
+ previous paragraph, plus a right to possession of the Corresponding
+ Source of the work from the predecessor in interest, if the predecessor
+ has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+ rights granted or affirmed under this License. For example, you may not
+ impose a license fee, royalty, or other charge for exercise of rights
+ granted under this License, and you may not initiate litigation
+ (including a cross-claim or counterclaim in a lawsuit) alleging that
+ any patent claim is infringed by making, using, selling, offering for
+ sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A “contributor” is a copyright holder who authorizes use under this
+ License of the Program or a work on which the Program is based. The
+ work thus licensed is called the contributor's “contributor version”.
+
+ A contributor's “essential patent claims” are all patent claims owned
+ or controlled by the contributor, whether already acquired or hereafter
+ acquired, that would be infringed by some manner, permitted by this
+ License, of making, using, or selling its contributor version, but do
+ not include claims that would be infringed only as a consequence of
+ further modification of the contributor version. For purposes of this
+ definition, “control” includes the right to grant patent sublicenses in
+ a manner consistent with the requirements of this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+ patent license under the contributor's essential patent claims, to
+ make, use, sell, offer for sale, import and otherwise run, modify and
+ propagate the contents of its contributor version.
+
+ In the following three paragraphs, a “patent license” is any express
+ agreement or commitment, however denominated, not to enforce a patent
+ (such as an express permission to practice a patent or covenant not to
+ sue for patent infringement). To “grant” such a patent license to a
+ party means to make such an agreement or commitment not to enforce a
+ patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+ and the Corresponding Source of the work is not available for anyone to
+ copy, free of charge and under the terms of this License, through a
+ publicly available network server or other readily accessible means,
+ then you must either (1) cause the Corresponding Source to be so
+ available, or (2) arrange to deprive yourself of the benefit of the
+ patent license for this particular work, or (3) arrange, in a manner
+ consistent with the requirements of this License, to extend the patent
+ license to downstream recipients. “Knowingly relying” means you have
+ actual knowledge that, but for the patent license, your conveying the
+ covered work in a country, or your recipient's use of the covered work
+ in a country, would infringe one or more identifiable patents in that
+ country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+ arrangement, you convey, or propagate by procuring conveyance of, a
+ covered work, and grant a patent license to some of the parties
+ receiving the covered work authorizing them to use, propagate, modify
+ or convey a specific copy of the covered work, then the patent license
+ you grant is automatically extended to all recipients of the covered
+ work and works based on it.
+
+ A patent license is “discriminatory” if it does not include within the
+ scope of its coverage, prohibits the exercise of, or is conditioned on
+ the non-exercise of one or more of the rights that are specifically
+ granted under this License. You may not convey a covered work if you
+ are a party to an arrangement with a third party that is in the
+ business of distributing software, under which you make payment to the
+ third party based on the extent of your activity of conveying the work,
+ and under which the third party grants, to any of the parties who would
+ receive the covered work from you, a discriminatory patent license (a)
+ in connection with copies of the covered work conveyed by you (or
+ copies made from those copies), or (b) primarily for and in connection
+ with specific products or compilations that contain the covered work,
+ unless you entered into that arrangement, or that patent license was
+ granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting any
+ implied license or other defenses to infringement that may otherwise be
+ available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+ otherwise) that contradict the conditions of this License, they do not
+ excuse you from the conditions of this License. If you cannot convey a
+ covered work so as to satisfy simultaneously your obligations under
+ this License and any other pertinent obligations, then as a consequence
+ you may not convey it at all. For example, if you agree to terms that
+ obligate you to collect a royalty for further conveying from those to
+ whom you convey the Program, the only way you could satisfy both those
+ terms and this License would be to refrain entirely from conveying the
+ Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+ permission to link or combine any covered work with a work licensed
+ under version 3 of the GNU Affero General Public License into a single
+ combined work, and to convey the resulting work. The terms of this
+ License will continue to apply to the part which is the covered work,
+ but the special requirements of the GNU Affero General Public License,
+ section 13, concerning interaction through a network will apply to the
+ combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+ the GNU General Public License from time to time. Such new versions
+ will be similar in spirit to the present version, but may differ in
+ detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the Program
+ specifies that a certain numbered version of the GNU General Public
+ License “or any later version” applies to it, you have the option of
+ following the terms and conditions either of that numbered version or
+ of any later version published by the Free Software Foundation. If the
+ Program does not specify a version number of the GNU General Public
+ License, you may choose any version ever published by the Free Software
+ Foundation.
+
+ If the Program specifies that a proxy can decide which future versions
+ of the GNU General Public License can be used, that proxy's public
+ statement of acceptance of a version permanently authorizes you to
+ choose that version for the Program.
+
+ Later license versions may give you additional or different
+ permissions. However, no additional obligations are imposed on any
+ author or copyright holder as a result of your choosing to follow a
+ later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+ APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+ HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT
+ WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
+ OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU
+ ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR
+ CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+ INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES
+ ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT
+ NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES
+ SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO
+ OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY
+ HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+ above cannot be given local legal effect according to their terms,
+ reviewing courts shall apply local law that most closely approximates
+ an absolute waiver of all civil liability in connection with the
+ Program, unless a warranty or assumption of liability accompanies a
+ copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+ possible use to the public, the best way to achieve this is to make it
+ free software which everyone can redistribute and change under these
+ terms.
+
+ To do so, attach the following notices to the program. It is safest to
+ attach them to the start of each source file to most effectively state
+ the exclusion of warranty; and each file should have at least the
+ “copyright” line and a pointer to where the full notice is found.
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ Also add information on how to contact you by electronic and paper
+ mail.
+
+ If the program does terminal interaction, make it output a short notice
+ like this when it starts in an interactive mode:
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+ The hypothetical commands `show w' and `show c' should show the
+ appropriate parts of the General Public License. Of course, your
+ program's commands might be different; for a GUI interface, you would
+ use an “about box”.
+
+ You should also get your employer (if you work as a programmer) or
+ school, if any, to sign a “copyright disclaimer” for the program, if
+ necessary. For more information on this, and how to apply and follow
+ the GNU GPL, see .
+
+ The GNU General Public License does not permit incorporating your
+ program into proprietary programs. If your program is a subroutine
+ library, you may consider it more useful to permit linking proprietary
+ applications with the library. If this is what you want to do, use the
+ GNU Lesser General Public License instead of this License. But first,
+ please read .
+
+ GNU General Public License Version 2
+
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+Preamble
+
+ The licenses for most software are designed to take away your freedom
+ to share and change it. By contrast, the GNU General Public License is
+ intended to guarantee your freedom to share and change free
+ software--to make sure the software is free for all its users. This
+ General Public License applies to most of the Free Software
+ Foundation's software and to any other program whose authors commit to
+ using it. (Some other Free Software Foundation software is covered by
+ the GNU Lesser General Public License instead.) You can apply it to
+ your programs, too.
+
+ When we speak of free software, we are referring to freedom, not price.
+ Our General Public Licenses are designed to make sure that you have the
+ freedom to distribute copies of free software (and charge for this
+ service if you wish), that you receive source code or can get it if you
+ want it, that you can change the software or use pieces of it in new
+ free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid anyone
+ to deny you these rights or to ask you to surrender the rights. These
+ restrictions translate to certain responsibilities for you if you
+ distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether gratis
+ or for a fee, you must give the recipients all the rights that you
+ have. You must make sure that they, too, receive or can get the source
+ code. And you must show them these terms so they know their rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+ (2) offer you this license which gives you legal permission to copy,
+ distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+ that everyone understands that there is no warranty for this free
+ software. If the software is modified by someone else and passed on, we
+ want its recipients to know that what they have is not the original, so
+ that any problems introduced by others will not reflect on the original
+ authors' reputations.
+
+ Finally, any free program is threatened constantly by software patents.
+ We wish to avoid the danger that redistributors of a free program will
+ individually obtain patent licenses, in effect making the program
+ proprietary. To prevent this, we have made it clear that any patent
+ must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+ modification follow.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains a
+ notice placed by the copyright holder saying it may be distributed
+ under the terms of this General Public License. The "Program", below,
+ refers to any such program or work, and a "work based on the Program"
+ means either the Program or any derivative work under copyright law:
+ that is to say, a work containing the Program or a portion of it,
+ either verbatim or with modifications and/or translated into another
+ language. (Hereinafter, translation is included without limitation in
+ the term "modification".) Each licensee is addressed as "you".
+
+ Activities other than copying, distribution and modification are not
+ covered by this License; they are outside its scope. The act of running
+ the Program is not restricted, and the output from the Program is
+ covered only if its contents constitute a work based on the Program
+ (independent of having been made by running the Program). Whether that
+ is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's source
+ code as you receive it, in any medium, provided that you conspicuously
+ and appropriately publish on each copy an appropriate copyright notice
+ and disclaimer of warranty; keep intact all the notices that refer to
+ this License and to the absence of any warranty; and give any other
+ recipients of the Program a copy of this License along with the
+ Program.
+
+ 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 Program or any portion of
+ it, thus forming a work based on the Program, and copy and distribute
+ such modifications or work under the terms of Section 1 above, provided
+ that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+ b) You must cause any work that you distribute or publish, that
+ in whole or in part contains or is derived from the Program or
+ any part thereof, to be licensed as a whole at no charge to all
+ third parties under the terms of this License.
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you
+ provide a warranty) and that users may redistribute the program
+ under these conditions, and telling the user how to view a copy
+ of this License. (Exception: if the Program itself is
+ interactive but does not normally print such an announcement,
+ your work based on the Program is not required to print an
+ announcement.)
+
+ These requirements apply to the modified work as a whole. If
+ identifiable sections of that work are not derived from the Program,
+ and can be reasonably considered independent and separate works in
+ themselves, then this License, and its terms, do not apply to those
+ sections when you distribute them as separate works. But when you
+ distribute the same sections as part of a whole which is a work based
+ on the Program, the distribution of the whole must be on the terms of
+ this License, whose permissions for other licensees extend to the
+ entire whole, and thus to each and every part regardless of who wrote
+ it.
+
+ Thus, it is not the intent of this section to claim rights or contest
+ your rights to work written entirely by you; rather, the intent is to
+ exercise the right to control the distribution of derivative or
+ collective works based on the Program.
+
+ In addition, mere aggregation of another work not based on the Program
+ with the Program (or with a work based on the Program) on a volume of a
+ storage or distribution medium does not bring the other work under the
+ scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+ under Section 2) in object code or executable form under the terms of
+ Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of
+ Sections 1 and 2 above on a medium customarily used for software
+ interchange; or,
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a
+ medium customarily used for software interchange; or,
+ c) Accompany it with the information you received as to the
+ offer to distribute corresponding source code. (This alternative
+ is allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+ The source code for a work means the preferred form of the work for
+ making modifications to it. For an executable work, complete source
+ code means all the source code for all modules it contains, plus any
+ associated interface definition files, plus the scripts used to control
+ compilation and installation of the executable. However, as a special
+ exception, the source code distributed need not include anything that
+ is normally distributed (in either source or binary form) with the
+ major components (compiler, kernel, and so on) of the operating system
+ on which the executable runs, unless that component itself accompanies
+ the executable.
+
+ If distribution of executable or object code is made by offering access
+ to copy from a designated place, then offering equivalent access to
+ copy the source code from the same place counts as distribution of the
+ source code, even though third parties are not compelled to copy the
+ source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+ except as expressly provided under this License. Any attempt otherwise
+ to copy, modify, sublicense or distribute the Program is void, and will
+ automatically terminate your rights under this License. However,
+ parties who have received copies, or rights, from you under this
+ License will not have their licenses terminated so long as such parties
+ remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+ signed it. However, nothing else grants you permission to modify or
+ distribute the Program or its derivative works. These actions are
+ prohibited by law if you do not accept this License. Therefore, by
+ modifying or distributing the Program (or any work based on the
+ Program), you indicate your acceptance of this License to do so, and
+ all its terms and conditions for copying, distributing or modifying the
+ Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+ Program), the recipient automatically receives a license from the
+ original licensor to copy, distribute or modify the Program 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 to this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+ infringement or for any other reason (not limited to patent issues),
+ conditions are imposed on you (whether by court order, agreement or
+ otherwise) that contradict the conditions of this License, they do not
+ excuse you from the conditions of this License. If you cannot
+ distribute so as to satisfy simultaneously your obligations under this
+ License and any other pertinent obligations, then as a consequence you
+ may not distribute the Program at all. For example, if a patent license
+ would not permit royalty-free redistribution of the Program by all
+ those who receive copies directly or indirectly through you, then the
+ only way you could satisfy both it and this License would be to refrain
+ entirely from distribution of the Program.
+
+ If any portion of this section is held invalid or unenforceable under
+ any particular circumstance, the balance of the section is intended to
+ apply and the section as a whole is intended to apply in other
+ circumstances.
+
+ It is not the purpose of this section to induce you to infringe any
+ patents or other property right claims or to contest validity of any
+ such claims; this section has the sole purpose of protecting the
+ integrity of the free software distribution system, which is
+ implemented by public license practices. Many people have made generous
+ contributions to the wide range of software distributed through that
+ system in reliance on consistent application of that system; it is up
+ to the author/donor to decide if he or she is willing to distribute
+ software through any other system and a licensee cannot impose that
+ choice.
+
+ This section is intended to make thoroughly clear what is believed to
+ be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+ certain countries either by patents or by copyrighted interfaces, the
+ original copyright holder who places the Program under this License may
+ add an explicit geographical distribution limitation excluding those
+ countries, so that distribution is permitted only in or among countries
+ not thus excluded. In such case, this License incorporates the
+ limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+ of the General Public License from time to time. Such new versions will
+ be similar in spirit to the present version, but may differ in detail
+ to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the Program
+ specifies a version number of this License which applies to it and "any
+ later version", you have the option of following the terms and
+ conditions either of that version or of any later version published by
+ the Free Software Foundation. If the Program does not specify a version
+ number of this License, you may choose any version ever published by
+ the Free Software Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+ programs whose distribution conditions are different, write to the
+ author to ask for permission. For software which is copyrighted by the
+ Free Software Foundation, write to the Free Software Foundation; we
+ sometimes make exceptions for this. Our decision will be guided by the
+ two goals of preserving the free status of all derivatives of our free
+ software and of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO
+ WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+ EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+ OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND,
+ EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH
+ YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
+ NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+ WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+ AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU
+ FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+ PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+ RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+ FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF
+ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+ possible use to the public, the best way to achieve this is to make it
+ free software which everyone can redistribute and change under these
+ terms.
+
+ To do so, attach the following notices to the program. It is safest to
+ attach them to the start of each source file to most effectively convey
+ the exclusion of warranty; and each file should have at least the
+ "copyright" line and a pointer to where the full notice is found.
+one line to give the program's name and an idea of what it does.
+Copyright (C) yyyy name of author
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ Also add information on how to contact you by electronic and paper
+ mail.
+
+ If the program is interactive, make it output a short notice like this
+ when it starts in an interactive mode:
+Gnomovision version 69, Copyright (C) year name of author
+Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
+type `show w'. This is free software, and you are welcome
+to redistribute it under certain conditions; type `show c'
+for details.
+
+ The hypothetical commands `show w' and `show c' should show the
+ appropriate parts of the General Public License. Of course, the
+ commands you use may be called something other than `show w' and `show
+ c'; they could even be mouse-clicks or menu items--whatever suits your
+ program.
+
+ You should also get your employer (if you work as a programmer) or your
+ school, if any, to sign a "copyright disclaimer" for the program, if
+ necessary. Here is a sample; alter the names:
+Yoyodyne, Inc., hereby disclaims all copyright
+interest in the program `Gnomovision'
+(which makes passes at compilers) written
+by James Hacker.
+
+signature of Ty Coon, 1 April 1989
+Ty Coon, President of Vice
+
+ This General Public License does not permit incorporating your program
+ into proprietary programs. If your program is a subroutine library, you
+ may consider it more useful to permit linking proprietary applications
+ with the library. If this is what you want to do, use the GNU
+ Lesser General Public License instead of this License.
+
+ Mozilla Public License Version 1.1
+
+1. Definitions.
+
+ 1.0.1. "Commercial Use"
+ means distribution or otherwise making the Covered Code
+ available to a third party.
+
+ 1.1. "Contributor"
+ means each entity that creates or contributes to the creation of
+ Modifications.
+
+ 1.2. "Contributor Version"
+ means the combination of the Original Code, prior Modifications
+ used by a Contributor, and the Modifications made by that
+ particular Contributor.
+
+ 1.3. "Covered Code"
+ means the Original Code or Modifications or the combination of
+ the Original Code and Modifications, in each case including
+ portions thereof.
+
+ 1.4. "Electronic Distribution Mechanism"
+ means a mechanism generally accepted in the software development
+ community for the electronic transfer of data.
+
+ 1.5. "Executable"
+ means Covered Code in any form other than Source Code.
+
+ 1.6. "Initial Developer"
+ means the individual or entity identified as the Initial
+ Developer in the Source Code notice required by Exhibit A.
+
+ 1.7. "Larger Work"
+ means a work which combines Covered Code or portions thereof
+ with code not governed by the terms of this License.
+
+ 1.8. "License"
+ means this document.
+
+ 1.8.1. "Licensable"
+ means having the right to grant, to the maximum extent possible,
+ whether at the time of the initial grant or subsequently
+ acquired, any and all of the rights conveyed herein.
+
+ 1.9. "Modifications"
+ means any addition to or deletion from the substance or
+ structure of either the Original Code or any previous
+ Modifications. When Covered Code is released as a series of
+ files, a Modification is:
+
+ a.
+ Any addition to or deletion from the contents of a file containing
+ Original Code or previous Modifications.
+ b.
+ Any new file that contains any part of the Original Code or
+ previous Modifications.
+
+ 1.10. "Original Code"
+ means Source Code of computer software code which is described
+ in the Source Code notice required by Exhibit A as Original
+ Code, and which, at the time of its release under this License
+ is not already Covered Code governed by this License.
+
+ 1.10.1. "Patent Claims"
+ means any patent claim(s), now owned or hereafter acquired,
+ including without limitation, method, process, and apparatus
+ claims, in any patent Licensable by grantor.
+
+ 1.11. "Source Code"
+ means the preferred form of the Covered Code for making
+ modifications to it, including all modules it contains, plus any
+ associated interface definition files, scripts used to control
+ compilation and installation of an Executable, or source code
+ differential comparisons against either the Original Code or
+ another well known, available Covered Code of the Contributor's
+ choice. The Source Code can be in a compressed or archival form,
+ provided the appropriate decompression or de-archiving software
+ is widely available for no charge.
+
+ 1.12. "You" (or "Your")
+ means an individual or a legal entity exercising rights under,
+ and complying with all of the terms of, this License or a future
+ version of this License issued under Section 6.1. For legal
+ entities, "You" includes any entity which controls, is
+ controlled by, or is under common control with You. For purposes
+ of this definition, "control" means (a) the power, direct or
+ indirect, to cause the direction or management of such entity,
+ whether by contract or otherwise, or (b) ownership of more than
+ fifty percent (50%) of the outstanding shares or beneficial
+ ownership of such entity.
+
+2. Source Code License.
+
+ 2.1. The Initial Developer Grant.
+
+ The Initial Developer hereby grants You a world-wide, royalty-free,
+ non-exclusive license, subject to third party intellectual property
+ claims:
+ a. under intellectual property rights (other than patent or trademark)
+ Licensable by Initial Developer to use, reproduce, modify, display,
+ perform, sublicense and distribute the Original Code (or portions
+ thereof) with or without Modifications, and/or as part of a Larger
+ Work; and
+ b. under Patents Claims infringed by the making, using or selling of
+ Original Code, to make, have made, use, practice, sell, and offer
+ for sale, and/or otherwise dispose of the Original Code (or
+ portions thereof).
+ c. the licenses granted in this Section 2.1 (a) and (b) are effective
+ on the date Initial Developer first distributes Original Code under
+ the terms of this License.
+ d. Notwithstanding Section 2.1 (b) above, no patent license is
+ granted: 1) for code that You delete from the Original Code; 2)
+ separate from the Original Code; or 3) for infringements caused by:
+ i) the modification of the Original Code or ii) the combination of
+ the Original Code with other software or devices.
+
+ 2.2. Contributor Grant.
+
+ Subject to third party intellectual property claims, each Contributor
+ hereby grants You a world-wide, royalty-free, non-exclusive license
+ a. under intellectual property rights (other than patent or trademark)
+ Licensable by Contributor, to use, reproduce, modify, display,
+ perform, sublicense and distribute the Modifications created by
+ such Contributor (or portions thereof) either on an unmodified
+ basis, with other Modifications, as Covered Code and/or as part of
+ a Larger Work; and
+ b. under Patent Claims infringed by the making, using, or selling of
+ Modifications made by that Contributor either alone and/or in
+ combination with its Contributor Version (or portions of such
+ combination), to make, use, sell, offer for sale, have made, and/or
+ otherwise dispose of: 1) Modifications made by that Contributor (or
+ portions thereof); and 2) the combination of Modifications made by
+ that Contributor with its Contributor Version (or portions of such
+ combination).
+ c. the licenses granted in Sections 2.2 (a) and 2.2 (b) are effective
+ on the date Contributor first makes Commercial Use of the Covered
+ Code.
+ d. Notwithstanding Section 2.2 (b) above, no patent license is
+ granted: 1) for any code that Contributor has deleted from the
+ Contributor Version; 2) separate from the Contributor Version; 3)
+ for infringements caused by: i) third party modifications of
+ Contributor Version or ii) the combination of Modifications made by
+ that Contributor with other software (except as part of the
+ Contributor Version) or other devices; or 4) under Patent Claims
+ infringed by Covered Code in the absence of Modifications made by
+ that Contributor.
+
+3. Distribution Obligations.
+
+ 3.1. Application of License.
+
+ The Modifications which You create or to which You contribute are
+ governed by the terms of this License, including without limitation
+ Section 2.2. The Source Code version of Covered Code may be distributed
+ only under the terms of this License or a future version of this
+ License released under Section 6.1, and You must include a copy of this
+ License with every copy of the Source Code You distribute. You may not
+ offer or impose any terms on any Source Code version that alters or
+ restricts the applicable version of this License or the recipients'
+ rights hereunder. However, You may include an additional document
+ offering the additional rights described in Section 3.5.
+
+ 3.2. Availability of Source Code.
+
+ Any Modification which You create or to which You contribute must be
+ made available in Source Code form under the terms of this License
+ either on the same media as an Executable version or via an accepted
+ Electronic Distribution Mechanism to anyone to whom you made an
+ Executable version available; and if made available via Electronic
+ Distribution Mechanism, must remain available for at least twelve (12)
+ months after the date it initially became available, or at least six
+ (6) months after a subsequent version of that particular Modification
+ has been made available to such recipients. You are responsible for
+ ensuring that the Source Code version remains available even if the
+ Electronic Distribution Mechanism is maintained by a third party.
+
+ 3.3. Description of Modifications.
+
+ You must cause all Covered Code to which You contribute to contain a
+ file documenting the changes You made to create that Covered Code and
+ the date of any change. You must include a prominent statement that the
+ Modification is derived, directly or indirectly, from Original Code
+ provided by the Initial Developer and including the name of the Initial
+ Developer in (a) the Source Code, and (b) in any notice in an
+ Executable version or related documentation in which You describe the
+ origin or ownership of the Covered Code.
+
+ 3.4. Intellectual Property Matters
+
+ (a) Third Party Claims
+
+ If Contributor has knowledge that a license under a third party's
+ intellectual property rights is required to exercise the rights granted
+ by such Contributor under Sections 2.1 or 2.2, Contributor must include
+ a text file with the Source Code distribution titled "LEGAL" which
+ describes the claim and the party making the claim in sufficient detail
+ that a recipient will know whom to contact. If Contributor obtains such
+ knowledge after the Modification is made available as described in
+ Section 3.2, Contributor shall promptly modify the LEGAL file in all
+ copies Contributor makes available thereafter and shall take other
+ steps (such as notifying appropriate mailing lists or newsgroups)
+ reasonably calculated to inform those who received the Covered Code
+ that new knowledge has been obtained.
+
+ (b) Contributor APIs
+
+ If Contributor's Modifications include an application programming
+ interface and Contributor has knowledge of patent licenses which are
+ reasonably necessary to implement that API, Contributor must also
+ include this information in the legal file.
+
+ (c) Representations.
+
+ Contributor represents that, except as disclosed pursuant to Section
+ 3.4 (a) above, Contributor believes that Contributor's Modifications
+ are Contributor's original creation(s) and/or Contributor has
+ sufficient rights to grant the rights conveyed by this License.
+
+ 3.5. Required Notices.
+
+ You must duplicate the notice in Exhibit A in each file of the Source
+ Code. If it is not possible to put such notice in a particular Source
+ Code file due to its structure, then You must include such notice in a
+ location (such as a relevant directory) where a user would be likely to
+ look for such a notice. If You created one or more Modification(s) You
+ may add your name as a Contributor to the notice described in Exhibit
+ A. You must also duplicate this License in any documentation for the
+ Source Code where You describe recipients' rights or ownership rights
+ relating to Covered Code. You may choose to offer, and to charge a fee
+ for, warranty, support, indemnity or liability obligations to one or
+ more recipients of Covered Code. However, You may do so only on Your
+ own behalf, and not on behalf of the Initial Developer or any
+ Contributor. You must make it absolutely clear than any such warranty,
+ support, indemnity or liability obligation is offered by You alone, and
+ You hereby agree to indemnify the Initial Developer and every
+ Contributor for any liability incurred by the Initial Developer or such
+ Contributor as a result of warranty, support, indemnity or liability
+ terms You offer.
+
+ 3.6. Distribution of Executable Versions.
+
+ You may distribute Covered Code in Executable form only if the
+ requirements of Sections 3.1, 3.2, 3.3, 3.4 and 3.5 have been met for
+ that Covered Code, and if You include a notice stating that the Source
+ Code version of the Covered Code is available under the terms of this
+ License, including a description of how and where You have fulfilled
+ the obligations of Section 3.2. The notice must be conspicuously
+ included in any notice in an Executable version, related documentation
+ or collateral in which You describe recipients' rights relating to the
+ Covered Code. You may distribute the Executable version of Covered Code
+ or ownership rights under a license of Your choice, which may contain
+ terms different from this License, provided that You are in compliance
+ with the terms of this License and that the license for the Executable
+ version does not attempt to limit or alter the recipient's rights in
+ the Source Code version from the rights set forth in this License. If
+ You distribute the Executable version under a different license You
+ must make it absolutely clear that any terms which differ from this
+ License are offered by You alone, not by the Initial Developer or any
+ Contributor. You hereby agree to indemnify the Initial Developer and
+ every Contributor for any liability incurred by the Initial Developer
+ or such Contributor as a result of any such terms You offer.
+
+ 3.7. Larger Works.
+
+ You may create a Larger Work by combining Covered Code with other code
+ not governed by the terms of this License and distribute the Larger
+ Work as a single product. In such a case, You must make sure the
+ requirements of this License are fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+ If it is impossible for You to comply with any of the terms of this
+ License with respect to some or all of the Covered Code due to statute,
+ judicial order, or regulation then You must: (a) comply with the terms
+ of this License to the maximum extent possible; and (b) describe the
+ limitations and the code they affect. Such description must be included
+ in the legal file described in Section 3.4 and must be included with
+ all distributions of the Source Code. Except to the extent prohibited
+ by statute or regulation, such description must be sufficiently
+ detailed for a recipient of ordinary skill to be able to understand it.
+
+5. Application of this License.
+
+ This License applies to code to which the Initial Developer has
+ attached the notice in Exhibit A and to related Covered Code.
+
+6. Versions of the License.
+
+ 6.1. New Versions
+
+ Netscape Communications Corporation ("Netscape") may publish revised
+ and/or new versions of the License from time to time. Each version will
+ be given a distinguishing version number.
+
+ 6.2. Effect of New Versions
+
+ Once Covered Code has been published under a particular version of the
+ License, You may always continue to use it under the terms of that
+ version. You may also choose to use such Covered Code under the terms
+ of any subsequent version of the License published by Netscape. No one
+ other than Netscape has the right to modify the terms applicable to
+ Covered Code created under this License.
+
+ 6.3. Derivative Works
+
+ If You create or use a modified version of this License (which you may
+ only do in order to apply it to code which is not already Covered Code
+ governed by this License), You must (a) rename Your license so that the
+ phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", "MPL", "NPL" or
+ any confusingly similar phrase do not appear in your license (except to
+ note that your license differs from this License) and (b) otherwise
+ make it clear that Your version of the license contains terms which
+ differ from the Mozilla Public License and Netscape Public License.
+ (Filling in the name of the Initial Developer, Original Code or
+ Contributor in the notice described in Exhibit A shall not of
+ themselves be deemed to be modifications of this License.)
+
+7. Disclaimer of warranty
+
+ Covered code is provided under this license on an "as is" basis,
+ without warranty of any kind, either expressed or implied, including,
+ without limitation, warranties that the covered code is free of
+ defects, merchantable, fit for a particular purpose or non-infringing.
+ The entire risk as to the quality and performance of the covered code
+ is with you. Should any covered code prove defective in any respect,
+ you (not the initial developer or any other contributor) assume the
+ cost of any necessary servicing, repair or correction. This disclaimer
+ of warranty constitutes an essential part of this license. No use of
+ any covered code is authorized hereunder except under this disclaimer.
+
+8. Termination
+
+ 8.1. This License and the rights granted hereunder will terminate
+ automatically if You fail to comply with terms herein and fail to cure
+ such breach within 30 days of becoming aware of the breach. All
+ sublicenses to the Covered Code which are properly granted shall
+ survive any termination of this License. Provisions which, by their
+ nature, must remain in effect beyond the termination of this License
+ shall survive.
+
+ 8.2. If You initiate litigation by asserting a patent infringement
+ claim (excluding declaratory judgment actions) against Initial
+ Developer or a Contributor (the Initial Developer or Contributor
+ against whom You file such action is referred to as "Participant")
+ alleging that:
+ a. such Participant's Contributor Version directly or indirectly
+ infringes any patent, then any and all rights granted by such
+ Participant to You under Sections 2.1 and/or 2.2 of this License
+ shall, upon 60 days notice from Participant terminate
+ prospectively, unless if within 60 days after receipt of notice You
+ either: (i) agree in writing to pay Participant a mutually
+ agreeable reasonable royalty for Your past and future use of
+ Modifications made by such Participant, or (ii) withdraw Your
+ litigation claim with respect to the Contributor Version against
+ such Participant. If within 60 days of notice, a reasonable royalty
+ and payment arrangement are not mutually agreed upon in writing by
+ the parties or the litigation claim is not withdrawn, the rights
+ granted by Participant to You under Sections 2.1 and/or 2.2
+ automatically terminate at the expiration of the 60 day notice
+ period specified above.
+ b. any software, hardware, or device, other than such Participant's
+ Contributor Version, directly or indirectly infringes any patent,
+ then any rights granted to You by such Participant under Sections
+ 2.1(b) and 2.2(b) are revoked effective as of the date You first
+ made, used, sold, distributed, or had made, Modifications made by
+ that Participant.
+
+ 8.3. If You assert a patent infringement claim against Participant
+ alleging that such Participant's Contributor Version directly or
+ indirectly infringes any patent where such claim is resolved (such as
+ by license or settlement) prior to the initiation of patent
+ infringement litigation, then the reasonable value of the licenses
+ granted by such Participant under Sections 2.1 or 2.2 shall be taken
+ into account in determining the amount or value of any payment or
+ license.
+
+ 8.4. In the event of termination under Sections 8.1 or 8.2 above, all
+ end user license agreements (excluding distributors and resellers)
+ which have been validly granted by You or any distributor hereunder
+ prior to termination shall survive termination.
+
+9. Limitation of liability
+
+ Under no circumstances and under no legal theory, whether tort
+ (including negligence), contract, or otherwise, shall you, the initial
+ developer, any other contributor, or any distributor of covered code,
+ or any supplier of any of such parties, be liable to any person for any
+ indirect, special, incidental, or consequential damages of any
+ character including, without limitation, damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all other
+ commercial damages or losses, even if such party shall have been
+ informed of the possibility of such damages. This limitation of
+ liability shall not apply to liability for death or personal injury
+ resulting from such party's negligence to the extent applicable law
+ prohibits such limitation. Some jurisdictions do not allow the
+ exclusion or limitation of incidental or consequential damages, so this
+ exclusion and limitation may not apply to you.
+
+10. U.S. government end users
+
+ The Covered Code is a "commercial item," as that term is defined in 48
+ C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer software"
+ and "commercial computer software documentation," as such terms are
+ used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212
+ and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S.
+ Government End Users acquire Covered Code with only those rights set
+ forth herein.
+
+11. Miscellaneous
+
+ This License represents the complete agreement concerning subject
+ matter hereof. If any provision of this License is held to be
+ unenforceable, such provision shall be reformed only to the extent
+ necessary to make it enforceable. This License shall be governed by
+ California law provisions (except to the extent applicable law, if any,
+ provides otherwise), excluding its conflict-of-law provisions. With
+ respect to disputes in which at least one party is a citizen of, or an
+ entity chartered or registered to do business in the United States of
+ America, any litigation relating to this License shall be subject to
+ the jurisdiction of the Federal Courts of the Northern District of
+ California, with venue lying in Santa Clara County, California, with
+ the losing party responsible for costs, including without limitation,
+ court costs and reasonable attorneys' fees and expenses. The
+ application of the United Nations Convention on Contracts for the
+ International Sale of Goods is expressly excluded. Any law or
+ regulation which provides that the language of a contract shall be
+ construed against the drafter shall not apply to this License.
+
+12. Responsibility for claims
+
+ As between Initial Developer and the Contributors, each party is
+ responsible for claims and damages arising, directly or indirectly, out
+ of its utilization of rights under this License and You agree to work
+ with Initial Developer and Contributors to distribute such
+ responsibility on an equitable basis. Nothing herein is intended or
+ shall be deemed to constitute any admission of liability.
+
+13. Multiple-licensed code
+
+ Initial Developer may designate portions of the Covered Code as
+ "Multiple-Licensed". "Multiple-Licensed" means that the Initial
+ Developer permits you to utilize portions of the Covered Code under
+ Your choice of the MPL or the alternative licenses, if any, specified
+ by the Initial Developer in the file described in Exhibit A.
+
+Exhibit A - Mozilla Public License.
+
+"The contents of this file are subject to the Mozilla Public License
+Version 1.1 (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.mozilla.org/MPL/
+
+Software distributed under the License is distributed on an "AS IS"
+basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+License for the specific language governing rights and limitations
+under the License.
+
+The Original Code is ______________________________________.
+
+The Initial Developer of the Original Code is ________________________.
+Portions created by ______________________ are Copyright (C) ______
+_______________________. All Rights Reserved.
+
+Contributor(s): ______________________________________.
+
+Alternatively, the contents of this file may be used under the terms
+of the _____ license (the "[___] License"), in which case the
+provisions of [______] License are applicable instead of those
+above. If you wish to allow use of your version of this file only
+under the terms of the [____] License and not to allow others to use
+your version of this file under the MPL, indicate your decision by
+deleting the provisions above and replace them with the notice and
+other provisions required by the [___] License. If you do not delete
+the provisions above, a recipient may use your version of this file
+under either the MPL or the [___] License."
+
+ NOTE: The text of this Exhibit A may differ slightly from the text of
+ the notices in the Source Code files of the Original Code. You should
+ use the text of this Exhibit A rather than the text found in the
+ Original Code Source Code for Your Modifications.
+
+ Mozilla Public License Version 2.0
+
+1. Definitions
+
+ 1.1. “Contributor”
+ means each individual or legal entity that creates, contributes
+ to the creation of, or owns Covered Software.
+
+ 1.2. “Contributor Version”
+ means the combination of the Contributions of others (if any)
+ used by a Contributor and that particular Contributor’s
+ Contribution.
+
+ 1.3. “Contribution”
+ means Covered Software of a particular Contributor.
+
+ 1.4. “Covered Software”
+ means Source Code Form to which the initial Contributor has
+ attached the notice in Exhibit A, the Executable Form of such
+ Source Code Form, and Modifications of such Source Code Form, in
+ each case including portions thereof.
+
+ 1.5. “Incompatible With Secondary Licenses”
+ means
+
+ a.
+ that the initial Contributor has attached the notice described in
+ Exhibit B to the Covered Software; or
+ b.
+ that the Covered Software was made available under the terms of
+ version 1.1 or earlier of the License, but not also under the terms
+ of a Secondary License.
+
+ 1.6. “Executable Form”
+ means any form of the work other than Source Code Form.
+
+ 1.7. “Larger Work”
+ means a work that combines Covered Software with other material,
+ in a separate file or files, that is not Covered Software.
+
+ 1.8. “License”
+ means this document.
+
+ 1.9. “Licensable”
+ means having the right to grant, to the maximum extent possible,
+ whether at the time of the initial grant or subsequently, any
+ and all of the rights conveyed by this License.
+
+ 1.10. “Modifications”
+ means any of the following:
+
+ a.
+ any file in Source Code Form that results from an addition to,
+ deletion from, or modification of the contents of Covered Software;
+ or
+ b.
+ any new file in Source Code Form that contains any Covered
+ Software.
+
+ 1.11. “Patent Claims” of a Contributor
+ means any patent claim(s), including without limitation, method,
+ process, and apparatus claims, in any patent Licensable by such
+ Contributor that would be infringed, but for the grant of the
+ License, by the making, using, selling, offering for sale,
+ having made, import, or transfer of either its Contributions or
+ its Contributor Version.
+
+ 1.12. “Secondary License”
+ means either the GNU General Public License, Version 2.0, the
+ GNU Lesser General Public License, Version 2.1, the GNU Affero
+ General Public License, Version 3.0, or any later versions of
+ those licenses.
+
+ 1.13. “Source Code Form”
+ means the form of the work preferred for making modifications.
+
+ 1.14. “You” (or “Your”)
+ means an individual or a legal entity exercising rights under
+ this License. For legal entities, “You” includes any entity that
+ controls, is controlled by, or is under common control with You.
+ For purposes of this definition, “control” means (a) the power,
+ direct or indirect, to cause the direction or management of such
+ entity, whether by contract or otherwise, or (b) ownership of
+ more than fifty percent (50%) of the outstanding shares or
+ beneficial ownership of such entity.
+
+2. License Grants and Conditions
+
+ 2.1. Grants
+
+ Each Contributor hereby grants You a world-wide, royalty-free,
+ non-exclusive license:
+ a. under intellectual property rights (other than patent or trademark)
+ Licensable by such Contributor to use, reproduce, make available,
+ modify, display, perform, distribute, and otherwise exploit its
+ Contributions, either on an unmodified basis, with Modifications,
+ or as part of a Larger Work; and
+ b. under Patent Claims of such Contributor to make, use, sell, offer
+ for sale, have made, import, and otherwise transfer either its
+ Contributions or its Contributor Version.
+
+ 2.2. Effective Date
+
+ The licenses granted in Section 2.1 with respect to any Contribution
+ become effective for each Contribution on the date the Contributor
+ first distributes such Contribution.
+
+ 2.3. Limitations on Grant Scope
+
+ The licenses granted in this Section 2 are the only rights granted
+ under this License. No additional rights or licenses will be implied
+ from the distribution or licensing of Covered Software under this
+ License. Notwithstanding Section 2.1(b) above, no patent license is
+ granted by a Contributor:
+ a. for any code that a Contributor has removed from Covered Software;
+ or
+ b. for infringements caused by: (i) Your and any other third party’s
+ modifications of Covered Software, or (ii) the combination of its
+ Contributions with other software (except as part of its
+ Contributor Version); or
+ c. under Patent Claims infringed by Covered Software in the absence of
+ its Contributions.
+
+ This License does not grant any rights in the trademarks, service
+ marks, or logos of any Contributor (except as may be necessary to
+ comply with the notice requirements in Section 3.4).
+
+ 2.4. Subsequent Licenses
+
+ No Contributor makes additional grants as a result of Your choice to
+ distribute the Covered Software under a subsequent version of this
+ License (see Section 10.2) or under the terms of a Secondary License
+ (if permitted under the terms of Section 3.3).
+
+ 2.5. Representation
+
+ Each Contributor represents that the Contributor believes its
+ Contributions are its original creation(s) or it has sufficient rights
+ to grant the rights to its Contributions conveyed by this License.
+
+ 2.6. Fair Use
+
+ This License is not intended to limit any rights You have under
+ applicable copyright doctrines of fair use, fair dealing, or other
+ equivalents.
+
+ 2.7. Conditions
+
+ Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
+ in Section 2.1.
+
+3. Responsibilities
+
+ 3.1. Distribution of Source Form
+
+ All distribution of Covered Software in Source Code Form, including any
+ Modifications that You create or to which You contribute, must be under
+ the terms of this License. You must inform recipients that the Source
+ Code Form of the Covered Software is governed by the terms of this
+ License, and how they can obtain a copy of this License. You may not
+ attempt to alter or restrict the recipients’ rights in the Source Code
+ Form.
+
+ 3.2. Distribution of Executable Form
+
+ If You distribute Covered Software in Executable Form then:
+ a. such Covered Software must also be made available in Source Code
+ Form, as described in Section 3.1, and You must inform recipients
+ of the Executable Form how they can obtain a copy of such Source
+ Code Form by reasonable means in a timely manner, at a charge no
+ more than the cost of distribution to the recipient; and
+ b. You may distribute such Executable Form under the terms of this
+ License, or sublicense it under different terms, provided that the
+ license for the Executable Form does not attempt to limit or alter
+ the recipients’ rights in the Source Code Form under this License.
+
+ 3.3. Distribution of a Larger Work
+
+ You may create and distribute a Larger Work under terms of Your choice,
+ provided that You also comply with the requirements of this License for
+ the Covered Software. If the Larger Work is a combination of Covered
+ Software with a work governed by one or more Secondary Licenses, and
+ the Covered Software is not Incompatible With Secondary Licenses, this
+ License permits You to additionally distribute such Covered Software
+ under the terms of such Secondary License(s), so that the recipient of
+ the Larger Work may, at their option, further distribute the Covered
+ Software under the terms of either this License or such Secondary
+ License(s).
+
+ 3.4. Notices
+
+ You may not remove or alter the substance of any license notices
+ (including copyright notices, patent notices, disclaimers of warranty,
+ or limitations of liability) contained within the Source Code Form of
+ the Covered Software, except that You may alter any license notices to
+ the extent required to remedy known factual inaccuracies.
+
+ 3.5. Application of Additional Terms
+
+ You may choose to offer, and to charge a fee for, warranty, support,
+ indemnity or liability obligations to one or more recipients of Covered
+ Software. However, You may do so only on Your own behalf, and not on
+ behalf of any Contributor. You must make it absolutely clear that any
+ such warranty, support, indemnity, or liability obligation is offered
+ by You alone, and You hereby agree to indemnify every Contributor for
+ any liability incurred by such Contributor as a result of warranty,
+ support, indemnity or liability terms You offer. You may include
+ additional disclaimers of warranty and limitations of liability
+ specific to any jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+
+ If it is impossible for You to comply with any of the terms of this
+ License with respect to some or all of the Covered Software due to
+ statute, judicial order, or regulation then You must: (a) comply with
+ the terms of this License to the maximum extent possible; and (b)
+ describe the limitations and the code they affect. Such description
+ must be placed in a text file included with all distributions of the
+ Covered Software under this License. Except to the extent prohibited by
+ statute or regulation, such description must be sufficiently detailed
+ for a recipient of ordinary skill to be able to understand it.
+
+5. Termination
+
+ 5.1. The rights granted under this License will terminate automatically
+ if You fail to comply with any of its terms. However, if You become
+ compliant, then the rights granted under this License from a particular
+ Contributor are reinstated (a) provisionally, unless and until such
+ Contributor explicitly and finally terminates Your grants, and (b) on
+ an ongoing basis, if such Contributor fails to notify You of the
+ non-compliance by some reasonable means prior to 60 days after You have
+ come back into compliance. Moreover, Your grants from a particular
+ Contributor are reinstated on an ongoing basis if such Contributor
+ notifies You of the non-compliance by some reasonable means, this is
+ the first time You have received notice of non-compliance with this
+ License from such Contributor, and You become compliant prior to 30
+ days after Your receipt of the notice.
+
+ 5.2. If You initiate litigation against any entity by asserting a
+ patent infringement claim (excluding declaratory judgment actions,
+ counter-claims, and cross-claims) alleging that a Contributor Version
+ directly or indirectly infringes any patent, then the rights granted to
+ You by any and all Contributors for the Covered Software under
+ Section 2.1 of this License shall terminate.
+
+ 5.3. In the event of termination under Sections 5.1 or 5.2 above, all
+ end user license agreements (excluding distributors and resellers)
+ which have been validly granted by You or Your distributors under this
+ License prior to termination shall survive termination.
+
+6. Disclaimer of Warranty
+
+ Covered Software is provided under this License on an “as is” basis,
+ without warranty of any kind, either expressed, implied, or statutory,
+ including, without limitation, warranties that the Covered Software is
+ free of defects, merchantable, fit for a particular purpose or
+ non-infringing. The entire risk as to the quality and performance of
+ the Covered Software is with You. Should any Covered Software prove
+ defective in any respect, You (not any Contributor) assume the cost of
+ any necessary servicing, repair, or correction. This disclaimer of
+ warranty constitutes an essential part of this License. No use of any
+ Covered Software is authorized under this License except under this
+ disclaimer.
+
+7. Limitation of Liability
+
+ Under no circumstances and under no legal theory, whether tort
+ (including negligence), contract, or otherwise, shall any Contributor,
+ or anyone who distributes Covered Software as permitted above, be
+ liable to You for any direct, indirect, special, incidental, or
+ consequential damages of any character including, without limitation,
+ damages for lost profits, loss of goodwill, work stoppage, computer
+ failure or malfunction, or any and all other commercial damages or
+ losses, even if such party shall have been informed of the possibility
+ of such damages. This limitation of liability shall not apply to
+ liability for death or personal injury resulting from such party’s
+ negligence to the extent applicable law prohibits such limitation. Some
+ jurisdictions do not allow the exclusion or limitation of incidental or
+ consequential damages, so this exclusion and limitation may not apply
+ to You.
+
+8. Litigation
+
+ Any litigation relating to this License may be brought only in the
+ courts of a jurisdiction where the defendant maintains its principal
+ place of business and such litigation shall be governed by laws of that
+ jurisdiction, without reference to its conflict-of-law provisions.
+ Nothing in this Section shall prevent a party’s ability to bring
+ cross-claims or counter-claims.
+
+9. Miscellaneous
+
+ This License represents the complete agreement concerning the subject
+ matter hereof. If any provision of this License is held to be
+ unenforceable, such provision shall be reformed only to the extent
+ necessary to make it enforceable. Any law or regulation which provides
+ that the language of a contract shall be construed against the drafter
+ shall not be used to construe this License against a Contributor.
+
+10. Versions of the License
+
+ 10.1. New Versions
+
+ Mozilla Foundation is the license steward. Except as provided in
+ Section 10.3, no one other than the license steward has the right to
+ modify or publish new versions of this License. Each version will be
+ given a distinguishing version number.
+
+ 10.2. Effect of New Versions
+
+ You may distribute the Covered Software under the terms of the version
+ of the License under which You originally received the Covered
+ Software, or under the terms of any subsequent version published by the
+ license steward.
+
+ 10.3. Modified Versions
+
+ If you create software not governed by this License, and you want to
+ create a new license for such software, you may create and use a
+ modified version of this License if you rename the license and remove
+ any references to the name of the license steward (except to note that
+ such modified license differs from this License).
+
+ 10.4. Distributing Source Code Form that is Incompatible With Secondary
+ Licenses
+
+ If You choose to distribute Source Code Form that is Incompatible With
+ Secondary Licenses under the terms of this version of the License, the
+ notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+
+ This Source Code Form is subject to the terms of the Mozilla Public
+ License, v. 2.0. If a copy of the MPL was not distributed with this
+ file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+ If it is not possible or desirable to put the notice in a particular
+ file, then You may include the notice in a location (such as a LICENSE
+ file in a relevant directory) where a recipient would be likely to look
+ for such a notice.
+
+ You may add additional accurate notices of copyright ownership.
+
+Exhibit B - “Incompatible With Secondary Licenses” Notice
+
+ This Source Code Form is “Incompatible With Secondary Licenses”, as
+ defined by the Mozilla Public License, v. 2.0.
+
+ SIL Open Font License Version 1.1 – 26 February 2007
+
+ PREAMBLE The goals of the Open Font License (OFL) are to stimulate
+ worldwide development of collaborative font projects, to support the
+ font creation efforts of academic and linguistic communities, and to
+ provide a free and open framework in which fonts may be shared and
+ improved in partnership with others.
+
+ The OFL allows the licensed fonts to be used, studied, modified and
+ redistributed freely as long as they are not sold by themselves. The
+ fonts, including any derivative works, can be bundled, embedded,
+ redistributed and/or sold with any software provided that the font
+ names of derivative works are changed. The fonts and derivatives,
+ however, cannot be released under any other type of license. The
+ requirement for fonts to remain under this license does not apply to
+ any document created using the fonts or their derivatives.
+
+ DEFINITIONS "Font Software" refers to the set of files released by the
+ Copyright Holder(s) under this license and clearly marked as such. This
+ may include source files, build scripts and documentation.
+
+ "Reserved Font Name" refers to any names specified as such after the
+ copyright statement(s).
+
+ "Original Version" refers to the collection of Font Software components
+ as distributed by the Copyright Holder(s).
+
+ "Modified Version" refers to any derivative made by adding to,
+ deleting, or substituting – in part or in whole -- any of the
+ components of the Original Version, by changing formats or by porting
+ the Font Software to a new environment.
+
+ "Author" refers to any designer, engineer, programmer, technical writer
+ or other person who contributed to the Font Software.
+
+ PERMISSION & CONDITIONS Permission is hereby granted, free of charge,
+ to any person obtaining a copy of the Font Software, to use, study,
+ copy, merge, embed, modify, redistribute, and sell modified and
+ unmodified copies of the Font Software, subject to the following
+ conditions:
+
+ 1) Neither the Font Software nor any of its individual components, in
+ Original or Modified Versions, may be sold by itself.
+
+ 2) Original or Modified Versions of the Font Software may be bundled,
+ redistributed and/or sold with any software, provided that each copy
+ contains the above copyright notice and this license. These can be
+ included either as stand-alone text files, human-readable headers or in
+ the appropriate machine-readable metadata fields within text or binary
+ files as long as those fields can be easily viewed by the user.
+
+ 3) No Modified Version of the Font Software may use the Reserved Font
+ Name(s) unless explicit written permission is granted by the
+ corresponding Copyright Holder. This restriction only applies to the
+ primary font name as presented to the users.
+
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+ Software shall not be used to promote, endorse or advertise any
+ Modified Version, except to acknowledge the contribution(s) of the
+ Copyright Holder(s) and the Author(s) or with their explicit written
+ permission.
+
+ 5) The Font Software, modified or unmodified, in part or in whole, must
+ be distributed entirely under this license, and must not be distributed
+ under any other license. The requirement for fonts to remain under this
+ license does not apply to any document created using the Font Software.
+
+ TERMINATION This license becomes null and void if any of the above
+ conditions are not met.
+
+ DISCLAIMER THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO
+ EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL,
+ OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT
+ SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
+
+ Apache License
+
+ Version 2.0, January 2004
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by the
+ copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all other
+ entities that control, are controlled by, or are under common control
+ with that entity. For the purposes of this definition, "control" means
+ (i) the power, direct or indirect, to cause the direction or management
+ of such entity, whether by contract or otherwise, or (ii) ownership of
+ fifty percent (50%) or more of the outstanding shares, or (iii)
+ beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity exercising
+ permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but not
+ limited to compiled object code, generated documentation, and
+ conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or Object
+ form, made available under the License, as indicated by a copyright
+ notice that is included in or attached to the work (an example is
+ provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including the
+ original version of the Work and any modifications or additions to that
+ Work or Derivative Works thereof, that is intentionally submitted to
+ Licensor for inclusion in the Work by the copyright owner or by an
+ individual or Legal Entity authorized to submit on behalf of the
+ copyright owner. For the purposes of this definition, "submitted" means
+ any form of electronic, verbal, or written communication sent to the
+ Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity on
+ behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of, publicly
+ display, publicly perform, sublicense, and distribute the Work and such
+ Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of this
+ License, each Contributor hereby grants to You a perpetual, worldwide,
+ non-exclusive, no-charge, royalty-free, irrevocable (except as stated
+ in this section) patent license to make, have made, use, offer to sell,
+ sell, import, and otherwise transfer the Work, where such license
+ applies only to those patent claims licensable by such Contributor that
+ are necessarily infringed by their Contribution(s) alone or by
+ combination of their Contribution(s) with the Work to which such
+ Contribution(s) was submitted. If You institute patent litigation
+ against any entity (including a cross-claim or counterclaim in a
+ lawsuit) alleging that the Work or a Contribution incorporated within
+ the Work constitutes direct or contributory patent infringement, then
+ any patent licenses granted to You under this License for that Work
+ shall terminate as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the Work
+ or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You meet the
+ following conditions:
+ 1. You must give any other recipients of the Work or Derivative Works
+ a copy of this License; and
+ 2. You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+ 3. You must retain, in the Source form of any Derivative Works that
+ You distribute, all copyright, patent, trademark, and attribution
+ notices from the Source form of the Work, excluding those notices
+ that do not pertain to any part of the Derivative Works; and
+ 4. If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained within
+ such NOTICE file, excluding those notices that do not pertain to
+ any part of the Derivative Works, in at least one of the following
+ places: within a NOTICE text file distributed as part of the
+ Derivative Works; within the Source form or documentation, if
+ provided along with the Derivative Works; or, within a display
+ generated by the Derivative Works, if and wherever such third-party
+ notices normally appear. The contents of the NOTICE file are for
+ informational purposes only and do not modify the License. You may
+ add Your own attribution notices within Derivative Works that You
+ distribute, alongside or as an addendum to the NOTICE text from the
+ Work, provided that such additional attribution notices cannot be
+ construed as modifying the License. You may add Your own copyright
+ statement to Your modifications and may provide additional or
+ different license terms and conditions for use, reproduction, or
+ distribution of Your modifications, or for any such Derivative
+ Works as a whole, provided Your use, reproduction, and distribution
+ of the Work otherwise complies with the conditions stated in this
+ License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work by
+ You to the Licensor shall be under the terms and conditions of this
+ License, without any additional terms or conditions. Notwithstanding
+ the above, nothing herein shall supersede or modify the terms of any
+ separate license agreement you may have executed with Licensor
+ regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed
+ to in writing, Licensor provides the Work (and each Contributor
+ provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ CONDITIONS OF ANY KIND, either express or implied, including, without
+ limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT,
+ MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely
+ responsible for determining the appropriateness of using or
+ redistributing the Work and assume any risks associated with Your
+ exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise, unless
+ required by applicable law (such as deliberate and grossly negligent
+ acts) or agreed to in writing, shall any Contributor be liable to You
+ for damages, including any direct, indirect, special, incidental, or
+ consequential damages of any character arising as a result of this
+ License or out of the use or inability to use the Work (including but
+ not limited to damages for loss of goodwill, work stoppage, computer
+ failure or malfunction, or any and all other commercial damages or
+ losses), even if such Contributor has been advised of the possibility
+ of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing the
+ Work or Derivative Works thereof, You may choose to offer, and charge a
+ fee for, acceptance of support, warranty, indemnity, or other liability
+ obligations and/or rights consistent with this License. However, in
+ accepting such obligations, You may act only on Your own behalf and on
+ Your sole responsibility, not on behalf of any other Contributor, and
+ only if You agree to indemnify, defend, and hold each Contributor
+ harmless for any liability incurred by, or claims asserted against,
+ such Contributor by reason of your accepting any such warranty or
+ additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "" replaced
+ with your own identifying information. (Don't include the brackets!)
+ The text should be enclosed in the appropriate comment syntax for the
+ file format. We also recommend that a file or class name and
+ description of purpose be included on the same "printed page" as the
+ copyright notice for easier identification within third-party archives.
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ The LaTeX Project Public License
+
+LPPL Version 1.3c 2008-05-04
+
+Copyright 1999 2002-2008 LaTeX3 Project
+ Everyone is allowed to distribute verbatim copies of this
+ license document, but modification of it is not allowed.
+
+
+PREAMBLE
+========
+
+The LaTeX Project Public License (LPPL) is the primary license under
+which the LaTeX kernel and the base LaTeX packages are distributed.
+
+You may use this license for any work of which you hold the copyright
+and which you wish to distribute. This license may be particularly
+suitable if your work is TeX-related (such as a LaTeX package), but
+it is written in such a way that you can use it even if your work is
+unrelated to TeX.
+
+The section `WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE',
+below, gives instructions, examples, and recommendations for authors
+who are considering distributing their works under this license.
+
+This license gives conditions under which a work may be distributed
+and modified, as well as conditions under which modified versions of
+that work may be distributed.
+
+We, the LaTeX3 Project, believe that the conditions below give you
+the freedom to make and distribute modified versions of your work
+that conform with whatever technical specifications you wish while
+maintaining the availability, integrity, and reliability of
+that work. If you do not see how to achieve your goal while
+meeting these conditions, then read the document `cfgguide.tex'
+and `modguide.tex' in the base LaTeX distribution for suggestions.
+
+
+DEFINITIONS
+===========
+
+In this license document the following terms are used:
+
+ `Work'
+ Any work being distributed under this License.
+
+ `Derived Work'
+ Any work that under any applicable law is derived from the Work.
+
+ `Modification'
+ Any procedure that produces a Derived Work under any applicable
+ law -- for example, the production of a file containing an
+ original file associated with the Work or a significant portion of
+ such a file, either verbatim or with modifications and/or
+ translated into another language.
+
+ `Modify'
+ To apply any procedure that produces a Derived Work under any
+ applicable law.
+
+ `Distribution'
+ Making copies of the Work available from one person to another, in
+ whole or in part. Distribution includes (but is not limited to)
+ making any electronic components of the Work accessible by
+ file transfer protocols such as FTP or HTTP or by shared file
+ systems such as Sun's Network File System (NFS).
+
+ `Compiled Work'
+ A version of the Work that has been processed into a form where it
+ is directly usable on a computer system. This processing may
+ include using installation facilities provided by the Work,
+ transformations of the Work, copying of components of the Work, or
+ other activities. Note that modification of any installation
+ facilities provided by the Work constitutes modification of the Work.
+
+ `Current Maintainer'
+ A person or persons nominated as such within the Work. If there is
+ no such explicit nomination then it is the `Copyright Holder' under
+ any applicable law.
+
+ `Base Interpreter'
+ A program or process that is normally needed for running or
+ interpreting a part or the whole of the Work.
+
+ A Base Interpreter may depend on external components but these
+ are not considered part of the Base Interpreter provided that each
+ external component clearly identifies itself whenever it is used
+ interactively. Unless explicitly specified when applying the
+ license to the Work, the only applicable Base Interpreter is a
+ `LaTeX-Format' or in the case of files belonging to the
+ `LaTeX-format' a program implementing the `TeX language'.
+
+
+
+CONDITIONS ON DISTRIBUTION AND MODIFICATION
+===========================================
+
+1. Activities other than distribution and/or modification of the Work
+are not covered by this license; they are outside its scope. In
+particular, the act of running the Work is not restricted and no
+requirements are made concerning any offers of support for the Work.
+
+2. You may distribute a complete, unmodified copy of the Work as you
+received it. Distribution of only part of the Work is considered
+modification of the Work, and no right to distribute such a Derived
+Work may be assumed under the terms of this clause.
+
+3. You may distribute a Compiled Work that has been generated from a
+complete, unmodified copy of the Work as distributed under Clause 2
+above, as long as that Compiled Work is distributed in such a way that
+the recipients may install the Compiled Work on their system exactly
+as it would have been installed if they generated a Compiled Work
+directly from the Work.
+
+4. If you are the Current Maintainer of the Work, you may, without
+restriction, modify the Work, thus creating a Derived Work. You may
+also distribute the Derived Work without restriction, including
+Compiled Works generated from the Derived Work. Derived Works
+distributed in this manner by the Current Maintainer are considered to
+be updated versions of the Work.
+
+5. If you are not the Current Maintainer of the Work, you may modify
+your copy of the Work, thus creating a Derived Work based on the Work,
+and compile this Derived Work, thus creating a Compiled Work based on
+the Derived Work.
+
+6. If you are not the Current Maintainer of the Work, you may
+distribute a Derived Work provided the following conditions are met
+for every component of the Work unless that component clearly states
+in the copyright notice that it is exempt from that condition. Only
+the Current Maintainer is allowed to add such statements of exemption
+to a component of the Work.
+
+ a. If a component of this Derived Work can be a direct replacement
+ for a component of the Work when that component is used with the
+ Base Interpreter, then, wherever this component of the Work
+ identifies itself to the user when used interactively with that
+ Base Interpreter, the replacement component of this Derived Work
+ clearly and unambiguously identifies itself as a modified version
+ of this component to the user when used interactively with that
+ Base Interpreter.
+
+ b. Every component of the Derived Work contains prominent notices
+ detailing the nature of the changes to that component, or a
+ prominent reference to another file that is distributed as part
+ of the Derived Work and that contains a complete and accurate log
+ of the changes.
+
+ c. No information in the Derived Work implies that any persons,
+ including (but not limited to) the authors of the original version
+ of the Work, provide any support, including (but not limited to)
+ the reporting and handling of errors, to recipients of the
+ Derived Work unless those persons have stated explicitly that
+ they do provide such support for the Derived Work.
+
+ d. You distribute at least one of the following with the Derived Work:
+
+ 1. A complete, unmodified copy of the Work;
+ if your distribution of a modified component is made by
+ offering access to copy the modified component from a
+ designated place, then offering equivalent access to copy
+ the Work from the same or some similar place meets this
+ condition, even though third parties are not compelled to
+ copy the Work along with the modified component;
+
+ 2. Information that is sufficient to obtain a complete,
+ unmodified copy of the Work.
+
+7. If you are not the Current Maintainer of the Work, you may
+distribute a Compiled Work generated from a Derived Work, as long as
+the Derived Work is distributed to all recipients of the Compiled
+Work, and as long as the conditions of Clause 6, above, are met with
+regard to the Derived Work.
+
+8. The conditions above are not intended to prohibit, and hence do not
+apply to, the modification, by any method, of any component so that it
+becomes identical to an updated version of that component of the Work as
+it is distributed by the Current Maintainer under Clause 4, above.
+
+9. Distribution of the Work or any Derived Work in an alternative
+format, where the Work or that Derived Work (in whole or in part) is
+then produced by applying some process to that format, does not relax or
+nullify any sections of this license as they pertain to the results of
+applying that process.
+
+10. a. A Derived Work may be distributed under a different license
+ provided that license itself honors the conditions listed in
+ Clause 6 above, in regard to the Work, though it does not have
+ to honor the rest of the conditions in this license.
+
+ b. If a Derived Work is distributed under a different license, that
+ Derived Work must provide sufficient documentation as part of
+ itself to allow each recipient of that Derived Work to honor the
+ restrictions in Clause 6 above, concerning changes from the Work.
+
+11. This license places no restrictions on works that are unrelated to
+the Work, nor does this license place any restrictions on aggregating
+such works with the Work by any means.
+
+12. Nothing in this license is intended to, or may be used to, prevent
+complete compliance by all parties with all applicable laws.
+
+
+NO WARRANTY
+===========
+
+There is no warranty for the Work. Except when otherwise stated in
+writing, the Copyright Holder provides the Work `as is', without
+warranty of any kind, either expressed or implied, including, but not
+limited to, the implied warranties of merchantability and fitness for a
+particular purpose. The entire risk as to the quality and performance
+of the Work is with you. Should the Work prove defective, you assume
+the cost of all necessary servicing, repair, or correction.
+
+In no event unless required by applicable law or agreed to in writing
+will The Copyright Holder, or any author named in the components of the
+Work, or any other party who may distribute and/or modify the Work as
+permitted above, be liable to you for damages, including any general,
+special, incidental or consequential damages arising out of any use of
+the Work or out of inability to use the Work (including, but not limited
+to, loss of data, data being rendered inaccurate, or losses sustained by
+anyone as a result of any failure of the Work to operate with any other
+programs), even if the Copyright Holder or said author or said other
+party has been advised of the possibility of such damages.
+
+
+MAINTENANCE OF THE WORK
+=======================
+
+The Work has the status `author-maintained' if the Copyright Holder
+explicitly and prominently states near the primary copyright notice in
+the Work that the Work can only be maintained by the Copyright Holder
+or simply that it is `author-maintained'.
+
+The Work has the status `maintained' if there is a Current Maintainer
+who has indicated in the Work that they are willing to receive error
+reports for the Work (for example, by supplying a valid e-mail
+address). It is not required for the Current Maintainer to acknowledge
+or act upon these error reports.
+
+The Work changes from status `maintained' to `unmaintained' if there
+is no Current Maintainer, or the person stated to be Current
+Maintainer of the work cannot be reached through the indicated means
+of communication for a period of six months, and there are no other
+significant signs of active maintenance.
+
+You can become the Current Maintainer of the Work by agreement with
+any existing Current Maintainer to take over this role.
+
+If the Work is unmaintained, you can become the Current Maintainer of
+the Work through the following steps:
+
+ 1. Make a reasonable attempt to trace the Current Maintainer (and
+ the Copyright Holder, if the two differ) through the means of
+ an Internet or similar search.
+
+ 2. If this search is successful, then enquire whether the Work
+ is still maintained.
+
+ a. If it is being maintained, then ask the Current Maintainer
+ to update their communication data within one month.
+
+ b. If the search is unsuccessful or no action to resume active
+ maintenance is taken by the Current Maintainer, then announce
+ within the pertinent community your intention to take over
+ maintenance. (If the Work is a LaTeX work, this could be
+ done, for example, by posting to comp.text.tex.)
+
+ 3a. If the Current Maintainer is reachable and agrees to pass
+ maintenance of the Work to you, then this takes effect
+ immediately upon announcement.
+
+ b. If the Current Maintainer is not reachable and the Copyright
+ Holder agrees that maintenance of the Work be passed to you,
+ then this takes effect immediately upon announcement.
+
+ 4. If you make an `intention announcement' as described in 2b. above
+ and after three months your intention is challenged neither by
+ the Current Maintainer nor by the Copyright Holder nor by other
+ people, then you may arrange for the Work to be changed so as
+ to name you as the (new) Current Maintainer.
+
+ 5. If the previously unreachable Current Maintainer becomes
+ reachable once more within three months of a change completed
+ under the terms of 3b) or 4), then that Current Maintainer must
+ become or remain the Current Maintainer upon request provided
+ they then update their communication data within one month.
+
+A change in the Current Maintainer does not, of itself, alter the fact
+that the Work is distributed under the LPPL license.
+
+If you become the Current Maintainer of the Work, you should
+immediately provide, within the Work, a prominent and unambiguous
+statement of your status as Current Maintainer. You should also
+announce your new status to the same pertinent community as
+in 2b) above.
+
+
+WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE
+======================================================
+
+This section contains important instructions, examples, and
+recommendations for authors who are considering distributing their
+works under this license. These authors are addressed as `you' in
+this section.
+
+Choosing This License or Another License
+----------------------------------------
+
+If for any part of your work you want or need to use *distribution*
+conditions that differ significantly from those in this license, then
+do not refer to this license anywhere in your work but, instead,
+distribute your work under a different license. You may use the text
+of this license as a model for your own license, but your license
+should not refer to the LPPL or otherwise give the impression that
+your work is distributed under the LPPL.
+
+The document `modguide.tex' in the base LaTeX distribution explains
+the motivation behind the conditions of this license. It explains,
+for example, why distributing LaTeX under the GNU General Public
+License (GPL) was considered inappropriate. Even if your work is
+unrelated to LaTeX, the discussion in `modguide.tex' may still be
+relevant, and authors intending to distribute their works under any
+license are encouraged to read it.
+
+A Recommendation on Modification Without Distribution
+-----------------------------------------------------
+
+It is wise never to modify a component of the Work, even for your own
+personal use, without also meeting the above conditions for
+distributing the modified component. While you might intend that such
+modifications will never be distributed, often this will happen by
+accident -- you may forget that you have modified that component; or
+it may not occur to you when allowing others to access the modified
+version that you are thus distributing it and violating the conditions
+of this license in ways that could have legal implications and, worse,
+cause problems for the community. It is therefore usually in your
+best interest to keep your copy of the Work identical with the public
+one. Many works provide ways to control the behavior of that work
+without altering any of its licensed components.
+
+How to Use This License
+-----------------------
+
+To use this license, place in each of the components of your work both
+an explicit copyright notice including your name and the year the work
+was authored and/or last substantially modified. Include also a
+statement that the distribution and/or modification of that
+component is constrained by the conditions in this license.
+
+Here is an example of such a notice and statement:
+
+ %% pig.dtx
+ %% Copyright 2005 M. Y. Name
+ %
+ % This work may be distributed and/or modified under the
+ % conditions of the LaTeX Project Public License, either version 1.3
+ % of this license or (at your option) any later version.
+ % The latest version of this license is in
+ % http://www.latex-project.org/lppl.txt
+ % and version 1.3 or later is part of all distributions of LaTeX
+ % version 2005/12/01 or later.
+ %
+ % This work has the LPPL maintenance status `maintained'.
+ %
+ % The Current Maintainer of this work is M. Y. Name.
+ %
+ % This work consists of the files pig.dtx and pig.ins
+ % and the derived file pig.sty.
+
+Given such a notice and statement in a file, the conditions
+given in this license document would apply, with the `Work' referring
+to the three files `pig.dtx', `pig.ins', and `pig.sty' (the last being
+generated from `pig.dtx' using `pig.ins'), the `Base Interpreter'
+referring to any `LaTeX-Format', and both `Copyright Holder' and
+`Current Maintainer' referring to the person `M. Y. Name'.
+
+If you do not want the Maintenance section of LPPL to apply to your
+Work, change `maintained' above into `author-maintained'.
+However, we recommend that you use `maintained', as the Maintenance
+section was added in order to ensure that your Work remains useful to
+the community even when you can no longer maintain and support it
+yourself.
+
+Derived Works That Are Not Replacements
+---------------------------------------
+
+Several clauses of the LPPL specify means to provide reliability and
+stability for the user community. They therefore concern themselves
+with the case that a Derived Work is intended to be used as a
+(compatible or incompatible) replacement of the original Work. If
+this is not the case (e.g., if a few lines of code are reused for a
+completely different task), then clauses 6b and 6d shall not apply.
+
+
+Important Recommendations
+-------------------------
+
+ Defining What Constitutes the Work
+
+ The LPPL requires that distributions of the Work contain all the
+ files of the Work. It is therefore important that you provide a
+ way for the licensee to determine which files constitute the Work.
+ This could, for example, be achieved by explicitly listing all the
+ files of the Work near the copyright notice of each file or by
+ using a line such as:
+
+ % This work consists of all files listed in manifest.txt.
+
+ in that place. In the absence of an unequivocal list it might be
+ impossible for the licensee to determine what is considered by you
+ to comprise the Work and, in such a case, the licensee would be
+ entitled to make reasonable conjectures as to which files comprise
+ the Work.
+
+ Creative Commons Attribution-ShareAlike 3.0 Unported
+
+ CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
+ LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN
+ ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
+ INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
+ REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES
+ RESULTING FROM ITS USE.
+
+License
+
+ THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS
+ CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS
+ PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK
+ OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS
+ PROHIBITED.
+
+ BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND
+ AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS
+ LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE
+ RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS
+ AND CONDITIONS.
+
+ 1. Definitions
+ a. "Adaptation" means a work based upon the Work, or upon the Work and
+ other pre-existing works, such as a translation, adaptation,
+ derivative work, arrangement of music or other alterations of a
+ literary or artistic work, or phonogram or performance and includes
+ cinematographic adaptations or any other form in which the Work may
+ be recast, transformed, or adapted including in any form
+ recognizably derived from the original, except that a work that
+ constitutes a Collection will not be considered an Adaptation for
+ the purpose of this License. For the avoidance of doubt, where the
+ Work is a musical work, performance or phonogram, the
+ synchronization of the Work in timed-relation with a moving image
+ ("synching") will be considered an Adaptation for the purpose of
+ this License.
+ b. "Collection" means a collection of literary or artistic works, such
+ as encyclopedias and anthologies, or performances, phonograms or
+ broadcasts, or other works or subject matter other than works
+ listed in Section 1(f) below, which, by reason of the selection and
+ arrangement of their contents, constitute intellectual creations,
+ in which the Work is included in its entirety in unmodified form
+ along with one or more other contributions, each constituting
+ separate and independent works in themselves, which together are
+ assembled into a collective whole. A work that constitutes a
+ Collection will not be considered an Adaptation (as defined below)
+ for the purposes of this License.
+ c. "Creative Commons Compatible License" means a license that is
+ listed at http://creativecommons.org/compatiblelicenses that has
+ been approved by Creative Commons as being essentially equivalent
+ to this License, including, at a minimum, because that license: (i)
+ contains terms that have the same purpose, meaning and effect as
+ the License Elements of this License; and, (ii) explicitly permits
+ the relicensing of adaptations of works made available under that
+ license under this License or a Creative Commons jurisdiction
+ license with the same License Elements as this License.
+ d. "Distribute" means to make available to the public the original and
+ copies of the Work or Adaptation, as appropriate, through sale or
+ other transfer of ownership.
+ e. "License Elements" means the following high-level license
+ attributes as selected by Licensor and indicated in the title of
+ this License: Attribution, ShareAlike.
+ f. "Licensor" means the individual, individuals, entity or entities
+ that offer(s) the Work under the terms of this License.
+ g. "Original Author" means, in the case of a literary or artistic
+ work, the individual, individuals, entity or entities who created
+ the Work or if no individual or entity can be identified, the
+ publisher; and in addition (i) in the case of a performance the
+ actors, singers, musicians, dancers, and other persons who act,
+ sing, deliver, declaim, play in, interpret or otherwise perform
+ literary or artistic works or expressions of folklore; (ii) in the
+ case of a phonogram the producer being the person or legal entity
+ who first fixes the sounds of a performance or other sounds; and,
+ (iii) in the case of broadcasts, the organization that transmits
+ the broadcast.
+ h. "Work" means the literary and/or artistic work offered under the
+ terms of this License including without limitation any production
+ in the literary, scientific and artistic domain, whatever may be
+ the mode or form of its expression including digital form, such as
+ a book, pamphlet and other writing; a lecture, address, sermon or
+ other work of the same nature; a dramatic or dramatico-musical
+ work; a choreographic work or entertainment in dumb show; a musical
+ composition with or without words; a cinematographic work to which
+ are assimilated works expressed by a process analogous to
+ cinematography; a work of drawing, painting, architecture,
+ sculpture, engraving or lithography; a photographic work to which
+ are assimilated works expressed by a process analogous to
+ photography; a work of applied art; an illustration, map, plan,
+ sketch or three-dimensional work relative to geography, topography,
+ architecture or science; a performance; a broadcast; a phonogram; a
+ compilation of data to the extent it is protected as a
+ copyrightable work; or a work performed by a variety or circus
+ performer to the extent it is not otherwise considered a literary
+ or artistic work.
+ i. "You" means an individual or entity exercising rights under this
+ License who has not previously violated the terms of this License
+ with respect to the Work, or who has received express permission
+ from the Licensor to exercise rights under this License despite a
+ previous violation.
+ j. "Publicly Perform" means to perform public recitations of the Work
+ and to communicate to the public those public recitations, by any
+ means or process, including by wire or wireless means or public
+ digital performances; to make available to the public Works in such
+ a way that members of the public may access these Works from a
+ place and at a place individually chosen by them; to perform the
+ Work to the public by any means or process and the communication to
+ the public of the performances of the Work, including by public
+ digital performance; to broadcast and rebroadcast the Work by any
+ means including signs, sounds or images.
+ k. "Reproduce" means to make copies of the Work by any means including
+ without limitation by sound or visual recordings and the right of
+ fixation and reproducing fixations of the Work, including storage
+ of a protected performance or phonogram in digital form or other
+ electronic medium.
+
+ 2. Fair Dealing Rights. Nothing in this License is intended to reduce,
+ limit, or restrict any uses free from copyright or rights arising from
+ limitations or exceptions that are provided for in connection with the
+ copyright protection under copyright law or other applicable laws.
+
+ 3. License Grant. Subject to the terms and conditions of this License,
+ Licensor hereby grants You a worldwide, royalty-free, non-exclusive,
+ perpetual (for the duration of the applicable copyright) license to
+ exercise the rights in the Work as stated below:
+ a. to Reproduce the Work, to incorporate the Work into one or more
+ Collections, and to Reproduce the Work as incorporated in the
+ Collections;
+ b. to create and Reproduce Adaptations provided that any such
+ Adaptation, including any translation in any medium, takes
+ reasonable steps to clearly label, demarcate or otherwise identify
+ that changes were made to the original Work. For example, a
+ translation could be marked "The original work was translated from
+ English to Spanish," or a modification could indicate "The original
+ work has been modified.";
+ c. to Distribute and Publicly Perform the Work including as
+ incorporated in Collections; and,
+ d. to Distribute and Publicly Perform Adaptations.
+ e. For the avoidance of doubt:
+ i. Non-waivable Compulsory License Schemes. In those
+ jurisdictions in which the right to collect royalties through
+ any statutory or compulsory licensing scheme cannot be waived,
+ the Licensor reserves the exclusive right to collect such
+ royalties for any exercise by You of the rights granted under
+ this License;
+ ii. Waivable Compulsory License Schemes. In those jurisdictions in
+ which the right to collect royalties through any statutory or
+ compulsory licensing scheme can be waived, the Licensor waives
+ the exclusive right to collect such royalties for any exercise
+ by You of the rights granted under this License; and,
+ iii. Voluntary License Schemes. The Licensor waives the right to
+ collect royalties, whether individually or, in the event that
+ the Licensor is a member of a collecting society that
+ administers voluntary licensing schemes, via that society,
+ from any exercise by You of the rights granted under this
+ License.
+
+ The above rights may be exercised in all media and formats whether now
+ known or hereafter devised. The above rights include the right to make
+ such modifications as are technically necessary to exercise the rights
+ in other media and formats. Subject to Section 8(f), all rights not
+ expressly granted by Licensor are hereby reserved.
+
+ 4. Restrictions. The license granted in Section 3 above is expressly
+ made subject to and limited by the following restrictions:
+ a. You may Distribute or Publicly Perform the Work only under the
+ terms of this License. You must include a copy of, or the Uniform
+ Resource Identifier (URI) for, this License with every copy of the
+ Work You Distribute or Publicly Perform. You may not offer or
+ impose any terms on the Work that restrict the terms of this
+ License or the ability of the recipient of the Work to exercise the
+ rights granted to that recipient under the terms of the License.
+ You may not sublicense the Work. You must keep intact all notices
+ that refer to this License and to the disclaimer of warranties with
+ every copy of the Work You Distribute or Publicly Perform. When You
+ Distribute or Publicly Perform the Work, You may not impose any
+ effective technological measures on the Work that restrict the
+ ability of a recipient of the Work from You to exercise the rights
+ granted to that recipient under the terms of the License. This
+ Section 4(a) applies to the Work as incorporated in a Collection,
+ but this does not require the Collection apart from the Work itself
+ to be made subject to the terms of this License. If You create a
+ Collection, upon notice from any Licensor You must, to the extent
+ practicable, remove from the Collection any credit as required by
+ Section 4(c), as requested. If You create an Adaptation, upon
+ notice from any Licensor You must, to the extent practicable,
+ remove from the Adaptation any credit as required by Section 4(c),
+ as requested.
+ b. You may Distribute or Publicly Perform an Adaptation only under the
+ terms of: (i) this License; (ii) a later version of this License
+ with the same License Elements as this License; (iii) a Creative
+ Commons jurisdiction license (either this or a later license
+ version) that contains the same License Elements as this License
+ (e.g., Attribution-ShareAlike 3.0 US)); (iv) a Creative Commons
+ Compatible License. If you license the Adaptation under one of the
+ licenses mentioned in (iv), you must comply with the terms of that
+ license. If you license the Adaptation under the terms of any of
+ the licenses mentioned in (i), (ii) or (iii) (the "Applicable
+ License"), you must comply with the terms of the Applicable License
+ generally and the following provisions: (I) You must include a copy
+ of, or the URI for, the Applicable License with every copy of each
+ Adaptation You Distribute or Publicly Perform; (II) You may not
+ offer or impose any terms on the Adaptation that restrict the terms
+ of the Applicable License or the ability of the recipient of the
+ Adaptation to exercise the rights granted to that recipient under
+ the terms of the Applicable License; (III) You must keep intact all
+ notices that refer to the Applicable License and to the disclaimer
+ of warranties with every copy of the Work as included in the
+ Adaptation You Distribute or Publicly Perform; (IV) when You
+ Distribute or Publicly Perform the Adaptation, You may not impose
+ any effective technological measures on the Adaptation that
+ restrict the ability of a recipient of the Adaptation from You to
+ exercise the rights granted to that recipient under the terms of
+ the Applicable License. This Section 4(b) applies to the Adaptation
+ as incorporated in a Collection, but this does not require the
+ Collection apart from the Adaptation itself to be made subject to
+ the terms of the Applicable License.
+ c. If You Distribute, or Publicly Perform the Work or any Adaptations
+ or Collections, You must, unless a request has been made pursuant
+ to Section 4(a), keep intact all copyright notices for the Work and
+ provide, reasonable to the medium or means You are utilizing: (i)
+ the name of the Original Author (or pseudonym, if applicable) if
+ supplied, and/or if the Original Author and/or Licensor designate
+ another party or parties (e.g., a sponsor institute, publishing
+ entity, journal) for attribution ("Attribution Parties") in
+ Licensor's copyright notice, terms of service or by other
+ reasonable means, the name of such party or parties; (ii) the title
+ of the Work if supplied; (iii) to the extent reasonably
+ practicable, the URI, if any, that Licensor specifies to be
+ associated with the Work, unless such URI does not refer to the
+ copyright notice or licensing information for the Work; and (iv) ,
+ consistent with Ssection 3(b), in the case of an Adaptation, a
+ credit identifying the use of the Work in the Adaptation (e.g.,
+ "French translation of the Work by Original Author," or "Screenplay
+ based on original Work by Original Author"). The credit required by
+ this Section 4(c) may be implemented in any reasonable manner;
+ provided, however, that in the case of a Adaptation or Collection,
+ at a minimum such credit will appear, if a credit for all
+ contributing authors of the Adaptation or Collection appears, then
+ as part of these credits and in a manner at least as prominent as
+ the credits for the other contributing authors. For the avoidance
+ of doubt, You may only use the credit required by this Section for
+ the purpose of attribution in the manner set out above and, by
+ exercising Your rights under this License, You may not implicitly
+ or explicitly assert or imply any connection with, sponsorship or
+ endorsement by the Original Author, Licensor and/or Attribution
+ Parties, as appropriate, of You or Your use of the Work, without
+ the separate, express prior written permission of the Original
+ Author, Licensor and/or Attribution Parties.
+ d. Except as otherwise agreed in writing by the Licensor or as may be
+ otherwise permitted by applicable law, if You Reproduce, Distribute
+ or Publicly Perform the Work either by itself or as part of any
+ Adaptations or Collections, You must not distort, mutilate, modify
+ or take other derogatory action in relation to the Work which would
+ be prejudicial to the Original Author's honor or reputation.
+ Licensor agrees that in those jurisdictions (e.g. Japan), in which
+ any exercise of the right granted in Section 3(b) of this License
+ (the right to make Adaptations) would be deemed to be a distortion,
+ mutilation, modification or other derogatory action prejudicial to
+ the Original Author's honor and reputation, the Licensor will waive
+ or not assert, as appropriate, this Section, to the fullest extent
+ permitted by the applicable national law, to enable You to
+ reasonably exercise Your right under Section 3(b) of this License
+ (right to make Adaptations) but not otherwise.
+
+ 5. Representations, Warranties and Disclaimer
+
+ UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR
+ OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY
+ KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE,
+ INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY,
+ FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF
+ LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF
+ ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW
+ THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO
+ YOU.
+
+ 6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE
+ LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR
+ ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES
+ ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR
+ HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+ 7. Termination
+ a. This License and the rights granted hereunder will terminate
+ automatically upon any breach by You of the terms of this License.
+ Individuals or entities who have received Adaptations or
+ Collections from You under this License, however, will not have
+ their licenses terminated provided such individuals or entities
+ remain in full compliance with those licenses. Sections 1, 2, 5, 6,
+ 7, and 8 will survive any termination of this License.
+ b. Subject to the above terms and conditions, the license granted here
+ is perpetual (for the duration of the applicable copyright in the
+ Work). Notwithstanding the above, Licensor reserves the right to
+ release the Work under different license terms or to stop
+ distributing the Work at any time; provided, however that any such
+ election will not serve to withdraw this License (or any other
+ license that has been, or is required to be, granted under the
+ terms of this License), and this License will continue in full
+ force and effect unless terminated as stated above.
+
+ 8. Miscellaneous
+ a. Each time You Distribute or Publicly Perform the Work or a
+ Collection, the Licensor offers to the recipient a license to the
+ Work on the same terms and conditions as the license granted to You
+ under this License.
+ b. Each time You Distribute or Publicly Perform an Adaptation,
+ Licensor offers to the recipient a license to the original Work on
+ the same terms and conditions as the license granted to You under
+ this License.
+ c. If any provision of this License is invalid or unenforceable under
+ applicable law, it shall not affect the validity or enforceability
+ of the remainder of the terms of this License, and without further
+ action by the parties to this agreement, such provision shall be
+ reformed to the minimum extent necessary to make such provision
+ valid and enforceable.
+ d. No term or provision of this License shall be deemed waived and no
+ breach consented to unless such waiver or consent shall be in
+ writing and signed by the party to be charged with such waiver or
+ consent.
+ e. This License constitutes the entire agreement between the parties
+ with respect to the Work licensed here. There are no
+ understandings, agreements or representations with respect to the
+ Work not specified here. Licensor shall not be bound by any
+ additional provisions that may appear in any communication from
+ You. This License may not be modified without the mutual written
+ agreement of the Licensor and You.
+ f. The rights granted under, and the subject matter referenced, in
+ this License were drafted utilizing the terminology of the Berne
+ Convention for the Protection of Literary and Artistic Works (as
+ amended on September 28, 1979), the Rome Convention of 1961, the
+ WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms
+ Treaty of 1996 and the Universal Copyright Convention (as revised
+ on July 24, 1971). These rights and subject matter take effect in
+ the relevant jurisdiction in which the License terms are sought to
+ be enforced according to the corresponding provisions of the
+ implementation of those treaty provisions in the applicable
+ national law. If the standard suite of rights granted under
+ applicable copyright law includes additional rights not granted
+ under this License, such additional rights are deemed to be
+ included in the License; this License is not intended to restrict
+ the license of any rights under applicable law.
+
+Creative Commons Notice
+
+ Creative Commons is not a party to this License, and makes no warranty
+ whatsoever in connection with the Work. Creative Commons will not be
+ liable to You or any party on any legal theory for any damages
+ whatsoever, including without limitation any general, special,
+ incidental or consequential damages arising in connection to this
+ license. Notwithstanding the foregoing two (2) sentences, if Creative
+ Commons has expressly identified itself as the Licensor hereunder, it
+ shall have all rights and obligations of Licensor.
+
+ Except for the limited purpose of indicating to the public that the
+ Work is licensed under the CCPL, Creative Commons does not authorize
+ the use by either party of the trademark "Creative Commons" or any
+ related trademark or logo of Creative Commons without the prior written
+ consent of Creative Commons. Any permitted use will be in compliance
+ with Creative Commons' then-current trademark usage guidelines, as may
+ be published on its website or otherwise made available upon request
+ from time to time. For the avoidance of doubt, this trademark
+ restriction does not form part of the License.
+
+ Creative Commons may be contacted at http://creativecommons.org/.
+
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/openssl.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/openssl.txt
new file mode 100644
index 00000000000..e47d101f102
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/openssl.txt
@@ -0,0 +1,127 @@
+
+ LICENSE ISSUES
+ ==============
+
+ The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
+ the OpenSSL License and the original SSLeay license apply to the toolkit.
+ See below for the actual license texts. Actually both licenses are BSD-style
+ Open Source licenses. In case of any license issues related to OpenSSL
+ please contact openssl-core@openssl.org.
+
+ OpenSSL License
+ ---------------
+
+/* ====================================================================
+ * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+ Original SSLeay License
+ -----------------------
+
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/pdfium.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/pdfium.txt
new file mode 100644
index 00000000000..8b4ed6dddf2
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/pdfium.txt
@@ -0,0 +1,27 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/tomcat.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/tomcat.txt
new file mode 100644
index 00000000000..0532f5bc2c2
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/tomcat.txt
@@ -0,0 +1,1050 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+
+APACHE TOMCAT SUBCOMPONENTS:
+
+Apache Tomcat includes a number of subcomponents with separate copyright notices
+and license terms. Your use of these subcomponents is subject to the terms and
+conditions of the following licenses.
+
+
+For the ecj-x.x.x.jar component:
+
+Eclipse Public License - v 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
+LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
+CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+a) in the case of the initial Contributor, the initial code and documentation
+distributed under this Agreement, and
+
+b) in the case of each subsequent Contributor:
+
+i) changes to the Program, and
+
+ii) additions to the Program;
+
+where such changes and/or additions to the Program originate from and are
+distributed by that particular Contributor. A Contribution 'originates' from a
+Contributor if it was added to the Program by such Contributor itself or anyone
+acting on such Contributor's behalf. Contributions do not include additions to
+the Program which: (i) are separate modules of software distributed in
+conjunction with the Program under their own license agreement, and (ii) are not
+derivative works of the Program.
+
+"Contributor" means any person or entity that distributes the Program.
+
+"Licensed Patents" mean patent claims licensable by a Contributor which are
+necessarily infringed by the use or sale of its Contribution alone or when
+combined with the Program.
+
+"Program" means the Contributions distributed in accordance with this Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement,
+including all Contributors.
+
+2. GRANT OF RIGHTS
+
+a) Subject to the terms of this Agreement, each Contributor hereby grants
+Recipient a non-exclusive, worldwide, royalty-free copyright license to
+reproduce, prepare derivative works of, publicly display, publicly perform,
+distribute and sublicense the Contribution of such Contributor, if any, and such
+derivative works, in source code and object code form.
+
+b) Subject to the terms of this Agreement, each Contributor hereby grants
+Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed
+Patents to make, use, sell, offer to sell, import and otherwise transfer the
+Contribution of such Contributor, if any, in source code and object code form.
+This patent license shall apply to the combination of the Contribution and the
+Program if, at the time the Contribution is added by the Contributor, such
+addition of the Contribution causes such combination to be covered by the
+Licensed Patents. The patent license shall not apply to any other combinations
+which include the Contribution. No hardware per se is licensed hereunder.
+
+c) Recipient understands that although each Contributor grants the licenses to
+its Contributions set forth herein, no assurances are provided by any
+Contributor that the Program does not infringe the patent or other intellectual
+property rights of any other entity. Each Contributor disclaims any liability to
+Recipient for claims brought by any other entity based on infringement of
+intellectual property rights or otherwise. As a condition to exercising the
+rights and licenses granted hereunder, each Recipient hereby assumes sole
+responsibility to secure any other intellectual property rights needed, if any.
+For example, if a third party patent license is required to allow Recipient to
+distribute the Program, it is Recipient's responsibility to acquire that license
+before distributing the Program.
+
+d) Each Contributor represents that to its knowledge it has sufficient copyright
+rights in its Contribution, if any, to grant the copyright license set forth in
+this Agreement.
+
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form under its
+own license agreement, provided that:
+
+a) it complies with the terms and conditions of this Agreement; and
+
+b) its license agreement:
+
+i) effectively disclaims on behalf of all Contributors all warranties and
+conditions, express and implied, including warranties or conditions of title and
+non-infringement, and implied warranties or conditions of merchantability and
+fitness for a particular purpose;
+
+ii) effectively excludes on behalf of all Contributors all liability for
+damages, including direct, indirect, special, incidental and consequential
+damages, such as lost profits;
+
+iii) states that any provisions which differ from this Agreement are offered by
+that Contributor alone and not by any other party; and
+
+iv) states that source code for the Program is available from such Contributor,
+and informs licensees how to obtain it in a reasonable manner on or through a
+medium customarily used for software exchange.
+
+When the Program is made available in source code form:
+
+a) it must be made available under this Agreement; and
+
+b) a copy of this Agreement must be included with each copy of the Program.
+
+Contributors may not remove or alter any copyright notices contained within the
+Program.
+
+Each Contributor must identify itself as the originator of its Contribution, if
+any, in a manner that reasonably allows subsequent Recipients to identify the
+originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities with
+respect to end users, business partners and the like. While this license is
+intended to facilitate the commercial use of the Program, the Contributor who
+includes the Program in a commercial product offering should do so in a manner
+which does not create potential liability for other Contributors. Therefore, if
+a Contributor includes the Program in a commercial product offering, such
+Contributor ("Commercial Contributor") hereby agrees to defend and indemnify
+every other Contributor ("Indemnified Contributor") against any losses, damages
+and costs (collectively "Losses") arising from claims, lawsuits and other legal
+actions brought by a third party against the Indemnified Contributor to the
+extent caused by the acts or omissions of such Commercial Contributor in
+connection with its distribution of the Program in a commercial product
+offering. The obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property infringement. In order
+to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
+Contributor in writing of such claim, and b) allow the Commercial Contributor
+to control, and cooperate with the Commercial Contributor in, the defense and
+any related settlement negotiations. The Indemnified Contributor may
+participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial product
+offering, Product X. That Contributor is then a Commercial Contributor. If that
+Commercial Contributor then makes performance claims, or offers warranties
+related to Product X, those performance claims and warranties are such
+Commercial Contributor's responsibility alone. Under this section, the
+Commercial Contributor would have to defend claims against the other
+Contributors related to those performance claims and warranties, and if a court
+requires any other Contributor to pay any damages as a result, the Commercial
+Contributor must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
+IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each
+Recipient is solely responsible for determining the appropriateness of using and
+distributing the Program and assumes all risks associated with its exercise of
+rights under this Agreement , including but not limited to the risks and costs
+of program errors, compliance with applicable laws, damage to or loss of data,
+programs or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
+CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST
+PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS
+GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under applicable
+law, it shall not affect the validity or enforceability of the remainder of the
+terms of this Agreement, and without further action by the parties hereto, such
+provision shall be reformed to the minimum extent necessary to make such
+provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity (including a
+cross-claim or counterclaim in a lawsuit) alleging that the Program itself
+(excluding combinations of the Program with other software or hardware)
+infringes such Recipient's patent(s), then such Recipient's rights granted under
+Section 2(b) shall terminate as of the date such litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it fails to
+comply with any of the material terms or conditions of this Agreement and does
+not cure such failure in a reasonable period of time after becoming aware of
+such noncompliance. If all Recipient's rights under this Agreement terminate,
+Recipient agrees to cease use and distribution of the Program as soon as
+reasonably practicable. However, Recipient's obligations under this Agreement
+and any licenses granted by Recipient relating to the Program shall continue and
+survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement, but in
+order to avoid inconsistency the Agreement is copyrighted and may only be
+modified in the following manner. The Agreement Steward reserves the right to
+publish new versions (including revisions) of this Agreement from time to time.
+No one other than the Agreement Steward has the right to modify this Agreement.
+The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation
+may assign the responsibility to serve as the Agreement Steward to a suitable
+separate entity. Each new version of the Agreement will be given a
+distinguishing version number. The Program (including Contributions) may always
+be distributed subject to the version of the Agreement under which it was
+received. In addition, after a new version of the Agreement is published,
+Contributor may elect to distribute the Program (including its Contributions)
+under the new version. Except as expressly stated in Sections 2(a) and 2(b)
+above, Recipient receives no rights or licenses to the intellectual property of
+any Contributor under this Agreement, whether expressly, by implication,
+estoppel or otherwise. All rights in the Program not expressly granted under
+this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the
+intellectual property laws of the United States of America. No party to this
+Agreement will bring a legal action under this Agreement more than one year
+after the cause of action arose. Each party waives its rights to a jury trial in
+any resulting litigation.
+
+
+For the Windows Installer component:
+
+ * All NSIS source code, plug-ins, documentation, examples, header files and
+ graphics, with the exception of the compression modules and where
+ otherwise noted, are licensed under the zlib/libpng license.
+ * The zlib compression module for NSIS is licensed under the zlib/libpng
+ license.
+ * The bzip2 compression module for NSIS is licensed under the bzip2 license.
+ * The lzma compression module for NSIS is licensed under the Common Public
+ License version 1.0.
+
+zlib/libpng license
+
+This software is provided 'as-is', without any express or implied warranty. In
+no event will the authors be held liable for any damages arising from the use of
+this software.
+
+Permission is granted to anyone to use this software for any purpose, including
+commercial applications, and to alter it and redistribute it freely, subject to
+the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not claim
+ that you wrote the original software. If you use this software in a
+ product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+bzip2 license
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. The origin of this software must not be misrepresented; you must not claim
+ that you wrote the original software. If you use this software in a
+ product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 3. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 4. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+OF SUCH DAMAGE.
+
+Julian Seward, Cambridge, UK.
+
+jseward@acm.org
+Common Public License version 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC
+LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
+CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+a) in the case of the initial Contributor, the initial code and documentation
+distributed under this Agreement, and b) in the case of each subsequent
+Contributor:
+
+i) changes to the Program, and
+
+ii) additions to the Program;
+
+where such changes and/or additions to the Program originate from and are
+distributed by that particular Contributor. A Contribution 'originates' from a
+Contributor if it was added to the Program by such Contributor itself or anyone
+acting on such Contributor's behalf. Contributions do not include additions to
+the Program which: (i) are separate modules of software distributed in
+conjunction with the Program under their own license agreement, and (ii) are not
+derivative works of the Program.
+
+"Contributor" means any person or entity that distributes the Program.
+
+"Licensed Patents " mean patent claims licensable by a Contributor which are
+necessarily infringed by the use or sale of its Contribution alone or when
+combined with the Program.
+
+"Program" means the Contributions distributed in accordance with this Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement,
+including all Contributors.
+
+2. GRANT OF RIGHTS
+
+a) Subject to the terms of this Agreement, each Contributor hereby grants
+Recipient a non-exclusive, worldwide, royalty-free copyright license to
+reproduce, prepare derivative works of, publicly display, publicly perform,
+distribute and sublicense the Contribution of such Contributor, if any, and such
+derivative works, in source code and object code form.
+
+b) Subject to the terms of this Agreement, each Contributor hereby grants
+Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed
+Patents to make, use, sell, offer to sell, import and otherwise transfer the
+Contribution of such Contributor, if any, in source code and object code form.
+This patent license shall apply to the combination of the Contribution and the
+Program if, at the time the Contribution is added by the Contributor, such
+addition of the Contribution causes such combination to be covered by the
+Licensed Patents. The patent license shall not apply to any other combinations
+which include the Contribution. No hardware per se is licensed hereunder.
+
+c) Recipient understands that although each Contributor grants the licenses to
+its Contributions set forth herein, no assurances are provided by any
+Contributor that the Program does not infringe the patent or other intellectual
+property rights of any other entity. Each Contributor disclaims any liability to
+Recipient for claims brought by any other entity based on infringement of
+intellectual property rights or otherwise. As a condition to exercising the
+rights and licenses granted hereunder, each Recipient hereby assumes sole
+responsibility to secure any other intellectual property rights needed, if any.
+For example, if a third party patent license is required to allow Recipient to
+distribute the Program, it is Recipient's responsibility to acquire that license
+before distributing the Program.
+
+d) Each Contributor represents that to its knowledge it has sufficient copyright
+rights in its Contribution, if any, to grant the copyright license set forth in
+this Agreement.
+
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form under its
+own license agreement, provided that:
+
+a) it complies with the terms and conditions of this Agreement; and
+
+b) its license agreement:
+
+i) effectively disclaims on behalf of all Contributors all warranties and
+conditions, express and implied, including warranties or conditions of title and
+non-infringement, and implied warranties or conditions of merchantability and
+fitness for a particular purpose;
+
+ii) effectively excludes on behalf of all Contributors all liability for
+damages, including direct, indirect, special, incidental and consequential
+damages, such as lost profits;
+
+iii) states that any provisions which differ from this Agreement are offered by
+that Contributor alone and not by any other party; and
+
+iv) states that source code for the Program is available from such Contributor,
+and informs licensees how to obtain it in a reasonable manner on or through a
+medium customarily used for software exchange.
+
+When the Program is made available in source code form:
+
+a) it must be made available under this Agreement; and
+
+b) a copy of this Agreement must be included with each copy of the Program.
+
+Contributors may not remove or alter any copyright notices contained within the
+Program.
+
+Each Contributor must identify itself as the originator of its Contribution, if
+any, in a manner that reasonably allows subsequent Recipients to identify the
+originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities with
+respect to end users, business partners and the like. While this license is
+intended to facilitate the commercial use of the Program, the Contributor who
+includes the Program in a commercial product offering should do so in a manner
+which does not create potential liability for other Contributors. Therefore, if
+a Contributor includes the Program in a commercial product offering, such
+Contributor ("Commercial Contributor") hereby agrees to defend and indemnify
+every other Contributor ("Indemnified Contributor") against any losses, damages
+and costs (collectively "Losses") arising from claims, lawsuits and other legal
+actions brought by a third party against the Indemnified Contributor to the
+extent caused by the acts or omissions of such Commercial Contributor in
+connection with its distribution of the Program in a commercial product
+offering. The obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property infringement. In order
+to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
+Contributor in writing of such claim, and b) allow the Commercial Contributor to
+control, and cooperate with the Commercial Contributor in, the defense and any
+related settlement negotiations. The Indemnified Contributor may participate in
+any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial product
+offering, Product X. That Contributor is then a Commercial Contributor. If that
+Commercial Contributor then makes performance claims, or offers warranties
+related to Product X, those performance claims and warranties are such
+Commercial Contributor's responsibility alone. Under this section, the
+Commercial Contributor would have to defend claims against the other
+Contributors related to those performance claims and warranties, and if a court
+requires any other Contributor to pay any damages as a result, the Commercial
+Contributor must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
+IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each
+Recipient is solely responsible for determining the appropriateness of using and
+distributing the Program and assumes all risks associated with its exercise of
+rights under this Agreement, including but not limited to the risks and costs of
+program errors, compliance with applicable laws, damage to or loss of data,
+programs or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
+CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST
+PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS
+GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under applicable
+law, it shall not affect the validity or enforceability of the remainder of the
+terms of this Agreement, and without further action by the parties hereto, such
+provision shall be reformed to the minimum extent necessary to make such
+provision valid and enforceable.
+
+If Recipient institutes patent litigation against a Contributor with respect to
+a patent applicable to software (including a cross-claim or counterclaim in a
+lawsuit), then any patent licenses granted by that Contributor to such Recipient
+under this Agreement shall terminate as of the date such litigation is filed. In
+addition, if Recipient institutes patent litigation against any entity
+(including a cross-claim or counterclaim in a lawsuit) alleging that the Program
+itself (excluding combinations of the Program with other software or hardware)
+infringes such Recipient's patent(s), then such Recipient's rights granted under
+Section 2(b) shall terminate as of the date such litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it fails to
+comply with any of the material terms or conditions of this Agreement and does
+not cure such failure in a reasonable period of time after becoming aware of
+such noncompliance. If all Recipient's rights under this Agreement terminate,
+Recipient agrees to cease use and distribution of the Program as soon as
+reasonably practicable. However, Recipient's obligations under this Agreement
+and any licenses granted by Recipient relating to the Program shall continue and
+survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement, but in
+order to avoid inconsistency the Agreement is copyrighted and may only be
+modified in the following manner. The Agreement Steward reserves the right to
+publish new versions (including revisions) of this Agreement from time to time.
+No one other than the Agreement Steward has the right to modify this Agreement.
+IBM is the initial Agreement Steward. IBM may assign the responsibility to serve
+as the Agreement Steward to a suitable separate entity. Each new version of the
+Agreement will be given a distinguishing version number. The Program (including
+Contributions) may always be distributed subject to the version of the Agreement
+under which it was received. In addition, after a new version of the Agreement
+is published, Contributor may elect to distribute the Program (including its
+Contributions) under the new version. Except as expressly stated in Sections
+2(a) and 2(b) above, Recipient receives no rights or licenses to the
+intellectual property of any Contributor under this Agreement, whether
+expressly, by implication, estoppel or otherwise. All rights in the Program not
+expressly granted under this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the
+intellectual property laws of the United States of America. No party to this
+Agreement will bring a legal action under this Agreement more than one year
+after the cause of action arose. Each party waives its rights to a jury trial in
+any resulting litigation.
+
+Special exception for LZMA compression module
+
+Igor Pavlov and Amir Szekely, the authors of the LZMA compression module for
+NSIS, expressly permit you to statically or dynamically link your code (or bind
+by name) to the files from the LZMA compression module for NSIS without
+subjecting your linked code to the terms of the Common Public license version
+1.0. Any modifications or additions to files from the LZMA compression module
+for NSIS, however, are subject to the terms of the Common Public License version
+1.0.
+
+
+For the following XML Schemas for Java EE Deployment Descriptors:
+ - javaee_5.xsd
+ - javaee_web_services_1_2.xsd
+ - javaee_web_services_client_1_2.xsd
+ - javaee_6.xsd
+ - javaee_web_services_1_3.xsd
+ - javaee_web_services_client_1_3.xsd
+ - jsp_2_2.xsd
+ - web-app_3_0.xsd
+ - web-common_3_0.xsd
+ - web-fragment_3_0.xsd
+
+COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
+
+1. Definitions.
+
+ 1.1. Contributor. means each individual or entity that creates or contributes
+ to the creation of Modifications.
+
+ 1.2. Contributor Version. means the combination of the Original Software,
+ prior Modifications used by a Contributor (if any), and the
+ Modifications made by that particular Contributor.
+
+ 1.3. Covered Software. means (a) the Original Software, or (b) Modifications,
+ or (c) the combination of files containing Original Software with files
+ containing Modifications, in each case including portions thereof.
+
+ 1.4. Executable. means the Covered Software in any form other than Source
+ Code.
+
+ 1.5. Initial Developer. means the individual or entity that first makes
+ Original Software available under this License.
+
+ 1.6. Larger Work. means a work which combines Covered Software or portions
+ thereof with code not governed by the terms of this License.
+
+ 1.7. License. means this document.
+
+ 1.8. Licensable. means having the right to grant, to the maximum extent
+ possible, whether at the time of the initial grant or subsequently
+ acquired, any and all of the rights conveyed herein.
+
+ 1.9. Modifications. means the Source Code and Executable form of any of the
+ following:
+
+ A. Any file that results from an addition to, deletion from or
+ modification of the contents of a file containing Original Software
+ or previous Modifications;
+
+ B. Any new file that contains any part of the Original Software or
+ previous Modification; or
+
+ C. Any new file that is contributed or otherwise made available under
+ the terms of this License.
+
+ 1.10. Original Software. means the Source Code and Executable form of
+ computer software code that is originally released under this License.
+
+ 1.11. Patent Claims. means any patent claim(s), now owned or hereafter
+ acquired, including without limitation, method, process, and apparatus
+ claims, in any patent Licensable by grantor.
+
+ 1.12. Source Code. means (a) the common form of computer software code in
+ which modifications are made and (b) associated documentation included
+ in or with such code.
+
+ 1.13. You. (or .Your.) means an individual or a legal entity exercising
+ rights under, and complying with all of the terms of, this License. For
+ legal entities, .You. includes any entity which controls, is controlled
+ by, or is under common control with You. For purposes of this
+ definition, .control. means (a) the power, direct or indirect, to cause
+ the direction or management of such entity, whether by contract or
+ otherwise, or (b) ownership of more than fifty percent (50%) of the
+ outstanding shares or beneficial ownership of such entity.
+
+2. License Grants.
+
+ 2.1. The Initial Developer Grant.
+
+ Conditioned upon Your compliance with Section 3.1 below and subject to
+ third party intellectual property claims, the Initial Developer hereby
+ grants You a world-wide, royalty-free, non-exclusive license:
+
+ (a) under intellectual property rights (other than patent or trademark)
+ Licensable by Initial Developer, to use, reproduce, modify, display,
+ perform, sublicense and distribute the Original Software (or
+ portions thereof), with or without Modifications, and/or as part of
+ a Larger Work; and
+
+ (b) under Patent Claims infringed by the making, using or selling of
+ Original Software, to make, have made, use, practice, sell, and
+ offer for sale, and/or otherwise dispose of the Original Software
+ (or portions thereof).
+
+ (c) The licenses granted in Sections 2.1(a) and (b) are effective on the
+ date Initial Developer first distributes or otherwise makes the
+ Original Software available to a third party under the terms of this
+ License.
+
+ (d) Notwithstanding Section 2.1(b) above, no patent license is granted:
+ (1) for code that You delete from the Original Software, or (2) for
+ infringements caused by: (i) the modification of the Original
+ Software, or (ii) the combination of the Original Software with
+ other software or devices.
+
+ 2.2. Contributor Grant.
+
+ Conditioned upon Your compliance with Section 3.1 below and subject to third
+ party intellectual property claims, each Contributor hereby grants You a
+ world-wide, royalty-free, non-exclusive license:
+
+ (a) under intellectual property rights (other than patent or trademark)
+ Licensable by Contributor to use, reproduce, modify, display,
+ perform, sublicense and distribute the Modifications created by such
+ Contributor (or portions thereof), either on an unmodified basis,
+ with other Modifications, as Covered Software and/or as part of a
+ Larger Work; and
+
+ (b) under Patent Claims infringed by the making, using, or selling of
+ Modifications made by that Contributor either alone and/or in
+ combination with its Contributor Version (or portions of such
+ combination), to make, use, sell, offer for sale, have made, and/or
+ otherwise dispose of: (1) Modifications made by that Contributor (or
+ portions thereof); and (2) the combination of Modifications made by
+ that Contributor with its Contributor Version (or portions of such
+ combination).
+
+ (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective on
+ the date Contributor first distributes or otherwise makes the
+ Modifications available to a third party.
+
+ (d) Notwithstanding Section 2.2(b) above, no patent license is granted:
+ (1) for any code that Contributor has deleted from the Contributor
+ Version; (2) for infringements caused by: (i) third party
+ modifications of Contributor Version, or (ii) the combination of
+ Modifications made by that Contributor with other software (except
+ as part of the Contributor Version) or other devices; or (3) under
+ Patent Claims infringed by Covered Software in the absence of
+ Modifications made by that Contributor.
+
+3. Distribution Obligations.
+
+ 3.1. Availability of Source Code.
+ Any Covered Software that You distribute or otherwise make available in
+ Executable form must also be made available in Source Code form and that
+ Source Code form must be distributed only under the terms of this License.
+ You must include a copy of this License with every copy of the Source Code
+ form of the Covered Software You distribute or otherwise make available.
+ You must inform recipients of any such Covered Software in Executable form
+ as to how they can obtain such Covered Software in Source Code form in a
+ reasonable manner on or through a medium customarily used for software
+ exchange.
+
+ 3.2. Modifications.
+ The Modifications that You create or to which You contribute are governed
+ by the terms of this License. You represent that You believe Your
+ Modifications are Your original creation(s) and/or You have sufficient
+ rights to grant the rights conveyed by this License.
+
+ 3.3. Required Notices.
+ You must include a notice in each of Your Modifications that identifies
+ You as the Contributor of the Modification. You may not remove or alter
+ any copyright, patent or trademark notices contained within the Covered
+ Software, or any notices of licensing or any descriptive text giving
+ attribution to any Contributor or the Initial Developer.
+
+ 3.4. Application of Additional Terms.
+ You may not offer or impose any terms on any Covered Software in Source
+ Code form that alters or restricts the applicable version of this License
+ or the recipients. rights hereunder. You may choose to offer, and to
+ charge a fee for, warranty, support, indemnity or liability obligations to
+ one or more recipients of Covered Software. However, you may do so only on
+ Your own behalf, and not on behalf of the Initial Developer or any
+ Contributor. You must make it absolutely clear that any such warranty,
+ support, indemnity or liability obligation is offered by You alone, and
+ You hereby agree to indemnify the Initial Developer and every Contributor
+ for any liability incurred by the Initial Developer or such Contributor as
+ a result of warranty, support, indemnity or liability terms You offer.
+
+ 3.5. Distribution of Executable Versions.
+ You may distribute the Executable form of the Covered Software under the
+ terms of this License or under the terms of a license of Your choice,
+ which may contain terms different from this License, provided that You are
+ in compliance with the terms of this License and that the license for the
+ Executable form does not attempt to limit or alter the recipient.s rights
+ in the Source Code form from the rights set forth in this License. If You
+ distribute the Covered Software in Executable form under a different
+ license, You must make it absolutely clear that any terms which differ
+ from this License are offered by You alone, not by the Initial Developer
+ or Contributor. You hereby agree to indemnify the Initial Developer and
+ every Contributor for any liability incurred by the Initial Developer or
+ such Contributor as a result of any such terms You offer.
+
+ 3.6. Larger Works.
+ You may create a Larger Work by combining Covered Software with other code
+ not governed by the terms of this License and distribute the Larger Work
+ as a single product. In such a case, You must make sure the requirements
+ of this License are fulfilled for the Covered Software.
+
+4. Versions of the License.
+
+ 4.1. New Versions.
+ Sun Microsystems, Inc. is the initial license steward and may publish
+ revised and/or new versions of this License from time to time. Each
+ version will be given a distinguishing version number. Except as provided
+ in Section 4.3, no one other than the license steward has the right to
+ modify this License.
+
+ 4.2. Effect of New Versions.
+ You may always continue to use, distribute or otherwise make the Covered
+ Software available under the terms of the version of the License under
+ which You originally received the Covered Software. If the Initial
+ Developer includes a notice in the Original Software prohibiting it from
+ being distributed or otherwise made available under any subsequent version
+ of the License, You must distribute and make the Covered Software
+ available under the terms of the version of the License under which You
+ originally received the Covered Software. Otherwise, You may also choose
+ to use, distribute or otherwise make the Covered Software available under
+ the terms of any subsequent version of the License published by the
+ license steward.
+
+ 4.3. Modified Versions.
+ When You are an Initial Developer and You want to create a new license for
+ Your Original Software, You may create and use a modified version of this
+ License if You: (a) rename the license and remove any references to the
+ name of the license steward (except to note that the license differs from
+ this License); and (b) otherwise make it clear that the license contains
+ terms which differ from this License.
+
+5. DISCLAIMER OF WARRANTY.
+
+ COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN .AS IS. BASIS, WITHOUT
+ WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT
+ LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS,
+ MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK
+ AS TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD
+ ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL
+ DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+ SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN
+ ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED SOFTWARE IS AUTHORIZED
+ HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+6. TERMINATION.
+
+ 6.1. This License and the rights granted hereunder will terminate
+ automatically if You fail to comply with terms herein and fail to
+ cure such breach within 30 days of becoming aware of the breach.
+ Provisions which, by their nature, must remain in effect beyond the
+ termination of this License shall survive.
+
+ 6.2. If You assert a patent infringement claim (excluding declaratory
+ judgment actions) against Initial Developer or a Contributor (the
+ Initial Developer or Contributor against whom You assert such claim
+ is referred to as .Participant.) alleging that the Participant
+ Software (meaning the Contributor Version where the Participant is a
+ Contributor or the Original Software where the Participant is the
+ Initial Developer) directly or indirectly infringes any patent, then
+ any and all rights granted directly or indirectly to You by such
+ Participant, the Initial Developer (if the Initial Developer is not
+ the Participant) and all Contributors under Sections 2.1 and/or 2.2
+ of this License shall, upon 60 days notice from Participant terminate
+ prospectively and automatically at the expiration of such 60 day
+ notice period, unless if within such 60 day period You withdraw Your
+ claim with respect to the Participant Software against such
+ Participant either unilaterally or pursuant to a written agreement
+ with Participant.
+
+ 6.3. In the event of termination under Sections 6.1 or 6.2 above, all end
+ user licenses that have been validly granted by You or any
+ distributor hereunder prior to termination (excluding licenses
+ granted to You by any distributor) shall survive termination.
+
+7. LIMITATION OF LIABILITY.
+
+ UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING
+ NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY
+ OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED SOFTWARE, OR ANY SUPPLIER OF
+ ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL,
+ INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT
+ LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK STOPPAGE,
+ COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR
+ LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
+ SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR
+ DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY.S NEGLIGENCE TO THE EXTENT
+ APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
+ EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS
+ EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+8. U.S. GOVERNMENT END USERS.
+
+ The Covered Software is a .commercial item,. as that term is defined in 48
+ C.F.R. 2.101 (Oct. 1995), consisting of .commercial computer software. (as
+ that term is defined at 48 C.F.R. ? 252.227-7014(a)(1)) and commercial
+ computer software documentation. as such terms are used in 48 C.F.R. 12.212
+ (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1
+ through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered
+ Software with only those rights set forth herein. This U.S. Government Rights
+ clause is in lieu of, and supersedes, any other FAR, DFAR, or other clause or
+ provision that addresses Government rights in computer software under this
+ License.
+
+9. MISCELLANEOUS.
+
+ This License represents the complete agreement concerning subject matter
+ hereof. If any provision of this License is held to be unenforceable, such
+ provision shall be reformed only to the extent necessary to make it
+ enforceable. This License shall be governed by the law of the jurisdiction
+ specified in a notice contained within the Original Software (except to the
+ extent applicable law, if any, provides otherwise), excluding such
+ jurisdiction's conflict-of-law provisions. Any litigation relating to this
+ License shall be subject to the jurisdiction of the courts located in the
+ jurisdiction and venue specified in a notice contained within the Original
+ Software, with the losing party responsible for costs, including, without
+ limitation, court costs and reasonable attorneys. fees and expenses. The
+ application of the United Nations Convention on Contracts for the
+ International Sale of Goods is expressly excluded. Any law or regulation
+ which provides that the language of a contract shall be construed against
+ the drafter shall not apply to this License. You agree that You alone are
+ responsible for compliance with the United States export administration
+ regulations (and the export control laws and regulation of any other
+ countries) when You use, distribute or otherwise make available any Covered
+ Software.
+
+10. RESPONSIBILITY FOR CLAIMS.
+
+ As between Initial Developer and the Contributors, each party is responsible
+ for claims and damages arising, directly or indirectly, out of its
+ utilization of rights under this License and You agree to work with Initial
+ Developer and Contributors to distribute such responsibility on an equitable
+ basis. Nothing herein is intended or shall be deemed to constitute any
+ admission of liability.
+
+ NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION
+ LICENSE (CDDL)
+
+ The code released under the CDDL shall be governed by the laws of the State
+ of California (excluding conflict-of-law provisions). Any litigation relating
+ to this License shall be subject to the jurisdiction of the Federal Courts of
+ the Northern District of California and the state courts of the State of
+ California, with venue lying in Santa Clara County, California.
+
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/xpdf-japanese.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/xpdf-japanese.txt
new file mode 100644
index 00000000000..e96f559f716
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/xpdf-japanese.txt
@@ -0,0 +1,47 @@
+Xpdf: Japanese support package
+==============================
+
+Xpdf project: http://www.foolabs.com/xpdf/
+2011-sep-02
+
+If this package includes CMap files, they contain their own copyright
+notices and distribution conditions. All other files in the package
+are Copyright 2002-2004 Glyph & Cog, LLC, and are licensed under the
+GNU General Public License (GPL), version 2 or 3.
+
+This package provides support files needed to use the Xpdf tools with
+Japanese PDF files.
+
+Contents:
+- Adobe-Japan1 character collection support
+- ISO-2022-JP encoding
+- EUC-JP encoding
+- Shift-JIS encoding
+
+Place all of these files in a directory, typically:
+
+ Unix - /usr/local/share/xpdf/japanese
+ Win32 - C:\Program Files\xpdf\japanese
+
+Add the contents of the "add-to-xpdfrc" file to your system-wide
+xpdfrc config file, which is typically:
+
+ Unix - /usr/local/etc/xpdfrc
+ Win32 - C:\Program Files\xpdf\xpdfrc
+
+Alternatively, on Unix systems you can add these lines to your
+personal xpdfrc file in $HOME/.xpdfrc.
+
+Make sure to edit the added lines to use the actual directory where
+the files were installed.
+
+To display PDF files that refer to non-embedded Japanese fonts, you
+will need to install a Japanese font. Free TrueType fonts are
+available:
+
+ http://packages.debian.org/stable/x11/ttf-kochi-mincho
+ http://packages.debian.org/stable/x11/ttf-kochi-gothic
+ ftp://ftp.turbolinux.co.jp/pub/TurboLinux/TurboLinux/ia32/Workstation/7/updates/RPMS/ricoh-gothic-1.1-1.noarch.rpm
+
+After installing a Japanese font, add an appropriate "fontFileCC" line
+to your xpdfrc file (see the sample in "add-to-xpdfrc").
diff --git a/packaging/distribution/src/main/resources/licenses/3rd-party/zlib.txt b/packaging/distribution/src/main/resources/licenses/3rd-party/zlib.txt
new file mode 100644
index 00000000000..758cc50020d
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/3rd-party/zlib.txt
@@ -0,0 +1,125 @@
+ZLIB DATA COMPRESSION LIBRARY
+
+zlib 1.2.3 is a general purpose data compression library. All the code is
+thread safe. The data format used by the zlib library is described by RFCs
+(Request for Comments) 1950 to 1952 in the files
+http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
+and rfc1952.txt (gzip format). These documents are also available in other
+formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
+
+All functions of the compression library are documented in the file zlib.h
+(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
+of the library is given in the file example.c which also tests that the library
+is working correctly. Another example is given in the file minigzip.c. The
+compression library itself is composed of all source files except example.c and
+minigzip.c.
+
+To compile all files and run the test program, follow the instructions given at
+the top of Makefile. In short "make test; make install" should work for most
+machines. For Unix: "./configure; make test; make install". For MSDOS, use one
+of the special makefiles such as Makefile.msc. For VMS, use make_vms.com.
+
+Questions about zlib should be sent to , or to Gilles Vollant
+ for the Windows DLL version. The zlib home page is
+http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem,
+please check this site to verify that you have the latest version of zlib;
+otherwise get the latest version and check whether the problem still exists or
+not.
+
+PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking
+for help.
+
+Mark Nelson wrote an article about zlib for the Jan. 1997
+issue of Dr. Dobb's Journal; a copy of the article is available in
+http://dogma.net/markn/articles/zlibtool/zlibtool.htm
+
+The changes made in version 1.2.3 are documented in the file ChangeLog.
+
+Unsupported third party contributions are provided in directory "contrib".
+
+A Java implementation of zlib is available in the Java Development Kit
+http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html
+See the zlib home page http://www.zlib.org for details.
+
+A Perl interface to zlib written by Paul Marquess is in the
+CPAN (Comprehensive Perl Archive Network) sites
+http://www.cpan.org/modules/by-module/Compress/
+
+A Python interface to zlib written by A.M. Kuchling is
+available in Python 1.5 and later versions, see
+http://www.python.org/doc/lib/module-zlib.html
+
+A zlib binding for TCL written by Andreas Kupries is
+availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html
+
+An experimental package to read and write files in .zip format, written on top
+of zlib by Gilles Vollant , is available in the
+contrib/minizip directory of zlib.
+
+
+Notes for some targets:
+
+- For Windows DLL versions, please see win32/DLL_FAQ.txt
+
+- For 64-bit Irix, deflate.c must be compiled without any optimization. With
+ -O, one libpng test fails. The test works in 32 bit mode (with the -n32
+ compiler flag). The compiler bug has been reported to SGI.
+
+- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
+ when compiled with cc.
+
+- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
+ necessary to get gzprintf working correctly. This is done by configure.
+
+- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
+ other compilers. Use "make test" to check your compiler.
+
+- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
+
+- For PalmOs, see http://palmzlib.sourceforge.net/
+
+- When building a shared, i.e. dynamic library on Mac OS X, the library must be
+ installed before testing (do "make install" before "make test"), since the
+ library location is specified in the library.
+
+
+Acknowledgments:
+
+ The deflate format used by zlib was defined by Phil Katz. The deflate
+ and zlib specifications were written by L. Peter Deutsch. Thanks to all the
+ people who reported problems and suggested various improvements in zlib;
+ they are too numerous to cite here.
+
+Copyright notice:
+
+ (C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+If you use the zlib library in a product, we would appreciate *not*
+receiving lengthy legal documents to sign. The sources are provided
+for free but without warranty of any kind. The library has been
+entirely written by Jean-loup Gailly and Mark Adler; it does not
+include third-party code.
+
+If you redistribute modified sources, we would appreciate that you include
+in the file ChangeLog history information documenting your changes. Please
+read the FAQ for more information on the distribution of modified source
+versions.
diff --git a/packaging/distribution/src/main/resources/licenses/license.txt b/packaging/distribution/src/main/resources/licenses/license.txt
new file mode 100644
index 00000000000..cca7fc278f5
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/license.txt
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ 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 that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/packaging/distribution/src/main/resources/licenses/notice.txt b/packaging/distribution/src/main/resources/licenses/notice.txt
new file mode 100644
index 00000000000..b066847e1d3
--- /dev/null
+++ b/packaging/distribution/src/main/resources/licenses/notice.txt
@@ -0,0 +1,311 @@
+Copyright (c) 2005-2016 Alfresco Software, Ltd. and others.
+All rights reserved. This program and the accompanying materials are made available under the terms of the Alfresco
+agreement located at www.alfresco.com/legal/agreements/ or other commercial agreement between Alfresco Software, Ltd.
+("Alfresco") and the user of this program.
+Portions of this product distribution require certain copyright or other notices to
+be included with the product distribution. These notices may also appear in individual
+source files.
+
+Below is the list of licenses and modules used under corresponding licenses,
+
+=== Apache 2.0 License ====
+acegi http://sourceforge.net/projects/acegisecurity/
+ActiveMQ http://activemq.apache.org/
+Activiti: If shipped or included with the commercial version of Alfresco software, the Activiti component is licensed under the terms of the associated Alfresco Master Services Agreement; If shipped or included with the open-source Community version of Alfresco software, then it will be governed by the Apache open source license specified at http://activiti.org/
+Activiti Webapp Explorer: If shipped or included with the commercial version of Alfresco software, the Activiti component is licensed under the terms of the associated Alfresco Master Services Agreement; If shipped or included with the open-source Community version of Alfresco software, then it will be governed by the Apache open source license specified at http://activiti.org/
+Alfresco OpenCMIS Extension http://code.google.com/a/apache-extras.org/p/alfresco-opencmis-extension/
+Apache Mime http://james.apache.org/mime4j/index.html
+Apache Avalon http://excalibur.apache.org/
+Axiom http://ws.apache.org/axiom/
+bcel http://jakarta.apache.org/bcel/
+Boilerpipe http://code.google.com/p/boilerpipe/
+Bean Scripting Framework http://jakarta.apache.org/bsf/
+Apache Camel http://camel.apache.org/
+CGLib http://cglib.sourceforge.net/
+Apache Chemistry http://chemistry.apache.org/
+commons-beanutils http://jakarta.apache.org/commons/
+commons-codec http://jakarta.apache.org/commons/
+commons-collections http://jakarta.apache.org/commons/
+commons-compress http://jakarta.apache.org/commons/
+commons-csv http://jakarta.apache.org/commons/
+commons-dbcp http://jakarta.apache.org/commons/
+commons-digester http://jakarta.apache.org/commons/
+commons-discovery http://jakarta.apache.org/commons/
+commons-el http://jakarta.apache.org/commons/
+commons-email http://jakarta.apache.org/commons/
+commons-fileupload http://jakarta.apache.org/commons/
+commons-httpclient http://jakarta.apache.org/commons/
+commons-io http://jakarta.apache.org/commons/
+commons-jxpath http://jakarta.apache.org/commons/
+commons-lang http://jakarta.apache.org/commons/
+commons-lang3 http://jakarta.apache.org/commons/
+commons-logging http://jakarta.apache.org/commons/
+commons-net http://jakarta.apache.org/commons/
+commons-pool http://jakarta.apache.org/commons/
+commons-validator http://jakarta.apache.org/commons/
+ConcurrentLinkedHashMap http://code.google.com/p/concurrentlinkedhashmap/
+Fast Infoset Project http://fi.java.net/
+PDFBox http://pdfbox.apache.org/
+Google Data Java Client Library http://code.google.com/p/gdata-java-client/
+Geronimo Activation http://geronimo.apache.org/
+Geronimo Annotation http://geronimo.apache.org/
+Geronimo J2EE Mgmt http://geronimo.apache.org/
+Geronimo JAX-WS http://geronimo.apache.org/
+Geronimo JMS http://geronimo.apache.org/
+Geronimo JTA http://geronimo.apache.org/
+Geronimo Stax API http://geronimo.apache.org/
+Geronimo WS-Metadata http://geronimo.apache.org/
+Greenmail http://www.icegreen.com/greenmail/
+Groovy http://groovy.codehaus.org/
+Guava https://github.com/google/guava
+guessencoding http://docs.codehaus.org/display/GUESSENC/
+Hawtbuf https://github.com/chirino/hawtbuf
+Hazelcast http://www.hazelcast.com/
+HttpClient http://hc.apache.org/httpcomponents-client-ga/
+imgscalr http://www.thebuzzmedia.com/software/imgscalr-java-image-scaling-library/
+ISO Parser http://code.google.com/p/mp4parser/
+Jackson http://jackson.codehaus.org/
+Jackson2 https://github.com/FasterXML/jackson
+Jasypt http://www.jasypt.org/
+java-libpst https://github.com/rjohnsondev/java-libpst
+javax.inject http://code.google.com/p/atinject
+joda-time http://joda-time.sourceforge.net/
+JSlidesShare http://code.google.com/p/jslideshare/
+JSON.simple http://code.google.com/p/json-simple/
+jsr107cache http://jsr107cache.sourceforge.net/
+JSR 305 http://findbugs.sourceforge.net/
+jug-asl http://jug.safehaus.org/
+LESS for Java http://www.asual.com/lesscss/
+LiveTribe http://livetribe.codehaus.org/
+log4j http://logging.apache.org/log4j
+log4javascript http://log4javascript.org/
+Lucene http://lucene.apache.org
+Maven http://maven.apache.org/
+Metadata Extractor http://code.google.com/p/metadata-extractor/
+mybatis http://www.mybatis.org/
+MyFaces http://myfaces.apache.org/
+Neethi http://ws.apache.org/commons/neethi/
+jakarta-oro http://jakarta.apache.org/oro/
+POI http://poi.apache.org/
+Qpid Proton http://qpid.apache.org/proton/
+quartz http://quartz-scheduler.org/
+regexp http://projects.apache.org/projects/regexp.html
+resolver http://xml.apache.org/commons/
+Rome http://rome.java.net/
+Solr http://lucene.apache.org/solr/
+Solr4 http://lucene.apache.org/solr/
+Spring Framework http://projects.spring.io/spring-framework/
+Spring Security http://projects.spring.io/spring-security/
+SpringModules http://springmodules.java.net/
+StAX http://stax.codehaus.org/
+STAX2 http://woodstox.codehaus.org/
+SubEtha SMTP http://code.google.com/p/subethasmtp/
+TagSoup http://home.ccil.org/~cowan/XML/tagsoup/
+Tika http://tika.apache.org/
+Vaadin http://vaadin.com/
+VorbisJava http://github.com/Gagravarr/VorbisJava
+WoodStox http://woodstox.codehaus.org/
+WS Common Utilities http://ws.apache.org/commons/util/
+wss4j http://ws.apache.org/wss4j/
+xalan http://xalan.apache.org/
+xbean http://geronimo.apache.org/xbean/
+xercesImpl http://xerces.apache.org/xerces2-j
+XML Commons External Components http://xml.apache.org/commons/components/external/
+XMLBeans http://xmlbeans.apache.org/
+XML Schema http://ws.apache.org/commons/XmlSchema/
+Santuario http://santuario.apache.org/
+OpenSSL http://www.openssl.org/
+Tomcat http://tomcat.apache.org
+
+
+=== Apache variant License ==
+JDOM http://www.jdom.org/
+xpp3 http://www.extreme.indiana.edu/xgws/xsoap/xpp/
+
+
+=== BSD-like License ===
+Antlr http://www.antlr.org/
+ASM http://asm.ow2.org/
+Bubbling Library https://github.com/caridy/bubbling-library
+Dojo http://www.dojotoolkit.org/
+dom4j http://dom4j.sourceforge.net/
+FreeMarker http://freemarker.sourceforge.net/
+Hamcrest http://hamcrest.org/
+jaxen http://jaxen.codehaus.org/
+JGraphX https://github.com/jgraph/jgraphx
+JiBX http://jibx.sourceforge.net/
+STAX Utils http://java.net/projects/stax-utils
+UrlRewriteFilter http://tuckey.org/urlrewrite/
+XMP Library http://www.adobe.com/devnet/xmp.html
+XStream http://xstream.codehaus.org/
+yuicompressor http://developer.yahoo.com/yui/compressor/
+YUI http://yuilibrary.com/
+LibTIFF http://www.libtiff.org/
+LibPNG http://www.libpng.org/
+libJPEG http://libjpeg.sourceforge.net/
+libgif http://giflib.sourceforge.net/
+libfreetype http://www.freetype.org/
+PostgreSQL http://www.postgresql.org/
+PostgreSQL JDBC Driver http://www.postgresql.org/
+
+
+=== CDDL 1.0 ===
+activation http://www.oracle.com/technetwork/java/javase/jaf-135115.html
+javax.mail http://glassfish.java.net/javaee5/mail/
+jaxrpc http://java.net/projects/jax-rpc/
+jhighlight https://www.openhub.net/p/jhighlight
+mail http://glassfish.java.net/javaee5/mail/
+MIME pull http://mimepull.java.net/
+SAAJ http://java.net/projects/saaj
+XML Stream Buffer http://xmlstreambuffer.java.net/
+
+
+=== CDDL 1.1 ===
+JaxB http://jaxb.java.net/
+JAXWS http://jax-ws.java.net/
+StAX Extended API http://stax-ex.java.net/
+
+
+=== Common Annotation license ===
+JSR 250 http://jcp.org/en/jsr/detail?id=250
+
+
+=== CPL 1.0 License ===
+htmlparser http://htmlparser.sourceforge.net/
+wsdl4j http://sourceforge.net/projects/wsdl4j
+
+
+=== Creative Commons Attribute License ===
+Lightbox JS http://lokeshdhakar.com/projects/lightbox/
+
+
+=== Eclipse Public License 1.0 ===
+AspectJ http://eclipse.org/aspectj/
+Bliki http://code.google.com/p/gwtwiki/
+JUnit http://junit.org/
+TrueLicense http://truelicense.java.net/
+truezip http://truezip.java.net/
+
+
+=== ICU License ===
+icu4j http://icu-project.org/
+
+
+=== Imagemagick ===
+Imagemagick http://www.imagemagick.org/script/license.php
+
+
+=== JSON license ===
+JSon http://www.json.org/java/
+
+
+=== JTA license ===
+jta http://www.oracle.com/technetwork/java/javaee/jta/
+
+
+=== LGPL 2.0 ===
+javaGeom http://geom-java.sourceforge.net/
+libwmf http://wvware.sourceforge.net/libwmf.html
+
+
+=== LGPL 2.1 ===
+Hibernate http://www.hibernate.org/
+jid3lib http://javamusictag.sourceforge.net/
+JMagick http://sourceforge.net/projects/jmagick/
+JODConverter http://jodconverter.sourceforge.net/
+PDF Renderer http://java.net/projects/pdf-renderer
+TinyMCE http://www.tinymce.com/
+
+
+=== LGPL 3.0 ===
+Gytheio https://github.com/Alfresco/gytheio
+Jut.jar http://www.openoffice.org/licenses/lgpl_license.html
+OpenOffice SDK http://www.openoffice.org/licenses/lgpl_license.html
+
+
+=== MIT License ===
+Bouncy Castle http://www.bouncycastle.org/
+CodeMirror http://codemirror.net/
+DateFormatJS http://blog.stevenlevithan.com/archives/date-time-format
+Enum.js https://github.com/adrai/enum
+extMouseWheel http://hasseg.org/blog/post/138/
+FullCalendar http://arshaw.com/fullcalendar/
+JQuery http://jquery.com/
+jQuery UI https://jqueryui.com/
+Jutf7 http://jutf7.sourceforge.net/
+SLF4J http://www.slf4j.org/
+
+
+=== Mozilla Public License 1.1 ===
+juniversalchardet http://code.google.com/p/juniversalchardet/
+
+
+=== Mozilla Public License 2.0 ===
+CCC2 http://www.webdetails.pt/ctools/ccc/
+rhino-js http://www.mozilla.org/rhino/
+LibreOffice http://www.libreoffice.org/
+
+
+=== Oracle Binary Code License ===
+Java Runtime Env + redistributable components http://java.oracle.com/
+
+
+=== Public Domain License ===
+AOP Alliance http://aopalliance.sourceforge.net/
+XZ http://tukaani.org/xz/
+
+
+=== Sun Public License ===
+BSH http://www.beanshell.org/
+
+
+=== Unidata ===
+NetCDF http://www.unidata.ucar.edu/software/netcdf/
+
+
+=== Web Services Metadata license ===
+JSR 181 http://jcp.org/en/jsr/detail?id=181
+
+
+=== Zlib ===
+libz http://zlib.net/
+
+
+
+
+Alfresco has modified the source code of the following third party libraries. Below is the list of modified modules and corresponding licenses.
+The svn diff files with the details of the changes can be found in the following location: root/projects/3rd-party/src.
+
+=== Apache 2.0 License ====
+acegi http://sourceforge.net/projects/acegisecurity/
+commons-dbcp http://jakarta.apache.org/commons/
+PDFBox http://pdfbox.apache.org/
+Greenmail http://www.icegreen.com/greenmail/
+POI http://poi.apache.org/
+quartz http://quartz-scheduler.org/
+Solr4 http://lucene.apache.org/solr/
+Spring Social http://projects.spring.io/spring-social/
+Tika http://tika.apache.org/
+xercesImpl http://xerces.apache.org/xerces2-j
+
+=== BSD-like License ===
+FreeMarker http://freemarker.sourceforge.net/
+Pdfium https://pdfium.googlesource.com/pdfium/
+
+=== Eclipse Public License 1.0 ===
+TrueLicense http://truelicense.java.net/
+
+=== LGPL 2.1 ===
+Hibernate http://www.hibernate.org/
+JODConverter http://jodconverter.sourceforge.net/
+PDF Renderer http://java.net/projects/pdf-renderer
+TinyMCE http://www.tinymce.com/
+
+=== LGPL 3.0 ===
+Jut.jar http://www.openoffice.org/licenses/lgpl_license.html
+
+=== Mozilla Public License 2.0 ===
+rhino-js http://www.mozilla.org/rhino/
+
+
+
diff --git a/packaging/distribution/src/main/resources/web-server/conf/Catalina/localhost/alfresco.xml b/packaging/distribution/src/main/resources/web-server/conf/Catalina/localhost/alfresco.xml
new file mode 100644
index 00000000000..ac2960c1485
--- /dev/null
+++ b/packaging/distribution/src/main/resources/web-server/conf/Catalina/localhost/alfresco.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/packaging/docker-alfresco/.maven-dockerignore b/packaging/docker-alfresco/.maven-dockerignore
new file mode 100644
index 00000000000..112bd18249e
--- /dev/null
+++ b/packaging/docker-alfresco/.maven-dockerignore
@@ -0,0 +1 @@
+target/docker/
\ No newline at end of file
diff --git a/packaging/docker-alfresco/Dockerfile b/packaging/docker-alfresco/Dockerfile
new file mode 100644
index 00000000000..691b4356c7e
--- /dev/null
+++ b/packaging/docker-alfresco/Dockerfile
@@ -0,0 +1,97 @@
+# Fetch image based on Tomcat 8.5.43 and Java 11
+# More infos about this image: https://github.com/Alfresco/alfresco-docker-base-tomcat
+FROM alfresco/alfresco-base-tomcat:8.5.43-java-11-openjdk-centos-7
+
+# Set default user information
+ARG GROUPNAME=Alfresco
+ARG GROUPID=1000
+ARG IMAGEUSERNAME=alfresco
+ARG USERID=33000
+
+# Set default environment args
+ARG TOMCAT_DIR=/usr/local/tomcat
+
+
+# Create prerequisite to store tools and properties
+RUN mkdir -p ${TOMCAT_DIR}/shared/classes/alfresco/extension && \
+ mkdir ${TOMCAT_DIR}/alfresco-mmt
+RUN touch ${TOMCAT_DIR}/shared/classes/alfresco-global.properties
+
+# You need to run `mvn clean install` in the root of this project to update the following dependencies
+# Copy the WAR files to the appropriate location for your application server
+# Copy the JDBC drivers for the database you are using to the lib/ directory.
+# Copy the alfresco-mmt.jar
+COPY target/war ${TOMCAT_DIR}/webapps
+COPY target/connector/* ${TOMCAT_DIR}/lib/
+COPY target/alfresco-mmt/* ${TOMCAT_DIR}/alfresco-mmt/
+
+# Copy Licenses to the root of the Docker image
+RUN mkdir /licenses
+COPY target/licenses/ /licenses/
+
+# Change the value of the shared.loader= property to the following:
+# shared.loader=${catalina.base}/shared/classes
+RUN sed -i "s/shared.loader=/shared.loader=\${catalina.base}\/shared\/classes/" ${TOMCAT_DIR}/conf/catalina.properties
+
+RUN mkdir -p ${TOMCAT_DIR}/amps \
+ ${TOMCAT_DIR}/shared/classes/alfresco/extension/mimetypes \
+ ${TOMCAT_DIR}/shared/classes/alfresco/extension/transform/renditions \
+ ${TOMCAT_DIR}/shared/classes/alfresco/extension/transform/pipelines
+
+#RUN echo -e '\n\
+#log4j.logger.org.alfresco.repo.content.transform.TransformerDebug=debug\n\
+#' >> ${TOMCAT_DIR}/shared/classes/alfresco/extension/custom-log4j.propertiesRUN mkdir -p ${TOMCAT_DIR}/amps
+
+# Copy the amps from build context to the appropriate location for your application server
+COPY target/amps ${TOMCAT_DIR}/amps
+
+# Install amps on alfresco.war
+RUN java -jar ${TOMCAT_DIR}/alfresco-mmt/alfresco-mmt*.jar install \
+ ${TOMCAT_DIR}/amps ${TOMCAT_DIR}/webapps/alfresco -directory -nobackup -force
+
+# Docker CMD from parent image starts the server
+
+# Make webapps folder read-only.
+RUN chmod -R =r ${TOMCAT_DIR}/webapps && \
+# Add catalina.policy to ROOT.war and alfresco.war
+# Grant all security permissions to alfresco webapp because of numerous permissions required in order to work properly.
+# Grant only deployXmlPermission to ROOT webapp.
+ sed -i -e "\$a\grant\ codeBase\ \"file:\$\{catalina.base\}\/webapps\/alfresco\/-\" \{\n\ permission\ java.security.AllPermission\;\n\};\ngrant\ codeBase\ \"file:\$\{catalina.base\}\/webapps\/ROOT\/-\" \{\n\ permission org.apache.catalina.security.DeployXmlPermission \"ROOT\";\n\};" ${TOMCAT_DIR}/conf/catalina.policy
+
+# fontconfig is required by Activiti worflow diagram generator
+# installing pinned dependencies as well
+RUN yum install -y fontconfig-2.13.0-4.3.el7 \
+ dejavu-fonts-common-2.33-6.el7 \
+ fontpackages-filesystem-1.44-8.el7 \
+ freetype-2.8-12.el7 \
+ libpng-1.5.13-7.el7_2 \
+ dejavu-sans-fonts-2.33-6.el7 && \
+ yum clean all
+
+# The standard configuration is to have all Tomcat files owned by root with group GROUPNAME and whilst owner has read/write privileges,
+# group only has restricted permissions and world has no permissions.
+RUN mkdir -p ${TOMCAT_DIR}/conf/Catalina/localhost && \
+ mkdir -p ${TOMCAT_DIR}/alf_data && \
+ groupadd -g ${GROUPID} ${GROUPNAME} && \
+ useradd -u ${USERID} -G ${GROUPNAME} ${IMAGEUSERNAME} && \
+ chgrp -R ${GROUPNAME} ${TOMCAT_DIR} && \
+ chmod g+w ${TOMCAT_DIR}/logs && \
+ chmod g+rx ${TOMCAT_DIR}/conf && \
+ chmod -R g+r ${TOMCAT_DIR}/conf && \
+ find ${TOMCAT_DIR}/webapps -type d -exec chmod 0750 {} \; && \
+ find ${TOMCAT_DIR}/webapps -type f -exec chmod 0640 {} \; && \
+ chmod -R g+r ${TOMCAT_DIR}/webapps && \
+ chmod g+r ${TOMCAT_DIR}/conf/Catalina && \
+ chmod g+rwx ${TOMCAT_DIR}/alf_data && \
+ chmod g+rwx ${TOMCAT_DIR}/logs && \
+ chmod g+rwx ${TOMCAT_DIR}/temp && \
+ chmod g+rwx ${TOMCAT_DIR}/work && \
+
+ sed -i -e "s_log4j.appender.File.File\=alfresco.log_log4j.appender.File.File\=${TOMCAT_DIR}/logs\/alfresco.log_" \
+ ${TOMCAT_DIR}/webapps/alfresco/WEB-INF/classes/log4j.properties
+
+# To remote debug into this image add: EXPOSE 8000
+# Changes are also required to the docker-compose/docker-compose.yml file.
+# EXPOSE 8000
+
+USER ${IMAGEUSERNAME}
\ No newline at end of file
diff --git a/packaging/docker-alfresco/pom.xml b/packaging/docker-alfresco/pom.xml
new file mode 100644
index 00000000000..3deda74e00e
--- /dev/null
+++ b/packaging/docker-alfresco/pom.xml
@@ -0,0 +1,374 @@
+
+ 4.0.0
+ content-services-community-docker-alfresco
+ ACS Community Docker Image Builder for Alfresco Community
+ pom
+
+
+ org.alfresco
+ acs-community-packaging
+ 6.2.2-SNAPSHOT
+ ../pom.xml
+
+
+
+ alfresco/alfresco-content-repository-community
+ quay.io
+
+
+
+
+ org.alfresco
+ content-services-community
+ ${project.version}
+ war
+
+
+ org.alfresco
+ api-explorer
+ ${dependency.alfresco-api-explorer.version}
+ war
+
+
+ org.alfresco
+ alfresco-server-root
+ ${dependency.alfresco-server-root.version}
+ war
+
+
+ org.postgresql
+ postgresql
+ ${dependency.postgresql.version}
+
+
+ org.alfresco
+ alfresco-mmt
+ ${dependency.alfresco-mmt.version}
+
+
+ org.alfresco
+ alfresco-share-services
+ ${alfresco.alfresco-share-services.version}
+ amp
+
+
+ org.alfresco.aos-module
+ alfresco-aos-module
+ ${alfresco.aos-module.version}
+ amp
+
+
+ org.alfresco.aos-module
+ alfresco-aos-repo-binding
+
+
+
+
+ org.alfresco.aos-module
+ alfresco-vti-bin
+ ${alfresco.aos-module.version}
+ war
+
+
+ org.alfresco.integrations
+ alfresco-googledrive-repo-community
+ ${alfresco.googledrive.version}
+ amp
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+ 3.1.0
+
+
+ copy-licenses
+ process-resources
+
+ copy-resources
+
+
+
+
+
+ ../distribution/src/main/resources/licenses
+ false
+
+
+ ${project.build.directory}/licenses
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+ 3.1.2
+
+
+ unpack-war-files
+ process-resources
+
+ unpack
+
+
+
+
+ org.alfresco
+ content-services-community
+ ${project.version}
+ war
+ false
+ ${project.build.directory}/war/alfresco
+
+
+ org.alfresco
+ api-explorer
+ ${dependency.alfresco-api-explorer.version}
+ war
+ ${project.build.directory}/war/api-explorer
+
+
+ org.alfresco
+ alfresco-server-root
+ ${dependency.alfresco-server-root.version}
+ war
+ ${project.build.directory}/war/ROOT
+
+
+ org.alfresco.aos-module
+ alfresco-vti-bin
+ ${alfresco.aos-module.version}
+ war
+ ${project.build.directory}/war/_vti_bin
+
+
+
+
+
+ copy-jdbc-connectors
+ process-resources
+
+ copy
+
+
+
+
+ org.postgresql
+ postgresql
+ ${dependency.postgresql.version}
+ jar
+ false
+ ${project.build.directory}/connector
+
+
+ org.alfresco
+ alfresco-mmt
+ ${dependency.alfresco-mmt.version}
+ jar
+ false
+ ${project.build.directory}/alfresco-mmt
+
+
+
+
+
+
+ copy-amps
+ process-resources
+
+ copy
+
+
+
+
+ org.alfresco
+ alfresco-share-services
+ ${alfresco.alfresco-share-services.version}
+ amp
+ false
+ ${project.build.directory}/amps
+
+
+ org.alfresco.aos-module
+ alfresco-aos-module
+ ${alfresco.aos-module.version}
+ amp
+ false
+ ${project.build.directory}/amps
+
+
+ org.alfresco.integrations
+ alfresco-googledrive-repo-community
+ ${alfresco.googledrive.version}
+ amp
+ false
+ ${project.build.directory}/amps
+
+
+
+
+
+
+
+
+ io.fabric8
+ fabric8-maven-plugin
+ ${dependency.fabric8.version}
+
+
+
+ ${image.name}
+
+ ${project.basedir}/
+
+
+
+
+
+
+
+
+
+
+ communityDocker
+
+
+
+ io.fabric8
+ fabric8-maven-plugin
+ ${dependency.fabric8.version}
+
+
+ build-image
+ install
+
+ build
+
+
+
+
+
+
+
+
+
+ internal
+
+
+
+ io.fabric8
+ fabric8-maven-plugin
+ ${dependency.fabric8.version}
+
+
+
+ ${image.name}:${image.tag}
+ ${image.registry}
+
+ ${project.basedir}/
+
+
+
+
+
+
+ build-push-image
+ install
+
+ build
+ push
+
+
+
+
+
+
+
+
+
+ master
+
+
+
+ io.fabric8
+ fabric8-maven-plugin
+ ${dependency.fabric8.version}
+
+
+
+ ${image.name}
+ ${image.registry}
+
+ ${project.basedir}/
+
+
+
+ ${image.name}
+
+ ${project.basedir}/
+
+
+
+
+
+
+ build-push-image
+ install
+
+ build
+ push
+
+
+
+
+
+
+
+
+
+ release
+
+
+
+ io.fabric8
+ fabric8-maven-plugin
+ ${dependency.fabric8.version}
+
+
+
+ quay.io
+ ${image.name}:${project.version}
+ ${image.registry}
+
+ ${project.basedir}/
+
+
+
+ dockerhub
+ ${image.name}:${project.version}
+
+ ${project.basedir}/
+
+
+
+
+
+
+ build-push-image
+ deploy
+
+ build
+ push
+
+
+
+
+
+
+
+
+
diff --git a/packaging/l10n.properties b/packaging/l10n.properties
new file mode 100644
index 00000000000..0f319072f58
--- /dev/null
+++ b/packaging/l10n.properties
@@ -0,0 +1,8 @@
+# Branch specific configuration file for localisation scripts
+# here is no localization needed in the acs-community-packaging project for now
+
+MESSAGE_SEARCH_PATH=""
+
+
+EXCLUDED_FILES=""
+
diff --git a/packaging/pom.xml b/packaging/pom.xml
new file mode 100644
index 00000000000..7f92efd6d93
--- /dev/null
+++ b/packaging/pom.xml
@@ -0,0 +1,559 @@
+
+ 4.0.0
+ acs-community-packaging
+ Alfresco Content Services Community Packaging
+ 6.2.2-SNAPSHOT
+ pom
+
+
+ org.alfresco
+ alfresco-super-pom
+ 12
+
+
+
+ scm:git:https://github.com/Alfresco/acs-community-packaging.git
+ scm:git:https://github.com/Alfresco/acs-community-packaging.git
+ https://github.com/Alfresco/acs-community-packaging
+ HEAD
+
+
+
+
+ alfresco-internal
+ https://artifacts.alfresco.com/nexus/content/repositories/releases
+
+
+ alfresco-internal-snapshots
+ https://artifacts.alfresco.com/nexus/content/repositories/snapshots
+
+
+
+
+
+ Community
+ latest
+
+ 7.147
+ 7.200
+ 8.50.18
+ 7.34
+
+ 1.0.12
+
+ 7.16
+ 6.0
+ 1.1
+ 2.3
+ 7.1
+ 6.0.1
+ 6.2.1.1
+ 1.2.15
+ 0.2
+
+ 5.1.15.RELEASE
+ 4.4.0
+ 2.10.2
+ 2.10.1
+ 3.3.6
+
+
+ 6.2.2
+ 6.2.2
+
+
+ 3.2.0
+
+
+ 1.3.1
+
+ ${project.version}
+ alfresco-community
+ ${alfresco.package.name}-distribution
+
+ 42.2.14
+
+ 3.0.20
+ 3.3.0
+ 1.1.4
+ 1.37
+ 1.13
+ 1.8
+ 1.6
+ 1.5
+ 2.3
+
+ 11
+
+
+
+
+ community
+
+ war
+
+
+
+ communityDocker
+
+ war
+ docker-alfresco
+
+
+
+ fullBuild
+
+ true
+
+
+ war
+ distribution
+ public-javadoc
+ docker-alfresco
+
+
+
+ all-tas-tests
+
+ tests
+
+
+
+
+
+
+
+ org.alfresco
+ alfresco-core
+ ${dependency.alfresco-core.version}
+
+
+ org.alfresco
+ alfresco-core
+ ${dependency.alfresco-core.version}
+ tests
+
+
+ org.alfresco
+ alfresco-data-model
+ ${dependency.alfresco-data-model.version}
+
+
+ org.alfresco
+ alfresco-jlan-embed
+ ${dependency.alfresco-jlan.version}
+
+
+ org.alfresco
+ alfresco-remote-api
+ ${dependency.alfresco-remote-api.version}
+
+
+ org.alfresco
+ alfresco-remote-api
+ ${dependency.alfresco-remote-api.version}
+ tests
+
+
+ org.alfresco
+ alfresco-repository
+ ${dependency.alfresco-repository.version}
+
+
+ org.alfresco
+ alfresco-repository
+ ${dependency.alfresco-repository.version}
+ tests
+
+
+ org.alfresco
+ alfresco-trashcan-cleaner
+ ${dependency.alfresco-trashcan-cleaner.version}
+
+
+ org.alfresco
+ alfresco-heartbeat-data-sender
+ ${dependency.alfresco-hb-data-sender.version}
+
+
+ xalan
+ xalan
+ 2.7.2-alfresco
+
+
+ org.alfresco.services
+ alfresco-messaging-repo
+ ${dependency.alfresco-messaging-repo.version}
+
+
+ org.alfresco
+ alfresco-mmt
+ ${dependency.alfresco-mmt.version}
+
+
+ org.alfresco
+ alfresco-pdf-renderer
+ ${dependency.alfresco-pdf-renderer.version}
+ linux
+ tgz
+
+
+ org.alfresco
+ alfresco-pdf-renderer
+ ${dependency.alfresco-pdf-renderer.version}
+ win64
+ tgz
+
+
+ org.alfresco
+ alfresco-pdf-renderer
+ ${dependency.alfresco-pdf-renderer.version}
+
+
+ org.alfresco
+ alfresco-server-root
+ ${dependency.alfresco-server-root.version}
+ war
+
+
+ org.alfresco.surf
+ spring-surf-core-configservice
+ ${dependency.alfresco-spring-webscripts.version}
+
+
+ org.alfresco.surf
+ spring-webscripts
+ ${dependency.alfresco-spring-webscripts.version}
+
+
+ org.alfresco.surf
+ spring-webscripts-api
+ ${dependency.alfresco-spring-webscripts.version}
+
+
+ org.quartz-scheduler
+ quartz
+ 2.3.2
+
+
+
+
+ com.mchange
+ *
+
+
+
+
+ org.apache.httpcomponents
+ httpcore
+ 4.4.13
+
+
+ joda-time
+ joda-time
+ 2.10.5
+
+
+ commons-httpclient
+ commons-httpclient
+ 3.1-HTTPCLIENT-1265
+
+
+ commons-logging
+ commons-logging
+ 1.2
+
+
+ commons-beanutils
+ commons-beanutils
+ 1.9.4
+
+
+ commons-codec
+ commons-codec
+ 1.14
+
+
+ commons-collections
+ commons-collections
+ 3.2.2
+
+
+
+ commons-digester
+ commons-digester
+ 2.1
+
+
+ commons-lang
+ commons-lang
+ 2.6
+
+
+ commons-fileupload
+ commons-fileupload
+ 1.4
+
+
+ com.sun.xml.bind
+ jaxb-impl
+ 2.3.2
+
+
+ org.apache.httpcomponents
+ httpclient
+ 4.5.12
+
+
+ org.apache.httpcomponents
+ httpclient-cache
+ 4.5.12
+
+
+ org.apache.xmlbeans
+ xmlbeans
+ 3.1.0
+
+
+ org.springframework
+ spring-aop
+ ${dependency.spring.version}
+
+
+ org.springframework
+ spring-beans
+ ${dependency.spring.version}
+
+
+ org.springframework
+ spring-context
+ ${dependency.spring.version}
+
+
+ org.springframework
+ spring-context-support
+ ${dependency.spring.version}
+
+
+ org.springframework
+ spring-core
+ ${dependency.spring.version}
+
+
+
+
+ org.springframework
+ spring-jcl
+
+
+
+
+ org.springframework
+ spring-expression
+ ${dependency.spring.version}
+
+
+ org.springframework
+ spring-jdbc
+ ${dependency.spring.version}
+
+
+ org.springframework
+ spring-jms
+ ${dependency.spring.version}
+
+
+ org.springframework
+ spring-orm
+ ${dependency.spring.version}
+
+
+
+
+ org.springframework
+ spring-jcl
+
+
+
+
+ org.springframework
+ spring-tx
+ ${dependency.spring.version}
+
+
+ org.springframework
+ spring-web
+ ${dependency.spring.version}
+
+
+ org.springframework
+ spring-webmvc
+ ${dependency.spring.version}
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+ ${dependency.jackson.version}
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${dependency.jackson-databind.version}
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+ ${dependency.jackson.version}
+
+
+
+ com.fasterxml.jackson.module
+ jackson-module-jaxb-annotations
+ ${dependency.jackson.version}
+
+
+ org.codehaus.woodstox
+ woodstox-core-asl
+ 4.4.1
+
+
+
+ org.apache.cxf
+ cxf-rt-frontend-jaxws
+ ${dependency.cxf.version}
+
+
+ org.apache.cxf
+ cxf-rt-frontend-jaxrs
+ ${dependency.cxf.version}
+
+
+ org.apache.cxf
+ cxf-rt-rs-client
+ ${dependency.cxf.version}
+
+
+ org.apache.cxf
+ cxf-rt-transports-http
+ ${dependency.cxf.version}
+
+
+ org.apache.cxf
+ cxf-rt-ws-policy
+ ${dependency.cxf.version}
+
+
+
+ org.apache.commons
+ commons-email
+ 1.5
+
+
+
+ junit
+ junit
+ 4.13
+ test
+
+
+ org.alfresco
+ alfresco-log-sanitizer
+ ${dependency.alfresco-log-sanitizer.version}
+
+
+ org.alfresco.aos-module
+ alfresco-aos-module
+ ${alfresco.aos-module.version}
+ amp
+
+
+ org.alfresco.aos-module
+ alfresco-aos-module-distributionzip
+ ${alfresco.aos-module.version}
+ zip
+
+
+ org.alfresco.aos-module
+ alfresco-vti-bin
+ ${alfresco.aos-module.version}
+ war
+
+
+ org.alfresco
+ alfresco-content-services-share-distribution
+ ${alfresco.share.version}
+ zip
+
+
+ org.alfresco
+ alfresco-share-services
+ ${alfresco.alfresco-share-services.version}
+ amp
+
+
+ org.alfresco
+ share
+ ${alfresco.share.version}
+ war
+
+
+ org.alfresco
+ alfresco-wcmqs-distribution
+ ${alfresco.share.version}
+ zip
+
+
+ org.alfresco
+ alfresco-wcmqs-web
+ ${alfresco.share.version}
+ classes
+
+
+ org.alfresco
+ alfresco-wcmqs-client-api
+ ${alfresco.share.version}
+
+
+ org.alfresco.integrations
+ alfresco-googledrive-repo-community
+ ${alfresco.googledrive.version}
+ amp
+
+
+ org.alfresco.integrations
+ alfresco-googledrive-share-community
+ ${alfresco.googledrive.version}
+ amp
+
+
+
+ org.bouncycastle
+ bcprov-jdk15on
+ 1.65
+
+
+ org.bouncycastle
+ bcmail-jdk15on
+ 1.65
+
+
+
+ com.github.junrar
+ junrar
+ 4.0.0
+
+
+
+ org.jsoup
+ jsoup
+ 1.13.1
+
+
+
+ com.drewnoakes
+ metadata-extractor
+ 2.13.0
+
+
+
+
diff --git a/packaging/public-javadoc/pom.xml b/packaging/public-javadoc/pom.xml
new file mode 100644
index 00000000000..32aadaad868
--- /dev/null
+++ b/packaging/public-javadoc/pom.xml
@@ -0,0 +1,100 @@
+
+ 4.0.0
+ alfresco-public-javadoc
+ Alfresco Content Services Public API Javadoc
+
+ org.alfresco
+ acs-community-packaging
+ 6.2.2-SNAPSHOT
+ ../pom.xml
+
+ pom
+
+
+ 1.6.1
+
+
+
+
+
+ org.alfresco
+ alfresco-remote-api
+
+
+ org.alfresco
+ share
+ classes
+ ${alfresco.share.version}
+
+
+
+
+ com.docflex
+ docflex-alfresco-license
+ 1.0
+ license
+ provided
+
+
+
+
+
+
+
+ maven-dependency-plugin
+
+
+
+ default-cli
+ false
+
+ unpack
+
+
+
+
+ com.docflex
+ docflex-javadoc
+ ${docflex.version}
+ zip
+
+
+ ${project.build.directory}
+
+
+
+
+
+
+ maven-javadoc-plugin
+
+ com.docflex.javadoc.Doclet
+ ${project.build.directory}/docflex-javadoc-${docflex.version}/lib/docflex-javadoc.jar
+
+ -license ${settings.localRepository}/com/docflex/docflex-alfresco-license/1.0/docflex-alfresco-license-1.0.license
+ -template ${project.build.directory}/docflex-javadoc-${docflex.version}/templates/JavadocPro/FramedDoc.tpl
+ -nodialog
+ -launchviewer=false
+ -p:filter.byAnns.include.classes=org.alfresco.api.AlfrescoPublicApi
+ -p:docTitle "Alfresco ${project.version} Public API"
+ -p:windowTitle "Alfresco ${project.version} Public API"
+
+ true
+ true
+
+ org.alfresco:*
+
+
+ org.alfresco:alfresco-xmlfactory
+ org.alfresco:alfresco-text-gen
+
+ org.customer,org.apache
+
+
+
+
+
+
+
diff --git a/packaging/scripts/travis/copy_to_release_bucket.sh b/packaging/scripts/travis/copy_to_release_bucket.sh
new file mode 100755
index 00000000000..f04dc95162b
--- /dev/null
+++ b/packaging/scripts/travis/copy_to_release_bucket.sh
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+set -ev
+
+if [ -z ${COMM_RELEASE_VERSION} ] || [ -z ${RELEASE_VERSION} ];
+then
+ echo "Please provide a COMM_RELEASE_VERSION and RELEASE_VERSION in the format - (6.3.0-EA or 6.3.0-SNAPSHOT)"
+ exit -1
+fi
+
+build_number=$1
+branch_name=$2
+build_stage=release
+SOURCE=s3://alfresco-artefacts-staging/alfresco-content-services-community/$build_stage/$branch_name/$build_number
+DESTINATION=s3://eu.dl.alfresco.com/release/community/$COMM_RELEASE_VERSION-build-$build_number
+
+aws s3 cp --acl private $SOURCE/alfresco.war $DESTINATION/alfresco.war
+aws s3 cp --acl private $SOURCE/alfresco-content-services-community-distribution-$RELEASE_VERSION.zip $DESTINATION/alfresco-content-services-community-distribution-$RELEASE_VERSION.zip
\ No newline at end of file
diff --git a/packaging/scripts/travis/maven_release.sh b/packaging/scripts/travis/maven_release.sh
new file mode 100755
index 00000000000..b4e9155643b
--- /dev/null
+++ b/packaging/scripts/travis/maven_release.sh
@@ -0,0 +1,31 @@
+#!/usr/bin/env bash
+set -e
+
+releaseVersion=$1
+developmentVersion=$2
+scm_path=$(mvn help:evaluate -Dexpression=project.scm.url -q -DforceStdout)
+
+# Use full history for release
+git checkout -B "${TRAVIS_BRANCH}"
+# Add email to link commits to user
+git config user.email "${GIT_EMAIL}"
+
+if [ -z ${releaseVersion} ] || [ -z ${developmentVersion} ];
+ then echo "Please provide a Release and Development verison in the format - (6.3.0-EA or 6.3.0-SNAPSHOT)"
+ exit -1
+else
+ mvn --batch-mode \
+ -PfullBuild,all-tas-tests \
+ -Dusername="${GIT_USERNAME}" \
+ -Dpassword="${GIT_PASSWORD}" \
+ -DreleaseVersion=${releaseVersion} \
+ -DdevelopmentVersion=${developmentVersion} \
+ -Dbuild-number=${TRAVIS_BUILD_NUMBER} \
+ -Dbuild-name="${TRAVIS_BUILD_STAGE_NAME}" \
+ -Dscm-path=${scm_path} \
+ -DscmCommentPrefix="[maven-release-plugin][skip ci]" \
+ -DskipTests \
+ "-Darguments=-DskipTests -Dbuild-number=${TRAVIS_BUILD_NUMBER} '-Dbuild-name=${TRAVIS_BUILD_STAGE_NAME}' -Dscm-path=${scm_path} -PfullBuild,all-tas-tests" \
+ release:clean release:prepare release:perform \
+ -Prelease
+fi
diff --git a/packaging/scripts/travis/verify_release_tag.sh b/packaging/scripts/travis/verify_release_tag.sh
new file mode 100755
index 00000000000..51086b8ec78
--- /dev/null
+++ b/packaging/scripts/travis/verify_release_tag.sh
@@ -0,0 +1,31 @@
+#!/usr/bin/env bash
+set -e
+
+if [ -v ${RELEASE_VERSION} ]||[ -z ${RELEASE_VERSION} ]; then
+ echo "Please provide a RELEASE_VERSION in the format - (6.3.0-EA or 6.3.0-SNAPSHOT)"
+ exit -1
+fi
+# get the image name from the pom file
+alfresco_docker_image=$(mvn help:evaluate -f ./docker-alfresco/pom.xml -Dexpression=image.name -q -DforceStdout)
+docker_image_full_name="$alfresco_docker_image:$RELEASE_VERSION"
+
+function docker_image_exists() {
+ local image_full_name="$1"; shift
+ local wait_time="${1:-5}"
+ local search_term='Pulling|is up to date|not found'
+ echo "Looking to see if $image_full_name already exists..."
+ local result="$((timeout --preserve-status "$wait_time" docker 2>&1 pull "$image_full_name" &) | grep -v 'Pulling repository' | egrep -o "$search_term")"
+ test "$result" || { echo "Timed out too soon. Try using a wait_time greater than $wait_time..."; return 1 ;}
+ if echo $result | grep -vq 'not found'; then
+ true
+ else
+ false
+ fi
+}
+
+if docker_image_exists $docker_image_full_name; then
+ echo "Tag $RELEASE_VERSION already pushed, release process will interrupt."
+ exit -1
+else
+ echo "The $RELEASE_VERSION tag was not found"
+fi
diff --git a/packaging/tests/environment/.env b/packaging/tests/environment/.env
new file mode 100644
index 00000000000..f13d730f800
--- /dev/null
+++ b/packaging/tests/environment/.env
@@ -0,0 +1,4 @@
+TRANSFORMERS_TAG=2.3.1
+SOLR6_TAG=1.4.2
+POSTGRES_TAG=11.7
+ACTIVEMQ_TAG=5.15.8
diff --git a/packaging/tests/environment/docker-compose-minimal+transforms.yml b/packaging/tests/environment/docker-compose-minimal+transforms.yml
new file mode 100644
index 00000000000..d8f0a1f7e6c
--- /dev/null
+++ b/packaging/tests/environment/docker-compose-minimal+transforms.yml
@@ -0,0 +1,90 @@
+version: "3"
+
+# The acs-community-deployment project contains the product version of docker-compose.
+#
+# This version is for testing and development use. For testing and debug we need to have a more open version.
+# For remote debug we need the CATALINA_OPTS and to expose port 8000.
+
+services:
+ alfresco:
+ image: alfresco/alfresco-content-repository-community:latest
+ environment:
+ CATALINA_OPTS : "-agentlib:jdwp=transport=dt_socket,address=*:8000,server=y,suspend=n"
+ # Some properties are built in Dockerfile because of cron expressions
+ JAVA_OPTS :
+ "
+ -Ddb.driver=org.postgresql.Driver
+ -Ddb.username=alfresco
+ -Ddb.password=alfresco
+ -Ddb.url=jdbc:postgresql://postgres:5432/alfresco
+ -Dsolr.host=solr6
+ -Dsolr.port=8983
+ -Dsolr.secureComms=none
+ -Dsolr.base.url=/solr
+ -Dindex.subsystem.name=solr6
+ -Dalfresco.restApi.basicAuthScheme=true
+ -Dimap.server.enabled=true
+ -Dftp.enabled=true
+ -Dftp.dataPortFrom=30000
+ -Dftp.dataPortTo=30099
+ -Dshare.host=localhost
+ -Daos.baseUrlOverwrite=http://localhost:8082/alfresco/aos
+ -Dmessaging.broker.url=\"failover:(tcp://activemq:61616)?timeout=3000&jms.useCompression=true\"
+
+ -DlocalTransform.core-aio.url=http://transform-core-aio:8090/
+
+ -Dalfresco-pdf-renderer.url=http://transform-core-aio:8090/
+ -Djodconverter.url=http://transform-core-aio:8090/
+ -Dimg.url=http://transform-core-aio:8090/
+ -Dtika.url=http://transform-core-aio:8090/
+ -Dtransform.misc.url=http://transform-core-aio:8090/
+
+ -Dimap.server.port=1143
+ -Dftp.port=1221
+ -Dcors.enabled=true
+ -Dcors.allowed.origins=http://localhost:4200,http://localhost:8080
+ "
+ ports:
+ - 8082:8080
+ - 8000:8000
+ - 143:1143
+ - 21:1221
+ - 30000-30099:30000-30099
+
+ postgres:
+ image: library/postgres:${POSTGRES_TAG}
+ environment:
+ - POSTGRES_PASSWORD=alfresco
+ - POSTGRES_USER=alfresco
+ - POSTGRES_DB=alfresco
+
+ solr6:
+ image: alfresco/alfresco-search-services:${SOLR6_TAG}
+ environment:
+ #Solr needs to know how to register itself with Alfresco
+ - SOLR_ALFRESCO_HOST=alfresco
+ - SOLR_ALFRESCO_PORT=8080
+ #Alfresco needs to know how to call solr
+ - SOLR_SOLR_HOST=solr6
+ - SOLR_SOLR_PORT=8983
+ #Create the default alfresco and archive cores
+ - SOLR_CREATE_ALFRESCO_DEFAULTS=alfresco,archive
+ #HTTP by default
+ - ALFRESCO_SECURE_COMMS=none
+ ports:
+ - 8083:8983 #Browser port
+
+ activemq:
+ image: alfresco/alfresco-activemq:${ACTIVEMQ_TAG}
+ ports:
+ - 8161:8161 # Web Console
+ - 5672:5672 # AMQP
+ - 61616:61616 # OpenWire
+ - 61613:61613 # STOMP
+
+ transform-core-aio:
+ image: alfresco/alfresco-transform-core-aio:${TRANSFORMERS_TAG}
+ environment:
+ JAVA_OPTS: " -Xms256m -Xmx512m"
+ ports:
+ - 8090:8090
diff --git a/packaging/tests/environment/docker-compose-minimal.yml b/packaging/tests/environment/docker-compose-minimal.yml
new file mode 100644
index 00000000000..453db3ae8b1
--- /dev/null
+++ b/packaging/tests/environment/docker-compose-minimal.yml
@@ -0,0 +1,77 @@
+version: "3"
+
+# The acs-community-deployment project contains the product version of docker-compose.
+#
+# This version is for testing and development use. For testing and debug we need to have a more open version.
+# For remote debug we need the CATALINA_OPTS and to expose port 8000.
+
+services:
+ alfresco:
+ image: alfresco/alfresco-content-repository-community:latest
+ environment:
+ CATALINA_OPTS : "-agentlib:jdwp=transport=dt_socket,address=*:8000,server=y,suspend=n"
+ JAVA_OPTS :
+ "
+ -Ddb.driver=org.postgresql.Driver
+ -Ddb.username=alfresco
+ -Ddb.password=alfresco
+ -Ddb.url=jdbc:postgresql://postgres:5432/alfresco
+ -Dsolr.host=solr6
+ -Dsolr.port=8983
+ -Dsolr.secureComms=none
+ -Dsolr.base.url=/solr
+ -Dindex.subsystem.name=solr6
+ -Dalfresco.restApi.basicAuthScheme=true
+ -Dimap.server.enabled=true
+ -Dftp.enabled=true
+ -Dftp.dataPortFrom=30000
+ -Dftp.dataPortTo=30099
+ -Dshare.host=localhost
+ -Daos.baseUrlOverwrite=http://localhost:8082/alfresco/aos
+ -Dmessaging.broker.url=\"failover:(tcp://activemq:61616)?timeout=3000&jms.useCompression=true\"
+
+ -Dlocal.transform.service.enabled=false
+ -Dlegacy.transform.service.enabled=false
+
+ -Dimap.server.port=1143
+ -Dftp.port=1221
+ -Dcors.enabled=true
+ -Dcors.allowed.origins=http://localhost:4200
+ "
+ ports:
+ - 8082:8080
+ - 8000:8000
+ - 143:1143
+ - 21:1221
+ - 30000-30099:30000-30099
+
+ postgres:
+ image: library/postgres:${POSTGRES_TAG}
+ environment:
+ - POSTGRES_PASSWORD=alfresco
+ - POSTGRES_USER=alfresco
+ - POSTGRES_DB=alfresco
+
+ solr6:
+ image: alfresco/alfresco-search-services:${SOLR6_TAG}
+ environment:
+ #Solr needs to know how to register itself with Alfresco
+ - SOLR_ALFRESCO_HOST=alfresco
+ - SOLR_ALFRESCO_PORT=8080
+ #Alfresco needs to know how to call solr
+ - SOLR_SOLR_HOST=solr6
+ - SOLR_SOLR_PORT=8983
+ #Create the default alfresco and archive cores
+ - SOLR_CREATE_ALFRESCO_DEFAULTS=alfresco,archive
+ #HTTP by default
+ - ALFRESCO_SECURE_COMMS=none
+ ports:
+ - 8083:8983 #Browser port
+
+ activemq:
+ image: alfresco/alfresco-activemq:${ACTIVEMQ_TAG}
+ ports:
+ - 8161:8161 # Web Console
+ - 5672:5672 # AMQP
+ - 61616:61616 # OpenWire
+ - 61613:61613 # STOMP
\ No newline at end of file
diff --git a/packaging/tests/pom.xml b/packaging/tests/pom.xml
new file mode 100644
index 00000000000..95381bbe8cb
--- /dev/null
+++ b/packaging/tests/pom.xml
@@ -0,0 +1,86 @@
+
+ 4.0.0
+ content-repository-community-tas-tests-parent
+ 6.2.2-SNAPSHOT
+ pom
+
+
+ org.alfresco
+ acs-community-packaging
+ 6.2.2-SNAPSHOT
+ ../pom.xml
+
+
+
+ tas-restapi
+ tas-cmis
+ tas-email
+ tas-webdav
+ tas-integration
+
+
+
+
+
+ org.alfresco.tas
+ utility
+ ${dependency.tas-utility.version}
+ test
+
+
+ io.rest-assured
+ rest-assured
+ ${dependency.rest-assured.version}
+ test
+
+
+ org.glassfish
+ javax.json
+ ${dependency.javax.json.version}
+ test
+
+
+ org.alfresco.tas
+ restapi
+ ${dependency.tas-restapi.version}
+ test
+
+
+ org.alfresco.tas
+ cmis
+ ${dependency.tas-cmis.version}
+ test
+
+
+ org.alfresco.tas
+ email
+ ${dependency.tas-email.version}
+ test
+
+
+ org.alfresco.tas
+ webdav
+ ${dependency.tas-webdav.version}
+ test
+
+
+ org.alfresco.tas
+ ftp
+ ${dependency.tas-ftp.version}
+ test
+
+
+ org.alfresco.test
+ dataprep
+ ${dependency.tas-dataprep.version}
+ test
+
+
+ org.springframework
+ spring-test
+ ${dependency.spring.version}
+ test
+
+
+
+
\ No newline at end of file
diff --git a/packaging/tests/scripts/start-compose.sh b/packaging/tests/scripts/start-compose.sh
new file mode 100755
index 00000000000..ace065bb0ca
--- /dev/null
+++ b/packaging/tests/scripts/start-compose.sh
@@ -0,0 +1,22 @@
+#!/usr/bin/env bash
+
+export DOCKER_COMPOSE_PATH=$1
+
+if [ -z "$DOCKER_COMPOSE_PATH" ]
+then
+ echo "Please provide path to docker-compose.yml: \"${0##*/} /path/to/docker-compose.yml\""
+ exit 1
+fi
+
+echo "Starting ACS stack in ${DOCKER_COMPOSE_PATH}"
+
+# .env files are picked up from project directory correctly on docker-compose 1.23.0+
+docker-compose --file "${DOCKER_COMPOSE_PATH}" --project-directory $(dirname "${DOCKER_COMPOSE_PATH}") up -d
+
+if [ $? -eq 0 ]
+then
+ echo "Docker Compose started ok"
+else
+ echo "Docker Compose failed to start" >&2
+ exit 1
+fi
\ No newline at end of file
diff --git a/packaging/tests/scripts/stop-compose.sh b/packaging/tests/scripts/stop-compose.sh
new file mode 100755
index 00000000000..6fe57386243
--- /dev/null
+++ b/packaging/tests/scripts/stop-compose.sh
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+
+export DOCKER_COMPOSE_PATH=$1
+
+if [ -z "$DOCKER_COMPOSE_PATH" ]
+then
+ echo "Please provide path to docker-compose.yml: \"${0##*/} /path/to/docker-compose.yml\""
+ exit 1
+fi
+
+echo "Killing ACS stack in ${DOCKER_COMPOSE_PATH}"
+
+cd ${DOCKER_COMPOSE_PATH}
+
+docker-compose ps
+# logs for debug
+docker-compose logs --no-color -t alfresco
+docker-compose kill
+docker-compose rm -fv
\ No newline at end of file
diff --git a/packaging/tests/scripts/wait-for-alfresco-start.sh b/packaging/tests/scripts/wait-for-alfresco-start.sh
new file mode 100755
index 00000000000..df481913065
--- /dev/null
+++ b/packaging/tests/scripts/wait-for-alfresco-start.sh
@@ -0,0 +1,31 @@
+#!/usr/bin/env bash
+
+export ALFRESCO_URL=$1
+
+if [ -z "$ALFRESCO_URL" ]
+then
+ echo "Please provide the Alfresco URL to check, for example: \"${0##*/} http://localhost:8080/alfresco\""
+ exit 1
+fi
+
+WAIT_INTERVAL=1
+COUNTER=0
+TIMEOUT=300
+t0=$(date +%s)
+
+echo "Waiting for alfresco to start"
+until $(curl --output /dev/null --silent --head --fail ${ALFRESCO_URL}) || [ "$COUNTER" -eq "$TIMEOUT" ]; do
+ printf '.'
+ sleep $WAIT_INTERVAL
+ COUNTER=$(($COUNTER+$WAIT_INTERVAL))
+done
+
+if (("$COUNTER" < "$TIMEOUT")) ; then
+ t1=$(date +%s)
+ delta=$((($t1 - $t0)/60))
+ echo "Alfresco Started in $delta minutes"
+else
+ echo "Waited $COUNTER seconds"
+ echo "Alfresco Could not start in time."
+ exit 1
+fi
\ No newline at end of file
diff --git a/packaging/tests/tas-cmis/pom.xml b/packaging/tests/tas-cmis/pom.xml
new file mode 100644
index 00000000000..a0e5c20dba5
--- /dev/null
+++ b/packaging/tests/tas-cmis/pom.xml
@@ -0,0 +1,66 @@
+
+
+ 4.0.0
+ org.alfresco.tas
+ content-repository-community-cmis-test
+ content-repository-community-cmis-test
+ 6.2.2-SNAPSHOT
+ jar
+
+
+ org.alfresco
+ content-repository-community-tas-tests-parent
+ 6.2.2-SNAPSHOT
+ ../pom.xml
+
+
+
+
+ Paul Brodner
+
+ Test Automation Architect
+
+
+
+
+
+ ${project.basedir}/src/test/resources/cmis-suite.xml
+
+
+
+
+ org.alfresco.tas
+ cmis
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ ${suiteXmlFile}
+
+
+ --illegal-access=warn
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+
+ test-jar
+
+
+
+
+
+
+
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/AclTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/AclTests.java
new file mode 100644
index 00000000000..ed372303ca6
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/AclTests.java
@@ -0,0 +1,645 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.FolderModel;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.data.PermissionMapping;
+import org.apache.chemistry.opencmis.commons.enums.AclPropagation;
+import org.apache.chemistry.opencmis.commons.enums.VersioningState;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.apache.chemistry.opencmis.commons.impl.jaxb.EnumBasicPermissions;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class AclTests extends CmisTest
+{
+ UserModel testUser, inviteUser, unauthorizedUser;
+ SiteModel testSite, privateSite;
+ FileModel testFile;
+ FolderModel testFolder;
+ private DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ inviteUser = dataUser.createRandomTestUser();
+ unauthorizedUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createPublicRandomSite();
+ privateSite = dataSite.usingUser(testUser).createPrivateRandomSite();
+ usersWithRoles = dataUser.usingUser(testUser)
+ .addUsersWithRolesToSite(testSite, UserRole.SiteContributor, UserRole.SiteCollaborator, UserRole.SiteConsumer);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Site manager can get the acls for valid document")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS })
+ public void siteManagerShouldGetDocumentAcls() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .and().assertThat().hasAcls();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Site manager can get the acls for valid folder")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerShouldGetFolderAcls() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(testFolder).and().assertThat().existsInRepo()
+ .and().assertThat().hasAcls();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Add Acl for valid document with AclPropagation set to REPOSITORYDETERMINED")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanAddAclWithRepositoryDeterminedPropagation() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo();
+ cmisApi.usingResource(testFile).addAcl(inviteUser, UserRole.SiteContributor, AclPropagation.REPOSITORYDETERMINED)
+ .then().assertThat().permissionIsSetForUser(inviteUser, UserRole.SiteContributor);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Add Acl for valid folder with AclPropagation set to PROPAGATE")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanAddAclWithPropagate() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(testFolder).and().assertThat().existsInRepo();
+ cmisApi.usingResource(testFolder).addAcl(inviteUser, UserRole.SiteConsumer, AclPropagation.PROPAGATE)
+ .then().assertThat().permissionIsSetForUser(inviteUser, UserRole.SiteConsumer);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Add Acl for valid folder with AclPropagation set to OBJECTONLY")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanAddAclWithObjectOnlyPropagation() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(testFolder).and().assertThat().existsInRepo();
+ cmisApi.usingResource(testFolder).addAcl(inviteUser, UserRole.SiteCollaborator, AclPropagation.OBJECTONLY)
+ .then().assertThat().permissionIsSetForUser(inviteUser, UserRole.SiteCollaborator);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Apply Acl for valid folder with AclPropagation set to OBJECTONLY")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanApplyAclWithObjectOnlyPropagation() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(testFolder).and().assertThat().existsInRepo();
+ cmisApi.usingResource(testFolder).addAcl(inviteUser, UserRole.SiteCollaborator, AclPropagation.OBJECTONLY)
+ .then().applyAcl(inviteUser, UserRole.SiteConsumer, UserRole.SiteCollaborator, AclPropagation.OBJECTONLY)
+ .and().assertThat().permissionIsSetForUser(inviteUser, UserRole.SiteConsumer)
+ .and().assertThat().permissionIsNotSetForUser(inviteUser, UserRole.SiteCollaborator);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify appply acl with invalid role that will be removed")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisConstraintException.class)
+ public void applyAclWithInvalidAddedRole() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .then().addAcl(inviteUser, UserRole.SiteCollaborator, AclPropagation.OBJECTONLY)
+ .then().applyAcl(inviteUser, UserRole.SiteConsumer, UserRole.SiteManager, AclPropagation.OBJECTONLY);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Apply Acl for valid folder with AclPropagation set to PROPAGATE")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerCanApplyAclWithPropagate() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.PDF);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile)
+ .and().addAcl(inviteUser, UserRole.SiteConsumer, AclPropagation.PROPAGATE)
+ .when().applyAcl(inviteUser, UserRole.SiteManager, UserRole.SiteConsumer, AclPropagation.PROPAGATE)
+ .assertThat().permissionIsSetForUser(inviteUser, UserRole.SiteManager)
+ .and().assertThat().permissionIsNotSetForUser(inviteUser, UserRole.SiteConsumer);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Apply Acl for valid folder with AclPropagation set to REPOSITORYDETERMINED")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanApplyAclWithRepositoryDeterminedPropagation() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.PDF);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile)
+ .and().addAcl(inviteUser, UserRole.SiteConsumer, AclPropagation.OBJECTONLY)
+ .when().applyAcl(inviteUser, UserRole.SiteManager, UserRole.SiteConsumer, AclPropagation.REPOSITORYDETERMINED)
+ .assertThat().permissionIsSetForUser(inviteUser, UserRole.SiteManager)
+ .and().assertThat().permissionIsNotSetForUser(inviteUser, UserRole.SiteConsumer);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Remove Acl for valid folder with AclPropagation set to REPOSITORYDETERMINED")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanRemoveAclWithRepositoryDeterminedPropagation() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.PDF);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile)
+ .and().addAcl(inviteUser, UserRole.SiteConsumer, AclPropagation.OBJECTONLY)
+ .when().removeAcl(inviteUser, UserRole.SiteConsumer, AclPropagation.REPOSITORYDETERMINED)
+ .and().assertThat().permissionIsNotSetForUser(inviteUser, UserRole.SiteConsumer);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Remove Acl for valid folder with AclPropagation set to REPOSITORYDETERMINED")
+ @Test(groups = {TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerCanRemoveAclWithPropagate() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.PDF);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile)
+ .and().addAcl(inviteUser, UserRole.SiteManager, AclPropagation.OBJECTONLY)
+ .when().removeAcl(inviteUser, UserRole.SiteManager, AclPropagation.PROPAGATE)
+ .and().assertThat().permissionIsNotSetForUser(inviteUser, UserRole.SiteManager);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Remove Acl for valid folder with AclPropagation set to REPOSITORYDETERMINED")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanRemoveAclWithObjectOnlyPropagation() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.PDF);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile)
+ .and().addAcl(inviteUser, UserRole.SiteContributor, AclPropagation.OBJECTONLY)
+ .when().removeAcl(inviteUser, UserRole.SiteContributor, AclPropagation.OBJECTONLY)
+ .and().assertThat().permissionIsNotSetForUser(inviteUser, UserRole.SiteContributor);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Remove Acl for valid folder with AclPropagation set to REPOSITORYDETERMINED")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisConstraintException.class)
+ public void siteManagerCannotRemoveInvalidAcl() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.PDF);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile)
+ .and().addAcl(inviteUser, UserRole.SiteContributor, AclPropagation.OBJECTONLY)
+ .when().removeAcl(inviteUser, UserRole.SiteManager, AclPropagation.OBJECTONLY);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Site manager can add acl with null AclPropagation")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanAddAclWithNullPropagation() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.PDF, "content");
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile)
+ .and().addAcl(inviteUser, UserRole.SiteContributor, null)
+ .then().assertThat().permissionIsSetForUser(inviteUser, UserRole.SiteContributor);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Site manager cannot get acl for pwc document")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisRuntimeException.class)
+ public void siteManagerCannotGetAclForPwcDocument() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.PDF, "content");
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile, VersioningState.CHECKEDOUT)
+ .usingPWCDocument().addAcl(inviteUser, UserRole.SiteContributor, AclPropagation.PROPAGATE)
+ .then().assertThat().permissionIsSetForUser(inviteUser, UserRole.SiteContributor);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Site manager cannot get acl for invalid object")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisObjectNotFoundException.class)
+ public void siteManagerCannotGetAclForInvalidObject() throws Exception
+ {
+ FolderModel folder = FolderModel.getRandomFolderModel();
+ folder.setCmisLocation("/" + folder.getName() + "/");
+ cmisApi.authenticateUser(testUser)
+ .usingResource(folder)
+ .assertThat().permissionIsSetForUser(inviteUser, UserRole.SiteContributor);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Apply Acl for valid document with null AclPropagation")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanApplyAclWithNullPropagation() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.PDF);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile)
+ .and().addAcl(inviteUser, UserRole.SiteConsumer, AclPropagation.OBJECTONLY)
+ .when().applyAcl(inviteUser, UserRole.SiteManager, UserRole.SiteConsumer, null)
+ .assertThat().permissionIsSetForUser(inviteUser, UserRole.SiteManager)
+ .and().assertThat().permissionIsNotSetForUser(inviteUser, UserRole.SiteConsumer);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Apply Acl for checked out document")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisRuntimeException.class)
+ public void siteManagerCannotGetAclForAppliedAclForPWC() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSEXCEL);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile)
+ .and().addAcl(inviteUser, UserRole.SiteConsumer, AclPropagation.OBJECTONLY)
+ .then().checkOut().assertThat().documentIsCheckedOut()
+ .usingPWCDocument().applyAcl(inviteUser, UserRole.SiteManager, UserRole.SiteConsumer)
+ .assertThat().permissionIsSetForUser(inviteUser, UserRole.SiteManager);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Remove Acl from valid folder with null AclPropagation")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanRemoveAclWithNullPropagation() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.PDF);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile)
+ .and().addAcl(inviteUser, UserRole.SiteContributor, AclPropagation.OBJECTONLY)
+ .when().removeAcl(inviteUser, UserRole.SiteContributor)
+ .and().assertThat().permissionIsNotSetForUser(inviteUser, UserRole.SiteContributor);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Unauthorized user cannot remove acl")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void removeAclByUnauthorizedUser() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSEXCEL);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile)
+ .and().addAcl(inviteUser, UserRole.SiteConsumer, AclPropagation.OBJECTONLY)
+ .assertThat().permissionIsSetForUser(inviteUser, UserRole.SiteConsumer)
+ .when().authenticateUser(unauthorizedUser)
+ .removeAcl(inviteUser, UserRole.SiteConsumer);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Unauthorized user cannot add acl")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void addAclByUnauthorizedUser() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSEXCEL);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile)
+ .then().authenticateUser(unauthorizedUser)
+ .and().addAcl(inviteUser, UserRole.SiteConsumer, AclPropagation.OBJECTONLY);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Unauthorized user cannot apply acl")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void applyAclByUnauthorizedUser() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSEXCEL);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile)
+ .and().addAcl(inviteUser, UserRole.SiteConsumer)
+ .when().authenticateUser(unauthorizedUser)
+ .and().applyAcl(inviteUser, UserRole.SiteManager, UserRole.SiteConsumer);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Add Acl for checked out document")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanAddAclForCheckedOutDocument() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile, VersioningState.CHECKEDOUT).and().assertThat().existsInRepo()
+ .and().assertThat().documentIsCheckedOut()
+ .then().usingResource(testFile)
+ .addAcl(inviteUser, UserRole.SiteContributor)
+ .and().assertThat().permissionIsSetForUser(inviteUser, UserRole.SiteContributor);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Add Acl by user with collaborator role for document created by himself")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorCanAddAclForDocumentCreatedByHimself() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .addAcl(inviteUser, UserRole.SiteContributor)
+ .and().assertThat().permissionIsSetForUser(inviteUser, UserRole.SiteContributor);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Add Acl by user with collaborator role for document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void collaboratorCannotAddAclForDocumentCreatedByManager() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .addAcl(inviteUser, UserRole.SiteContributor);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Get Acl by user with collaborator role for document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorCanGetAclForDocumentCreatedByManager() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .addAcl(inviteUser, UserRole.SiteContributor)
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingResource(testFile).refreshResource()
+ .and().assertThat().permissionIsSetForUser(inviteUser, UserRole.SiteContributor);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Apply Acl by user with collaborator role for document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void collaboratorCannotApplyAclForDocumentCreatedByManager() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .addAcl(inviteUser, UserRole.SiteContributor)
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .applyAcl(inviteUser, UserRole.SiteCollaborator, UserRole.SiteContributor);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Apply Acl by user with collaborator role for document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void collaboratorCannotRemoveAclForDocumentCreatedByManager() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .addAcl(inviteUser, UserRole.SiteContributor)
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .removeAcl(inviteUser, UserRole.SiteContributor);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Add Acl by user with contributor role for document created by himself")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorCanAddAclForDocumentCreatedByHimself() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .addAcl(inviteUser, UserRole.SiteContributor)
+ .and().assertThat().permissionIsSetForUser(inviteUser, UserRole.SiteContributor);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Add Acl by user with contributor role for document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void contributorCannotAddAclForDocumentCreatedByManager() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .addAcl(inviteUser, UserRole.SiteCollaborator);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Get Acl by user with collaborator role for document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorCanGetAclForDocumentCreatedByManager() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .addAcl(inviteUser, UserRole.SiteContributor)
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingResource(testFile).refreshResource()
+ .and().assertThat().permissionIsSetForUser(inviteUser, UserRole.SiteContributor);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Apply Acl by user with contributor role for document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void contributorCannotApplyAclForDocumentCreatedByManager() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .addAcl(inviteUser, UserRole.SiteContributor)
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .applyAcl(inviteUser, UserRole.SiteCollaborator, UserRole.SiteContributor);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Apply Acl by user with contributor role for document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void contributorCannotRemoveAclForDocumentCreatedByManager() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .addAcl(inviteUser, UserRole.SiteContributor)
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .removeAcl(inviteUser, UserRole.SiteContributor);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Add Acl by user with consumer role for document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void consumerCannotAddAclForDocumentCreatedByManager() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .addAcl(inviteUser, UserRole.SiteCollaborator);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Get Acl by user with consumer role for document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void consumerCanGetAclForDocumentCreatedByManager() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .addAcl(inviteUser, UserRole.SiteContributor)
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .usingResource(testFile).refreshResource()
+ .and().assertThat().permissionIsSetForUser(inviteUser, UserRole.SiteContributor);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Apply Acl by user with consumer role for document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void consumerCannotApplyAclForDocumentCreatedByManager() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .addAcl(inviteUser, UserRole.SiteContributor)
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .applyAcl(inviteUser, UserRole.SiteCollaborator, UserRole.SiteContributor);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Apply Acl by user with consumer role for document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void consumerCannotRemoveAclForDocumentCreatedByManager() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .addAcl(inviteUser, UserRole.SiteContributor)
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .removeAcl(inviteUser, UserRole.SiteContributor);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Add Acl by non invited user in private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonInvitedUserCannotAddAclInPrivateSite() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(privateSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .addAcl(inviteUser, UserRole.SiteCollaborator);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Get Acl by non invited user in private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonInvitedUserCannotGetAclInPrivateSite() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(privateSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .addAcl(inviteUser, UserRole.SiteContributor)
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .usingResource(testFile).refreshResource()
+ .and().assertThat().permissionIsSetForUser(inviteUser, UserRole.SiteContributor);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Apply Acl by non invited user in private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonInvitedUserCannotApplyAclInPrivateSite() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(privateSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .addAcl(inviteUser, UserRole.SiteContributor)
+ .applyAcl(inviteUser, UserRole.SiteCollaborator, UserRole.SiteContributor)
+ .and().assertThat().permissionIsSetForUser(inviteUser, UserRole.SiteCollaborator)
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .applyAcl(inviteUser, UserRole.SiteContributor, UserRole.SiteCollaborator);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Remove Acl by non invited user in private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonInvitedUserCannotRemoveAclFromPrivateSite() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(privateSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .addAcl(inviteUser, UserRole.SiteContributor)
+ .and().assertThat().permissionIsSetForUser(inviteUser, UserRole.SiteContributor)
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .removeAcl(inviteUser, UserRole.SiteContributor);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Add Acl for valid document with PermissionMapping")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanAddAclWithPermissionMapping() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .then().addAcl(inviteUser, PermissionMapping.CAN_UPDATE_PROPERTIES_OBJECT)
+ .assertThat().permissionIsSetForUser(inviteUser, EnumBasicPermissions.CMIS_WRITE.value())
+ .then().addAcl(inviteUser, PermissionMapping.CAN_DELETE_OBJECT)
+ .and().assertThat().permissionIsSetForUser(inviteUser, EnumBasicPermissions.CMIS_ALL.value());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Apply Acl for valid document with PermissionMapping")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanApplyAclWithPermissionMapping() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .then().addAcl(inviteUser, PermissionMapping.CAN_DELETE_OBJECT)
+ .and().assertThat().permissionIsSetForUser(inviteUser, EnumBasicPermissions.CMIS_ALL.value())
+ .then().applyAcl(inviteUser, PermissionMapping.CAN_UPDATE_PROPERTIES_OBJECT, PermissionMapping.CAN_DELETE_OBJECT)
+ .and().assertThat().permissionIsSetForUser(inviteUser, EnumBasicPermissions.CMIS_WRITE.value())
+ .and().assertThat().permissionIsNotSetForUser(inviteUser, EnumBasicPermissions.CMIS_ALL.value());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Remove Acl for valid document with PermissionMapping")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanRemoveAclWithPermissionMapping() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .then().addAcl(inviteUser, PermissionMapping.CAN_UPDATE_PROPERTIES_OBJECT)
+ .assertThat().permissionIsSetForUser(inviteUser, EnumBasicPermissions.CMIS_WRITE.value())
+ .then().addAcl(inviteUser, PermissionMapping.CAN_DELETE_OBJECT)
+ .and().assertThat().permissionIsSetForUser(inviteUser, EnumBasicPermissions.CMIS_ALL.value())
+ .then().removeAcl(inviteUser, PermissionMapping.CAN_DELETE_OBJECT)
+ .and().assertThat().permissionIsNotSetForUser(inviteUser, EnumBasicPermissions.CMIS_ALL.value());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Remove invalid Acl(that was not set) for valid document with PermissionMapping")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisConstraintException.class,
+ expectedExceptionsMessageRegExp="No matching ACE found to remove!*")
+ public void siteManagerCannotRemoveInvalidAclWithPermissionMapping() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .then().addAcl(inviteUser, PermissionMapping.CAN_UPDATE_PROPERTIES_OBJECT)
+ .assertThat().permissionIsSetForUser(inviteUser, EnumBasicPermissions.CMIS_WRITE.value())
+ .then().removeAcl(inviteUser, PermissionMapping.CAN_CHECKIN_DOCUMENT);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Apply invalid Acl(that was not set) for valid document with PermissionMapping")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisConstraintException.class,
+ expectedExceptionsMessageRegExp="No matching ACE found to remove!*")
+ public void siteManagerCannotApplyInvalidAclWithPermissionMapping() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .then().addAcl(inviteUser, PermissionMapping.CAN_DELETE_OBJECT)
+ .and().assertThat().permissionIsSetForUser(inviteUser, EnumBasicPermissions.CMIS_ALL.value())
+ .then().applyAcl(inviteUser, PermissionMapping.CAN_UPDATE_PROPERTIES_OBJECT, PermissionMapping.CAN_CREATE_FOLDER_FOLDER);
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/AddObjectToFolderTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/AddObjectToFolderTests.java
new file mode 100644
index 00000000000..558e46ee589
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/AddObjectToFolderTests.java
@@ -0,0 +1,222 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.FolderModel;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * Created by Claudia Agache on 9/28/2016.
+ */
+public class AddObjectToFolderTests extends CmisTest
+{
+ UserModel testUser;
+ SiteModel testSite;
+ FolderModel destinationFolder;
+ FileModel sourceFile;
+ private DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createPublicRandomSite();
+ destinationFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(destinationFolder)
+ .assertThat().existsInRepo();
+ usersWithRoles = dataUser.usingUser(testUser)
+ .addUsersWithRolesToSite(testSite, UserRole.SiteContributor, UserRole.SiteCollaborator, UserRole.SiteConsumer);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.SANITY,
+ description = "Verify site manager is able to add document object to folder with CMIS")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerShouldAddFileToFolder() throws Exception
+ {
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(sourceFile).assertThat().existsInRepo()
+ .then().addDocumentToFolder(destinationFolder, true)
+ .and().assertThat().existsInRepo()
+ .and().assertThat().objectIdIs(sourceFile.getNodeRef());
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to add folder object to folder with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisInvalidArgumentException.class,
+ expectedExceptionsMessageRegExp="Object is not a document!*")
+ public void siteManagerShouldNotAddFolderToFolder() throws Exception
+ {
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ FolderModel folderToAdd = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(folderToAdd).assertThat().existsInRepo()
+ .then().addDocumentToFolder(folderToAdd, true);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to add file a document object in more than one folder in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisObjectNotFoundException.class)
+ public void siteManagerShouldNotAddInvalidFileToFolder() throws Exception
+ {
+ FileModel randomFile = FileModel.getRandomFileModel(FileType.HTML);
+ randomFile.setCmisLocation("/" + randomFile.getName() + "/");
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .usingResource(randomFile)
+ .addDocumentToFolder(destinationFolder, true);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to add folder object to folder with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisObjectNotFoundException.class)
+ public void siteManagerShouldNotAddInvalidFolderToFolder() throws Exception
+ {
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ FolderModel randomFolder = FolderModel.getRandomFolderModel();
+ randomFolder.setCmisLocation("/" + randomFolder.getName() + "/");
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(sourceFile).assertThat().existsInRepo()
+ .then().addDocumentToFolder(randomFolder, true);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is able to add PWC document to folder with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerShouldAddPWCFileToFolder() throws Exception
+ {
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(sourceFile).assertThat().existsInRepo()
+ .then().checkOut().and().assertThat().documentIsCheckedOut()
+ .usingPWCDocument().addDocumentToFolder(destinationFolder, true)
+ .and().assertThat().existsInRepo()
+ .and().assertThat().documentIsCheckedOut();
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is able to add document object to folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanAddDocumentWithVersionsToFolderWithTrueAllVersions() throws Exception
+ {
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(sourceFile).assertThat().existsInRepo()
+ .then().update("first content").update("second content")
+ .and().assertThat().documentHasVersion(1.2)
+ .then().addDocumentToFolder(destinationFolder, true)
+ .and().assertThat().existsInRepo()
+ .and().assertThat().documentHasVersion(1.2);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to add document object to folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisInvalidArgumentException.class,
+ expectedExceptionsMessageRegExp="Only allVersions=true supported!*")
+ public void siteManagerCannotAddDocumentToFolderWithFalseAllVersions() throws Exception
+ {
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(sourceFile).assertThat().existsInRepo()
+ .then().update("update content")
+ .and().assertThat().documentHasVersion(1.1)
+ .then().addDocumentToFolder(destinationFolder, false);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to add document object to folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorCanAddFileToFolderCreatedByHimself() throws Exception
+ {
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingSite(testSite)
+ .createFile(sourceFile).assertThat().existsInRepo()
+ .then().addDocumentToFolder(destinationFolder, true)
+ .and().assertThat().existsInRepo()
+ .and().assertThat().objectIdIs(sourceFile.getNodeRef());
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to add document object created by manager to folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorCanAddFileToFolderCreatedByManager() throws Exception
+ {
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser)
+ .usingSite(testSite)
+ .createFile(sourceFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .then().addDocumentToFolder(destinationFolder, true)
+ .and().assertThat().existsInRepo();
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site contributor is able to add document object to folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorCanAddFileToFolderCreatedByHimself() throws Exception
+ {
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingSite(testSite)
+ .createFile(sourceFile).assertThat().existsInRepo()
+ .then().addDocumentToFolder(destinationFolder, true)
+ .and().assertThat().existsInRepo()
+ .and().assertThat().objectIdIs(sourceFile.getNodeRef());
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site contributor is able to add document object created by manager to folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorCanAddFileToFolderCreatedByManager() throws Exception
+ {
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser)
+ .usingSite(testSite)
+ .createFile(sourceFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .then().addDocumentToFolder(destinationFolder, true)
+ .and().assertThat().existsInRepo();
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site consumer is able to add document object created by manager to folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void consumerCanAddFileToFolderCreatedByManager() throws Exception
+ {
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser)
+ .usingSite(testSite)
+ .createFile(sourceFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .then().addDocumentToFolder(destinationFolder, true);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify non invited user is not able to delete parent folder with multiple children in private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonInvitedUserCannotDeleteFolderTreeInPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingUser(testUser).createPrivateRandomSite();
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ destinationFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(testUser)
+ .usingSite(privateSite)
+ .createFolder(destinationFolder).assertThat().existsInRepo()
+ .createFile(sourceFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .then().addDocumentToFolder(destinationFolder, true);
+ }
+}
+
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/AllowableActionTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/AllowableActionTests.java
new file mode 100644
index 00000000000..3047a32441f
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/AllowableActionTests.java
@@ -0,0 +1,217 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.FolderModel;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.enums.Action;
+import org.apache.chemistry.opencmis.commons.enums.VersioningState;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class AllowableActionTests extends CmisTest
+{
+ UserModel testUser;
+ SiteModel testSite;
+ FileModel testFile, managerFile;
+ FolderModel testFolder, managerFolder;
+ private DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ managerFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ managerFolder = FolderModel.getRandomFolderModel();
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createPublicRandomSite();
+ usersWithRoles = dataUser.usingUser(testUser)
+ .addUsersWithRolesToSite(testSite, UserRole.SiteContributor, UserRole.SiteCollaborator, UserRole.SiteConsumer);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(managerFile).assertThat().existsInRepo()
+ .createFolder(managerFolder).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify valid document has allowable action CAN_CHECK_OUT")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void verifyValidDocumentHasAllowableActionCanCheckOut() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingResource(managerFile)
+ .assertThat().hasAllowableActions(Action.CAN_CHECK_OUT)
+ .then().assertThat().isAllowableActionInList(Action.CAN_APPLY_ACL, Action.CAN_DELETE_CONTENT_STREAM, Action.CAN_GET_ALL_VERSIONS);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify valid folder has allowable action CAN_GET_CHILDREN, CAN_CREATE_FOLDER")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void verifyValidFolderHasAllowableAction() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(testUser).usingResource(managerFolder)
+ .assertThat().hasAllowableActions(Action.CAN_GET_CHILDREN, Action.CAN_CREATE_FOLDER);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify pwc document has allowable action CAN_CHECK_IN, CAN_CANCEL_CHECK_OUT and CAN_MOVE_OBJECT")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void verifyPWCDocumentHasAllowable() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile, VersioningState.CHECKEDOUT)
+ .assertThat().existsInRepo().and().assertThat().documentIsCheckedOut()
+ .usingPWCDocument()
+ .assertThat().hasAllowableActions(Action.CAN_CHECK_IN, Action.CAN_MOVE_OBJECT, Action.CAN_CANCEL_CHECK_OUT)
+ .and().assertThat().isAllowableActionInList(Action.CAN_CHECK_IN, Action.CAN_GET_CONTENT_STREAM, Action.CAN_CANCEL_CHECK_OUT);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify valid folder does not have allowable action CAN_CHECK_IN, CAN_CHECK_OUT, CAN_CANCEL_CHECK_OUT")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void verifyFolderDoesNotHaveCanCheckInAction() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(testUser).usingResource(managerFolder)
+ .assertThat().doesNotHaveAllowableActions(Action.CAN_CHECK_IN, Action.CAN_CHECK_OUT, Action.CAN_CANCEL_CHECK_OUT);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify delete document has allowable actions")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisObjectNotFoundException.class)
+ public void verifyDeletedDocumentHasAllowableActions() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().delete()
+ .and().assertThat().hasAllowableActions(Action.CAN_CHECK_IN, Action.CAN_MOVE_OBJECT, Action.CAN_CANCEL_CHECK_OUT);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify delete document has allowable actions")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisObjectNotFoundException.class)
+ public void verifyDeletedDocumentGetAllowableActions() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().delete()
+ .and().assertThat().isAllowableActionInList(Action.CAN_CHECK_IN, Action.CAN_MOVE_OBJECT, Action.CAN_CANCEL_CHECK_OUT);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify checked out document does not have allowable action CAN_CHECK_IN, CAN_CANCEL_CHECK_OUT")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void verifyCheckedOutDocumentHasAllowable() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile, VersioningState.CHECKEDOUT)
+ .assertThat().existsInRepo().and().assertThat().documentIsCheckedOut()
+ .usingResource(testFile)
+ .assertThat().hasAllowableActions(Action.CAN_GET_ALL_VERSIONS, Action.CAN_GET_CONTENT_STREAM, Action.CAN_GET_ACL, Action.CAN_GET_PROPERTIES)
+ .and().assertThat().doesNotHaveAllowableActions(Action.CAN_CHECK_IN, Action.CAN_CANCEL_CHECK_OUT);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify contributor can get allowable and not allowable actions for content created by mananger")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorGetAllowableActionForContentCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingResource(managerFile)
+ .assertThat().hasAllowableActions(Action.CAN_GET_PROPERTIES, Action.CAN_GET_ACL, Action.CAN_GET_CONTENT_STREAM)
+ .assertThat().doesNotHaveAllowableActions(Action.CAN_DELETE_OBJECT, Action.CAN_CHECK_OUT, Action.CAN_CHECK_IN, Action.CAN_MOVE_OBJECT)
+ .assertThat().isAllowableActionInList(Action.CAN_GET_PROPERTIES, Action.CAN_GET_ACL, Action.CAN_GET_CONTENT_STREAM)
+ .usingResource(managerFolder)
+ .assertThat().hasAllowableActions(Action.CAN_GET_FOLDER_PARENT, Action.CAN_GET_FOLDER_TREE, Action.CAN_CREATE_FOLDER)
+ .assertThat().doesNotHaveAllowableActions(Action.CAN_DELETE_OBJECT, Action.CAN_DELETE_TREE, Action.CAN_MOVE_OBJECT)
+ .assertThat().isAllowableActionInList(Action.CAN_GET_FOLDER_PARENT, Action.CAN_GET_FOLDER_TREE, Action.CAN_CREATE_FOLDER);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify collaborator can get allowable and not allowable actions for content created by mananger")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorGetAllowableActionForContentCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingResource(managerFile)
+ .assertThat().hasAllowableActions(Action.CAN_UPDATE_PROPERTIES, Action.CAN_GET_ACL, Action.CAN_CHECK_OUT, Action.CAN_ADD_OBJECT_TO_FOLDER)
+ .assertThat().doesNotHaveAllowableActions(Action.CAN_DELETE_OBJECT, Action.CAN_MOVE_OBJECT)
+ .assertThat().isAllowableActionInList(Action.CAN_GET_PROPERTIES, Action.CAN_GET_ACL, Action.CAN_GET_CONTENT_STREAM,
+ Action.CAN_UPDATE_PROPERTIES, Action.CAN_CHECK_OUT, Action.CAN_ADD_OBJECT_TO_FOLDER)
+ .usingResource(managerFolder)
+ .assertThat().hasAllowableActions(Action.CAN_GET_FOLDER_PARENT, Action.CAN_GET_FOLDER_TREE, Action.CAN_CREATE_FOLDER, Action.CAN_UPDATE_PROPERTIES)
+ .assertThat().doesNotHaveAllowableActions(Action.CAN_DELETE_OBJECT, Action.CAN_DELETE_TREE, Action.CAN_MOVE_OBJECT)
+ .assertThat().isAllowableActionInList(Action.CAN_GET_FOLDER_PARENT, Action.CAN_GET_FOLDER_TREE, Action.CAN_CREATE_FOLDER,Action.CAN_UPDATE_PROPERTIES);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify consumer can get allowable and not allowable actions for content created by mananger")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void consumerGetAllowableActionForContentCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .usingResource(managerFile)
+ .assertThat().hasAllowableActions(Action.CAN_GET_PROPERTIES, Action.CAN_GET_ACL, Action.CAN_GET_ALL_VERSIONS, Action.CAN_ADD_OBJECT_TO_FOLDER)
+ .assertThat().doesNotHaveAllowableActions(Action.CAN_DELETE_OBJECT, Action.CAN_MOVE_OBJECT, Action.CAN_CHECK_OUT)
+ .assertThat().isAllowableActionInList(Action.CAN_GET_PROPERTIES, Action.CAN_GET_ACL, Action.CAN_GET_ALL_VERSIONS, Action.CAN_ADD_OBJECT_TO_FOLDER)
+ .usingResource(managerFolder)
+ .assertThat().hasAllowableActions(Action.CAN_GET_FOLDER_PARENT, Action.CAN_GET_FOLDER_TREE, Action.CAN_GET_DESCENDANTS)
+ .assertThat().doesNotHaveAllowableActions(Action.CAN_DELETE_OBJECT, Action.CAN_DELETE_TREE, Action.CAN_MOVE_OBJECT)
+ .assertThat().isAllowableActionInList(Action.CAN_GET_FOLDER_PARENT, Action.CAN_GET_FOLDER_TREE, Action.CAN_GET_DESCENDANTS);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify consumer can get allowable and not allowable actions for content created by mananger")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void nonInvitedUserCanGetAllowableActionForContentCreatedByManager() throws Exception
+ {
+ UserModel nonInvitedUser = dataUser.createRandomTestUser();
+ cmisApi.authenticateUser(nonInvitedUser)
+ .usingResource(managerFile)
+ .assertThat().hasAllowableActions(Action.CAN_GET_PROPERTIES, Action.CAN_GET_ACL, Action.CAN_GET_ALL_VERSIONS, Action.CAN_ADD_OBJECT_TO_FOLDER)
+ .assertThat().doesNotHaveAllowableActions(Action.CAN_DELETE_OBJECT, Action.CAN_MOVE_OBJECT, Action.CAN_CHECK_OUT)
+ .assertThat().isAllowableActionInList(Action.CAN_GET_PROPERTIES, Action.CAN_GET_ACL, Action.CAN_GET_ALL_VERSIONS, Action.CAN_ADD_OBJECT_TO_FOLDER)
+ .usingResource(managerFolder)
+ .assertThat().hasAllowableActions(Action.CAN_GET_FOLDER_PARENT, Action.CAN_GET_FOLDER_TREE, Action.CAN_GET_DESCENDANTS)
+ .assertThat().doesNotHaveAllowableActions(Action.CAN_DELETE_OBJECT, Action.CAN_DELETE_TREE, Action.CAN_MOVE_OBJECT)
+ .assertThat().isAllowableActionInList(Action.CAN_GET_FOLDER_PARENT, Action.CAN_GET_FOLDER_TREE, Action.CAN_GET_DESCENDANTS);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify non invited user is not able to get allowable actions from private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonInvitedUserOnPrivateSiteCannotGetAllowableActions() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ SiteModel privateSite = dataSite.usingUser(testUser).createPrivateRandomSite();
+ cmisApi.authenticateUser(testUser).usingSite(privateSite).createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .usingResource(testFile)
+ .assertThat().hasAllowableActions(Action.CAN_GET_PROPERTIES);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify non invited user is not able to get allowable actions from private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonInvitedUserOnModeratedSiteCannotGetAllowableActions() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ SiteModel moderatedSite = dataSite.usingUser(testUser).createModeratedRandomSite();
+ cmisApi.authenticateUser(testUser).usingSite(moderatedSite).createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .usingResource(testFile)
+ .assertThat().hasAllowableActions(Action.CAN_GET_PROPERTIES);
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/AppendContentStreamTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/AppendContentStreamTests.java
new file mode 100644
index 00000000000..1cc3f5b753d
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/AppendContentStreamTests.java
@@ -0,0 +1,240 @@
+package org.alfresco.cmis;
+
+import org.alfresco.cmis.exception.InvalidCmisObjectException;
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.*;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUpdateConflictException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * Created by Claudia Agache on 9/26/2016.
+ */
+public class AppendContentStreamTests extends CmisTest
+{
+ UserModel siteManager;
+ SiteModel publicSite, privateSite;
+ FileModel testFile;
+ String initialContent = "initial content ";
+ String textToAppend = "text to append";
+ private DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ siteManager = dataUser.createRandomTestUser();
+ publicSite = dataSite.usingUser(siteManager).createPublicRandomSite();
+ privateSite = dataSite.usingUser(siteManager).createPrivateRandomSite();
+ usersWithRoles = dataUser.addUsersWithRolesToSite(publicSite, UserRole.SiteManager, UserRole.SiteContributor, UserRole.SiteCollaborator, UserRole.SiteConsumer);
+ }
+
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify site manager is able to append content to a not empty file in DocumentLibrary with CMIS")
+ public void siteManagerShouldAppendContentToNotEmptyFile() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, initialContent);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite).createFile(testFile).assertThat().existsInRepo()
+ .and().assertThat().contentIs(initialContent)
+ .then().update(textToAppend)
+ .assertThat().contentIs(initialContent + textToAppend);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisObjectNotFoundException.class)
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify user is not able to append content to a non existent Document in DocumentLibrary with CMIS")
+ public void userShouldNotAppendContentToNonexistentFile() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, initialContent);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite).createFile(testFile)
+ .assertThat().existsInRepo()
+ .and().assertThat().contentIs(initialContent)
+ .then().delete()
+ .and().assertThat().doesNotExistInRepo()
+ .then().update(textToAppend);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to append content to an empty file with version with CMIS")
+ public void siteManagerCanAppendContentToEmptyFileWithVersion() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, initialContent);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .and().assertThat().contentIs(initialContent)
+ .then().setContent("")
+ .assertThat().contentIs("")
+ .refreshResource()
+ .then().update(textToAppend)
+ .and().assertThat().contentIs(textToAppend);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to append content to an empty file with no version in DocumentLibrary with CMIS")
+ public void siteManagerCanAppendContentToEmptyFileWithNoVersion() throws Exception
+ {
+ FileModel emptyFile = FileModel.getRandomFileModel(FileType.HTML);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(emptyFile).assertThat().existsInRepo()
+ .and().assertThat().contentIs("")
+ .then().update(textToAppend)
+ .and().assertThat().contentIs(textToAppend);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to append content with last chunk parameter set to FALSE with CMIS")
+ public void siteManagerCanAppendContentWithLastChunkSetToFalse() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, initialContent);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .and().assertThat().contentIs(initialContent)
+ .then().update(textToAppend, false)
+ .and().assertThat().contentIs(initialContent + textToAppend);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify admin is able to append content to a file created by other user in DocumentLibrary with CMIS")
+ public void adminShouldAppendContentToFileCreatedByOtherUser() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, initialContent);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite).createFile(testFile).assertThat().existsInRepo()
+ .and().assertThat().contentIs(initialContent)
+ .then().authenticateUser(dataUser.getAdminUser()).update(textToAppend)
+ .assertThat().contentIs(initialContent + textToAppend);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to append content to a file created by other user in DocumentLibrary with CMIS")
+ public void siteManagerShouldAppendContentToFileCreatedByOtherUser() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, initialContent);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite).createFile(testFile).assertThat().existsInRepo()
+ .and().assertThat().contentIs(initialContent)
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager)).update(textToAppend)
+ .assertThat().contentIs(initialContent + textToAppend);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site contributor is able to append content to a file created by self in DocumentLibrary with CMIS")
+ public void contributorShouldAppendContentToFileCreatedBySelf() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, initialContent);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingSite(publicSite).createFile(testFile).assertThat().existsInRepo()
+ .and().assertThat().contentIs(initialContent)
+ .then().update(textToAppend)
+ .assertThat().contentIs(initialContent + textToAppend);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site contributor is not able to append content to a file created by other user in DocumentLibrary with CMIS")
+ public void contributorCannotAppendContentToFileCreatedByOtherUser() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, initialContent);
+ cmisApi.authenticateUser(siteManager)
+ .usingSite(publicSite).createFile(testFile).assertThat().existsInRepo()
+ .and().assertThat().contentIs(initialContent)
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).update(textToAppend);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to append content to a file created by other user in DocumentLibrary with CMIS")
+ public void collaboratorShouldAppendContentToFileCreatedByOtherUser() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, initialContent);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite).createFile(testFile).assertThat().existsInRepo()
+ .and().assertThat().contentIs(initialContent)
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).update(textToAppend)
+ .assertThat().contentIs(initialContent + textToAppend);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to append content to a file created by self in DocumentLibrary with CMIS")
+ public void collaboratorShouldAppendContentToFileCreatedBySelf() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, initialContent);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingSite(publicSite).createFile(testFile).assertThat().existsInRepo()
+ .and().assertThat().contentIs(initialContent)
+ .then().update(textToAppend)
+ .assertThat().contentIs(initialContent + textToAppend);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site consumer is not able to append content to a file with CMIS")
+ public void consumerCannotAppendContentToFile() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, initialContent);
+ cmisApi.authenticateUser(siteManager)
+ .usingSite(publicSite).createFile(testFile).assertThat().existsInRepo()
+ .and().assertThat().contentIs(initialContent)
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer)).update(textToAppend);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = CmisUpdateConflictException.class, expectedExceptionsMessageRegExp = "^.*Cannot perform operation since the node.*is locked.$")
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to append content to a checked out file with CMIS")
+ public void managerCannotAppendContentToCheckedOutFile() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, initialContent);
+ cmisApi.authenticateUser(siteManager)
+ .usingSite(publicSite).createFile(testFile).assertThat().existsInRepo()
+ .then().checkOut().assertThat().documentIsCheckedOut()
+ .when().update(textToAppend);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to append content to a PWC file with CMIS")
+ public void managerCanAppendContentToPWCFile() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, initialContent);
+ cmisApi.authenticateUser(siteManager)
+ .usingSite(publicSite).createFile(testFile).assertThat().existsInRepo()
+ .then().checkOut().assertThat().documentIsCheckedOut()
+ .usingPWCDocument().update(textToAppend)
+ .assertThat().contentIs(initialContent + textToAppend);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify unauthorized user is not able to append content to a file created in a private site with CMIS")
+ public void unauthorizedUserCannotAppendContentToFileFromPrivateSite() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, initialContent);
+ cmisApi.authenticateUser(siteManager)
+ .usingSite(privateSite).createFile(testFile).assertThat().existsInRepo()
+ .and().assertThat().contentIs(initialContent)
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager))
+ .usingResource(testFile).update(textToAppend);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify user is not able to append content to an invalid file with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = InvalidCmisObjectException.class, expectedExceptionsMessageRegExp = "^Content at.*is not a file$")
+ public void userCannotAppendContentOfInvalidFile() throws Exception
+ {
+ FolderModel testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFolder(testFolder).assertThat().existsInRepo()
+ .update(textToAppend);
+ }
+
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/CancelCheckOutTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/CancelCheckOutTests.java
new file mode 100644
index 00000000000..55f1971607c
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/CancelCheckOutTests.java
@@ -0,0 +1,154 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.enums.VersioningState;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class CancelCheckOutTests extends CmisTest
+{
+ UserModel siteManager;
+ SiteModel testSite;
+ FileModel testFile;
+ private String fileContent = "content";
+ private DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ siteManager = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(siteManager).createPublicRandomSite();
+ usersWithRoles = dataUser.addUsersWithRolesToSite(testSite, UserRole.SiteContributor, UserRole.SiteCollaborator);
+ }
+
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify cancel check out on a pwc")
+ public void cancelCheckOutOnPWC() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(siteManager).usingSite(testSite)
+ .createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .then().checkOut().and().assertThat().documentIsCheckedOut()
+ .and().assertThat().isPrivateWorkingCopy()
+ .then().cancelCheckOut()
+ .and().assertThat().isNotPrivateWorkingCopy()
+ .and().assertThat().existsInRepo()
+ .and().assertThat().documentIsNotCheckedOut();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify cancel check out on a document that isn't checked out")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = CmisRuntimeException.class)
+ public void cancelCheckOutOnADocumentThatIsntCheckedOut() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(siteManager).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .and().assertThat().isNotPrivateWorkingCopy()
+ .then().cancelCheckOut();
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisObjectNotFoundException.class)
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify cancel check out on deleted document")
+ public void cancelCheckOutOnDeletedDocument() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(siteManager).usingSite(testSite)
+ .createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .then().delete().and().assertThat().doesNotExistInRepo()
+ .then().cancelCheckOut();
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisRuntimeException.class)
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify cancel check out on a pwc twice")
+ public void cancelCheckOutTwice() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(siteManager).usingSite(testSite)
+ .createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .and().checkOut()
+ .and().assertThat().documentIsCheckedOut().assertThat().isPrivateWorkingCopy()
+ .and().cancelCheckOut()
+ .cancelCheckOut();
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify that cancel check out on document created with Versioning State CHECKED OUT deletes the document")
+ public void cancelCheckOutOnDocWithVersioningStateCheckedOut() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(siteManager).usingSite(testSite)
+ .createFile(testFile, VersioningState.CHECKEDOUT)
+ .and().assertThat().existsInRepo().assertThat().documentIsCheckedOut()
+ .then().usingPWCDocument()
+ .cancelCheckOut()
+ .and().assertThat().doesNotExistInRepo()
+ .usingResource(testFile).assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify that collaborator user can cancel check out on document created by self")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorCanCancelCheckInDocumentCreatedBySelf() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingSite(testSite)
+ .createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .and().checkOut()
+ .and().assertThat().documentIsCheckedOut()
+ .and().cancelCheckOut()
+ .and().assertThat().documentIsNotCheckedOut()
+ .then().assertThat().documentHasVersion(1.0);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify that collaborator user can cancel check out on document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorCanCancelCheckInDocumentCreatedByManager() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(siteManager).usingSite(testSite)
+ .createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .and().checkOut()
+ .and().assertThat().documentIsCheckedOut()
+ .and().cancelCheckOut()
+ .and().assertThat().documentIsNotCheckedOut()
+ .then().assertThat().documentHasVersion(1.0);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify that contributor user can cancel check out on document created by self")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorCanCancelCheckInDocumentCreatedBySelf() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingSite(testSite)
+ .createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .and().checkOut()
+ .and().assertThat().documentIsCheckedOut()
+ .and().cancelCheckOut()
+ .and().assertThat().documentIsNotCheckedOut()
+ .then().assertThat().documentHasVersion(1.0);
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/CheckInTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/CheckInTests.java
new file mode 100644
index 00000000000..f28b3e1233b
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/CheckInTests.java
@@ -0,0 +1,329 @@
+package org.alfresco.cmis;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.alfresco.utility.Utility;
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.PropertyIds;
+import org.apache.chemistry.opencmis.commons.enums.VersioningState;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisVersioningException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class CheckInTests extends CmisTest
+{
+ UserModel unauthorizedUser;
+ UserModel siteManager;
+ SiteModel testSite;
+ FileModel testFile;
+ private String fileContent = "content";
+ private DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ unauthorizedUser = dataUser.createRandomTestUser();
+ siteManager = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(siteManager).createPublicRandomSite();
+ usersWithRoles = dataUser.addUsersWithRolesToSite(testSite, UserRole.SiteContributor, UserRole.SiteCollaborator);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify check in document with minor version and no content")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void checkInDocumentWithMinorVersionAndNoContent() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(siteManager).usingSite(testSite)
+ .createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .and().checkOut()
+ .and().assertThat().documentIsCheckedOut()
+ .and().prepareDocumentForCheckIn()
+ .withMinorVersion()
+ .checkIn().refreshResource()
+ .and().assertThat().documentIsNotCheckedOut()
+ .then().assertThat().documentHasVersion(1.1);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify check in document with minor version and with content")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void checkInDocumentWithMinorVersionAndWithContent() throws Exception
+ {
+ String newContent = "new minor content";
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(siteManager).usingSite(testSite).createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .and().checkOut()
+ .and().assertThat().documentIsCheckedOut()
+ .assertThat().isPrivateWorkingCopy()
+ .and().prepareDocumentForCheckIn()
+ .withMinorVersion()
+ .withContent(newContent)
+ .checkIn()
+ .and().assertThat().documentIsNotCheckedOut()
+ .then().assertThat().documentHasVersion(1.1)
+ .and().assertThat().contentIs(newContent);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify check in document with major version and no content")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void checkInDocumentWithMajorVersionAndNoContent() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(siteManager).usingSite(testSite).createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .and().checkOut()
+ .and().assertThat().documentIsCheckedOut()
+ .and().prepareDocumentForCheckIn()
+ .withMajorVersion()
+ .checkIn().refreshResource()
+ .and().assertThat().documentIsNotCheckedOut()
+ .then().assertThat().documentHasVersion(2.0);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify check in document with major version and with content")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void checkInDocumentWithMajorVersionAndWithContent() throws Exception
+ {
+ String newContent = "new major content";
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(siteManager).usingSite(testSite).createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .and().checkOut()
+ .and().assertThat().documentIsCheckedOut()
+ .and().prepareDocumentForCheckIn()
+ .withMajorVersion()
+ .withContent(newContent)
+ .checkIn().refreshResource()
+ .and().assertThat().documentIsNotCheckedOut()
+ .then().assertThat().documentHasVersion(2.0);
+ Utility.sleep(100, 5000, () ->
+ cmisApi.assertThat().contentIs(newContent));
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify check in document that wasn't checked out")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = CmisVersioningException.class)
+ public void checkInDocumentThatWasntCheckedOut() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(siteManager).usingSite(testSite).createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .and().assertThat().documentIsNotCheckedOut()
+ .then().prepareDocumentForCheckIn()
+ .checkIn();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify check in comment for document with major version")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void getCheckInCommentForDocMajorVersion() throws Exception
+ {
+ String newContent = "new major content";
+ String comment = "major version comment";
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(siteManager).usingSite(testSite).createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .and().checkOut()
+ .and().assertThat().documentIsCheckedOut()
+ .and().prepareDocumentForCheckIn()
+ .withMajorVersion()
+ .withContent(newContent)
+ .withComment(comment)
+ .checkIn().refreshResource()
+ .and().assertThat().documentIsNotCheckedOut()
+ .then().assertThat().documentHasVersion(2.0)
+ .and().assertThat().contentIs(newContent)
+ .assertThat().hasCheckInCommentLastVersion(comment);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify check in comments for multiple versions")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void getCheckInCommentForDocWithMultipleVersions() throws Exception
+ {
+ String minorComment = "minor version comment";
+ String majorComment = "major version comment";
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(siteManager).usingSite(testSite).createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .and().checkOut()
+ .then().prepareDocumentForCheckIn()
+ .withMinorVersion()
+ .withContent("minor content")
+ .withComment(minorComment)
+ .checkIn().refreshResource()
+ .and().assertThat().documentIsNotCheckedOut()
+ .and().assertThat().hasCheckInCommentForVersion(1.1, minorComment)
+ .then().checkOut().prepareDocumentForCheckIn()
+ .withMajorVersion()
+ .withContent("major content")
+ .withComment(majorComment)
+ .checkIn().refreshResource()
+ .and().assertThat().documentIsNotCheckedOut()
+ .and().assertThat().hasCheckInCommentForVersion(2.0, majorComment);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify check in document with minor version and no content")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisVersioningException.class)
+ public void checkInDocumentTwice() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(siteManager).usingSite(testSite)
+ .createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .and().checkOut()
+ .and().assertThat().documentIsCheckedOut()
+ .and().prepareDocumentForCheckIn()
+ .withMinorVersion()
+ .checkIn()
+ .prepareDocumentForCheckIn()
+ .checkIn();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify check in document created with VersioningState checkedout")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void checkInDocumentCreatedWithVersioningStateCheckedOut() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(siteManager).usingSite(testSite)
+ .createFile(testFile, VersioningState.CHECKEDOUT)
+ .and().assertThat().existsInRepo().assertThat().documentIsCheckedOut()
+ .then().prepareDocumentForCheckIn()
+ .withMinorVersion()
+ .withContent("minor content")
+ .checkIn().refreshResource()
+ .and().assertThat().documentIsNotCheckedOut()
+ .then().assertThat().documentHasVersion(1.1);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify check in for deleted document")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisObjectNotFoundException.class)
+ public void checkInDeletedDocument() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(siteManager).usingSite(testSite)
+ .createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .then().delete().assertThat().doesNotExistInRepo()
+ .then().prepareDocumentForCheckIn()
+ .withMinorVersion()
+ .withContent("minor content")
+ .checkIn();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify check in document created with VersioningState checkedout")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void checkInDocumentWithProperties() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+
+ Map properties = new HashMap();
+ properties.put(PropertyIds.NAME, testFile.getName() + "-edit");
+ properties.put("cm:title", testFile.getName() + "-title");
+ properties.put("cm:description", "description after checkout");
+
+ cmisApi.authenticateUser(siteManager).usingSite(testSite)
+ .createFile(testFile, VersioningState.CHECKEDOUT)
+ .and().assertThat().existsInRepo().assertThat().documentIsCheckedOut()
+ .then().prepareDocumentForCheckIn()
+ .withMinorVersion()
+ .withContent("minor content")
+ .checkIn(properties).refreshResource()
+ .and().assertThat().documentIsNotCheckedOut()
+ .then().assertThat().documentHasVersion(1.1)
+ .and().assertThat().contentPropertyHasValue("cmis:description", "description after checkout")
+ .assertThat().contentPropertyHasValue("cmis:name", testFile.getName() + "-edit")
+ .assertThat().contentPropertyHasValue("cm:title", testFile.getName() + "-title");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify check in document created with VersioningState checkedout")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=IllegalArgumentException.class)
+ public void checkInDocumentWithInvalidProperties() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ Map properties = new HashMap();
+ properties.put("cmis:fakeProp","fake-value");
+ cmisApi.authenticateUser(siteManager).usingSite(testSite)
+ .createFile(testFile, VersioningState.CHECKEDOUT)
+ .and().assertThat().existsInRepo().assertThat().documentIsCheckedOut()
+ .then().prepareDocumentForCheckIn()
+ .withMinorVersion()
+ .withContent("minor content")
+ .checkIn(properties).refreshResource();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify that contributor user can check in document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorCanCheckInDocumentCreatedBySelf() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingSite(testSite)
+ .createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .and().checkOut()
+ .and().assertThat().documentIsCheckedOut()
+ .and().prepareDocumentForCheckIn()
+ .withMinorVersion()
+ .checkIn().refreshResource()
+ .and().assertThat().documentIsNotCheckedOut()
+ .then().assertThat().documentHasVersion(1.1);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify that collaborator user can check in document created by self")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorCanCheckInDocumentCreatedBySelf() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingSite(testSite)
+ .createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .and().checkOut()
+ .and().assertThat().documentIsCheckedOut()
+ .and().prepareDocumentForCheckIn()
+ .withMinorVersion()
+ .checkIn().refreshResource()
+ .and().assertThat().documentIsNotCheckedOut()
+ .then().assertThat().documentHasVersion(1.1);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify that collaborator user can check in document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorCanCheckInDocumentCreatedByManager() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(siteManager).usingSite(testSite)
+ .createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .and().checkOut()
+ .and().assertThat().documentIsCheckedOut()
+ .and().prepareDocumentForCheckIn()
+ .withMinorVersion()
+ .checkIn().refreshResource()
+ .and().assertThat().documentIsNotCheckedOut()
+ .then().assertThat().documentHasVersion(1.1);
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/CheckOutTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/CheckOutTests.java
new file mode 100644
index 00000000000..95affaa4cac
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/CheckOutTests.java
@@ -0,0 +1,148 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.exceptions.*;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class CheckOutTests extends CmisTest
+{
+ UserModel unauthorizedUser;
+ UserModel siteManager;
+ SiteModel testSite;
+ FileModel testFile;
+ private String fileContent = "content";
+ private DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ unauthorizedUser = dataUser.createRandomTestUser();
+ siteManager = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(siteManager).createPublicRandomSite();
+ usersWithRoles = dataUser.addUsersWithRolesToSite(testSite, UserRole.SiteContributor, UserRole.SiteConsumer);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify check out valid document")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void verifyCheckOutValidDocument() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(siteManager).usingSite(testSite).createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .and().checkOut()
+ .then().assertThat().documentIsCheckedOut()
+ .and().assertThat().isPrivateWorkingCopy();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify check out inexistent document")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = CmisObjectNotFoundException.class)
+ public void verifyCheckOutInexistentDocument() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(siteManager).usingSite(testSite).createFile(testFile)
+ .and().delete().assertThat().doesNotExistInRepo()
+ .then().checkOut();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify if PWC is created for document that is not checked out")
+ @Test(groups = {TestGroup.REGRESSION, TestGroup.CMIS})
+ public void verifyPWCForDocThatIsNotCheckedOut() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(siteManager).usingSite(testSite).createFile(testFile).assertThat().isNotPrivateWorkingCopy();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify error when a document is checked out twice")
+ @Test(groups = {TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisVersioningException.class, expectedExceptionsMessageRegExp = "^Check out failed.*This node is already checked out.$")
+ public void checkOutDocumentTwice() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(siteManager).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().checkOut().assertThat().documentIsCheckedOut()
+ .then().checkOut();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify private working copy does NOT exists for a document that was deleted")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void verifyPWCDoesNotExistsForDeletedDocument() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(siteManager).usingSite(testSite).createFile(testFile)
+ .and().checkOut()
+ .then().assertThat().documentIsCheckedOut()
+ .usingPWCDocument()
+ .delete()
+ .and().assertThat().doesNotExistInRepo()
+ .then().usingResource(testFile)
+ .assertThat().isNotPrivateWorkingCopy().and().assertThat().documentIsNotCheckedOut();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify that contributor user can NOT check out document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = { CmisUnauthorizedException.class, CmisPermissionDeniedException.class })
+ public void contributorCannotCheckOutDocumentCreatedByManager() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(siteManager).usingSite(testSite)
+ .createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .and().checkOut();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify that consumer user can NOT check out document")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = { CmisUnauthorizedException.class, CmisPermissionDeniedException.class })
+ public void consumerCannotCheckOutDocument() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(siteManager).usingSite(testSite)
+ .createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .and().checkOut();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify that unauthorized user can NOT check out document from private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = { CmisUnauthorizedException.class, CmisPermissionDeniedException.class })
+ public void unauthorizedUserCannotCheckOutDocumentFromPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingUser(siteManager).createPrivateRandomSite();
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(siteManager).usingSite(privateSite)
+ .createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .authenticateUser(unauthorizedUser)
+ .and().checkOut();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify that unauthorized user can NOT check out document from moderated site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = { CmisUnauthorizedException.class, CmisPermissionDeniedException.class })
+ public void unauthorizedUserCannotCheckOutDocumentModeratedSite() throws Exception
+ {
+ SiteModel moderatedSite = dataSite.usingUser(siteManager).createModeratedRandomSite();
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, fileContent);
+ cmisApi.authenticateUser(siteManager).usingSite(moderatedSite)
+ .createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .authenticateUser(unauthorizedUser)
+ .and().checkOut();
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/CmisTest.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/CmisTest.java
new file mode 100644
index 00000000000..cf83810ce95
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/CmisTest.java
@@ -0,0 +1,67 @@
+package org.alfresco.cmis;
+
+import java.lang.reflect.Method;
+
+import org.alfresco.utility.LogFactory;
+import org.alfresco.utility.data.DataContent;
+import org.alfresco.utility.data.DataSite;
+import org.alfresco.utility.data.DataUserAIS;
+import org.alfresco.utility.network.ServerHealth;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.BeforeSuite;
+
+@ContextConfiguration("classpath:alfresco-cmis-context.xml")
+@Component
+@Scope(value = "prototype")
+public abstract class CmisTest extends AbstractTestNGSpringContextTests
+{
+ private static Logger LOG = LogFactory.getLogger();
+
+ @Autowired
+ protected CmisWrapper cmisApi;
+
+ @Autowired
+ protected DataUserAIS dataUser;
+
+ @Autowired
+ protected DataSite dataSite;
+
+ @Autowired
+ protected DataContent dataContent;
+
+ @Autowired
+ ServerHealth serverHealth;
+
+ public String documentContent = "CMIS document content";
+
+ @BeforeSuite(alwaysRun = true)
+ public void checkServerHealth() throws Exception
+ {
+ super.springTestContextPrepareTestInstance();
+ serverHealth.assertServerIsOnline();
+ }
+
+ @BeforeMethod(alwaysRun = true)
+ public void showStartTestInfo(Method method)
+ {
+ LOG.info(String.format("*** STARTING Test: [%s] ***", method.getName()));
+ }
+
+ @AfterMethod(alwaysRun = true)
+ public void showEndTestInfo(Method method)
+ {
+ LOG.info(String.format("*** ENDING Test: [%s] ***", method.getName()));
+ }
+
+ public Integer getSolrWaitTimeInSeconds()
+ {
+ return cmisApi.cmisProperties.envProperty().getSolrWaitTimeInSeconds();
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/CopyTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/CopyTests.java
new file mode 100644
index 00000000000..668c52c039b
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/CopyTests.java
@@ -0,0 +1,318 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.FolderModel;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * Created by Claudia Agache on 9/28/2016.
+ */
+public class CopyTests extends CmisTest
+{
+ UserModel inexistentUser;
+ UserModel unauthorizedUser;
+ UserModel testUser;
+ UserModel contributorUser;
+ UserModel collaboratorUser;
+ UserModel consumerUser;
+ SiteModel testSite;
+ FileModel sourceFile;
+ FolderModel targetFolder, sourceFolder;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ unauthorizedUser = dataUser.createRandomTestUser();
+ testUser = dataUser.createRandomTestUser();
+ contributorUser = dataUser.createRandomTestUser();
+ collaboratorUser = dataUser.createRandomTestUser();
+ consumerUser = dataUser.createRandomTestUser();
+ inexistentUser = new UserModel("inexistent", "inexistent");
+ testSite = dataSite.usingUser(testUser).createPublicRandomSite();
+
+ dataUser.addUserToSite(consumerUser, testSite, UserRole.SiteConsumer);
+ dataUser.addUserToSite(collaboratorUser, testSite, UserRole.SiteCollaborator);
+ dataUser.addUserToSite(contributorUser, testSite, UserRole.SiteContributor);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.SANITY,
+ description = "Verify site manager is able to copy file to an existent location in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerCopyFile() throws Exception
+ {
+ targetFolder = FolderModel.getRandomFolderModel();
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "content");
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(targetFolder).and().assertThat().existsInRepo()
+ .createFile(sourceFile).and().assertThat().existsInRepo()
+ .then().copyTo(targetFolder)
+ .and().assertThat().existsInRepo().usingResource(sourceFile).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.SANITY,
+ description = "Verify site manager is able to copy folder to an existent location in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerCopyFolder() throws Exception
+ {
+ targetFolder = FolderModel.getRandomFolderModel();
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "content");
+ sourceFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(targetFolder).assertThat().existsInRepo()
+ .createFolder(sourceFolder).assertThat().existsInRepo()
+ .then().copyTo(targetFolder)
+ .and().assertThat().existsInRepo().usingResource(sourceFolder).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to copy file to a nonexistent location in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = CmisObjectNotFoundException.class)
+ public void siteManagerCopyFileToNonexistentTarget() throws Exception
+ {
+ targetFolder = FolderModel.getRandomFolderModel();
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "content");
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(sourceFile).assertThat().existsInRepo()
+ .createFolder(targetFolder).and().delete()
+ .then().copyTo(targetFolder);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to copy a nonexistent file in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = CmisObjectNotFoundException.class)
+ public void siteManagerCopyNonexistentSourceFile() throws Exception
+ {
+ targetFolder = FolderModel.getRandomFolderModel();
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "content");
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(targetFolder).assertThat().existsInRepo()
+ .createFile(sourceFile).delete()
+ .then().copyTo(targetFolder);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify non existing user is not able to copy file with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = CmisUnauthorizedException.class)
+ public void nonExistentUserIsNotAbleToCopyFile() throws Exception
+ {
+ targetFolder = FolderModel.getRandomFolderModel();
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "content");
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(targetFolder).and().assertThat().existsInRepo()
+ .createFile(sourceFile).and().assertThat().existsInRepo();
+ cmisApi.authenticateUser(inexistentUser)
+ .then().copyTo(targetFolder);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify non existing user is not able to copy folder with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = CmisUnauthorizedException.class)
+ public void nonExistentUserIsNotAbleToCopyFolder() throws Exception
+ {
+ targetFolder = FolderModel.getRandomFolderModel();
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "content");
+ sourceFolder = FolderModel.getRandomFolderModel();
+
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(targetFolder).assertThat().existsInRepo()
+ .createFolder(sourceFolder).assertThat().existsInRepo();
+ cmisApi.authenticateUser(inexistentUser)
+ .then().copyTo(targetFolder);
+ }
+
+// @Bug(id="ACE-5606")
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that checked out document can be copied with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void checkedOutDocumentCanBeCopied() throws Exception
+ {
+ targetFolder = FolderModel.getRandomFolderModel();
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "content");
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(targetFolder).and().assertThat().existsInRepo()
+ .createFile(sourceFile).and().assertThat().existsInRepo()
+ .then().checkOut()
+ .and().copyTo(targetFolder).refreshResource()
+ .then().assertThat().existsInRepo()
+ .then().usingResource(sourceFile).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that whole folder structure can be copied with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void folderStructureCanBeCopied() throws Exception
+ {
+ targetFolder = FolderModel.getRandomFolderModel();
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "content");
+ FolderModel randomFolder = FolderModel.getRandomFolderModel();
+ sourceFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(targetFolder).and().assertThat().existsInRepo()
+ .createFolder(sourceFolder).and().assertThat().existsInRepo()
+ .usingResource(sourceFolder).createFolder(randomFolder)
+ .then().createFile(sourceFile).and().assertThat().existsInRepo()
+ .then().usingResource(sourceFolder)
+ .copyTo(targetFolder)
+ .and().assertThat().existsInRepo()
+ .assertThat().hasFiles(sourceFile);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that version history of a copied document is not kept with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void versionHistoryIsNotKeptWhenCopyingFile() throws Exception
+ {
+ targetFolder = FolderModel.getRandomFolderModel();
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "content");
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(targetFolder).and().assertThat().existsInRepo()
+ .createFile(sourceFile).and().assertThat().existsInRepo()
+ .then().checkOut().refreshResource()
+ .prepareDocumentForCheckIn()
+ .withContent("First update").checkIn().refreshResource()
+ .and().assertThat().documentHasVersion(1.1)
+ .then().checkOut()
+ .prepareDocumentForCheckIn()
+ .withContent("Second update")
+ .withMajorVersion()
+ .checkIn().refreshResource()
+ .and().assertThat().documentHasVersion(2.0)
+ .then().copyTo(targetFolder)
+ .and().assertThat().existsInRepo()
+ .then().assertThat().documentHasVersion(1.0)
+ .and().assertThat().contentIs("Second update");
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify copy PWC document object")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void managerCopyPWCDocumentObject() throws Exception
+ {
+ sourceFile = dataContent.usingUser(testUser).usingSite(testSite).createContent(FileModel.getRandomFileModel(FileType.TEXT_PLAIN));
+ targetFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ FileModel pwcFile = cmisApi.authenticateUser(testUser).usingResource(sourceFile).checkOut().withCMISUtil().getPWCFileModel();
+ cmisApi.usingResource(pwcFile).copyTo(targetFolder)
+ .usingResource(targetFolder).assertThat().hasChildren(pwcFile);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify contributor can copy Document")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void contributorCanCopyDocument() throws Exception
+ {
+ sourceFile = dataContent.usingUser(testUser).usingSite(testSite).createContent(FileModel.getRandomFileModel(FileType.TEXT_PLAIN));
+ targetFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ cmisApi.authenticateUser(contributorUser).usingResource(sourceFile).copyTo(targetFolder)
+ .usingResource(targetFolder).assertThat().hasChildren(sourceFile);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify contributor can copy Folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void contributorCanCopyFolder() throws Exception
+ {
+ sourceFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ targetFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ cmisApi.authenticateUser(contributorUser).usingResource(sourceFolder).copyTo(targetFolder)
+ .usingResource(targetFolder).assertThat().hasChildren(sourceFolder);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify collaborator can copy Document")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void collaboratorCanCopyDocument() throws Exception
+ {
+ sourceFile = dataContent.usingUser(testUser).usingSite(testSite).createContent(FileModel.getRandomFileModel(FileType.TEXT_PLAIN));
+ targetFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ cmisApi.authenticateUser(collaboratorUser).usingResource(sourceFile).copyTo(targetFolder)
+ .usingResource(targetFolder).assertThat().hasChildren(sourceFile);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify collaborator can copy Folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void collaboratorCanCopyFolder() throws Exception
+ {
+ sourceFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ targetFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ cmisApi.authenticateUser(collaboratorUser).usingResource(sourceFolder).copyTo(targetFolder)
+ .usingResource(targetFolder).assertThat().hasChildren(sourceFolder);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify consumer cannot copy Document")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void consumerCannotCopyDocument() throws Exception
+ {
+ sourceFile = dataContent.usingUser(testUser).usingSite(testSite).createContent(FileModel.getRandomFileModel(FileType.TEXT_PLAIN));
+ targetFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ cmisApi.authenticateUser(consumerUser).usingResource(sourceFile).copyTo(targetFolder)
+ .usingResource(targetFolder).assertThat().hasChildren(sourceFile);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify consumer cannot copy Folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void consumerCannotCopyFolder() throws Exception
+ {
+ sourceFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ targetFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ cmisApi.authenticateUser(consumerUser).usingResource(sourceFolder).copyTo(targetFolder)
+ .usingResource(targetFolder).assertThat().hasChildren(sourceFolder);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify unauthorized user cannot copy Document from private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void unauthorizedUserCannotCopyDocumentFromPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingUser(testUser).createPrivateRandomSite();
+ sourceFile = dataContent.usingUser(testUser).usingSite(privateSite).createContent(FileModel.getRandomFileModel(FileType.TEXT_PLAIN));
+ targetFolder = dataContent.usingUser(testUser).usingSite(privateSite).createFolder();
+ cmisApi.authenticateUser(unauthorizedUser).usingResource(sourceFile).copyTo(targetFolder);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify unauthorized user cannot copy Folder from private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void unauthorizedUserCannotCopyFolderFromPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingUser(testUser).createPrivateRandomSite();
+ sourceFolder = dataContent.usingUser(testUser).usingSite(privateSite).createFolder();
+ targetFolder = dataContent.usingUser(testUser).usingSite(privateSite).createFolder();
+ cmisApi.authenticateUser(unauthorizedUser).usingResource(sourceFolder).copyTo(targetFolder);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify unauthorized user cannot copy Document from moderated site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void unauthorizedUserCannotCopyDocumentFromModeratedSite() throws Exception
+ {
+ SiteModel moderatedSite = dataSite.usingUser(testUser).createModeratedRandomSite();
+ sourceFile = dataContent.usingUser(testUser).usingSite(moderatedSite).createContent(FileModel.getRandomFileModel(FileType.TEXT_PLAIN));
+ targetFolder = dataContent.usingUser(testUser).usingSite(moderatedSite).createFolder();
+ cmisApi.authenticateUser(unauthorizedUser).usingResource(sourceFile).copyTo(targetFolder);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify unauthorized user cannot copy Folder from moderated site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void unauthorizedUserCannotCopyFolderFromModeratedSite() throws Exception
+ {
+ SiteModel moderatedSite = dataSite.usingUser(testUser).createModeratedRandomSite();
+ sourceFolder = dataContent.usingUser(testUser).usingSite(moderatedSite).createFolder();
+ targetFolder = dataContent.usingUser(testUser).usingSite(moderatedSite).createFolder();
+ cmisApi.authenticateUser(unauthorizedUser).usingResource(sourceFolder).copyTo(targetFolder);
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/CreateDocumentFromSourceTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/CreateDocumentFromSourceTests.java
new file mode 100644
index 00000000000..76c214646dc
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/CreateDocumentFromSourceTests.java
@@ -0,0 +1,307 @@
+package org.alfresco.cmis;
+
+import org.alfresco.cmis.exception.InvalidCmisObjectException;
+import org.alfresco.utility.Utility;
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.FolderModel;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.enums.VersioningState;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisContentAlreadyExistsException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * Created by Claudia Agache on 9/26/2016.
+ */
+public class CreateDocumentFromSourceTests extends CmisTest
+{
+ SiteModel publicSite, privateSite;
+ UserModel siteManager;
+ FileModel sourceFile, newFile;
+ String sourceContent = "source content";
+ private DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ siteManager = dataUser.createRandomTestUser();
+ publicSite = dataSite.usingUser(siteManager).createPublicRandomSite();
+ privateSite = dataSite.usingUser(siteManager).createPrivateRandomSite();
+ usersWithRoles = dataUser.addUsersWithRolesToSite(publicSite, UserRole.SiteManager, UserRole.SiteContributor,
+ UserRole.SiteCollaborator, UserRole.SiteConsumer);
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, sourceContent);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite).createFile(sourceFile).and().assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.SANITY,
+ description = "Verify site manager is able to create file from source in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS })
+ public void siteManagerShouldCreateDocumentFromSource() throws Exception
+ {
+ newFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite).createFileFromSource(newFile, sourceFile).and()
+ .refreshResource().then().assertThat().existsInRepo().and().assertThat().contentIs(sourceContent);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify inexistent user isn't able to create file from source in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = CmisUnauthorizedException.class)
+ public void inexistentUserShouldNotCreateDocumentFromSource() throws Exception
+ {
+ newFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ UserModel inexistentUser = new UserModel("inexistent", "inexistent");
+ cmisApi.authenticateUser(inexistentUser).usingSite(publicSite).createFileFromSource(newFile, sourceFile);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.SANITY,
+ description = "Verify unauthorized user isn't able to create file from source in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS }, expectedExceptions = { CmisPermissionDeniedException.class,
+ CmisUnauthorizedException.class })
+ public void unauthorizedUserShouldNotCreateDocumentFromSource() throws Exception
+ {
+ UserModel unauthorizedUser = dataUser.createRandomTestUser();
+ newFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(unauthorizedUser).usingSite(publicSite).createFileFromSource(newFile, sourceFile);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that manager user is not able to create document from source twice in the same location with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = CmisContentAlreadyExistsException.class)
+ public void siteManagerCannotCreateDocumentFromSourceTwice() throws Exception
+ {
+ newFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite).createFileFromSource(newFile, sourceFile).and().assertThat()
+ .existsInRepo().then().usingSite(publicSite).createFileFromSource(newFile, sourceFile);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that admin user is not able to create document from source with invalid source with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = CmisObjectNotFoundException.class)
+ public void adminCannotCreateDocFromInvalidSource() throws Exception
+ {
+ newFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ FileModel sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingSite(publicSite).createFile(sourceFile).and().assertThat()
+ .existsInRepo().then().delete().when().usingResource(sourceFile).createFileFromSource(newFile, sourceFile);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that manager user is not able to create document from source with invalid characters with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = CmisConstraintException.class)
+ public void siteManagerCannotCreateDocFromSourceWithInvalidChars() throws Exception
+ {
+ newFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ FileModel invalidCharDoc = new FileModel("/.:?|\\`\\.txt", FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite).createFileFromSource(invalidCharDoc, sourceFile);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that admin user is not able to create document from source at invalid location with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = CmisObjectNotFoundException.class)
+ public void adminCannotCreateDocumentAtInvalidPath() throws Exception
+ {
+ newFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ FolderModel invalidLocation = new FolderModel("/Shared/invalidFolder");
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingResource(invalidLocation).createFileFromSource(newFile,
+ sourceFile);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to create file from folder source CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = InvalidCmisObjectException.class)
+ public void siteManagerShouldNotCreateDocFromFolderSource() throws Exception
+ {
+ newFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ FolderModel folderSource = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite).createFolder(folderSource).then()
+ .createFileFromSource(newFile, folderSource);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that manager user is not able to create document from source with invalid base type id with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = CmisContentAlreadyExistsException.class)
+ public void siteManagerCannotCreateDocFromSourceWithInvalidBaseTypeId() throws Exception
+ {
+ newFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite).createFileFromSource(newFile, sourceFile).and().assertThat()
+ .existsInRepo().then().usingSite(publicSite).createFileFromSource(newFile, sourceFile, "cmis:fakeType");
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that manager user is not able to create an unnamed document from source with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteManagerCannotCreateUnnamedDocFromSource() throws Exception
+ {
+ newFile = new FileModel("");
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite).createFileFromSource(newFile, sourceFile).then()
+ .usingSite(publicSite).assertThat().doesNotHaveFile(newFile);
+ Utility.sleep(100, 10000, () ->
+ {
+ cmisApi.usingSite(publicSite).assertThat().doesNotHaveFile(newFile);
+ });
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is able to create file from source added by another user with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void anotherSiteManagerShouldCreateDocumentFromSource() throws Exception
+ {
+ newFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager)).usingSite(publicSite)
+ .createFileFromSource(newFile, sourceFile);
+ Utility.sleep(100, 10000, () ->
+ {
+ cmisApi.refreshResource().then().assertThat().existsInRepo().and().assertThat().contentIs(sourceContent);
+ });
+
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site contributor is able to create file from source added by another user with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void contributorShouldCreateDocumentFromSource() throws Exception
+ {
+ newFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingSite(publicSite)
+ .createFileFromSource(newFile, sourceFile);
+ Utility.sleep(100, 10000, () ->
+ {
+ cmisApi.refreshResource().then().assertThat().existsInRepo().and().assertThat().contentIs(sourceContent);
+ });
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to create file from source added by another user with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void collaboratorShouldCreateDocumentFromSource() throws Exception
+ {
+ newFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingSite(publicSite)
+ .createFileFromSource(newFile, sourceFile);
+ Utility.sleep(100, 10000, () ->
+ {
+ cmisApi.refreshResource().then().assertThat().existsInRepo().and()
+ .assertThat().contentIs(sourceContent);
+ });
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site consumer is not able to create file from source with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = { CmisPermissionDeniedException.class,
+ CmisUnauthorizedException.class })
+ public void consumerShouldNotCreateDocumentFromSource() throws Exception
+ {
+ newFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer)).usingSite(publicSite)
+ .createFileFromSource(newFile, sourceFile);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is able to create file from source with versioning state set to Minor with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void managerCreatesDocumentFromSourceWithVersionMinor() throws Exception
+ {
+ newFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFileFromSource(newFile, sourceFile, VersioningState.MINOR);
+ Utility.sleep(100, 10000, () ->
+ {
+ cmisApi.refreshResource().then().assertThat().existsInRepo().and()
+ .assertThat().contentIs(sourceContent).and()
+ .assertThat().documentHasVersion(0.1).and()
+ .assertThat().isNotLatestMajorVersion();
+ });
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is able to create file from source with versioning state set to None with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void managerShouldCreateDocumentFromSourceWithVersionNone() throws Exception
+ {
+ newFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFileFromSource(newFile, sourceFile, VersioningState.NONE);
+ Utility.sleep(100, 35000, () ->
+ {
+ cmisApi.refreshResource().then().assertThat().existsInRepo().and()
+ .assertThat().contentIs(sourceContent).and()
+ .assertThat().documentHasVersion(1.0);
+ });
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is able to create file from source with versioning state set to CHECKEDOUT with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void managerCreatesDocumentFromSourceWithVersionCHECKEDOUT() throws Exception
+ {
+ newFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFileFromSource(newFile, sourceFile, VersioningState.CHECKEDOUT);
+ Utility.sleep(100, 35000, () ->
+ {
+ cmisApi.refreshResource().then().assertThat().existsInRepo().and()
+ .assertThat().contentIs(sourceContent).and()
+ .assertThat().documentIsCheckedOut();
+ });
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that admin user is not able to create document from null source with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = NullPointerException.class)
+ public void adminCannotCreateDocFromNullSource() throws Exception
+ {
+ newFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ FileModel sourceFile = null;
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingSite(publicSite).createFileFromSource(newFile, sourceFile);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that manager is able to create document from a source that is checked out with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void managerShouldCreateDocFromSourceThatIsCheckedOut() throws Exception
+ {
+ newFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ FileModel sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, sourceContent);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite).createFile(sourceFile).and().assertThat().existsInRepo()
+ .then().checkOut().and().assertThat().documentIsCheckedOut().when().usingSite(publicSite)
+ .createFileFromSource(newFile, sourceFile).then().assertThat().existsInRepo().and().assertThat()
+ .contentIs(sourceContent).and().assertThat().documentIsNotCheckedOut();
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that manager is able to create document from a source from his private site with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void managerShouldCreateDocFromSourceFromHisPrivateSite() throws Exception
+ {
+ newFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ FileModel sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, sourceContent);
+ cmisApi.authenticateUser(siteManager).usingSite(privateSite).createFile(sourceFile).and().assertThat().existsInRepo()
+ .when().usingSite(publicSite).createFileFromSource(newFile, sourceFile).then().assertThat().existsInRepo().and()
+ .assertThat().contentIs(sourceContent);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that an user is not able to create document from a source from a private site with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = { CmisPermissionDeniedException.class,
+ CmisUnauthorizedException.class })
+ public void userShouldNotCreateDocFromSourceFromPrivateSite() throws Exception
+ {
+ newFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ FileModel sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, sourceContent);
+ cmisApi.authenticateUser(siteManager).usingSite(privateSite).createFile(sourceFile).and().assertThat().existsInRepo();
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager)).usingSite(publicSite)
+ .createFileFromSource(newFile, sourceFile);
+ }
+
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/CreateDocumentTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/CreateDocumentTests.java
new file mode 100644
index 00000000000..c212824ec2e
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/CreateDocumentTests.java
@@ -0,0 +1,313 @@
+package org.alfresco.cmis;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.alfresco.cmis.exception.InvalidCmisObjectException;
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.data.RandomData;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.FolderModel;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.report.Bug;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
+import org.apache.chemistry.opencmis.commons.enums.VersioningState;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisContentAlreadyExistsException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * Created by Claudia Agache on 9/26/2016.
+ */
+public class CreateDocumentTests extends CmisTest
+{
+ SiteModel testSite;
+ UserModel testUser;
+ UserModel inexistentUser;
+ FileModel testFile, adminFile;
+ private DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createPublicRandomSite();
+ inexistentUser = new UserModel("inexistent", "inexistent");
+ usersWithRoles = dataUser.usingUser(testUser)
+ .addUsersWithRolesToSite(testSite, UserRole.SiteContributor, UserRole.SiteCollaborator, UserRole.SiteConsumer);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify site manager is able to create files in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerShouldCreateDocument() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify inexistent user isn't able to create files in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisUnauthorizedException.class)
+ public void inexistentUserShouldNotCreateDocument() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+ cmisApi.authenticateUser(inexistentUser).usingSite(testSite).createFile(testFile);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify unauthorized user isn't able to create files in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void unauthorizedUserShouldNotCreateDocument() throws Exception
+ {
+ UserModel unauthorizedUser = dataUser.createRandomTestUser();
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+ cmisApi.authenticateUser(unauthorizedUser)
+ .usingSite(testSite).createFile(testFile);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType=ExecutionType.REGRESSION,
+ description = "Verify admin user is able to create files in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void adminShouldCreateDocument() throws Exception
+ {
+ adminFile = FileModel.getRandomFileModel(FileType.PDF);
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingSite(testSite)
+ .createFile(adminFile).and().assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType=ExecutionType.REGRESSION,
+ description = "Verify that manager user is not able to create document twice in the same location with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisContentAlreadyExistsException.class)
+ public void siteManagerCannotCreateDocumentTwice() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .then().createFile(testFile);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType=ExecutionType.REGRESSION,
+ description = "Verify that manager user is not able to create document ending with '.'")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisConstraintException.class)
+ public void siteManagerCannotCreateDocumentEndingWithPoint() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, documentContent);
+ testFile.setName(testFile.getName() + ".");
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType=ExecutionType.REGRESSION,
+ description = "Verify that admin user is not able to create document in invalid location with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisObjectNotFoundException.class)
+ public void adminCannotCreateDocumentAtInvalidPath() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+ FolderModel invalidLocation = new FolderModel("/Shared/invalidFolder");
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingResource(invalidLocation).createFile(testFile);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType=ExecutionType.REGRESSION,
+ description = "Verify that admin user is not able to create document with invalid characters in name with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisConstraintException.class)
+ public void adminCannotCreateDocumentWithInvalidCharacters() throws Exception
+ {
+ FileModel invalidCharDoc = new FileModel("/.:?|\\`\\.txt", FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(dataUser.getAdminUser())
+ .usingResource(FolderModel.getSharedFolderModel())
+ .createFile(invalidCharDoc);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to create document with invalid base type id with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisObjectNotFoundException.class)
+ public void siteManagerCannotCreateDocWithInvalidObjectTypeId() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile, "cmis:fakeType", VersioningState.MAJOR);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to create document with cmis:folder base type id with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisConstraintException.class)
+ public void siteManagerCannotCreateDocWithFolderTypeId() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile, BaseTypeId.CMIS_FOLDER.value(), VersioningState.MAJOR);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType=ExecutionType.REGRESSION,
+ description = "Verify that manager user is able to create document with valid symbols in name")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanCreateDocumentWithValidSymbols() throws Exception
+ {
+ FileModel validSymbolsDoc = new FileModel("!@#$%^&", FileType.TEXT_PLAIN, "content");
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(validSymbolsDoc).and().assertThat().existsInRepo();
+ Assert.assertNotNull(cmisApi.withCMISUtil().getCmisObject(validSymbolsDoc.getCmisLocation()));
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType=ExecutionType.REGRESSION,
+ description = "Verify that manager is not able to create document with empty name")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisInvalidArgumentException.class)
+ public void siteManagerCannotCreateDocumentWithEmptyName() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(new FileModel("", FileType.TEXT_PLAIN));
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to create file with Major versioning state")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerShouldCreateDocumentWithMajorVersioningState() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile, VersioningState.MAJOR).and().assertThat().existsInRepo()
+ .and().assertThat().documentHasVersion(1.0)
+ .assertThat().isLatestMajorVersion();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to create file with Minor versioning state")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerShouldCreateDocumentWithMinorVersioningState() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.HTML);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile, VersioningState.MINOR).and().assertThat().existsInRepo()
+ .and().assertThat().documentHasVersion(0.1)
+ .assertThat().isNotLatestMajorVersion();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to create file with CHECKEDOUT versioning state")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerShouldCreateDocumentWithCheckedOutVersioningState() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile, VersioningState.CHECKEDOUT).and().assertThat().existsInRepo()
+ .and().assertThat().documentIsCheckedOut()
+ .assertThat().isPrivateWorkingCopy();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site contributor is able to create file")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorShouldCreateDocument() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to create file")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorShouldCreateDocument() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site consumer is not able to create file")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void consumerShouldNotCreateDocument() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .usingSite(testSite)
+ .createFile(testFile);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify non invited user is not able to create file")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonInvitedUserShouldNotCreateDocumentInSite() throws Exception
+ {
+ UserModel outsider = dataUser.createRandomTestUser();
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(outsider)
+ .usingSite(testSite)
+ .createFile(testFile);
+ }
+
+ @Bug(id="REPO-4301")
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify disabled user is not able to create file in Shared folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void disabledUserShouldNotCreateDocument() throws Exception
+ {
+ UserModel disabled = dataUser.createRandomTestUser();
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(disabled);
+ dataUser.usingAdmin().disableUser(disabled);
+ cmisApi.usingShared()
+ .createFile(testFile);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify non invited user is not able to create file in private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonInvitedUserShouldNotCreateDocumentInPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingUser(testUser).createPrivateRandomSite();
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingSite(privateSite)
+ .createFile(testFile);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to create document with no properties")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=IllegalArgumentException.class,
+ expectedExceptionsMessageRegExp="Properties must not be empty!*")
+ public void siteManagerCannotCreateDocumentWithNoProperties() throws Exception
+ {
+ Map properties = new HashMap();
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile, properties, VersioningState.MAJOR);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to create file with a name containing multi byte characters.")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void managerIsAbleToCreateFileWithMultiByteName() throws Exception
+ {
+ testFile = new FileModel(RandomData.getRandomAlphanumeric() + "\ufeff\u6768\u6728\u91d1");
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType=ExecutionType.REGRESSION,
+ description = "Verify that manager user is not able to create document at document location")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=InvalidCmisObjectException.class)
+ public void siteManagerCannotCreateDocumentInDocumentLocation() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .then().usingResource(testFile)
+ .createFile(testFile);
+ }
+
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/CreateFolderTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/CreateFolderTests.java
new file mode 100644
index 00000000000..86743215027
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/CreateFolderTests.java
@@ -0,0 +1,232 @@
+package org.alfresco.cmis;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.data.RandomData;
+import org.alfresco.utility.model.FolderModel;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.report.Bug;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.PropertyIds;
+import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisContentAlreadyExistsException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * Created by Claudia Agache on 9/26/2016
+ */
+public class CreateFolderTests extends CmisTest
+{
+ UserModel testUser;
+ SiteModel testSite;
+ FolderModel testFolder;
+ private DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createPublicRandomSite();
+ usersWithRoles = dataUser.usingUser(testUser)
+ .addUsersWithRolesToSite(testSite, UserRole.SiteContributor, UserRole.SiteCollaborator, UserRole.SiteConsumer);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify admin user is able to create folder in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void adminShouldCreateFolder() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingSite(testSite)
+ .createFolder(testFolder).and().assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify site manager is able to create folder in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerShouldCreateFolder() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(testFolder).and().assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify inexistent user can't create folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisUnauthorizedException.class)
+ public void inexistentUserShouldNotCreateFolder() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(new UserModel("random user", "random password")).usingSite(testSite).createFolder(testFolder);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify a folder with same name can't be created in the same location")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisContentAlreadyExistsException.class,
+ expectedExceptionsMessageRegExp="An object with this name already exists.*")
+ public void shouldNotCreateFolderWithSameName() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder).and().assertThat().existsInRepo();
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify a folder can't be created at invalid path")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisObjectNotFoundException.class,
+ expectedExceptionsMessageRegExp="Object not found.*")
+ public void shouldNotCreateFolderAtInvalidPath() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(testUser).usingSite(new SiteModel("inexitentSite")).createFolder(testFolder);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to create folder with invalid base type id with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisObjectNotFoundException.class)
+ public void siteManagerCannotCreateFolderWithInvalidObjectTypeId() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(testFolder, "cmis:fakeType");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to create folder with cmis:document base type id with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisConstraintException.class)
+ public void siteManagerCannotCreateFolderWithDocumentTypeId() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(testFolder, BaseTypeId.CMIS_DOCUMENT.value());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType=ExecutionType.REGRESSION,
+ description = "Verify that admin user is not able to create folder with invalid characters in name")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisConstraintException.class)
+ public void adminCannotCreateFolderWithInvalidCharacters() throws Exception
+ {
+ testFolder = new FolderModel("/.:?|\\`\\.txt");
+ cmisApi.authenticateUser(dataUser.getAdminUser())
+ .usingResource(FolderModel.getSharedFolderModel())
+ .createFolder(testFolder);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType=ExecutionType.REGRESSION,
+ description = "Verify that admin user is not able to create folder with empty name")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisInvalidArgumentException.class,
+ expectedExceptionsMessageRegExp="Property cmis:name must be set!*")
+ public void adminCannotCreateFolderWithEmptyName() throws Exception
+ {
+ cmisApi.authenticateUser(dataUser.getAdminUser())
+ .usingResource(FolderModel.getSharedFolderModel())
+ .createFolder(new FolderModel(""));
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to create folder with empty properties")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=IllegalArgumentException.class,
+ expectedExceptionsMessageRegExp="Properties must not be empty!*")
+ public void siteManagerCannotCreateFolderWithNoParamenters() throws Exception
+ {
+ Map properties = new HashMap();
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(testUser)
+ .usingSite(testSite)
+ .createFolder(testFolder, properties);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to create folder with properties specific for documents")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=IllegalArgumentException.class,
+ expectedExceptionsMessageRegExp="Property 'cmis:isLatestMajorVersion' is not valid for this type or one of the secondary types!*")
+ public void siteManagerCannotCreateFolderWithDocumentParamenters() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ Map properties = new HashMap();
+ properties.put(PropertyIds.OBJECT_TYPE_ID, BaseTypeId.CMIS_FOLDER.value());
+ properties.put(PropertyIds.NAME, testFolder.getName());
+ properties.put(PropertyIds.IS_LATEST_MAJOR_VERSION, "true");
+ cmisApi.authenticateUser(testUser)
+ .usingSite(testSite)
+ .createFolder(testFolder, properties);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify contributor is able to create folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorCanCreateFolder() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingSite(testSite)
+ .createFolder(testFolder).and().assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify collaborator is able to create folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorCanCreateFolder() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingSite(testSite)
+ .createFolder(testFolder).and().assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify consumer is not able to create folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void consumerCannotCreateFolder() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer)).usingSite(testSite)
+ .createFolder(testFolder);
+ }
+
+ @Bug(id="REPO-4301")
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify disabled user is not able to create folder in Shared location")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void disabledUserShouldNotCreateFolder() throws Exception
+ {
+ UserModel disabled = dataUser.createRandomTestUser();
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(disabled);
+ dataUser.usingAdmin().disableUser(disabled);
+ cmisApi.usingShared()
+ .createFolder(testFolder);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify non invited user is not able to create folder in private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonInvitedUserShouldNotCreateDocumentInPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingUser(testUser).createPrivateRandomSite();
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingSite(privateSite)
+ .createFolder(testFolder);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to create folder with a name containing multi byte characters.")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void managerIsAbleToCreateFolderWithMultiByteName() throws Exception
+ {
+ testFolder = new FolderModel(RandomData.getRandomAlphanumeric() + "\ufeff\u6768\u6728\u91d1");
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(testFolder).and().assertThat().existsInRepo();
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/DataListsTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/DataListsTests.java
new file mode 100644
index 00000000000..fec6d4b7fcd
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/DataListsTests.java
@@ -0,0 +1,590 @@
+package org.alfresco.cmis;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.data.RandomData;
+import org.alfresco.utility.model.DataListItemModel;
+import org.alfresco.utility.model.DataListModel;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.PropertyIds;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisContentAlreadyExistsException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class DataListsTests extends CmisTest
+{
+ UserModel manager;
+ SiteModel testSite;
+ DataListModel dataListModel;
+ private DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ manager = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(manager).createPublicRandomSite();
+ usersWithRoles = dataUser.usingUser(manager)
+ .addUsersWithRolesToSite(testSite, UserRole.SiteContributor, UserRole.SiteCollaborator, UserRole.SiteConsumer);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify admin user is able to create data list type contact")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.REQUIRE_SHARE})
+ public void adminCanCreateContactDataList() throws Exception
+ {
+ dataListModel = DataListModel.getRandomDataListModel("dl:contact");
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingShared()
+ .createDataList(dataListModel).and().assertThat().existsInRepo()
+ .assertThat().objectTypeIdIs("F:dl:dataList");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify manager user is able to create data list type contact")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS, TestGroup.REQUIRE_SHARE})
+ public void managerCanCreateContactDataList() throws Exception
+ {
+ dataListModel = DataListModel.getRandomDataListModel("dl:contact");
+ cmisApi.authenticateUser(manager).usingSite(testSite)
+ .createDataList(dataListModel).and().assertThat().existsInRepo()
+ .assertThat().objectTypeIdIs("F:dl:dataList")
+ .and().assertThat().objectHasProperty("dl:dataListItemType", "dl:contact");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify collaborator user is able to create data list type contact")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.REQUIRE_SHARE})
+ public void collaboratorCanCreatedIssueDataList() throws Exception
+ {
+ dataListModel = DataListModel.getRandomDataListModel("dl:issue");
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingSite(testSite)
+ .createDataList(dataListModel).and().assertThat().existsInRepo()
+ .assertThat().objectTypeIdIs("F:dl:dataList")
+ .and().assertThat().objectHasProperty("dl:dataListItemType", "dl:issue");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify contributor user is able to create data list type contact")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.REQUIRE_SHARE})
+ public void contributorCanCreateEventAgendaDataList() throws Exception
+ {
+ dataListModel = DataListModel.getRandomDataListModel("dl:eventAgenda");
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingSite(testSite)
+ .createDataList(dataListModel).and().assertThat().existsInRepo()
+ .assertThat().objectTypeIdIs("F:dl:dataList")
+ .assertThat().objectHasProperty("dl:dataListItemType", "dl:eventAgenda");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify consumer user is able to create data list type contact")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.REQUIRE_SHARE}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void consumerCannotCreateEventAgendaDataList() throws Exception
+ {
+ dataListModel = DataListModel.getRandomDataListModel("dl:eventAgenda");
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer)).usingSite(testSite)
+ .createDataList(dataListModel).and().assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify manager user is able to create data list type contact")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.REQUIRE_SHARE})
+ public void managerCanCreateContactDataListItem() throws Exception
+ {
+ Map itemProperties = new HashMap();
+ itemProperties.put(PropertyIds.OBJECT_TYPE_ID, "D:dl:contact");
+ itemProperties.put(PropertyIds.NAME, RandomData.getRandomAlphanumeric());
+ itemProperties.put("dl:contactFirstName", "John");
+ itemProperties.put("dl:contactLastName", "Snow");
+ itemProperties.put("dl:contactEmail", "john.snow@stark.com");
+ itemProperties.put("dl:contactCompany", "GOT");
+ itemProperties.put("dl:contactJobTitle", "king");
+ itemProperties.put("dl:contactPhoneOffice", "1234");
+ itemProperties.put("dl:contactPhoneMobile", "5678");
+ itemProperties.put("dl:contactNotes", "you know nothing john snow");
+
+ DataListItemModel contactItem = new DataListItemModel(itemProperties);
+ dataListModel = DataListModel.getRandomDataListModel("dl:contact");
+ cmisApi.authenticateUser(manager).usingSite(testSite)
+ .then().createDataList(dataListModel).and().assertThat().existsInRepo()
+ .and().assertThat().objectHasProperty("dl:dataListItemType", "dl:contact")
+ .then().usingResource(dataListModel)
+ .createDataListItem(contactItem).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify manager user is able to create data list type contact")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.REQUIRE_SHARE})
+ public void managerCanCreateIssueListItem() throws Exception
+ {
+ UserModel assignUser = dataUser.createRandomTestUser();
+ FileModel attachDoc1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ FileModel attachDoc2 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+
+ Map itemProperties = new HashMap();
+ itemProperties.put(PropertyIds.OBJECT_TYPE_ID, "D:dl:issue");
+ itemProperties.put(PropertyIds.NAME, RandomData.getRandomAlphanumeric());
+ itemProperties.put("dl:issueID", RandomData.getRandomAlphanumeric());
+ itemProperties.put("dl:issueStatus", "Not Started");
+ itemProperties.put("dl:issuePriority", "Low");
+ itemProperties.put("dl:issueDueDate", new Date());
+ itemProperties.put("dl:issueComments", "comment");
+
+ DataListItemModel issueItem = new DataListItemModel(itemProperties);
+
+ dataListModel = DataListModel.getRandomDataListModel("dl:issue");
+ cmisApi.authenticateUser(manager).usingSite(testSite).createFile(attachDoc1).createFile(attachDoc2)
+ .then().createDataList(dataListModel).and().assertThat().existsInRepo()
+ .and().assertThat().objectHasProperty("dl:dataListItemType", "dl:issue")
+ .then().usingResource(dataListModel)
+ .createDataListItem(issueItem).assertThat().existsInRepo()
+ .then().attachDocument(attachDoc1)
+ .attachDocument(attachDoc2)
+ .assertThat().objectHasRelationshipWith(attachDoc1)
+ .assertThat().objectHasRelationshipWith(attachDoc2)
+ .then().assignToUser(assignUser, "R:dl:issueAssignedTo")
+ .assertThat().userIsAssigned(assignUser);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify manager user is able to create data list type contact")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.REQUIRE_SHARE}, expectedExceptions=CmisObjectNotFoundException.class,
+ expectedExceptionsMessageRegExp="Type 'D:dl:invalidItem' is unknown!*")
+ public void managerCannotCreateInvalidDataListItem() throws Exception
+ {
+ Map itemProperties = new HashMap();
+ itemProperties.put(PropertyIds.OBJECT_TYPE_ID, "D:dl:invalidItem");
+ itemProperties.put(PropertyIds.NAME, RandomData.getRandomAlphanumeric());
+
+ DataListItemModel contactItem = new DataListItemModel(itemProperties);
+ dataListModel = DataListModel.getRandomDataListModel("dl:contact");
+ cmisApi.authenticateUser(manager).usingSite(testSite)
+ .then().createDataList(dataListModel).and().assertThat().existsInRepo()
+ .and().assertThat().objectHasProperty("dl:dataListItemType", "dl:contact")
+ .then().usingResource(dataListModel)
+ .createDataListItem(contactItem).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify collaborator user is able to add issue item type for data list created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.REQUIRE_SHARE})
+ public void collaboratorCanAddIssueItem() throws Exception
+ {
+ UserModel assignUser = dataUser.createRandomTestUser();
+ FileModel attachDoc1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ FileModel attachDoc2 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+
+ Map itemProperties = new HashMap();
+ itemProperties.put(PropertyIds.OBJECT_TYPE_ID, "D:dl:issue");
+ itemProperties.put(PropertyIds.NAME, RandomData.getRandomAlphanumeric());
+ itemProperties.put("dl:issueID", RandomData.getRandomAlphanumeric());
+ itemProperties.put("dl:issueDueDate", new Date());
+ itemProperties.put("dl:issueComments", "comment");
+ DataListItemModel issueItem = new DataListItemModel(itemProperties);
+ dataListModel = DataListModel.getRandomDataListModel("dl:issue");
+
+ cmisApi.authenticateUser(manager).usingSite(testSite).createFile(attachDoc1).createFile(attachDoc2)
+ .then().createDataList(dataListModel).and().assertThat().existsInRepo()
+ .and().assertThat().objectHasProperty("dl:dataListItemType", "dl:issue")
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .then().usingResource(dataListModel)
+ .createDataListItem(issueItem).assertThat().existsInRepo()
+ .then().attachDocument(attachDoc1)
+ .attachDocument(attachDoc2)
+ .assertThat().objectHasRelationshipWith(attachDoc1)
+ .assertThat().objectHasRelationshipWith(attachDoc2)
+ .then().assignToUser(assignUser, "R:dl:issueAssignedTo")
+ .assertThat().userIsAssigned(assignUser);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify contributor user is able to add issue item type for data list created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.REQUIRE_SHARE})
+ public void contributorCanAddIssueItem() throws Exception
+ {
+ UserModel assignUser = dataUser.createRandomTestUser();
+ FileModel attachDoc1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ FileModel attachDoc2 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+
+ Map itemProperties = new HashMap();
+ itemProperties.put(PropertyIds.OBJECT_TYPE_ID, "D:dl:issue");
+ itemProperties.put(PropertyIds.NAME, RandomData.getRandomAlphanumeric());
+ itemProperties.put("dl:issueID", RandomData.getRandomAlphanumeric());
+ itemProperties.put("dl:issueStatus", "Not Started");
+ itemProperties.put("dl:issuePriority", "Low");
+ DataListItemModel issueItem = new DataListItemModel(itemProperties);
+ dataListModel = DataListModel.getRandomDataListModel("dl:issue");
+
+ cmisApi.authenticateUser(manager).usingSite(testSite).createFile(attachDoc1).createFile(attachDoc2)
+ .then().createDataList(dataListModel).and().assertThat().existsInRepo()
+ .and().assertThat().objectHasProperty("dl:dataListItemType", "dl:issue")
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .then().usingResource(dataListModel)
+ .createDataListItem(issueItem).assertThat().existsInRepo()
+ .then().attachDocument(attachDoc1)
+ .attachDocument(attachDoc2)
+ .assertThat().objectHasRelationshipWith(attachDoc1)
+ .assertThat().objectHasRelationshipWith(attachDoc2)
+ .then().assignToUser(assignUser, "R:dl:issueAssignedTo")
+ .assertThat().userIsAssigned(assignUser);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify consumer user is able to add issue item type for data list created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.REQUIRE_SHARE}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void consumerCannotAddIssueItem() throws Exception
+ {
+ Map itemProperties = new HashMap();
+ itemProperties.put(PropertyIds.OBJECT_TYPE_ID, "D:dl:issue");
+ itemProperties.put(PropertyIds.NAME, RandomData.getRandomAlphanumeric());
+ DataListItemModel issueItem = new DataListItemModel(itemProperties);
+ dataListModel = DataListModel.getRandomDataListModel("dl:issue");
+
+ cmisApi.authenticateUser(manager).usingSite(testSite)
+ .then().createDataList(dataListModel).and().assertThat().existsInRepo()
+ .and().assertThat().objectHasProperty("dl:dataListItemType", "dl:issue")
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .then().usingResource(dataListModel)
+ .createDataListItem(issueItem).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify non invited user is able to add issue item type for data list created by manager in private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.REQUIRE_SHARE}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonInvitedUserCannotAddIssueItemInPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingUser(manager).createPrivateRandomSite();
+
+ Map itemProperties = new HashMap();
+ itemProperties.put(PropertyIds.OBJECT_TYPE_ID, "D:dl:issue");
+ itemProperties.put(PropertyIds.NAME, RandomData.getRandomAlphanumeric());
+ DataListItemModel issueItem = new DataListItemModel(itemProperties);
+ dataListModel = DataListModel.getRandomDataListModel("dl:issue");
+
+ cmisApi.authenticateUser(manager).usingSite(privateSite)
+ .then().createDataList(dataListModel).and().assertThat().existsInRepo()
+ .and().assertThat().objectHasProperty("dl:dataListItemType", "dl:issue")
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingResource(dataListModel)
+ .createDataListItem(issueItem).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify manager user is not able to create data list item with invalid status")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.REQUIRE_SHARE}, expectedExceptions=CmisConstraintException.class)
+ public void managerCannotCreateTaskItemWithInvalidStatusValue() throws Exception
+ {
+ Map itemProperties = new HashMap();
+ itemProperties.put(PropertyIds.OBJECT_TYPE_ID, "D:dl:simpletask");
+ itemProperties.put(PropertyIds.NAME, RandomData.getRandomAlphanumeric());
+ itemProperties.put("dl:simpletaskStatus", "invalid-status");
+
+ DataListItemModel issueItem = new DataListItemModel(itemProperties);
+
+ dataListModel = DataListModel.getRandomDataListModel("dl:simpletask");
+ cmisApi.authenticateUser(manager).usingSite(testSite)
+ .then().createDataList(dataListModel).and().assertThat().existsInRepo()
+ .then().usingResource(dataListModel)
+ .createDataListItem(issueItem).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify manager user is not able to create data list item with invalid status")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.REQUIRE_SHARE}, expectedExceptions=IllegalArgumentException.class,
+ expectedExceptionsMessageRegExp="Property 'dl:fakePriority' is not valid for this type or one of the secondary types!*")
+ public void managerCannotCreateTaskItemWithInvalidParameter() throws Exception
+ {
+ Map itemProperties = new HashMap();
+ itemProperties.put(PropertyIds.OBJECT_TYPE_ID, "D:dl:simpletask");
+ itemProperties.put(PropertyIds.NAME, RandomData.getRandomAlphanumeric());
+ itemProperties.put("dl:fakePriority", "High");
+
+ DataListItemModel issueItem = new DataListItemModel(itemProperties);
+
+ dataListModel = DataListModel.getRandomDataListModel("dl:simpletask");
+ cmisApi.authenticateUser(manager).usingSite(testSite)
+ .then().createDataList(dataListModel).and().assertThat().existsInRepo()
+ .then().usingResource(dataListModel)
+ .createDataListItem(issueItem).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify manager user is not able to assign issue item to deleted user")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.REQUIRE_SHARE}, expectedExceptions=CmisInvalidArgumentException.class,
+ expectedExceptionsMessageRegExp="Property cmis:targetId must be set!*")
+ public void managerCannotAssignIssueItemToDeletedUser() throws Exception
+ {
+ UserModel assignUser = dataUser.createRandomTestUser();
+
+ Map itemProperties = new HashMap();
+ itemProperties.put(PropertyIds.OBJECT_TYPE_ID, "D:dl:issue");
+ itemProperties.put(PropertyIds.NAME, RandomData.getRandomAlphanumeric());
+ itemProperties.put("dl:issueID", RandomData.getRandomAlphanumeric());
+ itemProperties.put("dl:issueDueDate", new Date());
+ itemProperties.put("dl:issueComments", "comment");
+ DataListItemModel issueItem = new DataListItemModel(itemProperties);
+ dataListModel = DataListModel.getRandomDataListModel("dl:issue");
+
+ cmisApi.authenticateUser(manager).usingSite(testSite)
+ .then().createDataList(dataListModel).and().assertThat().existsInRepo()
+ .and().assertThat().objectHasProperty("dl:dataListItemType", "dl:issue")
+ .then().usingResource(dataListModel)
+ .createDataListItem(issueItem).assertThat().existsInRepo();
+ dataUser.usingAdmin().deleteUser(assignUser);
+ cmisApi.assignToUser(assignUser, "R:dl:issueAssignedTo").assertThat().userIsAssigned(assignUser);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify manager user is not able to assign issue item twice to same user")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.REQUIRE_SHARE}, expectedExceptions=CmisRuntimeException.class)
+ public void managerCannotAssignIssueItemTwice() throws Exception
+ {
+ UserModel assignUser = dataUser.createRandomTestUser();
+
+ Map itemProperties = new HashMap();
+ itemProperties.put(PropertyIds.OBJECT_TYPE_ID, "D:dl:issue");
+ itemProperties.put(PropertyIds.NAME, RandomData.getRandomAlphanumeric());
+ itemProperties.put("dl:issueID", RandomData.getRandomAlphanumeric());
+ itemProperties.put("dl:issueDueDate", new Date());
+ itemProperties.put("dl:issueComments", "comment");
+ DataListItemModel issueItem = new DataListItemModel(itemProperties);
+ dataListModel = DataListModel.getRandomDataListModel("dl:issue");
+
+ cmisApi.authenticateUser(manager).usingSite(testSite)
+ .then().createDataList(dataListModel).and().assertThat().existsInRepo()
+ .and().assertThat().objectHasProperty("dl:dataListItemType", "dl:issue")
+ .then().usingResource(dataListModel)
+ .createDataListItem(issueItem).assertThat().existsInRepo();
+ cmisApi.assignToUser(assignUser, "R:dl:issueAssignedTo").assertThat().userIsAssigned(assignUser)
+ .then().assignToUser(assignUser, "R:dl:issueAssignedTo");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify manager user is able to assign issue item for 2 users")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.REQUIRE_SHARE})
+ public void managerCanAssignIssueItemForTwoUsers() throws Exception
+ {
+ UserModel assignUser = dataUser.createRandomTestUser();
+ UserModel anotherUser = dataUser.createRandomTestUser();
+
+ Map itemProperties = new HashMap();
+ itemProperties.put(PropertyIds.OBJECT_TYPE_ID, "D:dl:issue");
+ itemProperties.put(PropertyIds.NAME, RandomData.getRandomAlphanumeric());
+ itemProperties.put("dl:issueID", RandomData.getRandomAlphanumeric());
+ itemProperties.put("dl:issueDueDate", new Date());
+ itemProperties.put("dl:issueComments", "comment");
+ DataListItemModel issueItem = new DataListItemModel(itemProperties);
+ dataListModel = DataListModel.getRandomDataListModel("dl:issue");
+
+ cmisApi.authenticateUser(manager).usingSite(testSite)
+ .then().createDataList(dataListModel).and().assertThat().existsInRepo()
+ .and().assertThat().objectHasProperty("dl:dataListItemType", "dl:issue")
+ .then().usingResource(dataListModel)
+ .createDataListItem(issueItem).assertThat().existsInRepo();
+ cmisApi.assignToUser(assignUser, "R:dl:issueAssignedTo").assertThat().userIsAssigned(assignUser)
+ .then().assignToUser(anotherUser, "R:dl:issueAssignedTo");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify manager user is able to delete contact data list with no items")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS, TestGroup.REQUIRE_SHARE})
+ public void managerCanDeleteContactDataList() throws Exception
+ {
+ dataListModel = DataListModel.getRandomDataListModel("dl:contact");
+ cmisApi.authenticateUser(manager).usingSite(testSite)
+ .createDataList(dataListModel).and().assertThat().existsInRepo()
+ .and().assertThat().objectHasProperty("dl:dataListItemType", "dl:contact")
+ .then().delete().assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify manager user is not able to create contact data list items with same name twice")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.REQUIRE_SHARE}, expectedExceptions=CmisContentAlreadyExistsException.class)
+ public void managerCannotCreateContactDataListWithSameNameTwice() throws Exception
+ {
+ Map itemProperties = new HashMap();
+ itemProperties.put(PropertyIds.OBJECT_TYPE_ID, "D:dl:contact");
+ itemProperties.put(PropertyIds.NAME, RandomData.getRandomAlphanumeric());
+ itemProperties.put("dl:contactFirstName", "John");
+ DataListItemModel contactItem = new DataListItemModel(itemProperties);
+
+ dataListModel = DataListModel.getRandomDataListModel("dl:contact");
+ cmisApi.authenticateUser(manager).usingSite(testSite)
+ .then().createDataList(dataListModel).and().assertThat().existsInRepo()
+ .and().assertThat().objectHasProperty("dl:dataListItemType", "dl:contact")
+ .then().usingResource(dataListModel)
+ .createDataListItem(contactItem).assertThat().existsInRepo()
+ .then().usingResource(dataListModel)
+ .then().createDataListItem(contactItem);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify manager user is not able to create contact data list items at item location")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.REQUIRE_SHARE}, expectedExceptions=CmisInvalidArgumentException.class,
+ expectedExceptionsMessageRegExp="Parent folder is not a folder!*")
+ public void managerCannotCreateContactDataListItemInsideItem() throws Exception
+ {
+ Map itemProperties = new HashMap();
+ itemProperties.put(PropertyIds.OBJECT_TYPE_ID, "D:dl:contact");
+ itemProperties.put(PropertyIds.NAME, RandomData.getRandomAlphanumeric());
+ itemProperties.put("dl:contactFirstName", "John");
+ DataListItemModel contactItem = new DataListItemModel(itemProperties);
+
+ dataListModel = DataListModel.getRandomDataListModel("dl:contact");
+ cmisApi.authenticateUser(manager).usingSite(testSite)
+ .then().createDataList(dataListModel).and().assertThat().existsInRepo()
+ .and().assertThat().objectHasProperty("dl:dataListItemType", "dl:contact")
+ .then().usingResource(dataListModel)
+ .createDataListItem(contactItem).assertThat().existsInRepo()
+ .then().usingResource(contactItem)
+ .createDataListItem(contactItem);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify manager user is not able to simple delete contact data list with items")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.REQUIRE_SHARE}, expectedExceptions=CmisConstraintException.class,
+ expectedExceptionsMessageRegExp="Could not delete folder with at least one child!*")
+ public void managerCannotSimpleDeleteContactDataListWithItems() throws Exception
+ {
+ Map itemProperties = new HashMap();
+ itemProperties.put(PropertyIds.OBJECT_TYPE_ID, "D:dl:contact");
+ itemProperties.put(PropertyIds.NAME, RandomData.getRandomAlphanumeric());
+ itemProperties.put("dl:contactFirstName", "John");
+ DataListItemModel contactItem = new DataListItemModel(itemProperties);
+
+ dataListModel = DataListModel.getRandomDataListModel("dl:contact");
+ cmisApi.authenticateUser(manager).usingSite(testSite)
+ .then().createDataList(dataListModel).and().assertThat().existsInRepo()
+ .then().usingResource(dataListModel)
+ .createDataListItem(contactItem).assertThat().existsInRepo()
+ .then().usingResource(dataListModel).delete();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify manager user is able to delete(delete tree) contact data list with items in it")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.REQUIRE_SHARE})
+ public void managerCanDeleteTreeContactDataListWithItems() throws Exception
+ {
+ Map itemProperties = new HashMap();
+ itemProperties.put(PropertyIds.OBJECT_TYPE_ID, "D:dl:contact");
+ itemProperties.put(PropertyIds.NAME, RandomData.getRandomAlphanumeric());
+ itemProperties.put("dl:contactFirstName", "John");
+ DataListItemModel contactItem = new DataListItemModel(itemProperties);
+
+ dataListModel = DataListModel.getRandomDataListModel("dl:contact");
+ cmisApi.authenticateUser(manager).usingSite(testSite)
+ .then().createDataList(dataListModel).and().assertThat().existsInRepo()
+ .then().usingResource(dataListModel)
+ .createDataListItem(contactItem).assertThat().existsInRepo()
+ .then().usingResource(dataListModel)
+ .deleteFolderTree().assertThat().doesNotExistInRepo()
+ .and().usingResource(contactItem).assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify collaborator user is not able to delete(delete tree) contact data list with items in it created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.REQUIRE_SHARE})
+ public void collaboratorCannotDeleteTreeContactDataListWithItems() throws Exception
+ {
+ Map itemProperties = new HashMap();
+ itemProperties.put(PropertyIds.OBJECT_TYPE_ID, "D:dl:contact");
+ itemProperties.put(PropertyIds.NAME, RandomData.getRandomAlphanumeric());
+ itemProperties.put("dl:contactFirstName", "John");
+ DataListItemModel contactItem = new DataListItemModel(itemProperties);
+
+ dataListModel = DataListModel.getRandomDataListModel("dl:contact");
+ cmisApi.authenticateUser(manager).usingSite(testSite)
+ .then().createDataList(dataListModel).and().assertThat().existsInRepo()
+ .then().usingResource(dataListModel)
+ .createDataListItem(contactItem).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingResource(dataListModel)
+ .deleteFolderTree().assertThat()
+ .hasFailedDeletedObject(dataListModel.getNodeRef())
+ .and().assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify contributor user is not able to delete(delete tree) contact data list with items in it created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.REQUIRE_SHARE})
+ public void contributorCannotDeleteTreeContactDataListWithItems() throws Exception
+ {
+ Map itemProperties = new HashMap();
+ itemProperties.put(PropertyIds.OBJECT_TYPE_ID, "D:dl:contact");
+ itemProperties.put(PropertyIds.NAME, RandomData.getRandomAlphanumeric());
+ itemProperties.put("dl:contactFirstName", "John");
+ DataListItemModel contactItem = new DataListItemModel(itemProperties);
+
+ dataListModel = DataListModel.getRandomDataListModel("dl:contact");
+ cmisApi.authenticateUser(manager).usingSite(testSite)
+ .then().createDataList(dataListModel).and().assertThat().existsInRepo()
+ .then().usingResource(dataListModel)
+ .createDataListItem(contactItem).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingResource(dataListModel)
+ .deleteFolderTree().assertThat()
+ .hasFailedDeletedObject(dataListModel.getNodeRef())
+ .and().assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify consumer user is not able to delete(delete tree) contact data list with items in it created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.REQUIRE_SHARE})
+ public void consumerCannotDeleteTreeContactDataListWithItems() throws Exception
+ {
+ Map itemProperties = new HashMap();
+ itemProperties.put(PropertyIds.OBJECT_TYPE_ID, "D:dl:contact");
+ itemProperties.put(PropertyIds.NAME, RandomData.getRandomAlphanumeric());
+ itemProperties.put("dl:contactFirstName", "John");
+ DataListItemModel contactItem = new DataListItemModel(itemProperties);
+
+ dataListModel = DataListModel.getRandomDataListModel("dl:contact");
+ cmisApi.authenticateUser(manager).usingSite(testSite)
+ .then().createDataList(dataListModel).and().assertThat().existsInRepo()
+ .then().usingResource(dataListModel)
+ .createDataListItem(contactItem).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .usingResource(dataListModel)
+ .deleteFolderTree().assertThat()
+ .hasFailedDeletedObject(dataListModel.getNodeRef())
+ .and().assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify non invited user is not able to delete(delete tree) contact data list with items in it created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.REQUIRE_SHARE})
+ public void nonInvitedUserCannotDeleteTreeContactDataListWithItems() throws Exception
+ {
+ UserModel nonInvited = dataUser.createRandomTestUser();
+ Map itemProperties = new HashMap();
+ itemProperties.put(PropertyIds.OBJECT_TYPE_ID, "D:dl:contact");
+ itemProperties.put(PropertyIds.NAME, RandomData.getRandomAlphanumeric());
+ itemProperties.put("dl:contactFirstName", "John");
+ DataListItemModel contactItem = new DataListItemModel(itemProperties);
+
+ dataListModel = DataListModel.getRandomDataListModel("dl:contact");
+ cmisApi.authenticateUser(manager).usingSite(testSite)
+ .then().createDataList(dataListModel).and().assertThat().existsInRepo()
+ .then().usingResource(dataListModel)
+ .createDataListItem(contactItem).assertThat().existsInRepo()
+ .then().authenticateUser(nonInvited)
+ .usingResource(dataListModel)
+ .deleteFolderTree().assertThat()
+ .hasFailedDeletedObject(dataListModel.getNodeRef())
+ .and().assertThat().existsInRepo();
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/DeleteAllVersionsTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/DeleteAllVersionsTests.java
new file mode 100644
index 00000000000..8beaee73bba
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/DeleteAllVersionsTests.java
@@ -0,0 +1,325 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.RandomData;
+import org.alfresco.utility.model.*;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * Created by Claudia Agache on 9/26/2016.
+ */
+public class DeleteAllVersionsTests extends CmisTest
+{
+ UserModel testUser;
+ UserModel consumerUser;
+ UserModel collaboratorUser;
+ UserModel contributorUser;
+ UserModel unauthorizedUser;
+ SiteModel testSite;
+ FileModel testFile;
+ FolderModel testFolder;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ consumerUser = dataUser.createRandomTestUser();
+ collaboratorUser = dataUser.createRandomTestUser();
+ contributorUser = dataUser.createRandomTestUser();
+ unauthorizedUser = dataUser.createRandomTestUser();
+
+ testSite = dataSite.usingUser(testUser).createPublicRandomSite();
+
+ dataUser.addUserToSite(consumerUser, testSite, UserRole.SiteConsumer);
+ dataUser.addUserToSite(collaboratorUser, testSite, UserRole.SiteCollaborator);
+ dataUser.addUserToSite(contributorUser, testSite, UserRole.SiteContributor);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify site manager is able to delete all document versions in DocumentLibrary with CMIS")
+ @Test(groups = {TestGroup.SANITY, TestGroup.CMIS })
+ public void siteManagerDeletesAllDocumentVersions() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).and().update(testFile.getName())
+ .then().deleteAllVersions(true).and().assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify site manager is able to delete only latest document version in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerDeletesLatestDocumentVersion() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).and().update(testFile.getName())
+ .then().deleteAllVersions(false).and().assertThat().documentHasVersion(1.0);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is NOT able to delete all versions of inexistent file with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = CmisObjectNotFoundException.class)
+ public void siteManagerCannotDeleteAllVersionsOfInexistentFile() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+ testFile.setCmisLocation("/fake-folder/inexistentFile.txt");
+ cmisApi.authenticateUser(testUser).usingSite(testSite).usingResource(testFile).deleteAllVersions(true);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to delete PWC file version of a file with multiple versions with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanDeletePWCFileWithDeleteAllVersionsTrue() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFile(testFile)
+ .usingResource(testFile).update("content 1")
+ .assertThat().documentHasVersion(1.1)
+ .usingResource(testFile).update("content 2")
+ .assertThat().documentHasVersion(1.2)
+ .usingResource(testFile).checkOut()
+ .assertThat().documentIsCheckedOut()
+ .usingPWCDocument().deleteAllVersions(true)
+ .assertThat().doesNotExistInRepo()
+ .usingResource(testFile).assertThat().existsInRepo().and().assertThat().documentHasVersion(1.2);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to delete PWC file version of a file with multiple versions set to false with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanDeletePWCFileWithDeleteAllVersionsFalse() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFile(testFile)
+ .then().update("content 1")
+ .assertThat().documentHasVersion(1.1)
+ .then().update("content 2")
+ .assertThat().documentHasVersion(1.2)
+ .then().checkOut().refreshResource()
+ .assertThat().documentIsCheckedOut()
+ .usingPWCDocument().deleteAllVersions(false)
+ .assertThat().doesNotExistInRepo()
+ .usingResource(testFile).assertThat().existsInRepo().and().assertThat().documentHasVersion(1.2);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is NOT able to delete file original multiple version which is checked out with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = CmisConstraintException.class, expectedExceptionsMessageRegExp = "^Could not delete/cancel checkout on the original checked out document$")
+ public void siteManagerCannotDeleteOriginalFileMultipleVersionWhenCheckedout() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFile(testFile)
+ .then().update("content 1")
+ .assertThat().documentHasVersion(1.1)
+ .then().update("content 2")
+ .assertThat().documentHasVersion(1.2)
+ .refreshResource().then().checkOut()
+ .assertThat().documentIsCheckedOut();
+ cmisApi.usingResource(testFile).deleteAllVersions(true);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify unauthorized user is NOT able to delete a checked out document")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void unauthorizedUserCannotDeletePWCDocument() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).then().update("content 1")
+ .and().checkOut().assertThat().documentIsCheckedOut()
+ .when().authenticateUser(unauthorizedUser)
+ .usingResource(testFile).usingPWCDocument().deleteAllVersions(true);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager can delete object Document")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanDeleteDocument() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFile(testFile).usingResource(testFile).update("content 1")
+ .usingResource(testFile).deleteAllVersions(true)
+ .assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager can delete object Folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanDeleteFolder() throws Exception
+ {
+ testFolder = new FolderModel(RandomData.getRandomName("Folder"));
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder).usingResource(testFolder)
+ .deleteAllVersions(true)
+ .assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify contributor can delete object Document created by self")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorCanDeleteDocumentCreatedBySelf() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(contributorUser).usingSite(testSite).createFile(testFile).usingResource(testFile).update("content 1")
+ .deleteAllVersions(true)
+ .assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify contributor cannot delete object Document created by site manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void contributorCannotDeleteDocumentCreatedByManager() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).then().update("content 1")
+ .when().authenticateUser(contributorUser).usingResource(testFile).deleteAllVersions(true);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify contributor can delete object Folder created by self")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorCanDeleteFolderCreatedBySelf() throws Exception
+ {
+ testFolder = new FolderModel(RandomData.getRandomName("Folder"));
+ cmisApi.authenticateUser(contributorUser).usingSite(testSite).createFolder(testFolder).usingResource(testFolder)
+ .deleteAllVersions(true)
+ .assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify contributor cannot delete object Folder created by site manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void contributorCannotDeleteFolderCreatedByManager() throws Exception
+ {
+ testFolder = new FolderModel(RandomData.getRandomName("Folder"));
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(testFolder).assertThat().existsInRepo()
+ .when().authenticateUser(contributorUser)
+ .usingResource(testFolder).deleteAllVersions(true);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify collaborator can delete object Document created by self")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorCanDeleteDocumentCreatedBySelf() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(collaboratorUser).usingSite(testSite).createFile(testFile).usingResource(testFile).update("content 1")
+ .deleteAllVersions(true)
+ .assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify collaborator cannot delete object Document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void collaboratorCannotDeleteDocumentCreatedByManager() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).then().update("content 1")
+ .when().authenticateUser(collaboratorUser)
+ .usingResource(testFile).deleteAllVersions(true);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify collaborator can delete object Folder created by self")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorCanDeleteFolderCreatedBySelf() throws Exception
+ {
+ testFolder = new FolderModel(RandomData.getRandomName("Folder"));
+ cmisApi.authenticateUser(collaboratorUser).usingSite(testSite).createFolder(testFolder).usingResource(testFolder)
+ .deleteAllVersions(true)
+ .assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify collaborator cannot delete object Folder created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void collaboratorCannotDeleteFolderCreatedByManager() throws Exception
+ {
+ testFolder = new FolderModel(RandomData.getRandomName("Folder"));
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(testFolder).assertThat().existsInRepo()
+ .then().authenticateUser(collaboratorUser)
+ .usingResource(testFolder).deleteAllVersions(true);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify consumer cannot delete object Document")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void consumerCannotDeleteDocumentCreated() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).update("content 1")
+ .when().authenticateUser(consumerUser)
+ .usingResource(testFile).deleteAllVersions(true);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify consumer cannot delete object Folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void consumerCannotDeleteFolderCreated() throws Exception
+ {
+ testFolder = new FolderModel(RandomData.getRandomName("Folder"));
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(testFolder).assertThat().existsInRepo()
+ .then().authenticateUser(consumerUser)
+ .usingResource(testFolder).deleteAllVersions(true);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify unauthorized user cannot delete Document from private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void unauthorizedUserCannotDeleteDocumentFromPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingUser(testUser).createPrivateRandomSite();
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(privateSite)
+ .createFile(testFile).then().update("content 1")
+ .when().authenticateUser(unauthorizedUser)
+ .usingResource(testFile).deleteAllVersions(true);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify unauthorized user cannot delete Folder from private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void unauthorizedUserCannotDeleteFolderFromPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingUser(testUser).createPrivateRandomSite();
+ testFolder = new FolderModel(RandomData.getRandomName("Folder"));
+ cmisApi.authenticateUser(testUser).usingSite(privateSite).createFolder(testFolder);
+ cmisApi.authenticateUser(unauthorizedUser).usingResource(testFolder).deleteAllVersions(true);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify unauthorized user cannot delete Document from moderated site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void unauthorizedUserCannotDeleteDocumentFromModeratedSite() throws Exception
+ {
+ SiteModel moderatedSite = dataSite.usingUser(testUser).createModeratedRandomSite();
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(moderatedSite).createFile(testFile).usingResource(testFile).update("content 1");
+ cmisApi.authenticateUser(unauthorizedUser).usingResource(testFile).deleteAllVersions(true);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify unauthorized user cannot delete Folder from moderated site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void unauthorizedUserCannotDeleteFolderFromModeratedSite() throws Exception
+ {
+ SiteModel moderatedSite = dataSite.usingUser(testUser).createModeratedRandomSite();
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ testFolder = new FolderModel(RandomData.getRandomName("Folder"));
+ cmisApi.authenticateUser(testUser).usingSite(moderatedSite).createFolder(testFolder);
+ cmisApi.authenticateUser(unauthorizedUser).usingResource(testFolder).deleteAllVersions(true);
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/DeleteContentStreamTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/DeleteContentStreamTests.java
new file mode 100644
index 00000000000..04ea6091dce
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/DeleteContentStreamTests.java
@@ -0,0 +1,236 @@
+package org.alfresco.cmis;
+
+import org.alfresco.cmis.exception.InvalidCmisObjectException;
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.*;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUpdateConflictException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * Created by Claudia Agache on 9/27/2016.
+ */
+public class DeleteContentStreamTests extends CmisTest
+{
+ UserModel siteManager;
+ SiteModel publicSite, privateSite;
+ FileModel testFile;
+ String content = "file content";
+ private DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ siteManager = dataUser.createRandomTestUser();
+ publicSite = dataSite.usingUser(siteManager).createPublicRandomSite();
+ privateSite = dataSite.usingUser(siteManager).createPrivateRandomSite();
+ usersWithRoles = dataUser.addUsersWithRolesToSite(publicSite, UserRole.SiteManager, UserRole.SiteContributor, UserRole.SiteCollaborator, UserRole.SiteConsumer);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify site manager is able to delete content of a not empty document in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerDeletesDocumentContent() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, content);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile)
+ .deleteContent().and().assertThat().contentIs("");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify user is not able to delete content of a nonexistent document in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisObjectNotFoundException.class)
+ public void userCantDeleteContentFromNonexistentFile() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, content);
+ testFile.setCmisLocation("/fake-folder/test.txt");
+ cmisApi.authenticateUser(siteManager)
+ .usingResource(testFile).deleteContent();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to delete content of a empty document in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanDeleteContentOfEmptyDocument() throws Exception
+ {
+ FileModel emptyDoc = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(siteManager)
+ .usingSite(publicSite).createFile(emptyDoc).and().assertThat().existsInRepo()
+ .and().assertThat().contentIs("")
+ .then().deleteContent().and().assertThat().contentIs("");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify nonexistent user is not able to delete content of a document with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisUnauthorizedException.class)
+ public void nonexistentUserCannotDeleteDocumentContent() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, content);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile)
+ .then().authenticateUser(UserModel.getRandomUserModel())
+ .usingResource(testFile).deleteContent();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to delete content of a not empty document with refresh set to TRUE with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanDeleteDocContentWithRefreshTrue() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.HTML, content);
+ cmisApi.authenticateUser(siteManager)
+ .usingSite(publicSite).createFile(testFile)
+ .deleteContent(true).and().assertThat().contentIs("");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to delete content of a not empty document with refresh set to FALSE with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanDeleteDocContentWithRefreshFalse() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.HTML, content);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile)
+ .deleteContent(true).and().assertThat().contentIs("");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify admin is able to delete content of a not empty document created by other user in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void adminDeletesContentOfFileCreatedByOtherUser() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, content);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(dataUser.getAdminUser())
+ .deleteContent().and().assertThat().contentIs("");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to delete content of a not empty document created by other user in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerDeletesContentOfFileCreatedByOtherUser() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, content);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager))
+ .deleteContent().and().assertThat().contentIs("");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to delete content of a not empty document created by other user in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorDeletesContentOfFileCreatedByOtherUser() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, content);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .deleteContent().and().assertThat().contentIs("");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to delete content of a not empty document created by self in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorDeletesContentOfFileCreatedBySelf() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, content);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().deleteContent()
+ .and().assertThat().contentIs("");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site contributor is not able to delete content of a not empty document created by other user in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void contributorCannotDeleteContentOfFileCreatedByOtherUser() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, content);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .deleteContent();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site contributor is able to delete content of a not empty document created by self in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorDeletesContentOfFileCreatedBySelf() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, content);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().deleteContent()
+ .and().assertThat().contentIs("");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site consumer is not able to delete content of a not empty document in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void consumerCannotDeleteContentOfFileCreatedByOtherUser() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, content);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .deleteContent();
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = CmisUpdateConflictException.class, expectedExceptionsMessageRegExp = "^.*Cannot perform operation since the node.*is locked.$")
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to delete content of a checked out file with CMIS")
+ public void managerCannotDeleteContentOfCheckedOutFile() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, content);
+ cmisApi.authenticateUser(siteManager)
+ .usingSite(publicSite).createFile(testFile).assertThat().existsInRepo()
+ .then().checkOut().assertThat().documentIsCheckedOut()
+ .when().deleteContent();
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to delete content of a PWC file with CMIS")
+ public void managerDeletesContentOfPWCFile() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, content);
+ cmisApi.authenticateUser(siteManager)
+ .usingSite(publicSite).createFile(testFile).assertThat().existsInRepo()
+ .then().checkOut().assertThat().documentIsCheckedOut()
+ .usingPWCDocument().deleteContent()
+ .assertThat().contentIs("");
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify unauthorized user is not able to delete content of a file created in a private site with CMIS")
+ public void unauthorizedUserCannotDeleteContentOfFileFromPrivateSite() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, content);
+ cmisApi.authenticateUser(siteManager)
+ .usingSite(privateSite).createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager))
+ .usingResource(testFile).deleteContent();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify user is not able to delete content of invalid file with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = InvalidCmisObjectException.class, expectedExceptionsMessageRegExp = "^Content at.*is not a file$")
+ public void userShouldNotDeleteContentOfInvalidFile() throws Exception
+ {
+ FolderModel testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFolder(testFolder).assertThat().existsInRepo()
+ .deleteContent();
+ }
+
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/DeleteTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/DeleteTests.java
new file mode 100644
index 00000000000..a9a63e7eef8
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/DeleteTests.java
@@ -0,0 +1,321 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.*;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * Created by Claudia Agache on 9/26/2016.
+ */
+public class DeleteTests extends CmisTest
+{
+ UserModel siteManager;
+ SiteModel publicSite, privateSite;
+ FolderModel testFolder;
+ FileModel testFile;
+ private DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ siteManager = dataUser.createRandomTestUser();
+ publicSite = dataSite.usingUser(siteManager).createPublicRandomSite();
+ privateSite = dataSite.usingUser(siteManager).createPrivateRandomSite();
+ usersWithRoles = dataUser.addUsersWithRolesToSite(publicSite, UserRole.SiteManager, UserRole.SiteContributor, UserRole.SiteCollaborator, UserRole.SiteConsumer);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify site manager is able to delete files in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerShouldDeleteDocument() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite).createFile(testFile).and().assertThat().existsInRepo()
+ .then().delete()
+ .and().assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify site manager is able to delete empty folders in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerShouldDeleteEmptyFolder() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite).createFolder(testFolder).and().assertThat().existsInRepo()
+ .then().delete()
+ .and().assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is NOT able to delete folders with chidren with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = CmisConstraintException.class, expectedExceptionsMessageRegExp = "^Could not delete folder with at least one child!$")
+ public void siteManagerCannotDeleteFolderWithChildren() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite).createFolder(testFolder)
+ .usingResource(testFolder).createFile(testFile)
+ .usingResource(testFolder).delete();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to delete file with multiple versions with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanDeleteFileWithVersions() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite).createFolder(testFolder)
+ .usingResource(testFolder).createFile(testFile)
+ .then().update("content 1").assertThat().documentHasVersion(1.1)
+ .then().update("content 2").assertThat().documentHasVersion(1.2)
+ .then().usingResource(testFile).delete()
+ .assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is NOT able to delete file which is checked out with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = CmisConstraintException.class, expectedExceptionsMessageRegExp = "^Could not delete/cancel checkout on the original checked out document$")
+ public void siteManagerCannotDeleteCheckedOutFile() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite).createFile(testFile).usingResource(testFile).checkOut()
+ .assertThat().documentIsCheckedOut()
+ .then().delete();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to delete PWC file version with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanDeletePWCFile() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite).createFile(testFile).then().checkOut()
+ .assertThat().documentIsCheckedOut()
+ .usingPWCDocument().delete()
+ .assertThat().doesNotExistInRepo()
+ .usingResource(testFile).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is NOT able to delete nonexistent file with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = CmisObjectNotFoundException.class)
+ public void siteManagerCannotDeleteNonexistentFile() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+ testFile.setCmisLocation("/" + testFile.getName() + "/");
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .usingResource(testFile).delete();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is NOT able to delete nonexistent folder with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = CmisObjectNotFoundException.class)
+ public void siteManagerCannotDeleteNonexistentFolder() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ testFolder.setCmisLocation("/" + testFolder.getName() + "/");
+ cmisApi.authenticateUser(siteManager)
+ .usingResource(testFolder).delete();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to delete files created by another users in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerShouldDeleteDocumentCreatedByAnotherUser() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile).and().assertThat().existsInRepo();
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager))
+ .usingResource(testFile).delete()
+ .and().assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site contributor is able to delete content created by self in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorShouldDeleteContentCreatedBySelf() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+ testFolder = FolderModel.getRandomFolderModel();
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingSite(publicSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .createFolder(testFolder).and().assertThat().existsInRepo()
+ .then().usingResource(testFile).delete()
+ .and().assertThat().doesNotExistInRepo()
+ .then().usingResource(testFolder).delete()
+ .and().assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site contributor is not able to delete file created by other user in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void contributorShouldNotDeleteFileCreatedByOtherUser() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+ cmisApi.authenticateUser(siteManager)
+ .usingSite(publicSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .when().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingResource(testFile).delete();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site contributor is not able to delete folder created by other user in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void contributorShouldNotDeleteFolderCreatedByOtherUser() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(siteManager)
+ .usingSite(publicSite)
+ .createFolder(testFolder).and().assertThat().existsInRepo()
+ .when().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingResource(testFolder).delete();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to delete content created by self in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorShouldDeleteContentCreatedBySelf() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+ testFolder = FolderModel.getRandomFolderModel();
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingSite(publicSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .createFolder(testFolder).and().assertThat().existsInRepo()
+ .then().usingResource(testFile).delete()
+ .and().assertThat().doesNotExistInRepo()
+ .then().usingResource(testFolder).delete()
+ .and().assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site collaborator is not able to delete file created by other user in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void collaboratorShouldNotDeleteFileCreatedByOtherUser() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+
+ cmisApi.authenticateUser(siteManager)
+ .usingSite(publicSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .when().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingResource(testFile).delete();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site collaborator is not able to delete folder created by other user in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void collaboratorShouldNotDeleteFolderCreatedByOtherUser() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+
+ cmisApi.authenticateUser(siteManager)
+ .usingSite(publicSite)
+ .createFolder(testFolder).and().assertThat().existsInRepo()
+ .when().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingResource(testFolder).delete();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site consumer is not able to delete file created by other user in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void consumerShouldNotDeleteFile() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+
+ cmisApi.authenticateUser(siteManager)
+ .usingSite(publicSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .when().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .usingResource(testFile).delete();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site consumer is not able to delete folder created by other user in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void consumerShouldNotDeleteFolder() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+
+ cmisApi.authenticateUser(siteManager)
+ .usingSite(publicSite)
+ .createFolder(testFolder).and().assertThat().existsInRepo()
+ .when().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .usingResource(testFolder).delete();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify admin is able to delete files created by another users in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void adminShouldDeleteDocumentCreatedByAnotherUser() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile).and().assertThat().existsInRepo();
+ cmisApi.authenticateUser(dataUser.getAdminUser())
+ .usingResource(testFile).delete()
+ .and().assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify unauthorized user is not able to delete file created inside a private site with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void unauthorizedUserShouldNotDeleteFile() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+
+ cmisApi.authenticateUser(siteManager)
+ .usingSite(privateSite)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .when().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager))
+ .usingResource(testFile).delete();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify unauthorized user is not able to delete folder created inside a private site with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void unauthorizedUserShouldNotDeleteFolder() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+
+ cmisApi.authenticateUser(siteManager)
+ .usingSite(privateSite)
+ .createFolder(testFolder).and().assertThat().existsInRepo()
+ .when().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager))
+ .usingResource(testFolder).delete();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify unauthorized user is not able to delete content created inside a private site with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void unauthorizedUserCannotDeleteCheckedOutFile() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+
+ cmisApi.authenticateUser(siteManager).usingSite(privateSite)
+ .createFile(testFile).then().checkOut()
+ .and().assertThat().documentIsCheckedOut()
+ .when().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager))
+ .usingResource(testFile).delete();
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/DeleteTreeTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/DeleteTreeTests.java
new file mode 100644
index 00000000000..f1c0b0dd088
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/DeleteTreeTests.java
@@ -0,0 +1,385 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.FolderModel;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.enums.UnfileObject;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * Created by Claudia Agache on 9/27/2016.
+ */
+public class DeleteTreeTests extends CmisTest
+{
+ UserModel testUser;
+ SiteModel testSite;
+ FileModel testFile;
+ FolderModel parentTestFolder, childTestFolder;
+ private String content = "content";
+ private DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createPublicRandomSite();
+ usersWithRoles = dataUser.usingUser(testUser)
+ .addUsersWithRolesToSite(testSite, UserRole.SiteContributor, UserRole.SiteCollaborator, UserRole.SiteConsumer);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify site manager is able to delete parent folder with multiple children in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerDeletesFolderTree() throws Exception
+ {
+ parentTestFolder = FolderModel.getRandomFolderModel();
+ childTestFolder = FolderModel.getRandomFolderModel();
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, content);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(parentTestFolder).and().assertThat().existsInRepo()
+ .usingResource(parentTestFolder)
+ .createFolder(childTestFolder).and().assertThat().existsInRepo()
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .when().usingResource(parentTestFolder).refreshResource()
+ .deleteFolderTree()
+ .and().assertThat().doesNotExistInRepo()
+ .then().usingResource(childTestFolder).assertThat().doesNotExistInRepo()
+ .usingResource(testFile).assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify exception is thrown when deleting inexistent folder tree in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisObjectNotFoundException.class)
+ public void siteManagerDeletesInexistentFolderTree() throws Exception
+ {
+ parentTestFolder = FolderModel.getRandomFolderModel();
+ childTestFolder = FolderModel.getRandomFolderModel();
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, content);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(parentTestFolder).and().assertThat().existsInRepo()
+ .usingResource(parentTestFolder)
+ .createFolder(childTestFolder).and().assertThat().existsInRepo()
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .when().usingResource(parentTestFolder).deleteFolderTree().assertThat().doesNotExistInRepo()
+ .deleteFolderTree();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify inexistent user is NOT able to delete parent folder with multiple children in DocumentLibrary")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisUnauthorizedException.class)
+ public void inexistentUserCannotDeleteFolderTree() throws Exception
+ {
+ parentTestFolder = FolderModel.getRandomFolderModel();
+ childTestFolder = FolderModel.getRandomFolderModel();
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, content);
+ UserModel inexistentUser = UserModel.getRandomUserModel();
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(parentTestFolder).and().assertThat().existsInRepo()
+ .usingResource(parentTestFolder)
+ .createFolder(childTestFolder).and().assertThat().existsInRepo()
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .then().authenticateUser(inexistentUser)
+ .usingResource(parentTestFolder).deleteFolderTree();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to delete parent folder with allVersions parameter set to true")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerDeletesFolderTreeWithAllVersionsParamTrue() throws Exception
+ {
+ parentTestFolder = FolderModel.getRandomFolderModel();
+ childTestFolder = FolderModel.getRandomFolderModel();
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, content);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(parentTestFolder).and().assertThat().existsInRepo()
+ .usingResource(parentTestFolder)
+ .createFolder(childTestFolder).and().assertThat().existsInRepo()
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .when().usingResource(parentTestFolder).deleteFolderTree(true, UnfileObject.DELETE, true)
+ .and().assertThat().doesNotExistInRepo()
+ .then().usingResource(childTestFolder).assertThat().doesNotExistInRepo()
+ .usingResource(testFile).assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Only allVersions=true is supported for delete parent folder tree, allVersions=true is not supported")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisInvalidArgumentException.class})
+ public void deleteFolderTreeWithAllVersionsParamFalseNotSupported() throws Exception
+ {
+ parentTestFolder = FolderModel.getRandomFolderModel();
+ childTestFolder = FolderModel.getRandomFolderModel();
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, content);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(parentTestFolder).and().assertThat().existsInRepo()
+ .usingResource(parentTestFolder)
+ .createFolder(childTestFolder).and().assertThat().existsInRepo()
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .when().usingResource(parentTestFolder).deleteFolderTree(false, UnfileObject.DELETE, true)
+ .and().assertThat().doesNotExistInRepo()
+ .then().usingResource(childTestFolder).assertThat().doesNotExistInRepo()
+ .usingResource(testFile).assertThat().doesNotExistInRepo();
+ }
+
+// @Bug(id="REPO-1108")
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is NOT able to delete parent folder with unfile parameter set to DELETESINGLEFILED, using checked out document")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteManagerDeletesFolderTreeWithDeleteSingleFieldWithCheckoutDoc() throws Exception
+ {
+ parentTestFolder = FolderModel.getRandomFolderModel();
+ childTestFolder = FolderModel.getRandomFolderModel();
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, content);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(parentTestFolder)
+ .usingResource(parentTestFolder)
+ .createFolder(childTestFolder)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .and().checkOut()
+ .when().usingResource(parentTestFolder).deleteFolderTree(true, UnfileObject.DELETESINGLEFILED, true)
+ .and().assertThat().doesNotExistInRepo()
+ .then().usingResource(childTestFolder).assertThat().doesNotExistInRepo()
+ .usingResource(testFile).assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is NOT able to delete parent folder with unfile parameter set to DELETESINGLEFILED, using add object to folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerDeletesFolderTreeWithDeleteSingleFieldWithAddDocToFolder1() throws Exception
+ {
+ parentTestFolder = FolderModel.getRandomFolderModel();
+ childTestFolder = FolderModel.getRandomFolderModel();
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, content);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(parentTestFolder)
+ .createFolder(childTestFolder)
+ .usingResource(parentTestFolder)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .usingResource(testFile).addDocumentToFolder(childTestFolder, true)
+ .then().usingResource(childTestFolder).deleteFolderTree(true, UnfileObject.DELETESINGLEFILED, true)
+ .and().assertThat().doesNotExistInRepo()
+ .then().usingResource(parentTestFolder).assertThat().existsInRepo()
+ .usingResource(testFile).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to delete parent folder with unfile parameter set to DELETESINGLEFILED, using add object to folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerDeletesFolderTreeWithDeleteSingleFieldWithAddDocToFolder2() throws Exception
+ {
+ parentTestFolder = FolderModel.getRandomFolderModel();
+ childTestFolder = FolderModel.getRandomFolderModel();
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, content);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(parentTestFolder)
+ .createFolder(childTestFolder)
+ .usingResource(parentTestFolder)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .usingResource(testFile).addDocumentToFolder(childTestFolder, true)
+ .then().usingResource(childTestFolder).deleteFolderTree(true, UnfileObject.DELETE, true)
+ .and().assertThat().doesNotExistInRepo()
+ .then().usingResource(parentTestFolder).assertThat().existsInRepo()
+ .usingResource(testFile).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Unfile-ing is not supported for delete parent folder tree")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisInvalidArgumentException.class},
+ expectedExceptionsMessageRegExp="Unfiling not supported!*")
+ public void deleteFolderTreeWithUnfileNotSupported() throws Exception
+ {
+ parentTestFolder = FolderModel.getRandomFolderModel();
+ childTestFolder = FolderModel.getRandomFolderModel();
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, content);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(parentTestFolder).and().assertThat().existsInRepo()
+ .usingResource(parentTestFolder)
+ .createFolder(childTestFolder).and().assertThat().existsInRepo()
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .when().usingResource(parentTestFolder).deleteFolderTree(true, UnfileObject.UNFILE, true)
+ .and().assertThat().doesNotExistInRepo()
+ .then().usingResource(childTestFolder).assertThat().doesNotExistInRepo()
+ .usingResource(testFile).assertThat().doesNotExistInRepo();
+ }
+
+// @Bug(id="REPO-1108")
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to delete parent folder with continueOnFailure parameter set to false")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerDeletesFolderTreeWithContinueOnFailureParamFalse() throws Exception
+ {
+ parentTestFolder = FolderModel.getRandomFolderModel();
+ childTestFolder = FolderModel.getRandomFolderModel();
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, content);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(parentTestFolder)
+ .usingResource(parentTestFolder)
+ .createFolder(childTestFolder)
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .when().usingResource(parentTestFolder).deleteFolderTree(true, UnfileObject.DELETE, false)
+ .and().assertThat().doesNotExistInRepo()
+ .then().usingResource(childTestFolder).assertThat().doesNotExistInRepo()
+ .usingResource(testFile).assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site contributor is able to delete parent folder with multiple children created by himself")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorDeletesOwnFolderTree() throws Exception
+ {
+ parentTestFolder = FolderModel.getRandomFolderModel();
+ childTestFolder = FolderModel.getRandomFolderModel();
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, content);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingSite(testSite)
+ .createFolder(parentTestFolder).and().assertThat().existsInRepo()
+ .usingResource(parentTestFolder)
+ .createFolder(childTestFolder).and().assertThat().existsInRepo()
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .when().usingResource(parentTestFolder).refreshResource()
+ .deleteFolderTree()
+ .and().assertThat().doesNotExistInRepo()
+ .then().usingResource(childTestFolder).assertThat().doesNotExistInRepo()
+ .usingResource(testFile).assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site contributor is not able to delete parent folder with multiple children created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorCannotDeleteFolderTreeCreatedByManager() throws Exception
+ {
+ parentTestFolder = FolderModel.getRandomFolderModel();
+ childTestFolder = FolderModel.getRandomFolderModel();
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, content);
+ cmisApi.authenticateUser(testUser)
+ .usingSite(testSite)
+ .createFolder(parentTestFolder).and().assertThat().existsInRepo()
+ .usingResource(parentTestFolder)
+ .createFolder(childTestFolder).and().assertThat().existsInRepo()
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .when().usingResource(parentTestFolder).refreshResource()
+ .deleteFolderTree().and().assertThat().hasFailedDeletedObject(parentTestFolder.getNodeRef())
+ .and().assertThat().existsInRepo()
+ .then().usingResource(childTestFolder).assertThat().existsInRepo()
+ .usingResource(testFile).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site collaborator is not able to delete parent folder with multiple children created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorCannotDeleteFolderTreeCreatedByManager() throws Exception
+ {
+ parentTestFolder = FolderModel.getRandomFolderModel();
+ childTestFolder = FolderModel.getRandomFolderModel();
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, content);
+ cmisApi.authenticateUser(testUser)
+ .usingSite(testSite)
+ .createFolder(parentTestFolder).and().assertThat().existsInRepo()
+ .usingResource(parentTestFolder)
+ .createFolder(childTestFolder).and().assertThat().existsInRepo()
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .when().usingResource(parentTestFolder).refreshResource()
+ .deleteFolderTree().and().assertThat().hasFailedDeletedObject(parentTestFolder.getNodeRef())
+ .and().assertThat().existsInRepo()
+ .then().usingResource(childTestFolder).assertThat().existsInRepo()
+ .usingResource(testFile).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to delete parent folder with multiple children created by himself")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorDeletesOwnFolderTree() throws Exception
+ {
+ parentTestFolder = FolderModel.getRandomFolderModel();
+ childTestFolder = FolderModel.getRandomFolderModel();
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, content);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingSite(testSite)
+ .createFolder(parentTestFolder).and().assertThat().existsInRepo()
+ .usingResource(parentTestFolder)
+ .createFolder(childTestFolder).and().assertThat().existsInRepo()
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .when().usingResource(parentTestFolder).refreshResource()
+ .deleteFolderTree()
+ .and().assertThat().doesNotExistInRepo()
+ .then().usingResource(childTestFolder).assertThat().doesNotExistInRepo()
+ .usingResource(testFile).assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site consumer is not able to delete parent folder with multiple children created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void consumerCannotDeleteFolderTreeCreatedByManager() throws Exception
+ {
+ parentTestFolder = FolderModel.getRandomFolderModel();
+ childTestFolder = FolderModel.getRandomFolderModel();
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, content);
+ cmisApi.authenticateUser(testUser)
+ .usingSite(testSite)
+ .createFolder(parentTestFolder).and().assertThat().existsInRepo()
+ .usingResource(parentTestFolder)
+ .createFolder(childTestFolder).and().assertThat().existsInRepo()
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .when().usingResource(parentTestFolder).refreshResource()
+ .deleteFolderTree().and().assertThat().hasFailedDeletedObject(parentTestFolder.getNodeRef())
+ .and().assertThat().existsInRepo()
+ .then().usingResource(childTestFolder).assertThat().existsInRepo()
+ .usingResource(testFile).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify non invited user is not able to delete parent folder with multiple children in private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonInvitedUserCannotDeleteFolderTreeInPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingUser(testUser).createPrivateRandomSite();
+ parentTestFolder = FolderModel.getRandomFolderModel();
+ childTestFolder = FolderModel.getRandomFolderModel();
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, content);
+ cmisApi.authenticateUser(testUser)
+ .usingSite(privateSite)
+ .createFolder(parentTestFolder).and().assertThat().existsInRepo()
+ .usingResource(parentTestFolder)
+ .createFolder(childTestFolder).and().assertThat().existsInRepo()
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .when().usingResource(parentTestFolder)
+ .deleteFolderTree();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify that only the parent folder is displayed in trash can after deleting it")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void checkTrashCanAfterDeletingParentFolder() throws Exception
+ {
+ parentTestFolder = FolderModel.getRandomFolderModel();
+ childTestFolder = FolderModel.getRandomFolderModel();
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, content);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(parentTestFolder).and().assertThat().existsInRepo()
+ .usingResource(parentTestFolder)
+ .createFolder(childTestFolder).and().assertThat().existsInRepo()
+ .createFile(testFile).and().assertThat().existsInRepo()
+ .when().usingResource(parentTestFolder).refreshResource()
+ .deleteFolderTree()
+ .and().assertThat().doesNotExistInRepo()
+ .then().usingResource(childTestFolder).assertThat().doesNotExistInRepo()
+ .usingResource(testFile).assertThat().doesNotExistInRepo();
+ dataUser.assertTrashCanHasContent(parentTestFolder);
+ dataUser.assertTrashCanDoesNotHaveContent(childTestFolder, testFile);
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetAllVersionsTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetAllVersionsTests.java
new file mode 100644
index 00000000000..f9a948b29ba
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetAllVersionsTests.java
@@ -0,0 +1,186 @@
+package org.alfresco.cmis;
+
+import org.alfresco.cmis.exception.InvalidCmisObjectException;
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.*;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.client.api.OperationContext;
+import org.apache.chemistry.opencmis.commons.PropertyIds;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class GetAllVersionsTests extends CmisTest
+{
+ UserModel siteManager;
+ SiteModel publicSite;
+ FileModel testFile, managerFile;
+ private DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ managerFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ siteManager = dataUser.createRandomTestUser();
+ publicSite = dataSite.usingUser(siteManager).createPublicRandomSite();
+ usersWithRoles = dataUser.usingUser(siteManager)
+ .addUsersWithRolesToSite(publicSite, UserRole.SiteContributor, UserRole.SiteCollaborator, UserRole.SiteConsumer);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(managerFile).assertThat().existsInRepo()
+ .and().checkOut().assertThat().documentIsCheckedOut()
+ .then().prepareDocumentForCheckIn().checkIn()
+ .and().checkOut().assertThat().documentIsCheckedOut()
+ .then().prepareDocumentForCheckIn()
+ .withMajorVersion().checkIn();
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.SANITY,
+ description = "Verify site manager can get all versions for a valid document")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerShouldGetAllVersionsForAValidDocument() throws Exception
+ {
+ cmisApi.authenticateUser(siteManager).usingResource(managerFile)
+ .usingVersion().getAllDocumentVersions().assertHasVersions(1.0, 1.1, 2.0);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager can not get all versions for a document that was deleted")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = CmisObjectNotFoundException.class)
+ public void siteManagerShouldNotGetAllVersionsForADeletedDocument() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .and().update("content 1").update("content 2")
+ .assertThat().documentHasVersion(1.2).usingVersion().getAllDocumentVersions().assertHasVersions(1.0, 1.1, 1.2)
+ .and().delete()
+ .then().usingVersion().getAllDocumentVersions();
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager can get all versions for a document using OperationContext: OrderBy")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerShouldGetAllVersionsWithOperationContextForADocument() throws Exception
+ {
+ OperationContext context = cmisApi.authenticateUser(siteManager).getSession().createOperationContext();
+ context.setOrderBy(PropertyIds.OBJECT_ID + " DESC");
+
+ cmisApi.authenticateUser(siteManager).usingResource(managerFile)
+ .usingVersion().getAllDocumentVersionsBy(context).assertHasVersionsInOrder(2.0, 1.1, 1.0);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager cannot get all versions for a folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=InvalidCmisObjectException.class)
+ public void siteManagerCannotGetAllVersionsForFolder() throws Exception
+ {
+ FolderModel folder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFolder(folder).assertThat().existsInRepo()
+ .usingVersion().getAllDocumentVersions();
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager can get all versions for a valid checked out document")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerShouldGetAllVersionsForCheckedOutDocument() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .and().checkOut().assertThat().documentIsCheckedOut()
+ .then().prepareDocumentForCheckIn().checkIn()
+ .and().checkOut().assertThat().documentIsCheckedOut()
+ .then().usingResource(testFile)
+ .usingVersion().getAllDocumentVersions().assertHasVersions("pwc", 1.1, 1.0);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager can get all versions for a valid pwc document")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerShouldGetAllVersionsForPWCDocument() throws Exception
+ {
+ OperationContext context = cmisApi.getSession().createOperationContext();
+ context.setOrderBy(PropertyIds.OBJECT_ID + " DESC");
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .and().checkOut().assertThat().documentIsCheckedOut()
+ .then().prepareDocumentForCheckIn().checkIn()
+ .and().checkOut().assertThat().documentIsCheckedOut()
+ .then().usingResource(testFile).usingPWCDocument()
+ .usingVersion().getAllDocumentVersions().assertHasVersions(1.1, 1.0, "pwc")
+ .usingVersion().getAllDocumentVersionsBy(context).assertHasVersionsInOrder("pwc", 1.1, 1.0);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site collaborator can get all versions for a document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorCanGetAllVersionsForDocumentCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingResource(managerFile)
+ .usingVersion().getAllDocumentVersions().assertHasVersions(1.0, 1.1, 2.0);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site collaborator can get all versions for a document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorCanGetAllVersionsForDocumentCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingResource(managerFile)
+ .usingVersion().getAllDocumentVersions().assertHasVersions(1.0, 1.1, 2.0);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site consumer can get all versions for a document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void consumerCanGetAllVersionsForDocumentCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .usingResource(managerFile)
+ .usingVersion().getAllDocumentVersions().assertHasVersions(1.0, 1.1, 2.0);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify non invited user can get all versions for a document in public site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void nonInvitedUserCannotGetAllVersionsForDocumentFromPublicSite() throws Exception
+ {
+ UserModel nonInvitedUser = dataUser.createRandomTestUser();
+ cmisApi.authenticateUser(nonInvitedUser)
+ .usingResource(managerFile)
+ .usingVersion().getAllDocumentVersions().assertHasVersions(1.0, 1.1, 2.0);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify non invited user cannot get all versions for a document in private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonInvitedUserCannotGetAllVersionsForDocumentFromPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingUser(siteManager).createPrivateRandomSite();
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(siteManager).usingSite(privateSite).createFile(testFile)
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .usingResource(testFile)
+ .usingVersion().getAllDocumentVersions().assertHasVersions(1.0);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify non invited user cannot get all versions for a document in moderated site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonInvitedUserCannotGetAllVersionsForDocumentFromModeratedSite() throws Exception
+ {
+ SiteModel moderated = dataSite.usingUser(siteManager).createPrivateRandomSite();
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(siteManager).usingSite(moderated).createFile(testFile)
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .usingResource(testFile)
+ .usingVersion().getAllDocumentVersions().assertHasVersions(1.0);
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetCheckedOutDocumentsTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetCheckedOutDocumentsTests.java
new file mode 100644
index 00000000000..0d49f2f5c0c
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetCheckedOutDocumentsTests.java
@@ -0,0 +1,200 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.Utility;
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.*;
+import org.alfresco.utility.report.Bug;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.client.api.OperationContext;
+import org.apache.chemistry.opencmis.commons.PropertyIds;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class GetCheckedOutDocumentsTests extends CmisTest
+{
+ UserModel testUser;
+ SiteModel testSite;
+ FileModel testFile;
+ FolderModel testFolder;
+ private DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ testFolder = FolderModel.getRandomFolderModel();
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createPublicRandomSite();
+ usersWithRoles = dataUser.usingUser(testUser)
+ .addUsersWithRolesToSite(testSite, UserRole.SiteContributor, UserRole.SiteCollaborator, UserRole.SiteConsumer);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(testFolder)
+ .usingResource(testFolder).createFile(testFile).assertThat().existsInRepo()
+ .and().checkOut().assertThat().documentIsCheckedOut();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify site manager is able to get checked out documents from a valid folder")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerShouldGetCheckedOutDocumentsFromAValidFolder() throws Exception
+ {
+ cmisApi.authenticateUser(testUser)
+ .usingResource(testFolder)
+ .assertThat().folderHasCheckedOutDocument(testFile);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify site manager is able to get checked out documents from session")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerShouldGetCheckedOutDocumentsFromSession() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).assertThat().sessionHasCheckedOutDocument(testFile);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager CANNOT get checked out documents from inexistent folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisObjectNotFoundException.class})
+ public void siteManagerCannotGetCheckedOutDocumentsFromInexistentFolder() throws Exception
+ {
+ FolderModel testFolder = FolderModel.getRandomFolderModel();
+ testFolder.setCmisLocation(Utility.buildPath("/", testFolder.getCmisLocation()));
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .and().usingResource(testFolder)
+ .assertThat().folderHasCheckedOutDocument(testFile);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify that user is not able to get checked out documents from session created by admin in root")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void userShouldNotGetCheckedOutDocumentFromSessionCreatedByAdminInRoot() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingRoot()
+ .createFile(testFile).assertThat().existsInRepo()
+ .and().checkOut()
+ .then().authenticateUser(testUser)
+ .and().assertThat().sessioDoesNotHaveCheckedOutDocument(testFile);
+ }
+
+ @Bug(id="MNT-17357")
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to get checked out documents created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorShouldGetCheckedOutDocumentsFromFolderCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingResource(testFolder)
+ .assertThat().folderHasCheckedOutDocument(testFile);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to get checked out documents created by himslef")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorShouldGetCheckedOutDocumentsCreatedByHimself() throws Exception
+ {
+ FileModel collaboratorFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingResource(testFolder)
+ .createFile(collaboratorFile).checkOut()
+ .usingResource(testFolder)
+ .assertThat().folderHasCheckedOutDocument(collaboratorFile)
+ .assertThat().sessionHasCheckedOutDocument(collaboratorFile);
+ }
+
+ @Bug(id="MNT-17357")
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site contributor is able to get checked out documents created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorShouldGetCheckedOutDocumentsFromFolderCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingResource(testFolder)
+ .assertThat().folderHasCheckedOutDocument(testFile);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to get checked out documents created by himslef")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorShouldGetCheckedOutDocumentsCreatedByHimself() throws Exception
+ {
+ FileModel contributorFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingResource(testFolder)
+ .createFile(contributorFile).checkOut()
+ .usingResource(testFolder)
+ .assertThat().folderHasCheckedOutDocument(contributorFile)
+ .assertThat().sessionHasCheckedOutDocument(contributorFile);
+ }
+
+ @Bug(id="MNT-17357")
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to get checked out documents created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void consumerShouldGetCheckedOutDocumentsFromFolderCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingResource(testFolder)
+ .assertThat().folderHasCheckedOutDocument(testFile);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify non invited user is not able to get checked out documents")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonInvitedUserShouldNotGetCheckedOutDocuments() throws Exception
+ {
+ FileModel doc = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ FolderModel folder = FolderModel.getRandomFolderModel();
+ SiteModel privateSite = dataSite.usingUser(testUser).createPrivateRandomSite();
+ cmisApi.authenticateUser(testUser).usingSite(privateSite)
+ .createFolder(folder).usingResource(folder)
+ .createFile(doc).checkOut()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingResource(folder)
+ .assertThat().folderHasCheckedOutDocument(doc);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager user is able to get checked out documents from folder with operation context")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanGetCheckedOutDocumentsFromFolderWithOperationContext() throws Exception
+ {
+ OperationContext context = cmisApi.authenticateUser(testUser).getSession().createOperationContext();
+ context.setOrderBy(PropertyIds.NAME + " DESC");
+ FileModel doc1 = new FileModel("a-file.txt", FileType.TEXT_PLAIN, documentContent);
+ FileModel doc2 = new FileModel("b-file.txt", FileType.TEXT_PLAIN, documentContent);
+ FileModel doc3 = new FileModel("c-file.txt", FileType.TEXT_PLAIN, documentContent);
+ FolderModel folder = FolderModel.getRandomFolderModel();
+ SiteModel privateSite = dataSite.usingUser(testUser).createPrivateRandomSite();
+ cmisApi.authenticateUser(testUser).usingSite(privateSite)
+ .createFolder(folder).usingResource(folder)
+ .createFile(doc1).checkOut()
+ .createFile(doc2).checkOut()
+ .createFile(doc3)
+ .usingResource(folder)
+ .assertThat().folderHasCheckedOutDocument(context, doc2, doc1);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify user is able to get checked out documents from session with operation context")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanGetCheckedOutDocumentsFromSessionWithOperationContext() throws Exception
+ {
+ UserModel user = dataUser.createRandomTestUser();
+ OperationContext context = cmisApi.authenticateUser(user).getSession().createOperationContext();
+ context.setOrderBy(PropertyIds.NAME + " DESC");
+ FileModel doc1 = new FileModel("a-file.txt", FileType.TEXT_PLAIN, documentContent);
+ FileModel doc2 = new FileModel("b-file.txt", FileType.TEXT_PLAIN, documentContent);
+ FileModel doc3 = new FileModel("c-file.txt", FileType.TEXT_PLAIN, documentContent);
+ SiteModel publicSite = dataSite.usingUser(user).createPublicRandomSite();
+ cmisApi.authenticateUser(user).usingSite(publicSite)
+ .createFile(doc1).checkOut()
+ .createFile(doc2).checkOut()
+ .createFile(doc3)
+ .then().assertThat().sessionHasCheckedOutDocument(context, doc2, doc1);
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetChildrenTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetChildrenTests.java
new file mode 100644
index 00000000000..9716ae64406
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetChildrenTests.java
@@ -0,0 +1,203 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.FolderModel;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class GetChildrenTests extends CmisTest
+{
+ UserModel testUser;
+ SiteModel testSite;
+ FileModel testFile;
+ FileModel secondFile;
+ FolderModel testFolder;
+ FolderModel subFolder;
+ DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createPublicRandomSite();
+ usersWithRoles = dataUser.addUsersWithRolesToSite(testSite, UserRole.SiteCollaborator, UserRole.SiteContributor, UserRole.SiteConsumer);
+ }
+
+ @BeforeMethod(alwaysRun = true)
+ public void generateRandomContent()
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ secondFile = FileModel.getRandomFileModel(FileType.MSEXCEL);
+ testFolder = FolderModel.getRandomFolderModel();
+ subFolder = FolderModel.getRandomFolderModel();
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.SANITY, description = "Get children from valid folder")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void getChildrenFromValidFolder() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(testFolder).assertThat().existsInRepo()
+ .and().usingResource(testFolder)
+ .createFile(testFile)
+ .createFile(secondFile)
+ .createFolder(subFolder)
+ .then().usingResource(testFolder).assertThat().hasChildren(testFile, secondFile, subFolder)
+ .assertThat().hasFiles(testFile, secondFile)
+ .assertThat().hasFolders(subFolder);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Fails to get children from folder that was previously deleted")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS} , expectedExceptions = CmisObjectNotFoundException.class)
+ public void getChildrenFromDeletedFolder() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(testFolder)
+ .and().usingResource(testFolder)
+ .createFile(testFile)
+ .createFile(secondFile)
+ .createFolder(subFolder)
+ .then().usingResource(testFolder)
+ .assertThat().hasChildren(testFile, secondFile, subFolder)
+ .and().usingResource(testFolder).refreshResource().and().deleteFolderTree()
+ .then().usingResource(testFolder).assertThat().hasChildren(testFile, secondFile, subFolder);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site collaborator can get children for a folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteCollaboratorCanGetChildrenFromValidFolderCreatedBySelf() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingSite(testSite)
+ .createFolder(testFolder).assertThat().existsInRepo()
+ .and().usingResource(testFolder)
+ .createFile(testFile)
+ .createFile(secondFile)
+ .createFolder(subFolder)
+ .then().usingResource(testFolder).assertThat().hasChildren(testFile, secondFile, subFolder)
+ .assertThat().hasFiles(testFile, secondFile)
+ .assertThat().hasFolders(subFolder);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site collaborator can get children for a folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteCollaboratorCanGetChildrenFromValidFolderCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(testFolder).assertThat().existsInRepo()
+ .and().usingResource(testFolder)
+ .createFile(testFile)
+ .createFile(secondFile)
+ .createFolder(subFolder);
+
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingResource(testFolder).assertThat().hasChildren(testFile, secondFile, subFolder)
+ .assertThat().hasFiles(testFile, secondFile)
+ .assertThat().hasFolders(subFolder);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site contributor can get children for a folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteContributorCanGetChildrenFromValidFolderCreatedBySelf() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingSite(testSite)
+ .createFolder(testFolder).assertThat().existsInRepo()
+ .and().usingResource(testFolder)
+ .createFile(testFile)
+ .createFile(secondFile)
+ .createFolder(subFolder)
+ .then().usingResource(testFolder).assertThat().hasChildren(testFile, secondFile, subFolder)
+ .assertThat().hasFiles(testFile, secondFile)
+ .assertThat().hasFolders(subFolder);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site contributor can get children for a folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteContributorCanGetChildrenFromValidFolderCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(testFolder).assertThat().existsInRepo()
+ .and().usingResource(testFolder)
+ .createFile(testFile)
+ .createFile(secondFile)
+ .createFolder(subFolder);
+
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingResource(testFolder).assertThat().hasChildren(testFile, secondFile, subFolder)
+ .assertThat().hasFiles(testFile, secondFile)
+ .assertThat().hasFolders(subFolder);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site consumer can get children for a folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteConsumerCanGetChildrenFromValidFolder() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(testFolder).assertThat().existsInRepo()
+ .and().usingResource(testFolder)
+ .createFile(testFile)
+ .createFile(secondFile)
+ .createFolder(subFolder);
+
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .usingResource(testFolder).assertThat().hasChildren(testFile, secondFile, subFolder)
+ .assertThat().hasFiles(testFile, secondFile)
+ .assertThat().hasFolders(subFolder);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify non site member cannot get children for a folder from a private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions={ CmisPermissionDeniedException.class, CmisUnauthorizedException.class })
+ public void nonSiteMemberCannotGetChildrenFromValidFolderFromAPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingAdmin().createPrivateRandomSite();
+
+ cmisApi.authenticateUser(testUser).usingSite(privateSite)
+ .createFolder(testFolder).assertThat().existsInRepo()
+ .and().usingResource(testFolder)
+ .createFile(testFile)
+ .createFile(secondFile)
+ .createFolder(subFolder);
+
+ cmisApi.authenticateUser(testUser)
+ .usingResource(testFolder).assertThat().hasChildren(testFile, secondFile, subFolder);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify non site member cannot get children for a folder from a moderated site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions={ CmisPermissionDeniedException.class, CmisUnauthorizedException.class })
+ public void nonSiteMemberCannotGetChildrenFromValidFolderFromAModeratedSite() throws Exception
+ {
+ SiteModel moderatedSite = dataSite.usingAdmin().createModeratedRandomSite();
+
+ cmisApi.authenticateUser(testUser).usingSite(moderatedSite)
+ .createFolder(testFolder).assertThat().existsInRepo()
+ .and().usingResource(testFolder)
+ .createFile(testFile)
+ .createFile(secondFile)
+ .createFolder(subFolder);
+
+ cmisApi.authenticateUser(testUser)
+ .usingResource(testFolder).assertThat().hasChildren(testFile, secondFile, subFolder);
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetContentStreamTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetContentStreamTests.java
new file mode 100644
index 00000000000..5de39f20262
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetContentStreamTests.java
@@ -0,0 +1,200 @@
+package org.alfresco.cmis;
+
+import org.alfresco.cmis.exception.InvalidCmisObjectException;
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.*;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * Created by Claudia Agache on 9/27/2016.
+ */
+public class GetContentStreamTests extends CmisTest
+{
+ SiteModel publicSite, privateSite;
+ UserModel siteManager;
+ FileModel testFile;
+ String content = "file content";
+ private DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ siteManager = dataUser.createRandomTestUser();
+ publicSite = dataSite.usingUser(siteManager).createPublicRandomSite();
+ privateSite = dataSite.usingUser(siteManager).createPrivateRandomSite();
+ usersWithRoles = dataUser.addUsersWithRolesToSite(publicSite, UserRole.SiteManager, UserRole.SiteContributor, UserRole.SiteCollaborator, UserRole.SiteConsumer);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify site manager is able to get a document content in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerShouldGetDocumentContent() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, content);
+ cmisApi.authenticateUser(siteManager)
+ .usingSite(publicSite).createFile(testFile)
+ .then().assertThat().existsInRepo()
+ .and().assertThat().contentIs(content);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify site manager is able to get empty document content in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerShouldGetEmptyDocumentContent() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+ cmisApi.authenticateUser(siteManager)
+ .usingSite(publicSite).createFile(testFile)
+ .then().assertThat().existsInRepo().and().assertThat().contentIs("");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to get content from checked out document with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerShouldGetContentFromCheckedOutDoc() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, content);
+ cmisApi.authenticateUser(siteManager)
+ .usingSite(publicSite).createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .then().checkOut()
+ .and().assertThat().contentIs(content);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify admin is able to get document content with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void adminShouldGetContentOfFileCreatedByOtherUser() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, content);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(dataUser.getAdminUser())
+ .usingResource(testFile).assertThat().contentIs(content);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to get content of file created by other user in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerShouldGetContentOfFileCreatedByOtherUser() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, content);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager))
+ .usingResource(testFile).assertThat().contentIs(content);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to get content of file created by other user in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorShouldGetContentOfFileCreatedByOtherUser() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, content);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingResource(testFile).assertThat().contentIs(content);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to get content of file created by self in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorShouldGetContentOfFileCreatedBySelf() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, content);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .and().assertThat().contentIs(content);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site contributor is able to get content of file created by other user in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorShouldGetContentOfFileCreatedByOtherUser() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, content);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingResource(testFile).assertThat().contentIs(content);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site contributor is able to get content of file created by self in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorShouldGetContentOfFileCreatedBySelf() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, content);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .and().assertThat().contentIs(content);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site consumer is able to get content of file created by other user in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void consumerShouldGetContentOfFileCreatedByOtherUser() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, content);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .usingResource(testFile).assertThat().contentIs(content);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to get content from checked out document with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerShouldGetContentOfPWCDoc() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, content);
+ cmisApi.authenticateUser(siteManager)
+ .usingSite(publicSite).createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .then().checkOut().assertThat().documentIsCheckedOut()
+ .usingPWCDocument().assertThat().contentIs(content);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify unauthorized is not able to get content of file created in a private site with CMIS")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS }, expectedExceptions = { CmisPermissionDeniedException.class, CmisUnauthorizedException.class })
+ public void unauthorizedUserShouldNotGetFileContent() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, content);
+ cmisApi.authenticateUser(siteManager).usingSite(privateSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager))
+ .usingResource(testFile).assertThat().contentIs(content);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify user is not able to get content of non existent file with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = CmisObjectNotFoundException.class)
+ public void userShouldNotGetContentOfNonexistentFile() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, content);
+ testFile.setCmisLocation("/" + testFile.getName() + "/");
+ cmisApi.authenticateUser(siteManager)
+ .usingResource(testFile).assertThat().contentIs(content);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify user is not able to get content of invalid file with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = InvalidCmisObjectException.class, expectedExceptionsMessageRegExp = "^Content at.*is not a file$")
+ public void userShouldNotGetContentOfInvalidFile() throws Exception
+ {
+ FolderModel testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFolder(testFolder).assertThat().existsInRepo()
+ .and().assertThat().contentIs(content);
+ }
+
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetDescendantsTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetDescendantsTests.java
new file mode 100644
index 00000000000..043e3b20c4e
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetDescendantsTests.java
@@ -0,0 +1,194 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.*;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class GetDescendantsTests extends CmisTest
+{
+ UserModel testUser;
+ SiteModel testSite;
+ FileModel testFile;
+ FileModel fileModel;
+ FolderModel testFolder;
+ FolderModel folderModel;
+ DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createPublicRandomSite();
+ usersWithRoles = dataUser.addUsersWithRolesToSite(testSite, UserRole.SiteCollaborator, UserRole.SiteContributor, UserRole.SiteConsumer);
+ }
+
+ @BeforeMethod(alwaysRun = true)
+ public void generateRandomContent()
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ fileModel = FileModel.getRandomFileModel(FileType.MSPOWERPOINT);
+ testFolder = FolderModel.getRandomFolderModel();
+ folderModel = FolderModel.getRandomFolderModel();
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.SANITY,
+ description = "Verify site manager can get descendants for valid parent folder with at least 3 children and depth set to >=1")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void getDescendantsForValidParentFolderWithAtLeast3ChildrenAndDepthGreaterThan1() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder)
+ .and().assertThat().existsInRepo()
+ .and().usingResource(testFolder).createFile(testFile)
+ .and().createFile(fileModel)
+ .and().createFolder(folderModel)
+ .then().usingResource(testFolder).assertThat().hasDescendants(1, folderModel, fileModel, testFile);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.SANITY,
+ description = "Verify site manager can get descendants for valid parent folder with at least 3 children and depth set to -1")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void getDescendantsForValidParentFolderWithAtLeast3ChildrenAndDepthSetToMinus1() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder)
+ .and().assertThat().existsInRepo()
+ .and().usingResource(testFolder).createFile(testFile)
+ .then().createFile(fileModel)
+ .and().createFolder(folderModel)
+ .then().usingResource(testFolder).assertThat().hasDescendants(-1, folderModel, fileModel, testFile);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager CANNOT get descendants for valid parent folder with at least 2 children and depth set to 0")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisInvalidArgumentException.class})
+ public void getDescendantsForValidParentFolderWithAtLeast2ChildrenAndDepthSetTo0() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder)
+ .and().usingResource(testFolder).createFile(testFile)
+ .and().createFolder(folderModel)
+ .then().usingResource(testFolder).assertThat().hasDescendants(0, folderModel, testFile);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager CANNOT get descendants for valid parent folder with at least 2 children and depth set to -2")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisInvalidArgumentException.class})
+ public void getDescendantsForValidParentFolderWithAtLeast2ChildrenAndDepthSetToMinus2() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder)
+ .and().usingResource(testFolder).createFile(testFile)
+ .and().createFolder(folderModel)
+ .then().usingResource(testFolder).assertThat().hasDescendants(-2, folderModel, testFile);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager CANNOT get descendants for parent folder with at least 2 children that was previously deleted")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisObjectNotFoundException.class})
+ public void getDescendantsForDeletedParentFolderWithAtLeast2Children() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder)
+ .and().usingResource(testFolder).createFile(testFile)
+ .and().createFolder(folderModel)
+ .and().usingResource(testFolder).deleteFolderTree()
+ .then().usingResource(testFolder)
+ .assertThat().hasDescendants(1, folderModel, testFile);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site collaborator can get descendants for parent folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteCollaboratorCanGetDescendantsForValidFolderCreatedBySelf() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingSite(testSite)
+ .createFolder(testFolder)
+ .usingResource(testFolder).createFile(testFile)
+ .usingResource(testFolder).assertThat().hasDescendants(-1, testFile);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site collaborator can get descendants for parent folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteCollaboratorCanGetDescendantsForValidFolderCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(testFolder)
+ .usingResource(testFolder).createFile(testFile);
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingResource(testFolder)
+ .assertThat().hasDescendants(-1, testFile);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site contributor can get descendants for parent folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteContributorCanGetDescendantsForValidFolderCreatedBySelf() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingSite(testSite)
+ .createFolder(testFolder)
+ .usingResource(testFolder).createFile(testFile)
+ .usingResource(testFolder).assertThat().hasDescendants(-1, testFile);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site contributor can get descendants for parent folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteContributorCanGetDescendantsForValidFolderCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(testFolder)
+ .usingResource(testFolder).createFile(testFile);
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingResource(testFolder)
+ .assertThat().hasDescendants(-1, testFile);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site consumer can get descendants for parent folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteConsumerCanGetDescendantsForValidFolder() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(testFolder)
+ .usingResource(testFolder).createFile(testFile);
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer)).usingResource(testFolder)
+ .assertThat().hasDescendants(-1, testFile);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that non site member cannot get descendants for a folder from a private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions={ CmisPermissionDeniedException.class, CmisUnauthorizedException.class })
+ public void nonSiteMemberCannotGetDescendantsAFolderFromAPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingAdmin().createPrivateRandomSite();
+
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingSite(privateSite)
+ .createFolder(testFolder)
+ .usingResource(testFolder).createFile(testFile);
+
+ cmisApi.authenticateUser(testUser).usingResource(testFolder)
+ .assertThat().hasDescendants(-1, testFile);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that non site member cannot get descendants for a folder from a moderated site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions={ CmisPermissionDeniedException.class, CmisUnauthorizedException.class })
+ public void nonSiteMemberCannotGetDescendantsAFolderFromAModeratedSite() throws Exception
+ {
+ SiteModel moderatedSite = dataSite.usingAdmin().createModeratedRandomSite();
+
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingSite(moderatedSite)
+ .createFolder(testFolder)
+ .usingResource(testFolder).createFile(testFile);
+
+ cmisApi.authenticateUser(testUser).usingResource(testFolder)
+ .assertThat().hasDescendants(-1, testFile);
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetExtensionTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetExtensionTests.java
new file mode 100644
index 00000000000..83ac7bd4068
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetExtensionTests.java
@@ -0,0 +1,153 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.FolderModel;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class GetExtensionTests extends CmisTest
+{
+ UserModel testUser, nonInvitedUser;
+ SiteModel testSite;
+ FileModel testFile, managerFile;
+ FolderModel managerFolder;
+ private DataUser.ListUserWithRoles usersWithRoles;
+ private String titledAspect = "P:cm:titled";
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ managerFile = FileModel.getRandomFileModel(FileType.XML, documentContent);
+ managerFolder = FolderModel.getRandomFolderModel();
+ testUser = dataUser.createRandomTestUser();
+ nonInvitedUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createPublicRandomSite();
+ usersWithRoles = dataUser.usingUser(testUser)
+ .addUsersWithRolesToSite(testSite, UserRole.SiteContributor, UserRole.SiteCollaborator, UserRole.SiteConsumer);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(managerFile)
+ .createFolder(managerFolder);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Site manager can get extensions from a valid folder")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerCanGetExtensionsForValidFolder() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingResource(managerFolder)
+ .assertThat().hasAspectExtension(titledAspect);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Site manager can get extensions from a valid file")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerCanGetExtensionsForValidFile() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingResource(managerFile)
+ .assertThat().hasAspectExtension(titledAspect);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Site manager cannot get extensions from an invalid document - that was deleted")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisObjectNotFoundException.class})
+ public void siteManagerCannotGetExtensionsForInvalidDocument() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFile(testFile)
+ .then().assertThat().hasAspectExtension(titledAspect)
+ .and().delete()
+ .then().assertThat().hasAspectExtension(titledAspect);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Site manager can get extensions from checkedout document")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanGetExtensionsForCheckedOutDocument() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD, documentContent);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).checkOut()
+ .then().assertThat().hasAspectExtension(titledAspect)
+ .then().usingPWCDocument()
+ .assertThat().hasAspectExtension(titledAspect);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Site collaborator can get extensions")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorCanGetExtensions() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingResource(managerFolder)
+ .assertThat().hasAspectExtension(titledAspect)
+ .then().usingResource(managerFile)
+ .assertThat().hasAspectExtension(titledAspect);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Site contributor can get extensions")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorCanGetExtensions() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingResource(managerFolder)
+ .assertThat().hasAspectExtension(titledAspect)
+ .then().usingResource(managerFile)
+ .assertThat().hasAspectExtension(titledAspect);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Site consumer can get extensions")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void consumerCanGetExtensions() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingResource(managerFolder)
+ .assertThat().hasAspectExtension(titledAspect)
+ .then().usingResource(managerFile)
+ .assertThat().hasAspectExtension(titledAspect);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Non invited user can get extensions in public site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void nonInvitedUserCanGetExtensionsInPublicSite() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingResource(managerFolder)
+ .assertThat().hasAspectExtension(titledAspect)
+ .then().usingResource(managerFile)
+ .assertThat().hasAspectExtension(titledAspect);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Non invited user cannot get extensions in private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonInvitedUserCannotGetExtensionsInPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingUser(testUser).createPrivateRandomSite();
+ FileModel privateDoc = FileModel.getRandomFileModel(FileType.HTML, documentContent);
+ cmisApi.authenticateUser(testUser).usingSite(privateSite)
+ .createFile(privateDoc)
+ .then().authenticateUser(nonInvitedUser).assertThat().hasAspectExtension(titledAspect);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Non invited user cannot get extensions in moderated site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonInvitedUserCannotGetExtensionsInModeratedSite() throws Exception
+ {
+ SiteModel moderatedSite = dataSite.usingUser(testUser).createPrivateRandomSite();
+ FileModel moderatedDoc = FileModel.getRandomFileModel(FileType.HTML, documentContent);
+ cmisApi.authenticateUser(testUser).usingSite(moderatedSite)
+ .createFile(moderatedDoc)
+ .then().authenticateUser(nonInvitedUser).assertThat().hasAspectExtension(titledAspect);
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetFolderParentTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetFolderParentTests.java
new file mode 100644
index 00000000000..946b8c7e21f
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetFolderParentTests.java
@@ -0,0 +1,151 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.*;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class GetFolderParentTests extends CmisTest
+{
+ UserModel testUser;
+ SiteModel testSite;
+ FolderModel testFolder;
+ FolderModel parentFolder;
+ DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createPublicRandomSite();
+ usersWithRoles = dataUser.addUsersWithRolesToSite(testSite, UserRole.SiteCollaborator, UserRole.SiteContributor, UserRole.SiteConsumer);
+ }
+
+ @BeforeMethod(alwaysRun = true)
+ public void generateRandomContent()
+ {
+ parentFolder = FolderModel.getRandomFolderModel();
+ testFolder = FolderModel.getRandomFolderModel();
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.SANITY, description = "Verify folder parent")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void verifyFolderParent() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder)
+ .and().assertThat().existsInRepo()
+ .and().usingResource(testFolder).createFolder(FolderModel.getRandomFolderModel())
+ .then().assertThat().folderHasParent(testFolder);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION, description = "Verify folder parent that was previously deleted")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisObjectNotFoundException.class})
+ public void verifyFolderParentThatWasDeleted() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(parentFolder)
+ .and().assertThat().existsInRepo()
+ .and().usingResource(parentFolder).createFolder(testFolder)
+ .then().assertThat().folderHasParent(parentFolder)
+ .and().usingResource(parentFolder).deleteFolderTree()
+ .then().usingResource(testFolder).assertThat().folderHasParent(parentFolder);
+ }
+
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site contributor can get folder parent")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteContributorVerifyFolderParentCreatedBySelf() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingSite(testSite).createFolder(testFolder)
+ .and().assertThat().existsInRepo()
+ .and().usingResource(testFolder).createFolder(FolderModel.getRandomFolderModel())
+ .then().assertThat().folderHasParent(testFolder);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site contributor can get folder parent")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteContributorVerifyFolderParentCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(parentFolder)
+ .and().assertThat().existsInRepo()
+ .and().usingResource(parentFolder).createFolder(testFolder);
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingResource(testFolder)
+ .assertThat().folderHasParent(parentFolder);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site collaborator can get folder parent")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteCollaboratorVerifyFolderParentCreatedBySelf() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingSite(testSite).createFolder(testFolder)
+ .and().assertThat().existsInRepo()
+ .and().usingResource(testFolder).createFolder(FolderModel.getRandomFolderModel())
+ .then().assertThat().folderHasParent(testFolder);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site collaborator can get folder parent")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteCollaboratorVerifyFolderParentCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(parentFolder)
+ .and().assertThat().existsInRepo()
+ .and().usingResource(parentFolder).createFolder(testFolder);
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingResource(testFolder)
+ .assertThat().folderHasParent(parentFolder);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site consumer can get folder parent")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteConsumerVerifyFolderParent() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(parentFolder)
+ .and().assertThat().existsInRepo()
+ .and().usingResource(parentFolder).createFolder(testFolder);
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer)).usingResource(testFolder)
+ .assertThat().folderHasParent(parentFolder);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify non site member for a private site is not able to get folder parent")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions={ CmisPermissionDeniedException.class, CmisUnauthorizedException.class })
+ public void nonSiteMemberGetFolderParentFromPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingAdmin().createPrivateRandomSite();
+
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingSite(privateSite).createFolder(parentFolder)
+ .and().assertThat().existsInRepo()
+ .and().usingResource(parentFolder).createFolder(testFolder);
+
+ cmisApi.authenticateUser(testUser).usingResource(testFolder)
+ .assertThat().folderHasParent(parentFolder);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify non site member for a moderated site is not able to get folder parent")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions={ CmisPermissionDeniedException.class, CmisUnauthorizedException.class })
+ public void nonSiteMemberGetFolderParentFromModeratedSite() throws Exception
+ {
+ SiteModel moderatedSite = dataSite.usingAdmin().createModeratedRandomSite();
+
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingSite(moderatedSite).createFolder(parentFolder)
+ .and().assertThat().existsInRepo()
+ .and().usingResource(parentFolder).createFolder(testFolder);
+
+ cmisApi.authenticateUser(testUser).usingResource(testFolder)
+ .assertThat().folderHasParent(parentFolder);
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetFolderTreeTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetFolderTreeTests.java
new file mode 100644
index 00000000000..93f389b7076
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetFolderTreeTests.java
@@ -0,0 +1,211 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.*;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class GetFolderTreeTests extends CmisTest
+{
+ UserModel testUser;
+ SiteModel testSite;
+ FolderModel testFolder;
+ FolderModel folderModel1;
+ FolderModel folderModel11;
+ FolderModel folderModel12;
+ FolderModel folderModel2;
+ DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createPublicRandomSite();
+ usersWithRoles = dataUser.addUsersWithRolesToSite(testSite, UserRole.SiteCollaborator, UserRole.SiteContributor, UserRole.SiteConsumer);
+ }
+
+ @BeforeMethod(alwaysRun = true)
+ public void generateRandomContent()
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ folderModel1 = FolderModel.getRandomFolderModel();
+ folderModel11 = FolderModel.getRandomFolderModel();
+ folderModel12 = FolderModel.getRandomFolderModel();
+ folderModel2 = FolderModel.getRandomFolderModel();
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.SANITY,
+ description = "Verify site manager can get folder tree for valid parent folder with at least 2 children" +
+ " folders and depth set to 1")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void getFolderTreeForValidParentFolderWithAtLeast2ChildrenFoldersAndDepthGreaterThan1() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder)
+ .and().assertThat().existsInRepo()
+ .and().usingResource(testFolder)
+ .and().createFolder(folderModel1)
+ .and().createFolder(folderModel2)
+ .then().usingResource(testFolder).assertThat().hasFolderTree(1, folderModel1, folderModel2);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.SANITY,
+ description = "Verify site manager can get folder tree for valid parent folder with at least 2 children" +
+ " folders and depth set to -1")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void getFolderTreeForValidParentFolderWithAtLeast2ChildrenFoldersAndDepthSetToMinus1() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder)
+ .and().assertThat().existsInRepo()
+ .and().usingResource(testFolder)
+ .and().createFolder(folderModel1)
+ .and().usingResource(folderModel1).createFolder(folderModel2)
+ .then().usingResource(testFolder).assertThat().hasFolderTree(-1, folderModel1, folderModel2);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager can NOT get folder tree for valid parent folder with at least 2 children" +
+ " folders and depth set to 0")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisInvalidArgumentException.class})
+ public void getFolderTreeForValidParentFolderWithAtLeast2ChildrenFoldersAndDepthSetTo0() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder)
+ .and().assertThat().existsInRepo()
+ .and().usingResource(testFolder)
+ .and().createFolder(folderModel11)
+ .and().createFolder(folderModel12)
+ .and().usingResource(folderModel11).createFolder(folderModel2)
+ .then().usingResource(testFolder)
+ .assertThat().hasFolderTree(0, folderModel11);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager can NOT get folder tree for valid parent folder with at least 2 children" +
+ " folders and depth set to -2")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisInvalidArgumentException.class})
+ public void getFolderTreeForValidParentFolderWithAtLeast2ChildrenFoldersAndDepthSetToMinus2() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder)
+ .and().assertThat().existsInRepo()
+ .and().usingResource(testFolder)
+ .and().createFolder(folderModel11)
+ .and().createFolder(folderModel12)
+ .and().usingResource(folderModel11).createFolder(folderModel2)
+ .then().usingResource(testFolder)
+ .assertThat().hasFolderTree(-2, folderModel11);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager can NOT get folder tree for parent folder with children" +
+ " that was previously deleted")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisObjectNotFoundException.class})
+ public void getFolderTreeForDeletedParentFolderWithChildren() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder)
+ .and().assertThat().existsInRepo()
+ .and().usingResource(testFolder)
+ .and().createFolder(folderModel11)
+ .and().createFolder(folderModel12)
+ .and().usingResource(folderModel11).createFolder(folderModel2)
+ .and().usingResource(testFolder).deleteFolderTree()
+ .then().usingResource(testFolder)
+ .assertThat().hasFolderTree(1, folderModel11);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site collaborator can get folder tree for valid parent folder with at least 2 children folders")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteCollaboratorCanGetFolderTreeForValidParentFolder() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingSite(testSite)
+ .createFolder(testFolder)
+ .usingResource(testFolder).createFolder(folderModel1).and().createFolder(folderModel2)
+ .usingResource(testFolder).assertThat().hasFolderTree(-1, folderModel1, folderModel2);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site collaborator can get folder tree for valid parent folder with at least 2 children folders")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteCollaboratorCanGetFolderTreeForValidParentFolderCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder)
+ .usingResource(testFolder).createFolder(folderModel1).and().createFolder(folderModel2);
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingResource(testFolder).assertThat().hasFolderTree(-1, folderModel1, folderModel2);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site contributor can get folder tree for valid parent folder with at least 2 children folders")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteContributorCanGetFolderTreeForValidParentFolder() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingSite(testSite)
+ .createFolder(testFolder)
+ .usingResource(testFolder).createFolder(folderModel1).and().createFolder(folderModel2)
+ .usingResource(testFolder).assertThat().hasFolderTree(-1, folderModel1, folderModel2);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site contributor can get folder tree for valid parent folder with at least 2 children folders")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteContributorCanGetFolderTreeForValidParentFolderCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(testFolder)
+ .usingResource(testFolder).createFolder(folderModel1).and().createFolder(folderModel2);
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingResource(testFolder).assertThat().hasFolderTree(-1, folderModel1, folderModel2);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site consumer can get folder tree for valid parent folder with at least 2 children folders")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteConsumerCanGetFolderTreeForValidParentFolder() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(testFolder)
+ .usingResource(testFolder).createFolder(folderModel1).and().createFolder(folderModel2);
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .usingResource(testFolder).assertThat().hasFolderTree(-1, folderModel1, folderModel2);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify non site member of a private site cannot get folder tree for valid parent folder with at least 2 children folders")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions={ CmisPermissionDeniedException.class, CmisUnauthorizedException.class })
+ public void nonSiteMemberCannotGetFolderTreeForAFolderFromAPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingAdmin().createPrivateRandomSite();
+
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingSite(privateSite)
+ .createFolder(testFolder)
+ .usingResource(testFolder).createFolder(folderModel1).and().createFolder(folderModel2);
+
+ cmisApi.authenticateUser(testUser).usingResource(testFolder)
+ .assertThat().hasFolderTree(-1, folderModel1, folderModel2);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify non site member of a moderated site cannot get folder tree for valid parent folder with at least 2 children folders")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions={ CmisPermissionDeniedException.class, CmisUnauthorizedException.class })
+ public void nonSiteMemberCannotGetFolderTreeForAFolderFromAModeratedSite() throws Exception
+ {
+ SiteModel moderatedSite = dataSite.usingAdmin().createModeratedRandomSite();
+
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingSite(moderatedSite)
+ .createFolder(testFolder)
+ .usingResource(testFolder).createFolder(folderModel1).and().createFolder(folderModel2);
+
+ cmisApi.authenticateUser(testUser).usingResource(testFolder)
+ .assertThat().hasFolderTree(-1, folderModel1, folderModel2);
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetObjectOfLatestVersionTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetObjectOfLatestVersionTests.java
new file mode 100644
index 00000000000..a230df2d39a
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetObjectOfLatestVersionTests.java
@@ -0,0 +1,202 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.enums.VersioningState;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class GetObjectOfLatestVersionTests extends CmisTest
+{
+ UserModel testUser, nonInvitedUser;
+ SiteModel testSite;
+ FileModel testFile, managerFile;
+ private DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ managerFile = FileModel.getRandomFileModel(FileType.HTML, documentContent);
+ testUser = dataUser.createRandomTestUser();
+ nonInvitedUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createPublicRandomSite();
+ usersWithRoles = dataUser.usingUser(testUser)
+ .addUsersWithRolesToSite(testSite, UserRole.SiteContributor, UserRole.SiteCollaborator, UserRole.SiteConsumer);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(managerFile).assertThat().existsInRepo()
+ .then().checkOut()
+ .and().prepareDocumentForCheckIn().withMajorVersion().checkIn()
+ .then().checkOut()
+ .and().prepareDocumentForCheckIn().withMinorVersion().checkIn();
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.SANITY,
+ description = "Verify site manager is able to get last major version for document checked in with minor version")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerShouldGetLastMajorVersionForDocumentCheckedInWithMajorVersion() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingResource(managerFile)
+ .usingVersion().assertLatestMajorVersionIs(2.0);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.SANITY,
+ description = "Verify site manager is able to get last minor version for document checked in with major version")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerShouldGetLastMinorVersionForDocumentCheckedInWithMajorVersion() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingResource(managerFile)
+ .usingVersion().assertLatestMinorVersionIs(2.1);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is NOT able to get last major version for document that was already deleted")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisObjectNotFoundException.class})
+ public void siteManagerCannotGetLastMajorVersionForInexistentDocument() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .and().checkOut()
+ .and().prepareDocumentForCheckIn().withMajorVersion().checkIn()
+ .then().usingVersion().assertLatestMajorVersionIs(2.0)
+ .and().delete()
+ .then().usingVersion().assertLatestMajorVersionIs(2.0);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is able to get last major version for document that was checked out")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanGetLastMajorVersionForCheckedOutDocument() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .and().checkOut()
+ .and().prepareDocumentForCheckIn().withMajorVersion().checkIn()
+ .usingVersion().assertLatestMajorVersionIs(2.0)
+ .checkOut()
+ .then().usingVersion().assertLatestMajorVersionIs(2.0);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is able to get last minor version for document created with minor VersioningState")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanGetLastMinorVersionForDocumentWithMinorVersioningState() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile, VersioningState.MINOR).and().assertThat().existsInRepo()
+ .then().usingVersion().assertLatestMinorVersionIs(0.1);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to get last major version for document created with minor VersioningState")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisObjectNotFoundException.class,
+ expectedExceptionsMessageRegExp="There is no major version!*")
+ public void siteManagerCannotGetLastMajorVersionForDocumentWithMinorVersioningState() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile, VersioningState.MINOR).and().assertThat().existsInRepo()
+ .then().usingVersion().assertLatestMajorVersionIs(0.1);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is able to get last minor version for document created with checked out VersioningState")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanGetLastVersionForDocumentWithCheckedOutVersioningState() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile, VersioningState.CHECKEDOUT).and().assertThat().existsInRepo()
+ .then().usingVersion().assertLatestMinorVersionIs(1.0)
+ .usingVersion().assertLatestMajorVersionIs(1.0)
+ .then().usingPWCDocument()
+ .usingVersion().assertLatestMajorVersionIs(1.0)
+ .usingVersion().assertLatestMinorVersionIs(1.0);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to get last versions for document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorCanGetLastVersionsForDocumentCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingResource(managerFile)
+ .usingVersion().assertLatestMinorVersionIs(2.1)
+ .usingVersion().assertLatestMajorVersionIs(2.0);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site contributor is able to get last versions for document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorCanGetLastVersionsForDocumentCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingResource(managerFile)
+ .usingVersion().assertLatestMinorVersionIs(2.1)
+ .usingVersion().assertLatestMajorVersionIs(2.0);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site consumer is able to get last versions for document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void consumerCanGetLastVersionsForDocumentCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingResource(managerFile)
+ .usingVersion().assertLatestMinorVersionIs(2.1)
+ .usingVersion().assertLatestMajorVersionIs(2.0);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify non invited user is able to get last versions for document created in public site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void nonInvitedUserCanGetLastVersionsForDocumentInPublicSite() throws Exception
+ {
+ cmisApi.authenticateUser(nonInvitedUser)
+ .usingResource(managerFile)
+ .usingVersion().assertLatestMinorVersionIs(2.1)
+ .usingVersion().assertLatestMajorVersionIs(2.0);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify non invited user is not able to get last versions for document from private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonInvitedUserCannotGetLastVersionsForDocumentCreatedByManagerInPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.createPrivateRandomSite();
+ FileModel privateDoc = FileModel.getRandomFileModel(FileType.XML, documentContent);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingSite(privateSite)
+ .createFile(privateDoc)
+ .then().checkOut()
+ .and().prepareDocumentForCheckIn().withMajorVersion().checkIn()
+ .authenticateUser(nonInvitedUser).usingVersion().assertLatestMinorVersionIs(2.0);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify non invited user is not able to get last versions for document from moderated site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonInvitedUserCannotGetLastVersionsForDocumentCreatedByManagerInModeratedSite() throws Exception
+ {
+ SiteModel moderatedSite = dataSite.createModeratedRandomSite();
+ FileModel moderatedDoc = FileModel.getRandomFileModel(FileType.XML, documentContent);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingSite(moderatedSite)
+ .createFile(moderatedDoc)
+ .then().checkOut()
+ .and().prepareDocumentForCheckIn().withMajorVersion().checkIn()
+ .authenticateUser(nonInvitedUser).usingVersion().assertLatestMinorVersionIs(2.0);
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetObjectTypeTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetObjectTypeTests.java
new file mode 100644
index 00000000000..bf5d3a2057f
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetObjectTypeTests.java
@@ -0,0 +1,191 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.*;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class GetObjectTypeTests extends CmisTest
+{
+ UserModel siteManager;
+ SiteModel testSite;
+ FolderModel testFolder;
+ FileModel testFile;
+ DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ siteManager = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(siteManager).createPublicRandomSite();
+ usersWithRoles = dataUser.addUsersWithRolesToSite(testSite, UserRole.SiteCollaborator, UserRole.SiteContributor, UserRole.SiteConsumer);
+
+ testFolder = FolderModel.getRandomFolderModel();
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+
+ cmisApi.authenticateUser(siteManager).usingSite(testSite)
+ .createFolder(testFolder).and().assertThat().existsInRepo()
+ .createFile(testFile).and().assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.SANITY,
+ description = "Verify CMIS folder type")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void verifyCmisFolderType() throws Exception
+ {
+ cmisApi.authenticateUser(siteManager).usingSite(testSite)
+ .usingResource(testFolder)
+ .assertThat().baseTypeIdIs(BaseTypeId.CMIS_FOLDER.value());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.SANITY,
+ description = "Verify CMIS document type")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void verifyCmisDocumentType() throws Exception
+ {
+ cmisApi.authenticateUser(siteManager).usingSite(testSite)
+ .usingResource(testFile)
+ .assertThat().baseTypeIdIs(BaseTypeId.CMIS_DOCUMENT.value());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify CMIS folder type of folder that was deleted")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisObjectNotFoundException.class})
+ public void verifyCmisFolderTypeOfDeletedFolder() throws Exception
+ {
+ FolderModel folderModel = FolderModel.getRandomFolderModel();
+
+ cmisApi.authenticateUser(siteManager).usingSite(testSite).createFolder(folderModel)
+ .usingResource(folderModel).delete()
+ .assertThat().baseTypeIdIs(BaseTypeId.CMIS_FOLDER.value());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify CMIS document type of file that was deleted")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisObjectNotFoundException.class})
+ public void verifyCmisDocumentTypeOfDeletedDocument() throws Exception
+ {
+ FileModel fileModel = FileModel.getRandomFileModel(FileType.MSWORD);
+
+ cmisApi.authenticateUser(siteManager).usingSite(testSite).createFile(fileModel)
+ .usingResource(fileModel).delete()
+ .assertThat().baseTypeIdIs(BaseTypeId.CMIS_DOCUMENT.value());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Site contributor verifies CMIS document type")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteContributorVerifiesCmisDocumentType() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingResource(testFile)
+ .assertThat().baseTypeIdIs(BaseTypeId.CMIS_DOCUMENT.value());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Site contributor verifies CMIS folder type")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteContributorVerifiesCmisFolderType() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingResource(testFolder)
+ .assertThat().baseTypeIdIs(BaseTypeId.CMIS_FOLDER.value());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Site collaborator verifies CMIS document type")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteCollaboratorVerifiesCmisDocumentType() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingResource(testFile)
+ .assertThat().baseTypeIdIs(BaseTypeId.CMIS_DOCUMENT.value());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Site collaborator verifies CMIS folder type")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteCollaboratorVerifiesCmisFolderType() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingResource(testFolder)
+ .assertThat().baseTypeIdIs(BaseTypeId.CMIS_FOLDER.value());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Site consumer verifies CMIS document type")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteConsumerVerifiesCmisDocumentType() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer)).usingResource(testFile)
+ .assertThat().baseTypeIdIs(BaseTypeId.CMIS_DOCUMENT.value());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Site consumer verifies CMIS folder type")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteConsumerVerifiesCmisFolderType() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer)).usingResource(testFolder)
+ .assertThat().baseTypeIdIs(BaseTypeId.CMIS_FOLDER.value());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Non site member is not able to verify CMIS document type for a document from a private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonSiteMemberCannotVerifyCmisObjectTypeForADocumentFromPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingAdmin().createPrivateRandomSite();
+ FileModel privateSiteFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingSite(privateSite).createFile(privateSiteFile);
+
+ cmisApi.authenticateUser(siteManager).usingResource(privateSiteFile)
+ .assertThat().baseTypeIdIs(BaseTypeId.CMIS_DOCUMENT.value());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Non site member is not able to verify CMIS document type for a folder from a private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonSiteMemberCannotVerifyCmisFolderTypeForAFolderFromPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingAdmin().createPrivateRandomSite();
+ FolderModel privateSiteFolder = FolderModel.getRandomFolderModel();
+
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingSite(privateSite).createFolder(privateSiteFolder);
+
+ cmisApi.authenticateUser(siteManager).usingResource(privateSiteFolder)
+ .assertThat().baseTypeIdIs(BaseTypeId.CMIS_FOLDER.value());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Non site member is not able to verify CMIS document type for a document from a moderated site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonSiteMemberCannotVerifyCmisObjectTypeForADocumentFromModeratedSite() throws Exception
+ {
+ SiteModel moderatedSite = dataSite.usingAdmin().createModeratedRandomSite();
+ FileModel moderatedSiteFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingSite(moderatedSite).createFile(moderatedSiteFile);
+
+ cmisApi.authenticateUser(siteManager).usingResource(moderatedSiteFile)
+ .assertThat().baseTypeIdIs(BaseTypeId.CMIS_DOCUMENT.value());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Non site member is not able to verify CMIS document type for a folder from a moderated site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonSiteMemberCannotVerifyCmisObjectTypeForAFolderFromModeratedSite() throws Exception
+ {
+ SiteModel moderatedSite = dataSite.usingAdmin().createModeratedRandomSite();
+ FolderModel moderatedSiteFolder = FolderModel.getRandomFolderModel();
+
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingSite(moderatedSite).createFolder(moderatedSiteFolder);
+
+ cmisApi.authenticateUser(siteManager).usingResource(moderatedSiteFolder)
+ .assertThat().baseTypeIdIs(BaseTypeId.CMIS_FOLDER.value());
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetParentsTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetParentsTests.java
new file mode 100644
index 00000000000..49b67b613a7
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetParentsTests.java
@@ -0,0 +1,263 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.FolderModel;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/**
+ * Created by Claudia Agache on 10/5/2016.
+ */
+public class GetParentsTests extends CmisTest
+{
+ UserModel testUser;
+ SiteModel testSite;
+ FolderModel testFolder, parentFolder;
+ FileModel testFile;
+ DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createPublicRandomSite();
+ usersWithRoles = dataUser.addUsersWithRolesToSite(testSite, UserRole.SiteCollaborator, UserRole.SiteContributor, UserRole.SiteConsumer);
+ }
+
+ @BeforeMethod(alwaysRun = true)
+ public void generateRandomContent()
+ {
+ parentFolder = FolderModel.getRandomFolderModel();
+ testFolder = FolderModel.getRandomFolderModel();
+ testFile = FileModel.getRandomFileModel(FileType.MSWORD);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify site manager is able to get file parents with CMIS")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerGetsFileParents() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(testFolder).and().assertThat().existsInRepo()
+ .createFolder(parentFolder).and().assertThat().existsInRepo()
+ .usingResource(parentFolder).createFile(testFile).and().assertThat().existsInRepo()
+ .addDocumentToFolder(testFolder, true).and().assertThat().existsInRepo()
+ .then().assertThat().hasParents(testFolder.getName(), parentFolder.getName());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify site manager is able to get folder parents with CMIS")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerGetsFolderParents() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(parentFolder).and().assertThat().existsInRepo()
+ .usingResource(parentFolder).createFolder(testFolder).and().assertThat().existsInRepo()
+ .then().assertThat().hasParents(parentFolder.getName());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is NOT able to get parents for an inexistent folder with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisObjectNotFoundException.class})
+ public void siteManagerCannotGetInexistentFolderParents() throws Exception
+ {
+ FolderModel inexistentFolder = FolderModel.getRandomFolderModel();
+ inexistentFolder.setCmisLocation("/" + inexistentFolder.getName() + "/");
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(parentFolder).and().assertThat().existsInRepo()
+ .and().usingResource(inexistentFolder).assertThat().hasParents(parentFolder.getName());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site contributor is able to get folder parents with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteContributorGetsFolderParentsCreatedBySelf() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingSite(testSite)
+ .createFolder(parentFolder).and().assertThat().existsInRepo()
+ .usingResource(parentFolder).createFolder(testFolder).and().assertThat().existsInRepo()
+ .then().assertThat().hasParents(parentFolder.getName());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site contributor is able to get file parents with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteContributorGetsFileParentsCreatedBySelf() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingSite(testSite)
+ .createFolder(parentFolder).and().assertThat().existsInRepo()
+ .usingResource(parentFolder).createFile(testFile).and().assertThat().existsInRepo()
+ .assertThat().hasParents(parentFolder.getName());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site contributor is able to get folder parents with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteContributorGetsFolderParentsCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(parentFolder).and().assertThat().existsInRepo()
+ .usingResource(parentFolder).createFolder(testFolder).and().assertThat().existsInRepo();
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingResource(testFolder)
+ .assertThat().hasParents(parentFolder.getName());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site contributor is able to get file parents with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteContributorGetsFileParentsCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(parentFolder).and().assertThat().existsInRepo()
+ .usingResource(parentFolder).createFolder(testFolder).and().assertThat().existsInRepo()
+ .usingResource(testFolder).createFile(testFile).and().assertThat().existsInRepo();
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingResource(testFile)
+ .assertThat().hasParents(testFolder.getName());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to get folder parents with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteCollaboratorGetsFolderParentsCreatedBySelf() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingSite(testSite)
+ .createFolder(parentFolder).and().assertThat().existsInRepo()
+ .usingResource(parentFolder).createFolder(testFolder).and().assertThat().existsInRepo()
+ .then().assertThat().hasParents(parentFolder.getName());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to get file parents with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteCollaboratorGetsFileParentsCreatedBySelf() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingSite(testSite)
+ .createFolder(parentFolder).and().assertThat().existsInRepo()
+ .usingResource(parentFolder).createFile(testFile).and().assertThat().existsInRepo()
+ .assertThat().hasParents(parentFolder.getName());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to get folder parents with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteCollaboratorGetsFolderParentsCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(parentFolder).and().assertThat().existsInRepo()
+ .usingResource(parentFolder).createFolder(testFolder).and().assertThat().existsInRepo();
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingResource(testFolder)
+ .assertThat().hasParents(parentFolder.getName());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to get file parents with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteCollaboratorGetsFileParentsCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(parentFolder).and().assertThat().existsInRepo()
+ .usingResource(parentFolder).createFolder(testFolder).and().assertThat().existsInRepo()
+ .usingResource(testFolder).createFile(testFile).and().assertThat().existsInRepo();
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingResource(testFile)
+ .assertThat().hasParents(testFolder.getName());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site consumer is able to get folder parents with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteConsumerGetsFolderParents() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(parentFolder).and().assertThat().existsInRepo()
+ .usingResource(parentFolder).createFolder(testFolder).and().assertThat().existsInRepo();
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer)).usingResource(testFolder)
+ .assertThat().hasParents(parentFolder.getName());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site consumer is able to get file parents with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteConsumerGetsFileParents() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(parentFolder).and().assertThat().existsInRepo()
+ .usingResource(parentFolder).createFolder(testFolder).and().assertThat().existsInRepo()
+ .usingResource(testFolder).createFile(testFile).and().assertThat().existsInRepo();
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer)).usingResource(testFile)
+ .assertThat().hasParents(testFolder.getName());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify non site member for a private site is not able to get folder parents with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonSiteMemberGetsFolderParentsFromPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingAdmin().createPrivateRandomSite();
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingSite(privateSite)
+ .createFolder(parentFolder).and().assertThat().existsInRepo()
+ .usingResource(parentFolder).createFolder(testFolder).and().assertThat().existsInRepo();
+
+ cmisApi.authenticateUser(testUser).usingResource(testFolder)
+ .assertThat().hasParents(parentFolder.getName());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify non site member for a private site is not able to get file parents with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonSiteMemberGetsFileParentsFromPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingAdmin().createPrivateRandomSite();
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingSite(privateSite)
+ .createFolder(parentFolder).and().assertThat().existsInRepo()
+ .usingResource(parentFolder).createFile(testFile).and().assertThat().existsInRepo();
+
+ cmisApi.authenticateUser(testUser).usingResource(testFile)
+ .assertThat().hasParents(parentFolder.getName());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify non site member for a moderated site is not able to get folder parents with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonSiteMemberGetsFolderParentsFromModeratedSite() throws Exception
+ {
+ SiteModel moderatedSite = dataSite.usingAdmin().createModeratedRandomSite();
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingSite(moderatedSite)
+ .createFolder(parentFolder).and().assertThat().existsInRepo()
+ .usingResource(parentFolder).createFolder(testFolder).and().assertThat().existsInRepo();
+
+ cmisApi.authenticateUser(testUser).usingResource(testFolder)
+ .assertThat().hasParents(parentFolder.getName());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify non site member for a moderated site is not able to get file parents with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonSiteMemberGetsFileParentsFromModeratedSite() throws Exception
+ {
+ SiteModel moderatedSite = dataSite.usingAdmin().createModeratedRandomSite();
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingSite(moderatedSite)
+ .createFolder(parentFolder).and().assertThat().existsInRepo()
+ .usingResource(parentFolder).createFile(testFile).and().assertThat().existsInRepo();
+
+ cmisApi.authenticateUser(testUser).usingResource(testFile)
+ .assertThat().hasParents(parentFolder.getName());
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetPropertiesTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetPropertiesTests.java
new file mode 100644
index 00000000000..6503983bf2f
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetPropertiesTests.java
@@ -0,0 +1,266 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.*;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class GetPropertiesTests extends CmisTest
+{
+ UserModel testUser;
+ SiteModel testSite;
+ FileModel testFile;
+ FolderModel testFolder;
+ DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createPublicRandomSite();
+ usersWithRoles = dataUser.addUsersWithRolesToSite(testSite, UserRole.SiteManager, UserRole.SiteCollaborator,
+ UserRole.SiteContributor, UserRole.SiteConsumer);
+ }
+
+ @BeforeMethod(alwaysRun = true)
+ public void generateRandomContent()
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ testFolder = FolderModel.getRandomFolderModel();
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.SANITY,
+ description = "Verify secondaryObjectTypeIds property for valid document")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void verifySecondaryObjectTypeIdsPropertyForValidDocument() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .then().assertThat().objectHasProperty("cmis:secondaryObjectTypeIds", "Secondary Object Type Ids",
+ "secondaryObjectTypeIds", "cmis:secondaryObjectTypeIds", "P:cm:titled", "P:sys:localized");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.SANITY,
+ description = "Verify secondaryObjectTypeIds property for valid folder")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void verifySecondaryObjectTypeIdsPropertyForValidFolder() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder)
+ .and().assertThat().existsInRepo()
+ .then().assertThat().objectHasProperty("cmis:secondaryObjectTypeIds", "Secondary Object Type Ids",
+ "secondaryObjectTypeIds", "cmis:secondaryObjectTypeIds", "P:cm:titled", "P:sys:localized");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify secondaryObjectTypeIds property for inexistent folder (that was previously deleted)")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisObjectNotFoundException.class})
+ public void verifySecondaryObjectTypeIdsPropertyForInexistentFolder() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder)
+ .then().assertThat().objectHasProperty("cmis:secondaryObjectTypeIds", "Secondary Object Type Ids",
+ "secondaryObjectTypeIds", "cmis:secondaryObjectTypeIds", "P:cm:titled", "P:sys:localized")
+ .and().usingResource(testFolder).deleteFolderTree()
+ .then().assertThat().objectHasProperty("cmis:secondaryObjectTypeIds", "Secondary Object Type Ids",
+ "secondaryObjectTypeIds", "cmis:secondaryObjectTypeIds", "P:cm:titled", "P:sys:localized");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify secondaryObjectTypeIds property for valid folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void managerVerifiesSecondaryObjectTypeIdsPropertyForValidFolder() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager)).usingSite(testSite).usingResource(testFolder)
+ .then().assertThat().objectHasProperty("cmis:secondaryObjectTypeIds", "Secondary Object Type Ids",
+ "secondaryObjectTypeIds", "cmis:secondaryObjectTypeIds", "P:cm:titled", "P:sys:localized");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify secondaryObjectTypeIds property as site collaborator for valid document")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorVerifiesSecondaryObjectTypeIdsPropertyForValidDocumentCreatedBySelf() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingSite(testSite).createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .then().assertThat().objectHasProperty("cmis:secondaryObjectTypeIds", "Secondary Object Type Ids",
+ "secondaryObjectTypeIds", "cmis:secondaryObjectTypeIds", "P:cm:titled", "P:sys:localized");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify secondaryObjectTypeIds property as site collaborator for valid folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorVerifiesSecondaryObjectTypeIdsPropertyForValidFolderCreatedBySelf() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingSite(testSite).createFolder(testFolder)
+ .and().assertThat().existsInRepo()
+ .then().assertThat().objectHasProperty("cmis:secondaryObjectTypeIds", "Secondary Object Type Ids",
+ "secondaryObjectTypeIds", "cmis:secondaryObjectTypeIds", "P:cm:titled", "P:sys:localized");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify secondaryObjectTypeIds property as site collaborator for valid document")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorVerifiesSecondaryObjectTypeIdsPropertyForValidDocumentCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFile(testFile)
+ .and().assertThat().existsInRepo();
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingResource(testFile)
+ .assertThat().objectHasProperty("cmis:secondaryObjectTypeIds", "Secondary Object Type Ids",
+ "secondaryObjectTypeIds", "cmis:secondaryObjectTypeIds", "P:cm:titled", "P:sys:localized");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify secondaryObjectTypeIds property as site collaborator for valid folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorVerifiesSecondaryObjectTypeIdsPropertyForValidFolderCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder)
+ .and().assertThat().existsInRepo();
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingResource(testFolder)
+ .assertThat().objectHasProperty("cmis:secondaryObjectTypeIds", "Secondary Object Type Ids",
+ "secondaryObjectTypeIds", "cmis:secondaryObjectTypeIds", "P:cm:titled", "P:sys:localized");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify secondaryObjectTypeIds property as site contributor for valid document")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorVerifiesSecondaryObjectTypeIdsPropertyForValidDocumentCreatedBySelf() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingSite(testSite).createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .then().assertThat().objectHasProperty("cmis:secondaryObjectTypeIds", "Secondary Object Type Ids",
+ "secondaryObjectTypeIds", "cmis:secondaryObjectTypeIds", "P:cm:titled", "P:sys:localized");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify secondaryObjectTypeIds property as site contributor for valid folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorVerifiesSecondaryObjectTypeIdsPropertyForValidFolderCreatedBySelf() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingSite(testSite).createFolder(testFolder)
+ .and().assertThat().existsInRepo()
+ .then().assertThat().objectHasProperty("cmis:secondaryObjectTypeIds", "Secondary Object Type Ids",
+ "secondaryObjectTypeIds", "cmis:secondaryObjectTypeIds", "P:cm:titled", "P:sys:localized");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify secondaryObjectTypeIds property as site contributor for valid document")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorVerifiesSecondaryObjectTypeIdsPropertyForValidDocumentCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFile(testFile)
+ .and().assertThat().existsInRepo();
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingResource(testFile)
+ .assertThat().objectHasProperty("cmis:secondaryObjectTypeIds", "Secondary Object Type Ids",
+ "secondaryObjectTypeIds", "cmis:secondaryObjectTypeIds", "P:cm:titled", "P:sys:localized");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify secondaryObjectTypeIds property as site contributor for valid folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorVerifiesSecondaryObjectTypeIdsPropertyForValidFolderCreatedByManager() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder)
+ .and().assertThat().existsInRepo();
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingResource(testFolder)
+ .assertThat().objectHasProperty("cmis:secondaryObjectTypeIds", "Secondary Object Type Ids",
+ "secondaryObjectTypeIds", "cmis:secondaryObjectTypeIds", "P:cm:titled", "P:sys:localized");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify secondaryObjectTypeIds property as site consumer for valid document")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void consumerVerifiesSecondaryObjectTypeIdsPropertyForValidDocument() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFile(testFile)
+ .and().assertThat().existsInRepo();
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer)).usingResource(testFile)
+ .assertThat().objectHasProperty("cmis:secondaryObjectTypeIds", "Secondary Object Type Ids",
+ "secondaryObjectTypeIds", "cmis:secondaryObjectTypeIds", "P:cm:titled", "P:sys:localized");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify secondaryObjectTypeIds property as site consumer for valid folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void consumerVerifiesSecondaryObjectTypeIdsPropertyForValidFolder() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder)
+ .and().assertThat().existsInRepo();
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer)).usingResource(testFolder)
+ .assertThat().objectHasProperty("cmis:secondaryObjectTypeIds", "Secondary Object Type Ids",
+ "secondaryObjectTypeIds", "cmis:secondaryObjectTypeIds", "P:cm:titled", "P:sys:localized");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify that non site member cannot get secondaryObjectTypeIds property for a valid document from a private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonSiteMemberCannotGetSecondaryObjectTypeIdsForAValidDocumentFromAPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingAdmin().createPrivateRandomSite();
+
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingSite(privateSite).createFile(testFile)
+ .and().assertThat().existsInRepo();
+
+ cmisApi.authenticateUser(testUser).usingResource(testFile).assertThat()
+ .objectHasProperty("cmis:secondaryObjectTypeIds", "Secondary Object Type Ids",
+ "secondaryObjectTypeIds", "cmis:secondaryObjectTypeIds", "P:cm:titled", "P:sys:localized");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify that non site member cannot get secondaryObjectTypeIds property for a valid folder from a private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonSiteMemberCannotGetSecondaryObjectTypeIdsForAValidFolderFromAPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingAdmin().createPrivateRandomSite();
+
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingSite(privateSite).createFolder(testFolder)
+ .and().assertThat().existsInRepo();
+
+ cmisApi.authenticateUser(testUser).usingResource(testFolder).assertThat()
+ .objectHasProperty("cmis:secondaryObjectTypeIds", "Secondary Object Type Ids",
+ "secondaryObjectTypeIds", "cmis:secondaryObjectTypeIds", "P:cm:titled", "P:sys:localized");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify that non site member cannot get secondaryObjectTypeIds property for a valid document from a moderated site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonSiteMemberCannotGetSecondaryObjectTypeIdsForAValidDocumentFromAModeratedSite() throws Exception
+ {
+ SiteModel moderatedSite = dataSite.usingAdmin().createModeratedRandomSite();
+
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingSite(moderatedSite).createFile(testFile)
+ .and().assertThat().existsInRepo();
+
+ cmisApi.authenticateUser(testUser).usingResource(testFile).assertThat()
+ .objectHasProperty("cmis:secondaryObjectTypeIds", "Secondary Object Type Ids",
+ "secondaryObjectTypeIds", "cmis:secondaryObjectTypeIds", "P:cm:titled", "P:sys:localized");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify that non site member cannot get secondaryObjectTypeIds property for a valid folder from a moderated site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonSiteMemberCannotGetSecondaryObjectTypeIdsForAValidFolderFromAModeratedSite() throws Exception
+ {
+ SiteModel moderatedSite = dataSite.usingAdmin().createModeratedRandomSite();
+
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingSite(moderatedSite).createFolder(testFolder)
+ .and().assertThat().existsInRepo();
+
+ cmisApi.authenticateUser(testUser).usingResource(testFolder).assertThat()
+ .objectHasProperty("cmis:secondaryObjectTypeIds", "Secondary Object Type Ids",
+ "secondaryObjectTypeIds", "cmis:secondaryObjectTypeIds", "P:cm:titled", "P:sys:localized");
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetTypeChildrenTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetTypeChildrenTests.java
new file mode 100644
index 00000000000..9a7fe34fca6
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetTypeChildrenTests.java
@@ -0,0 +1,123 @@
+package org.alfresco.cmis;
+
+
+import org.alfresco.utility.exception.DataPreparationException;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.report.Bug;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * Created by Claudia Agache on 10/6/2016.
+ */
+public class GetTypeChildrenTests extends CmisTest
+{
+ @BeforeClass(alwaysRun = true)
+ public void setup() throws Exception
+ {
+ cmisApi.authenticateUser(dataUser.getAdminUser());
+ }
+
+ /**
+ * Get type children for a valid type id and includePropertyDefinitions set to false
+ * (verify that Map> is empty)
+ */
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.SANITY,
+ description = "Verify admin can get type children for BaseTypeId.CMIS_DOCUMENT and includePropertyDefinitions = false")
+ @Test(groups = { TestGroup.CMIS, TestGroup.SANITY })
+ public void getTypeChildrenWithoutPropertyDefinitions()
+ {
+ cmisApi.authenticateUser(dataUser.getAdminUser())
+ .usingObjectType(BaseTypeId.CMIS_DOCUMENT.value())
+ .withoutPropertyDefinitions()
+ .hasChildren("D:srft:facetField").propertyDefinitionIsEmpty();
+ }
+
+ /**
+ * Get type children for a valid type id and includePropertyDefinitions set to true
+ * (verify that Map> is not empty)
+ */
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.SANITY,
+ description = "Verify admin can get type children for valid type id and includePropertyDefinitions = true")
+ @Test(groups = { TestGroup.CMIS, TestGroup.SANITY })
+ public void getTypeChildrenWithPropertyDefinitions()
+ {
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingObjectType(BaseTypeId.CMIS_FOLDER.value())
+ .withPropertyDefinitions()
+ .hasChildren("F:pub:DeliveryChannel").propertyDefinitionIsNotEmpty();
+ cmisApi.usingObjectType(BaseTypeId.CMIS_FOLDER.value()).withPropertyDefinitions()
+ .doesNotHaveChildren("D:srft:facetField");
+ }
+
+ /**
+ * Get invalid type children for a valid type id and includePropertyDefinitions set to true
+ * (verify that Map> is not empty)
+ */
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify admin can get invalid type children for valid type id")
+ @Test(groups = { TestGroup.CMIS, TestGroup.REGRESSION })
+ public void getInvalidTypeChildrenForATypeId()
+ {
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingObjectType(BaseTypeId.CMIS_FOLDER.value())
+ .withPropertyDefinitions()
+ .doesNotHaveChildren("F:pub:invalidDeliveryChannelv");
+ }
+
+ /**
+ * Get valid type children for a invalid type id and includePropertyDefinitions set to true
+ * (verify that Map> is not empty)
+ */
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify admin can get valid type children for invalid type id")
+ @Test(groups = { TestGroup.CMIS, TestGroup.REGRESSION }, expectedExceptions = {CmisObjectNotFoundException.class},
+ expectedExceptionsMessageRegExp="Type 'cmis:invalidfolder' is unknown!*")
+ public void getValidTypeChildrenForInvalidTypeId()
+ {
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingObjectType("cmis:invalidfolder")
+ .withPropertyDefinitions()
+ .hasChildren("F:pub:DeliveryChannel").propertyDefinitionIsNotEmpty();;
+ }
+
+ /**
+ * Deleted user is not authorized to get type children for a valid type id
+ * (verify that Map> is not empty)
+ * @throws DataPreparationException
+ */
+ @Bug(id="REPO-4301")
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify deleted user is not authorized to get type children for valid type id")
+ @Test(groups = { TestGroup.CMIS, TestGroup.REGRESSION }, expectedExceptions = {CmisUnauthorizedException.class})
+ public void getTypeChildrenWithWithDeletedUser() throws DataPreparationException
+ {
+ UserModel deletedUser = dataUser.createRandomTestUser();
+ cmisApi.authenticateUser(deletedUser)
+ .usingObjectType(BaseTypeId.CMIS_FOLDER.value())
+ .withPropertyDefinitions()
+ .hasChildren("F:pub:DeliveryChannel").propertyDefinitionIsNotEmpty();
+ dataUser.deleteUser(deletedUser);
+ cmisApi.disconnect()
+ .usingObjectType(BaseTypeId.CMIS_FOLDER.value()).withPropertyDefinitions().doesNotHaveChildren("D:srft:facetField");
+ }
+
+ @Bug(id="REPO-4301")
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify disabled user is not authorized to get type children for valid type id")
+ @Test(groups = { TestGroup.CMIS, TestGroup.REGRESSION }, expectedExceptions = {CmisUnauthorizedException.class})
+ public void getTypeChildrenWithWithDisabledUser() throws DataPreparationException
+ {
+ UserModel disabledUser = dataUser.createRandomTestUser();
+ cmisApi.authenticateUser(disabledUser)
+ .usingObjectType(BaseTypeId.CMIS_FOLDER.value())
+ .withPropertyDefinitions()
+ .hasChildren("F:pub:DeliveryChannel").propertyDefinitionIsNotEmpty();
+ dataUser.usingAdmin().disableUser(disabledUser);
+ cmisApi.disconnect()
+ .usingObjectType(BaseTypeId.CMIS_FOLDER.value()).withPropertyDefinitions().doesNotHaveChildren("D:srft:facetField");
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetTypeDefinitionTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetTypeDefinitionTests.java
new file mode 100644
index 00000000000..ed6097558f7
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetTypeDefinitionTests.java
@@ -0,0 +1,248 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.*;
+import org.alfresco.utility.report.Bug;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class GetTypeDefinitionTests extends CmisTest
+{
+ UserModel testUser;
+ SiteModel publicSite, privateSite, moderatedSite;
+ FileModel testFile;
+ FolderModel testFolder;
+
+ DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ publicSite = dataSite.usingUser(testUser).createPublicRandomSite();
+ privateSite = dataSite.usingUser(testUser).createPrivateRandomSite();
+ moderatedSite = dataSite.usingUser(testUser).createModeratedRandomSite();
+ cmisApi.authenticateUser(testUser);
+
+ usersWithRoles = dataUser.addUsersWithRolesToSite(publicSite, UserRole.SiteManager, UserRole.SiteCollaborator, UserRole.SiteContributor,
+ UserRole.SiteConsumer);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.SANITY,
+ description = "Verify site manager can get Type Definition for a valid folder")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS })
+ public void siteManagerShouldGetTypeDefinitionForValidFolder() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(testUser).usingSite(publicSite).createFolder(testFolder)
+ .and().assertThat().existsInRepo()
+ .then().assertThat()
+ .typeDefinitionIs(testFolder);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.SANITY,
+ description = "Verify site manager can get Type Definition for a valid document")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS })
+ public void siteManagerShouldGetTypeDefinitionForValidDocument() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(publicSite).createFile(testFile)
+ .and().assertThat().existsInRepo()
+ .then().assertThat()
+ .typeDefinitionIs(testFile);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager cannot get Type Definition for a deleted document")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = { CmisObjectNotFoundException.class })
+ public void siteManagerShouldGetTypeDefinitionForDeletedDocument() throws Exception
+ {
+ FileModel deletedFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+
+ cmisApi.authenticateUser(testUser).usingSite(publicSite).createFile(deletedFile)
+ .and().usingResource(deletedFile).delete()
+ .then().assertThat()
+ .typeDefinitionIs(deletedFile);
+ }
+
+ @Bug(id="REPO-4301")
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user that was deleted cannot get Type Definition for a valid folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = { CmisUnauthorizedException.class })
+ public void deletedUserCannotGetTypeDefinitionForValidFolder() throws Exception
+ {
+ UserModel deletedUser = dataUser.createRandomTestUser();
+
+ dataUser.usingUser(testUser).addUserToSite(deletedUser, publicSite, UserRole.SiteManager);
+ testFolder = FolderModel.getRandomFolderModel();
+
+ cmisApi.authenticateUser(testUser).usingSite(publicSite).createFolder(testFolder);
+ cmisApi.authenticateUser(deletedUser).usingSite(publicSite).usingResource(testFolder)
+ .then().assertThat()
+ .typeDefinitionIs(testFolder);
+
+ dataUser.deleteUser(deletedUser);
+ cmisApi.disconnect().assertThat().baseTypeIdIs(BaseTypeId.CMIS_FOLDER.value());
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user that was deleted can NOT get Type Definition for a valid folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteManagerGetTypeDefinitionForValidFolder() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager)).usingSite(publicSite).createFolder(testFolder)
+ .usingResource(testFolder).and().assertThat().existsInRepo()
+ .then().assertThat().typeDefinitionIs(testFolder);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site Contributor is able to get Type Definition for a valid folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteContributorGetTypeDefinitionForValidFolder() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(testUser).usingSite(publicSite).createFolder(testFolder).and().assertThat().existsInRepo();
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingResource(testFolder).assertThat().typeDefinitionIs(testFolder);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site Collaborator is able to get Type Definition for a valid folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteCollaboratorGetTypeDefinitionForValidFolder() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingSite(publicSite).createFolder(testFolder)
+ .usingResource(testFolder).and().assertThat().existsInRepo()
+ .then().assertThat().typeDefinitionIs(testFolder);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site Consumer is NOT able to get Type Definition for a valid folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = { CmisPermissionDeniedException.class, CmisUnauthorizedException.class })
+ public void siteConsumerCantGetTypeDefinitionForValidFolder() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer)).usingSite(publicSite).createFolder(testFolder)
+ .usingResource(testFolder).and().assertThat().existsInRepo()
+ .then().assertThat().typeDefinitionIs(testFolder);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site Manager is able to get Type Definition for a valid file")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteManagerGetTypeDefinitionForValidFile() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.PDF);
+
+ cmisApi.authenticateUser(testUser).usingSite(publicSite).createFile(testFile).and().assertThat().existsInRepo();
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager))
+ .usingResource(testFile).assertThat().typeDefinitionIs(testFile);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site Contributor is able to get Type Definition for a valid file")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteContributorGetTypeDefinitionForValidFile() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.HTML);
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingSite(publicSite).createFile(testFile)
+ .usingResource(testFile).and().assertThat().existsInRepo()
+ .then().assertThat().typeDefinitionIs(testFile);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site Collaborator is able to get Type Definition for a valid file")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteCollaboratorGetTypeDefinitionForValidFile() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.XML);
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingSite(publicSite).createFile(testFile)
+ .usingResource(testFile).and().assertThat().existsInRepo()
+ .then().assertThat().typeDefinitionIs(testFile);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site Consumer is NOT able to get Type Definition for a valid file")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = { CmisPermissionDeniedException.class, CmisUnauthorizedException.class })
+ public void siteConsumerCantGetTypeDefinitionForValidFile() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.UNDEFINED);
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer)).usingSite(publicSite).createFile(testFile)
+ .usingResource(testFile)
+ .and().assertThat().existsInRepo()
+ .then().assertThat().typeDefinitionIs(testFile);
+ }
+
+ @Bug(id="REPO-4301")
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user outside private site cannot get Type Definition for a valid file")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = { CmisPermissionDeniedException.class })
+ public void outsideUserPrivateSiteCantGetTypeDefinitionForValidFile() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.XML);
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingSite(privateSite).createFile(testFile)
+ .usingResource(testFile).and().assertThat().existsInRepo()
+ .then().assertThat().typeDefinitionIs(testFile);
+ }
+
+ @Bug(id="REPO-4301")
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user outside moderated site cannot get Type Definition for a valid file")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = { CmisPermissionDeniedException.class})
+ public void outsideUserModeratedSiteGetTypeDefinitionForValidFile() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.XML);
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager)).usingSite(moderatedSite).createFile(testFile)
+ .usingResource(testFile)
+ .and().assertThat().existsInRepo()
+ .then().assertThat().typeDefinitionIs(testFile);
+ }
+
+ @Bug(id="REPO-4301")
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user outside private site cannot get Type Definition for a valid folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = { CmisPermissionDeniedException.class })
+ public void outsideUserPrivateSiteCantGetTypeDefinitionForValidFolder() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ testFile = FileModel.getRandomFileModel(FileType.XML);
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingSite(privateSite).createFolder(testFolder)
+ .usingResource(testFolder).createFile(testFile)
+ .usingResource(testFolder).and().assertThat().existsInRepo()
+ .then().assertThat().typeDefinitionIs(testFolder);
+ }
+
+ @Bug(id="REPO-4301")
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user outside moderated site cannot get Type Definition for a valid folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = { CmisPermissionDeniedException.class})
+ public void outsideUserModeratedSiteGetTypeDefinitionForValidFolder() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ testFile = FileModel.getRandomFileModel(FileType.XML);
+
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager)).usingSite(moderatedSite).createFolder(testFolder)
+ .usingResource(testFolder).createFile(testFile)
+ .usingResource(testFolder)
+ .and().assertThat().existsInRepo()
+ .then().assertThat().typeDefinitionIs(testFolder);
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetTypeDescendantsTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetTypeDescendantsTests.java
new file mode 100644
index 00000000000..cf897a85460
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/GetTypeDescendantsTests.java
@@ -0,0 +1,139 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.report.Bug;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class GetTypeDescendantsTests extends CmisTest
+{
+ @BeforeClass(alwaysRun = true)
+ public void setup() throws Exception
+ {
+ cmisApi.authenticateUser(dataUser.getAdminUser());
+ }
+
+ /**
+ * Get type descendants for a valid type id and includePropertyDefinitions set to true
+ * and depth set to -1 (verify that Map> is not empty)
+ */
+ @Test(groups = { TestGroup.CMIS , TestGroup.REGRESSION })
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify admin can get type descendantes for valid type id and includePropertyDefinitions = true and depth = -1")
+ public void adminShouldGetTypeDescendantsValidInputCase1()
+ {
+ cmisApi.usingObjectType(BaseTypeId.CMIS_DOCUMENT.value())
+ .withPropertyDefinitions().hasDescendantType(-1, "D:cm:dictionaryModel", "D:trx:transferLock");
+ }
+
+ /**
+ * Get type descendants for a valid type id and includePropertyDefinitions set to true
+ * and depth set to 1 (verify that Map> is not empty)
+ */
+ @Test(groups = { TestGroup.CMIS , TestGroup.REGRESSION })
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify admin can get type descendantes for valid type id and includePropertyDefinitions = true and depth = 1")
+ public void adminShouldGetTypeDescendantsValidInputCase2()
+ {
+ cmisApi.usingObjectType(BaseTypeId.CMIS_DOCUMENT.value())
+ .withPropertyDefinitions().hasDescendantType(1, "D:cm:dictionaryModel", "D:trx:transferLock");
+ }
+
+ /**
+ * Get type descendants for a valid type id and includePropertyDefinitions set to false
+ * and depth set to 1 (verify that Map> is not empty)
+ */
+ @Test(groups = { TestGroup.CMIS , TestGroup.REGRESSION })
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify admin can get type descendants for valid type id and includePropertyDefinitions = false and depth = 1")
+ public void adminShouldGetTypeDescendantsValidInputCase3()
+ {
+ cmisApi.usingObjectType(BaseTypeId.CMIS_DOCUMENT.value())
+ .withoutPropertyDefinitions().hasDescendantType(1, "D:cm:dictionaryModel", "D:trx:transferLock");
+ }
+
+ /**
+ * Get type descendantes for a valid type id and includePropertyDefinitions set to false
+ * and depth set to -1 (verify that Map> is not empty)
+ */
+ @Test(groups = { TestGroup.CMIS , TestGroup.REGRESSION })
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify admin can get type descendantes for valid type id and includePropertyDefinitions = false and depth = -1")
+ public void adminShouldGetTypeDescendantsValidInputCase4()
+ {
+ cmisApi.usingObjectType(BaseTypeId.CMIS_DOCUMENT.value())
+ .withoutPropertyDefinitions().hasDescendantType(-1, "D:cm:dictionaryModel", "D:trx:transferLock");
+ }
+
+ /**
+ * Get type descendantes for an invalid type id and includePropertyDefinitions set to false
+ * and depth set to -1 (verify that Map> is not empty)
+ */
+ @Test(groups = { TestGroup.CMIS , TestGroup.REGRESSION }, expectedExceptions = {CmisObjectNotFoundException.class},
+ expectedExceptionsMessageRegExp="Type 'cmis:documentfake' is unknown!*")
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify admin cannot get type descendantes for invalid type id and includePropertyDefinitions = false and depth = -1")
+ public void adminCannotGetTypeDescendantsForInvalidType()
+ {
+ cmisApi.usingObjectType(BaseTypeId.CMIS_DOCUMENT.value() +"fake")
+ .withoutPropertyDefinitions().hasDescendantType(-1, "D:cm:dictionaryModel", "D:trx:transferLock");
+ }
+
+ /**
+ * Get type descendantes for a valid type id and includePropertyDefinitions set to false
+ * and incorrect depth set to -2 (verify that Map> is not empty)
+ */
+ @Test(groups = { TestGroup.CMIS , TestGroup.REGRESSION }, expectedExceptions = {CmisInvalidArgumentException.class})
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify admin can get type descendantes for valid type id and includePropertyDefinitions = false and incorrect depth = -2")
+ public void adminShouldGetTypeDescendantsValidTypeWithIncorrectDepth()
+ {
+ cmisApi.usingObjectType(BaseTypeId.CMIS_DOCUMENT.value())
+ .withoutPropertyDefinitions().hasDescendantType(-2, "D:cm:dictionaryModel", "D:trx:transferLock");
+ }
+
+ @Test(groups = { TestGroup.CMIS , TestGroup.SANITY })
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.SANITY,
+ description = "Verify random user can get type descendantes for valid type id and includePropertyDefinitions = false and depth = 1")
+ public void userGetTypeDescendants() throws Exception
+ {
+ UserModel user = dataUser.createRandomTestUser();
+ cmisApi.authenticateUser(user).usingObjectType(BaseTypeId.CMIS_DOCUMENT.value())
+ .withoutPropertyDefinitions().hasDescendantType(1, "D:cm:dictionaryModel", "D:trx:transferLock");
+ }
+
+ @Bug(id="REPO-4301")
+ @Test(groups = { TestGroup.CMIS , TestGroup.REGRESSION }, expectedExceptions=CmisUnauthorizedException.class)
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify deleted user cannot get type descendantes for valid type id and includePropertyDefinitions = false and depth = 1")
+ public void deletedUserCannotGetTypeDescendants() throws Exception
+ {
+ UserModel deletedUser = dataUser.createRandomTestUser();
+ cmisApi.authenticateUser(deletedUser).usingObjectType(BaseTypeId.CMIS_DOCUMENT.value())
+ .withoutPropertyDefinitions().hasDescendantType(1, "D:cm:dictionaryModel", "D:trx:transferLock");
+ dataUser.usingAdmin().deleteUser(deletedUser);
+ cmisApi.disconnect().usingObjectType(BaseTypeId.CMIS_DOCUMENT.value())
+ .withoutPropertyDefinitions().hasDescendantType(1, "D:cm:dictionaryModel", "D:trx:transferLock");
+ }
+
+ @Bug(id="REPO-4301")
+ @Test(groups = { TestGroup.CMIS , TestGroup.REGRESSION }, expectedExceptions=CmisUnauthorizedException.class)
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify disabled user cannot get type descendantes for valid type id and includePropertyDefinitions = false and depth = 1")
+ public void disabledUserCannotGetTypeDescendants() throws Exception
+ {
+ UserModel disabledUser = dataUser.createRandomTestUser();
+ cmisApi.authenticateUser(disabledUser).usingObjectType(BaseTypeId.CMIS_DOCUMENT.value())
+ .withoutPropertyDefinitions().hasDescendantType(1, "D:cm:dictionaryModel", "D:trx:transferLock");
+ dataUser.usingAdmin().disableUser(disabledUser);
+ cmisApi.disconnect().usingObjectType(BaseTypeId.CMIS_DOCUMENT.value())
+ .withoutPropertyDefinitions().hasDescendantType(1, "D:cm:dictionaryModel", "D:trx:transferLock");
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/IsLatestMajorVersionTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/IsLatestMajorVersionTests.java
new file mode 100644
index 00000000000..d5fdb7b46af
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/IsLatestMajorVersionTests.java
@@ -0,0 +1,188 @@
+package org.alfresco.cmis;
+
+import org.alfresco.cmis.exception.InvalidCmisObjectException;
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.FolderModel;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.report.Bug;
+import org.alfresco.utility.report.Bug.Status;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.enums.VersioningState;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class IsLatestMajorVersionTests extends CmisTest
+{
+ UserModel managerUser, nonInviteUser;
+ SiteModel testSite;
+ FileModel minorVersionDoc, majorVersionDoc;
+ private DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ minorVersionDoc = FileModel.getRandomFileModel(FileType.XML, documentContent);
+ majorVersionDoc = FileModel.getRandomFileModel(FileType.XML, documentContent);
+ managerUser = dataUser.createRandomTestUser();
+ nonInviteUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(managerUser).createPublicRandomSite();
+ usersWithRoles = dataUser.usingUser(managerUser)
+ .addUsersWithRolesToSite(testSite, UserRole.SiteContributor, UserRole.SiteCollaborator, UserRole.SiteConsumer);
+ cmisApi.authenticateUser(managerUser).usingSite(testSite)
+ .createFile(minorVersionDoc, VersioningState.MINOR)
+ .createFile(majorVersionDoc, VersioningState.MAJOR);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify is latest major version for document created with VersioningState set to major")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void verifyIsLatestMajorVersionForMajorState() throws Exception
+ {
+ cmisApi.authenticateUser(managerUser).usingResource(majorVersionDoc)
+ .and().assertThat().isLatestMajorVersion();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify latest major version for folder")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS}, expectedExceptions=InvalidCmisObjectException.class)
+ public void verifyIsLatestMajorVersionOnFolders() throws Exception
+ {
+ FolderModel folderModel = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(managerUser).usingSite(testSite)
+ .createFolder(folderModel)
+ .and().assertThat().isLatestMajorVersion();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify is latest major version for document created with VersioningState set to minor")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void verifyIsLatestMajorVersionForMinorState() throws Exception
+ {
+ cmisApi.authenticateUser(managerUser).usingResource(minorVersionDoc)
+ .and().assertThat().isNotLatestMajorVersion();
+ }
+
+ @Bug(id = "MNT-17961", status = Status.FIXED)
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify that major version doesn't change for document created with VersioningState set to none")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void verifyMajorVersionNotChangedForNoneState() throws Exception
+ {
+ FileModel testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(managerUser).usingSite(testSite)
+ .createFile(testFile, VersioningState.NONE).and().assertThat().existsInRepo()
+ .and().assertThat().isLatestMajorVersion()
+ .and().checkOut().and().assertThat().documentIsCheckedOut()
+ .and().prepareDocumentForCheckIn()
+ .withMinorVersion()
+ .checkIn().refreshResource()
+ .and().assertThat().documentIsNotCheckedOut()
+ .then().assertThat().documentHasVersion(1.0);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify is latest major version for document created with VersioningState set to checkedout")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void verifyIsLatestMajorVersionForCheckedOutState() throws Exception
+ {
+ FileModel testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(managerUser).usingSite(testSite)
+ .createFile(testFile, VersioningState.CHECKEDOUT)
+ .usingPWCDocument()
+ .assertThat().existsInRepo()
+ .and().assertThat().isNotLatestMajorVersion()
+ .and().assertThat().documentIsCheckedOut();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify latest major version fails for document that was deleted")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisObjectNotFoundException.class)
+ public void verifyIsLatestMajorVersionFailsOnDeletedDocument() throws Exception
+ {
+ FileModel testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(managerUser).usingSite(testSite)
+ .createFile(testFile)
+ .and().assertThat().isLatestMajorVersion()
+ .and().delete()
+ .then().assertThat().isLatestMajorVersion();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify collaborator can verify is latest major version for document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorCanVerifyIsLatestMajorVersion() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingResource(majorVersionDoc)
+ .usingResource(majorVersionDoc)
+ .and().assertThat().isLatestMajorVersion()
+ .then().usingResource(minorVersionDoc).assertThat().isNotLatestMajorVersion();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify contributor can verify is latest major version for document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorCanVerifyIsLatestMajorVersion() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingResource(majorVersionDoc)
+ .usingResource(majorVersionDoc)
+ .and().assertThat().isLatestMajorVersion()
+ .then().usingResource(minorVersionDoc).assertThat().isNotLatestMajorVersion();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify consumer can verify is latest major version for document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void consumerCanVerifyIsLatestMajorVersion() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer)).usingResource(majorVersionDoc)
+ .usingResource(majorVersionDoc)
+ .and().assertThat().isLatestMajorVersion()
+ .then().usingResource(minorVersionDoc).assertThat().isNotLatestMajorVersion();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify non invited user can verify is latest major version for document in public site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void nonInvitedUserCanVerifyIsLatestMajorVersionInPublicSite() throws Exception
+ {
+ cmisApi.authenticateUser(nonInviteUser).usingResource(majorVersionDoc)
+ .usingResource(majorVersionDoc)
+ .and().assertThat().isLatestMajorVersion()
+ .then().usingResource(minorVersionDoc).assertThat().isNotLatestMajorVersion();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify non invited user can verify is latest major version for document in private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonInvitedUserCannotVerifyIsLatestMajorVersionInPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingUser(managerUser).createPrivateRandomSite();
+ FileModel privateDoc = FileModel.getRandomFileModel(FileType.HTML, documentContent);
+ cmisApi.authenticateUser(managerUser)
+ .usingSite(privateSite).createFile(privateDoc)
+ .then().authenticateUser(nonInviteUser).usingResource(privateDoc)
+ .and().assertThat().isLatestMajorVersion();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify non invited user can verify is latest major version for document in moderated site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonInvitedUserCannotVerifyIsLatestMajorVersionInModeratedSite() throws Exception
+ {
+ SiteModel moderatedSite = dataSite.usingUser(managerUser).createPrivateRandomSite();
+ FileModel moderatedDoc = FileModel.getRandomFileModel(FileType.HTML, documentContent);
+ cmisApi.authenticateUser(managerUser)
+ .usingSite(moderatedSite).createFile(moderatedDoc)
+ .then().authenticateUser(nonInviteUser).usingResource(moderatedDoc)
+ .and().assertThat().isLatestMajorVersion();
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/IsPrivateWorkingCopyTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/IsPrivateWorkingCopyTests.java
new file mode 100644
index 00000000000..e7ea845023b
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/IsPrivateWorkingCopyTests.java
@@ -0,0 +1,153 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.enums.VersioningState;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class IsPrivateWorkingCopyTests extends CmisTest
+{
+ SiteModel testSite;
+ UserModel managerUser, nonInvitedUser;
+ FileModel checkedOutDoc, simpleDoc;
+ private DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ checkedOutDoc = FileModel.getRandomFileModel(FileType.XML, documentContent);
+ simpleDoc = FileModel.getRandomFileModel(FileType.HTML, documentContent);
+ managerUser = dataUser.createRandomTestUser();
+ nonInvitedUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(managerUser).createPublicRandomSite();
+ usersWithRoles = dataUser.usingUser(managerUser)
+ .addUsersWithRolesToSite(testSite, UserRole.SiteContributor, UserRole.SiteCollaborator, UserRole.SiteConsumer);
+ cmisApi.authenticateUser(managerUser).usingSite(testSite)
+ .createFile(checkedOutDoc).and().checkOut()
+ .createFile(simpleDoc);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify site manager is able to verify if checked out document is private working copy")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerCanVerifyIsPrivateWorkingCopy() throws Exception
+ {
+ cmisApi.authenticateUser(managerUser).usingResource(checkedOutDoc)
+ .assertThat().isPrivateWorkingCopy()
+ .then().usingResource(simpleDoc).assertThat().isNotPrivateWorkingCopy();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify site manager is able to verify if pwc document is private working copy")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerCanVerifyIsPrivateWorkingCopyOnPwc() throws Exception
+ {
+ cmisApi.authenticateUser(managerUser).usingResource(checkedOutDoc)
+ .usingPWCDocument()
+ .assertThat().isPrivateWorkingCopy();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to verify if deleted document is private working copy")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisObjectNotFoundException.class)
+ public void siteManagerCannotVerifyIsPrivateWorkingCopyOnDeletedDoc() throws Exception
+ {
+ FileModel deletedDoc = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(managerUser).usingSite(testSite)
+ .createFile(deletedDoc)
+ .then().delete().and().assertThat().doesNotExistInRepo()
+ .assertThat().isPrivateWorkingCopy();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to verify if checked out document is private working copy")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorCanVerifyIsPrivateWorkingCopy() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingResource(checkedOutDoc)
+ .assertThat().isPrivateWorkingCopy()
+ .then().usingResource(simpleDoc).assertThat().isNotPrivateWorkingCopy();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site contributor is able to verify if checked out document is private working copy")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorCanVerifyIsPrivateWorkingCopy() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingResource(checkedOutDoc)
+ .assertThat().isPrivateWorkingCopy()
+ .then().usingResource(simpleDoc).assertThat().isNotPrivateWorkingCopy();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site consumer is able to verify if checked out document is private working copy")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void consumerCanVerifyIsPrivateWorkingCopy() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .usingResource(checkedOutDoc)
+ .assertThat().isPrivateWorkingCopy()
+ .then().usingResource(simpleDoc).assertThat().isNotPrivateWorkingCopy();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify non invited user is able to verify if checked out document is private working copy in public site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void nonInvitedUserCanVerifyIsPrivateWorkingCopyInPublicSite() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .usingResource(checkedOutDoc)
+ .assertThat().isPrivateWorkingCopy()
+ .then().usingResource(simpleDoc).assertThat().isNotPrivateWorkingCopy();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify non invited user is not able to verify if checked out document is private working copy in private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonInvitedUserCannotVerifyIsPrivateWorkingCopyInPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingUser(managerUser).createPrivateRandomSite();
+ FileModel privateFile = FileModel.getRandomFileModel(FileType.HTML);
+ cmisApi.authenticateUser(managerUser).usingSite(privateSite)
+ .createFile(privateFile)
+ .then().authenticateUser(nonInvitedUser)
+ .assertThat().isPrivateWorkingCopy();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify non invited user is not able to verify if checked out document is private working copy in moderated site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonInvitedUserCannotVerifyIsPrivateWorkingCopyInModeratedSite() throws Exception
+ {
+ SiteModel moderatedSite = dataSite.usingUser(managerUser).createPrivateRandomSite();
+ FileModel moderatedFile = FileModel.getRandomFileModel(FileType.HTML);
+ cmisApi.authenticateUser(managerUser).usingSite(moderatedSite)
+ .createFile(moderatedFile)
+ .then().authenticateUser(nonInvitedUser)
+ .assertThat().isPrivateWorkingCopy();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to verify if document created with CHECKEDOUT versioning state is private working copy")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void verifyIsPrivateWorkingCopyForDocumentWithCheckedOutVersioningState() throws Exception
+ {
+ FileModel checkedDoc = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(managerUser).usingSite(testSite)
+ .createFile(checkedDoc, VersioningState.CHECKEDOUT).refreshResource()
+ .assertThat().isPrivateWorkingCopy();
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/MoveTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/MoveTests.java
new file mode 100644
index 00000000000..b6f9fccc19e
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/MoveTests.java
@@ -0,0 +1,357 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.FolderModel;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.enums.VersioningState;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUpdateConflictException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * Created by Claudia Agache on 9/28/2016.
+ */
+public class MoveTests extends CmisTest
+{
+ UserModel unauthorizedUser;
+ UserModel siteManager;
+ UserModel contributorUser;
+ UserModel collaboratorUser;
+ UserModel consumerUser;
+ SiteModel publicSite;
+ FileModel sourceFile;
+ FolderModel targetFolder, sourceFolder;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ unauthorizedUser = dataUser.createRandomTestUser();
+ siteManager = dataUser.createRandomTestUser();
+ contributorUser = dataUser.createRandomTestUser();
+ collaboratorUser = dataUser.createRandomTestUser();
+ consumerUser = dataUser.createRandomTestUser();
+ publicSite = dataSite.usingUser(siteManager).createPublicRandomSite();
+
+ dataUser.addUserToSite(consumerUser, publicSite, UserRole.SiteConsumer);
+ dataUser.addUserToSite(collaboratorUser, publicSite, UserRole.SiteCollaborator);
+ dataUser.addUserToSite(contributorUser, publicSite, UserRole.SiteContributor);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify site manager is able to move a file to an existent location in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerMovesFile() throws Exception
+ {
+ targetFolder = FolderModel.getRandomFolderModel();
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "content");
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFolder(targetFolder).and().assertThat().existsInRepo()
+ .createFile(sourceFile).and().assertThat().existsInRepo()
+ .then().moveTo(targetFolder).and().assertThat().existsInRepo()
+ .usingResource(sourceFile).assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to move file to a nonexistent location in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisObjectNotFoundException.class)
+ public void siteManagerMovesFileToNonExistentTarget() throws Exception
+ {
+ targetFolder = FolderModel.getRandomFolderModel();
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "content");
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(sourceFile).and().assertThat().existsInRepo()
+ .createFolder(targetFolder).and().delete()
+ .then().moveTo(targetFolder);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to move a nonexistent file in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisObjectNotFoundException.class)
+ public void siteManagerMovesNonExistentSourceFile() throws Exception
+ {
+ targetFolder = FolderModel.getRandomFolderModel();
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "content");
+ cmisApi.usingSite(publicSite)
+ .createFolder(targetFolder).and().assertThat().existsInRepo()
+ .createFile(sourceFile).and().delete()
+ .then().moveTo(targetFolder);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to move file that has multiple versions with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerShouldMoveFileWithMultipleVersions() throws Exception
+ {
+ targetFolder = FolderModel.getRandomFolderModel();
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "content");
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFolder(targetFolder).and().assertThat().existsInRepo()
+ .createFile(sourceFile).and().assertThat().existsInRepo()
+ .then().update("first content")
+ .assertThat().documentHasVersion(1.1)
+ .update("second content")
+ .assertThat().documentHasVersion(1.2)
+ .then().moveTo(targetFolder).and().assertThat().existsInRepo()
+ .and().usingVersion().assertHasVersions(1.0, 1.1, 1.2)
+ .usingResource(sourceFile).assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to move folder structure to an existent location in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerMovesFolderStructure() throws Exception
+ {
+ targetFolder = FolderModel.getRandomFolderModel();
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "content");
+ FolderModel sourceParentFolder = FolderModel.getRandomFolderModel();
+ FolderModel subFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFolder(targetFolder).and().assertThat().existsInRepo()
+ .createFolder(sourceParentFolder).and().assertThat().existsInRepo()
+ .then().usingResource(sourceParentFolder)
+ .createFile(sourceFile).and().assertThat().existsInRepo()
+ .createFolder(subFolder).and().assertThat().existsInRepo()
+ .when().usingResource(sourceParentFolder)
+ .moveTo(targetFolder).and().assertThat().existsInRepo()
+ .and().assertThat().hasChildren(sourceFile, subFolder);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify inexistent is not able to move file with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisUnauthorizedException.class)
+ public void inexistentUserCannotMoveFile() throws Exception
+ {
+ targetFolder = FolderModel.getRandomFolderModel();
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "content");
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFolder(targetFolder).and().assertThat().existsInRepo()
+ .createFile(sourceFile).and().assertThat().existsInRepo()
+ .then().authenticateUser(UserModel.getRandomUserModel())
+ .moveTo(targetFolder).and().assertThat().existsInRepo()
+ .usingResource(sourceFile).assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to move checked out file with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions=CmisUpdateConflictException.class)
+ public void siteManagerShouldNotMoveCheckedOutFile() throws Exception
+ {
+ targetFolder = FolderModel.getRandomFolderModel();
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "content");
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFolder(targetFolder).and().assertThat().existsInRepo()
+ .createFile(sourceFile).and().assertThat().existsInRepo()
+ .and().checkOut().assertThat().documentIsCheckedOut()
+ .then().usingResource(sourceFile)
+ .moveTo(targetFolder).and().assertThat().existsInRepo()
+ .and().assertThat().documentIsCheckedOut();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to move folder with checked out document")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void siteManagerShouldMoveFolderWithCheckedOutFile() throws Exception
+ {
+ targetFolder = FolderModel.getRandomFolderModel();
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "content");
+ sourceFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFolder(targetFolder).and().assertThat().existsInRepo()
+ .createFolder(sourceFolder).and().assertThat().existsInRepo()
+ .then().usingResource(sourceFolder)
+ .createFile(sourceFile, VersioningState.CHECKEDOUT)
+ .and().assertThat().existsInRepo()
+ .assertThat().documentIsCheckedOut()
+ .then().usingResource(sourceFolder)
+ .moveTo(targetFolder).and().assertThat().existsInRepo()
+ .and().assertThat().hasFiles(sourceFile);
+ FileModel checkedOutDoc = cmisApi.getFiles().get(0);
+ cmisApi.usingResource(checkedOutDoc).assertThat().documentIsCheckedOut();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify unauthorized user is no able to move a file")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void unauthorizedUserCannotMovesFile() throws Exception
+ {
+ targetFolder = FolderModel.getRandomFolderModel();
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "content");
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFolder(targetFolder).and().assertThat().existsInRepo()
+ .createFile(sourceFile).and().assertThat().existsInRepo()
+ .then().authenticateUser(unauthorizedUser)
+ .then().moveTo(targetFolder);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Manager verify PWC document object cannot be moved")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = CmisUpdateConflictException.class)
+ public void managerCannotMovePWCDocumentObject() throws Exception
+ {
+ sourceFile = dataContent.usingUser(siteManager).usingSite(publicSite).createContent(FileModel.getRandomFileModel(FileType.TEXT_PLAIN));
+ targetFolder = dataContent.usingUser(siteManager).usingSite(publicSite).createFolder();
+ FileModel pwcFile = cmisApi.authenticateUser(siteManager).usingResource(sourceFile).checkOut().withCMISUtil().getPWCFileModel();
+ cmisApi.usingResource(pwcFile).moveTo(targetFolder);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify contributor can move Document created by self")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void contributorCanMoveDocumentCreatedBySelf() throws Exception
+ {
+ sourceFile = dataContent.usingUser(contributorUser).usingSite(publicSite).createContent(FileModel.getRandomFileModel(FileType.TEXT_PLAIN));
+ targetFolder = dataContent.usingUser(contributorUser).usingSite(publicSite).createFolder();
+ cmisApi.authenticateUser(contributorUser).usingResource(sourceFile).moveTo(targetFolder)
+ .usingResource(targetFolder).assertThat().hasChildren(sourceFile)
+ .usingSite(publicSite).assertThat().doesNotHaveFile(sourceFile);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify contributor cannot move Document created by Manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void contributorCannotMoveDocumentCreatedByManager() throws Exception
+ {
+ sourceFile = dataContent.usingUser(siteManager).usingSite(publicSite).createContent(FileModel.getRandomFileModel(FileType.TEXT_PLAIN));
+ targetFolder = dataContent.usingUser(siteManager).usingSite(publicSite).createFolder();
+ cmisApi.authenticateUser(contributorUser).usingResource(sourceFile).moveTo(targetFolder);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify contributor can move Folder created by self")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void contributorCanMoveFolderCreatedBySelf() throws Exception
+ {
+ sourceFolder = dataContent.usingUser(contributorUser).usingSite(publicSite).createFolder();
+ targetFolder = dataContent.usingUser(contributorUser).usingSite(publicSite).createFolder();
+ cmisApi.authenticateUser(contributorUser).usingResource(sourceFolder).moveTo(targetFolder)
+ .usingResource(targetFolder).assertThat().hasChildren(sourceFolder)
+ .usingSite(publicSite).assertThat().doesNotHaveFolder(sourceFolder);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify contributor cannot move Folder created by Manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void contributorCannotMoveFolderCreatedByManager() throws Exception
+ {
+ sourceFolder = dataContent.usingUser(siteManager).usingSite(publicSite).createFolder();
+ targetFolder = dataContent.usingUser(siteManager).usingSite(publicSite).createFolder();
+ cmisApi.authenticateUser(contributorUser).usingResource(sourceFolder).moveTo(targetFolder);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify collaborator can move Document created by self")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void collaboratorCanMoveDocumentCreatedBySelf() throws Exception
+ {
+ sourceFile = dataContent.usingUser(collaboratorUser).usingSite(publicSite).createContent(FileModel.getRandomFileModel(FileType.TEXT_PLAIN));
+ targetFolder = dataContent.usingUser(collaboratorUser).usingSite(publicSite).createFolder();
+ cmisApi.authenticateUser(collaboratorUser).usingResource(sourceFile).moveTo(targetFolder)
+ .usingResource(targetFolder).assertThat().hasChildren(sourceFile)
+ .usingSite(publicSite).assertThat().doesNotHaveFile(sourceFile);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify collaborator cannot move Document created by Manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void collaboratorCannotMoveDocumentCreatedByManager() throws Exception
+ {
+ sourceFile = dataContent.usingUser(siteManager).usingSite(publicSite).createContent(FileModel.getRandomFileModel(FileType.TEXT_PLAIN));
+ targetFolder = dataContent.usingUser(siteManager).usingSite(publicSite).createFolder();
+ cmisApi.authenticateUser(collaboratorUser).usingResource(sourceFile).moveTo(targetFolder);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify collaborator can move Folder created by self")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void collaboratorCanMoveFolderCreatedBySelf() throws Exception
+ {
+ sourceFolder = dataContent.usingUser(collaboratorUser).usingSite(publicSite).createFolder();
+ targetFolder = dataContent.usingUser(collaboratorUser).usingSite(publicSite).createFolder();
+ cmisApi.authenticateUser(collaboratorUser).usingResource(sourceFolder).moveTo(targetFolder)
+ .usingResource(targetFolder).assertThat().hasChildren(sourceFolder)
+ .usingSite(publicSite).assertThat().doesNotHaveFolder(sourceFolder);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify collaborator cannot move Folder created by Manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void collaboratorCannotMoveFolderCreatedByManager() throws Exception
+ {
+ sourceFolder = dataContent.usingUser(siteManager).usingSite(publicSite).createFolder();
+ targetFolder = dataContent.usingUser(siteManager).usingSite(publicSite).createFolder();
+ cmisApi.authenticateUser(collaboratorUser).usingResource(sourceFolder).moveTo(targetFolder);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify consumer cannot move Document")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void consumerCannotMoveDocument() throws Exception
+ {
+ sourceFile = dataContent.usingUser(siteManager).usingSite(publicSite).createContent(FileModel.getRandomFileModel(FileType.TEXT_PLAIN));
+ targetFolder = dataContent.usingUser(siteManager).usingSite(publicSite).createFolder();
+ cmisApi.authenticateUser(consumerUser).usingResource(sourceFile).moveTo(targetFolder);
+ }
+
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify consumer cannot move Folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void consumerCannotMoveFolder() throws Exception
+ {
+ sourceFolder = dataContent.usingUser(siteManager).usingSite(publicSite).createFolder();
+ targetFolder = dataContent.usingUser(siteManager).usingSite(publicSite).createFolder();
+ cmisApi.authenticateUser(consumerUser).usingResource(sourceFolder).moveTo(targetFolder);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify unauthorized user cannot move Document from private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void unauthorizedUserCannotMoveDocumentFromPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingUser(siteManager).createPrivateRandomSite();
+ sourceFile = dataContent.usingUser(siteManager).usingSite(privateSite).createContent(FileModel.getRandomFileModel(FileType.TEXT_PLAIN));
+ targetFolder = dataContent.usingUser(siteManager).usingSite(privateSite).createFolder();
+ cmisApi.authenticateUser(unauthorizedUser).usingResource(sourceFile).moveTo(targetFolder);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify unauthorized user cannot move Folder from private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void unauthorizedUserCannotMoveFolderFromPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingUser(siteManager).createPrivateRandomSite();
+ sourceFolder = dataContent.usingUser(siteManager).usingSite(privateSite).createFolder();
+ targetFolder = dataContent.usingUser(siteManager).usingSite(privateSite).createFolder();
+ cmisApi.authenticateUser(unauthorizedUser).usingResource(sourceFolder).moveTo(targetFolder);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify unauthorized user cannot move Document from moderated site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void unauthorizedUserCannotMoveDocumentFromModeratedSite() throws Exception
+ {
+ SiteModel moderatedSite = dataSite.usingUser(siteManager).createModeratedRandomSite();
+ sourceFile = dataContent.usingUser(siteManager).usingSite(moderatedSite).createContent(FileModel.getRandomFileModel(FileType.TEXT_PLAIN));
+ targetFolder = dataContent.usingUser(siteManager).usingSite(moderatedSite).createFolder();
+ cmisApi.authenticateUser(unauthorizedUser).usingResource(sourceFile).moveTo(targetFolder);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify unauthorized user cannot move Folder from moderated site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisUnauthorizedException.class, CmisPermissionDeniedException.class})
+ public void unauthorizedUserCannotMoveFolderFromModeratedSite() throws Exception
+ {
+ SiteModel moderatedSite = dataSite.usingUser(siteManager).createModeratedRandomSite();
+ sourceFolder = dataContent.usingUser(siteManager).usingSite(moderatedSite).createFolder();
+ targetFolder = dataContent.usingUser(siteManager).usingSite(moderatedSite).createFolder();
+ cmisApi.authenticateUser(unauthorizedUser).usingResource(sourceFolder).moveTo(targetFolder);
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/RelationshipTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/RelationshipTests.java
new file mode 100644
index 00000000000..d5662fafeb4
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/RelationshipTests.java
@@ -0,0 +1,267 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.FolderModel;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.report.Bug;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * Created by Claudia Agache on 9/29/2016.
+ */
+public class RelationshipTests extends CmisTest
+{
+ UserModel siteManager;
+ SiteModel publicSite, privateSite;
+ FileModel sourceFile, targetFile;
+ private DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ siteManager = dataUser.createRandomTestUser();
+ publicSite = dataSite.usingUser(siteManager).createPublicRandomSite();
+ privateSite = dataSite.usingUser(siteManager).createPrivateRandomSite();
+ usersWithRoles = dataUser.addUsersWithRolesToSite(publicSite, UserRole.SiteManager, UserRole.SiteContributor, UserRole.SiteCollaborator, UserRole.SiteConsumer);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify site manager is able to create relationship between a source object and a target object in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerCreatesRelationshipBetween2Files() throws Exception
+ {
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ targetFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(targetFile).and().assertThat().existsInRepo()
+ .createFile(sourceFile).and().assertThat().existsInRepo()
+ .then().createRelationshipWith(targetFile)
+ .and().assertThat().objectHasRelationshipWith(targetFile);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to create relationship between a invalid sources with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisObjectNotFoundException.class)
+ public void siteManagerCannotCreateRelWithInvalidSources() throws Exception
+ {
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ targetFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(targetFile).and().delete().assertThat().doesNotExistInRepo()
+ .createFile(sourceFile).and().delete().assertThat().doesNotExistInRepo()
+ .then().createRelationshipWith(targetFile);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to create relationship with checkout source document with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanCreateRelWithCheckedOutSourceDocument() throws Exception
+ {
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ targetFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(targetFile).and().assertThat().existsInRepo()
+ .createFile(sourceFile).and().assertThat().existsInRepo()
+ .then().checkOut().and().assertThat().documentIsCheckedOut()
+ .then().createRelationshipWith(targetFile)
+ .and().assertThat().objectHasRelationshipWith(targetFile);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify that inexistent user is not able to create relationship between documents with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisUnauthorizedException.class)
+ public void inexistentUserCannotCreateRelationship() throws Exception
+ {
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ targetFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(targetFile).and().assertThat().existsInRepo()
+ .createFile(sourceFile).and().assertThat().existsInRepo()
+ .then().authenticateUser(UserModel.getRandomUserModel())
+ .createRelationshipWith(targetFile)
+ .and().assertThat().objectHasRelationshipWith(targetFile);
+ }
+
+ @Bug(id="REPO-4301")
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify that user that was deleted is not able to create relationship between documents with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisUnauthorizedException.class)
+ public void deletedUserCannotCreateRelationship() throws Exception
+ {
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ targetFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ UserModel toBeDeleted = dataUser.createRandomTestUser();
+ FolderModel shared = FolderModel.getSharedFolderModel();
+ cmisApi.authenticateUser(toBeDeleted)
+ .usingResource(shared)
+ .createFile(targetFile).and().assertThat().existsInRepo()
+ .createFile(sourceFile).and().assertThat().existsInRepo();
+ dataUser.deleteUser(toBeDeleted);
+ cmisApi.createRelationshipWith(targetFile);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify that site manager is able to create relationship between documents with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanCreateRelationshipInPrivateSite() throws Exception
+ {
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ targetFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(dataUser.getAdminUser())
+ .usingSite(privateSite)
+ .createFile(targetFile).and().assertThat().existsInRepo()
+ .createFile(sourceFile).and().assertThat().existsInRepo()
+ .then().authenticateUser(siteManager)
+ .createRelationshipWith(targetFile)
+ .and().assertThat().objectHasRelationshipWith(targetFile);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to create relationship between a invalid sources with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisObjectNotFoundException.class)
+ public void siteManagerCannotGetRelWithInvalidObject() throws Exception
+ {
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ targetFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ FileModel invalidFile = FileModel.getRandomFileModel(FileType.HTML);
+ invalidFile.setCmisLocation("/" + invalidFile.getName() + "/");
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(targetFile)
+ .createFile(sourceFile)
+ .then().createRelationshipWith(targetFile)
+ .and().assertThat().objectHasRelationshipWith(targetFile)
+ .assertThat().objectHasRelationshipWith(invalidFile);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify admin is able to create relationship between a source folder and a target file with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void adminCreatesRelBetweenSourceFolderAndTargetFile() throws Exception
+ {
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ targetFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ FolderModel sourceFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingSite(publicSite)
+ .createFile(targetFile).assertThat().existsInRepo()
+ .createFolder(sourceFolder).assertThat().existsInRepo()
+ .then().createRelationshipWith(targetFile)
+ .and().assertThat().objectHasRelationshipWith(targetFile);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify contributor is not able to create relationship between a source object and a target object in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS},expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void contributorCannotCreateRelationship() throws Exception
+ {
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ targetFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(targetFile).and().assertThat().existsInRepo()
+ .createFile(sourceFile).and().assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingResource(sourceFile).createRelationshipWith(targetFile)
+ .and().assertThat().objectHasRelationshipWith(targetFile);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify collaborator is able to create relationship between a source object and a target object in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorCanCreateRelationship() throws Exception
+ {
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ targetFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(targetFile).and().assertThat().existsInRepo()
+ .createFile(sourceFile).and().assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingResource(sourceFile).createRelationshipWith(targetFile)
+ .and().assertThat().objectHasRelationshipWith(targetFile);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify consumer is not able to create relationship between a source object and a target object in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS},expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void consumerCannotCreateRelationship() throws Exception
+ {
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ targetFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(targetFile).and().assertThat().existsInRepo()
+ .createFile(sourceFile).and().assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .usingResource(sourceFile).createRelationshipWith(targetFile)
+ .and().assertThat().objectHasRelationshipWith(targetFile);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify unauthorized user is not able to create relationship between a source object and a target object from a private site with CMIS")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void unauthorizedUserCannotCreateRelationship() throws Exception
+ {
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ targetFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(siteManager).usingSite(privateSite)
+ .createFile(targetFile).and().assertThat().existsInRepo()
+ .createFile(sourceFile).and().assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager))
+ .usingResource(sourceFile).createRelationshipWith(targetFile);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify unauthorized user is not able to get relationship between a source object and a target object from a private site with CMIS")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void unauthorizedUserCannotGetRelationship() throws Exception
+ {
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ targetFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(siteManager).usingSite(privateSite)
+ .createFile(targetFile).and().assertThat().existsInRepo()
+ .createFile(sourceFile).and().assertThat().existsInRepo()
+ .usingResource(sourceFile).createRelationshipWith(targetFile)
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager))
+ .and().assertThat().objectHasRelationshipWith(targetFile);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to create relationship for PWC source document with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisInvalidArgumentException.class,
+ expectedExceptionsMessageRegExp = "^Source is not the latest version of a document, a folder or an item object!$")
+ public void siteManagerCannotCreateRelationshipPWCSourceFile() throws Exception
+ {
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ targetFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(targetFile).and().assertThat().existsInRepo()
+ .createFile(sourceFile).and().assertThat().existsInRepo().then().checkOut()
+ .assertThat().documentIsCheckedOut()
+ .usingPWCDocument().createRelationshipWith(targetFile);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to create relationship with checkout target document with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanCreateRelWithCheckedOutTargetDocument() throws Exception
+ {
+ sourceFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ targetFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(targetFile).and().assertThat().existsInRepo()
+ .then().checkOut().and().assertThat().documentIsCheckedOut()
+ .createFile(sourceFile).and().assertThat().existsInRepo()
+ .then().createRelationshipWith(targetFile)
+ .and().assertThat().objectHasRelationshipWith(targetFile);
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/RemoveObjectFromFolderTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/RemoveObjectFromFolderTests.java
new file mode 100644
index 00000000000..9d164edca64
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/RemoveObjectFromFolderTests.java
@@ -0,0 +1,243 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.FolderModel;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * Created by Claudia Agache on 10/3/2016.
+ */
+public class RemoveObjectFromFolderTests extends CmisTest
+{
+ UserModel unauthorizedUser;
+ UserModel siteManager;
+ UserModel contributorUser;
+ UserModel collaboratorUser;
+ UserModel consumerUser;
+ SiteModel publicSite;
+ FolderModel parentFolder, testFolder;
+ FileModel testFile;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ unauthorizedUser = dataUser.createRandomTestUser();
+ siteManager = dataUser.createRandomTestUser();
+ contributorUser = dataUser.createRandomTestUser();
+ collaboratorUser = dataUser.createRandomTestUser();
+ consumerUser = dataUser.createRandomTestUser();
+ publicSite = dataSite.usingUser(siteManager).createPublicRandomSite();
+ dataUser.addUserToSite(consumerUser, publicSite, UserRole.SiteConsumer);
+ dataUser.addUserToSite(collaboratorUser, publicSite, UserRole.SiteCollaborator);
+ dataUser.addUserToSite(contributorUser, publicSite, UserRole.SiteContributor);
+ parentFolder = FolderModel.getRandomFolderModel();
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFolder(testFolder).assertThat().existsInRepo()
+ .createFolder(parentFolder).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.SANITY,
+ description = "Verify site manager is able to remove a document from folder in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerShouldRemoveFileToFolder() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(siteManager).usingResource(parentFolder)
+ .createFile(testFile).assertThat().existsInRepo()
+ .and().addDocumentToFolder(testFolder, true).then().assertThat().existsInRepo()
+ .when().removeDocumentFromFolder(testFolder).assertThat().doesNotExistInRepo()
+ .usingResource(testFile).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is able to leave a document without parent folder with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisInvalidArgumentException.class, expectedExceptionsMessageRegExp = "^Object is not a document!$")
+ public void siteManagerShouldNotRemoveFolderFromFolder() throws Exception
+ {
+ FolderModel subFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(siteManager).usingResource(parentFolder)
+ .createFolder(subFolder).assertThat().existsInRepo()
+ .when().removeDocumentFromFolder(testFolder).assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to remove a document without parent folder with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisObjectNotFoundException.class)
+ public void siteManagerShouldNotRemoveInvalidFileFromFolder() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ testFile.setCmisLocation("/" + testFile.getName() + "/");
+ cmisApi.authenticateUser(siteManager).usingResource(testFile)
+ .when().removeDocumentFromFolder(testFolder).assertThat().doesNotExistInRepo()
+ .usingResource(testFile).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to remove valid document from invalid folder with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisObjectNotFoundException.class)
+ public void siteManagerShouldNotRemoveFileToInvalidFolder() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ FolderModel invalidFolder = FolderModel.getRandomFolderModel();
+ invalidFolder.setCmisLocation("/" + invalidFolder.getName() + "/");
+ cmisApi.authenticateUser(siteManager).usingResource(parentFolder)
+ .createFile(testFile).assertThat().existsInRepo()
+ .and().addDocumentToFolder(testFolder, true).then().assertThat().existsInRepo()
+ .when().removeDocumentFromFolder(invalidFolder)
+ .assertThat().doesNotExistInRepo()
+ .usingResource(testFile).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is able to remove a checked out document from folder in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerShouldRemovePWCFileToFolder() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(siteManager).usingResource(parentFolder)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().checkOut().and().assertThat().documentIsCheckedOut()
+ .usingPWCDocument().addDocumentToFolder(testFolder, true)
+ .then().assertThat().existsInRepo()
+ .and().assertThat().documentIsCheckedOut()
+ .when().removeDocumentFromFolder(testFolder).assertThat().doesNotExistInRepo()
+ .usingResource(testFile).assertThat().existsInRepo()
+ .and().assertThat().documentIsCheckedOut();
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.SANITY,
+ description = "Verify unauthorized user is not able to remove a document from folder")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void unauthorizedUserShouldNotRemoveFileToFolder() throws Exception
+ {
+ UserModel unauthorizedUser = dataUser.createRandomTestUser();
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(siteManager)
+ .usingResource(parentFolder)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(unauthorizedUser)
+ .removeDocumentFromFolder(testFolder);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify contributor can remove document from folder created by self")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void contributorCanRemoveDocumentFromFolderCreatedBySelf() throws Exception
+ {
+ parentFolder = dataContent.usingUser(contributorUser).usingSite(publicSite).createFolder();
+ testFolder = dataContent.usingUser(contributorUser).usingSite(publicSite).createFolder();
+ testFile = dataContent.usingUser(contributorUser).usingResource(parentFolder)
+ .createContent(FileModel.getRandomFileModel(FileType.TEXT_PLAIN));
+
+ cmisApi.authenticateUser(contributorUser).usingResource(testFile)
+ .addDocumentToFolder(testFolder, true).then().assertThat().existsInRepo()
+ .removeDocumentFromFolder(testFolder).assertThat().doesNotExistInRepo()
+ .usingResource(testFile).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify contributor can remove document from folder created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void contributorCannotRemoveDocumentFromFolderCreatedByManager() throws Exception
+ {
+ parentFolder = dataContent.usingUser(siteManager).usingSite(publicSite).createFolder();
+ testFolder = dataContent.usingUser(siteManager).usingSite(publicSite).createFolder();
+ testFile = dataContent.usingUser(siteManager).usingResource(parentFolder)
+ .createContent(FileModel.getRandomFileModel(FileType.TEXT_PLAIN));
+ cmisApi.authenticateUser(siteManager).usingResource(testFile)
+ .addDocumentToFolder(testFolder, true);
+
+ cmisApi.authenticateUser(contributorUser).usingResource(testFile).removeDocumentFromFolder(testFolder);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify collaborator can remove document from folder created by self")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS })
+ public void collaboratorCanRemoveDocumentFromFolderCreatedBySelf() throws Exception
+ {
+ parentFolder = dataContent.usingUser(collaboratorUser).usingSite(publicSite).createFolder();
+ testFolder = dataContent.usingUser(collaboratorUser).usingSite(publicSite).createFolder();
+ testFile = dataContent.usingUser(collaboratorUser).usingResource(parentFolder)
+ .createContent(FileModel.getRandomFileModel(FileType.TEXT_PLAIN));
+
+ cmisApi.authenticateUser(collaboratorUser).usingResource(testFile)
+ .addDocumentToFolder(testFolder, true).then().assertThat().existsInRepo()
+ .removeDocumentFromFolder(testFolder).assertThat().doesNotExistInRepo()
+ .usingResource(testFile).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify collaborator can remove document from folder created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void collaboratorCannotRemoveDocumentFromFolderCreatedByManager() throws Exception
+ {
+ parentFolder = dataContent.usingUser(siteManager).usingSite(publicSite).createFolder();
+ testFolder = dataContent.usingUser(siteManager).usingSite(publicSite).createFolder();
+ testFile = dataContent.usingUser(siteManager).usingResource(parentFolder)
+ .createContent(FileModel.getRandomFileModel(FileType.TEXT_PLAIN));
+ cmisApi.authenticateUser(siteManager).usingResource(testFile)
+ .addDocumentToFolder(testFolder, true);
+
+ cmisApi.authenticateUser(collaboratorUser).usingResource(testFile).removeDocumentFromFolder(testFolder);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify consumer cannot remove document from folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void consumerCannotRemoveDocumentFromFolder() throws Exception
+ {
+ parentFolder = dataContent.usingUser(siteManager).usingSite(publicSite).createFolder();
+ testFolder = dataContent.usingUser(siteManager).usingSite(publicSite).createFolder();
+ testFile = dataContent.usingUser(siteManager).usingResource(parentFolder)
+ .createContent(FileModel.getRandomFileModel(FileType.TEXT_PLAIN));
+ cmisApi.authenticateUser(siteManager).usingResource(testFile)
+ .addDocumentToFolder(testFolder, true).then().assertThat().existsInRepo();
+
+ cmisApi.authenticateUser(consumerUser).usingResource(testFile).removeDocumentFromFolder(testFolder);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify remove document from folder by user that is outside a private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void unauthorizedUserCannotRemoveDocumentFromPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingUser(siteManager).createPrivateRandomSite();
+ parentFolder = dataContent.usingUser(siteManager).usingSite(privateSite).createFolder();
+ testFolder = dataContent.usingUser(siteManager).usingSite(privateSite).createFolder();
+ testFile = dataContent.usingUser(siteManager).usingResource(parentFolder)
+ .createContent(FileModel.getRandomFileModel(FileType.TEXT_PLAIN));
+ cmisApi.authenticateUser(siteManager).usingResource(testFile)
+ .addDocumentToFolder(testFolder, true).then().assertThat().existsInRepo();
+
+ cmisApi.authenticateUser(unauthorizedUser).usingResource(testFile).removeDocumentFromFolder(testFolder);
+ }
+
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify remove document from folder by user that is outside a moderated site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS }, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void unauthorizedUserCannotRemoveDocumentFromModeratedSite() throws Exception
+ {
+ SiteModel moderatedSite = dataSite.usingUser(siteManager).createModeratedRandomSite();
+ parentFolder = dataContent.usingUser(siteManager).usingSite(moderatedSite).createFolder();
+ testFolder = dataContent.usingUser(siteManager).usingSite(moderatedSite).createFolder();
+ testFile = dataContent.usingUser(siteManager).usingResource(parentFolder)
+ .createContent(FileModel.getRandomFileModel(FileType.TEXT_PLAIN));
+ cmisApi.authenticateUser(siteManager).usingResource(testFile)
+ .addDocumentToFolder(testFolder, true).then().assertThat().existsInRepo();
+
+ cmisApi.authenticateUser(unauthorizedUser).usingResource(testFile).removeDocumentFromFolder(testFolder);
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/RenameTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/RenameTests.java
new file mode 100644
index 00000000000..a7206e83882
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/RenameTests.java
@@ -0,0 +1,351 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.FolderModel;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisContentAlreadyExistsException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUpdateConflictException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class RenameTests extends CmisTest
+{
+ SiteModel testSite;
+ UserModel managerUser, inexistentUser, nonInvitedUser;
+ FileModel testFile;
+ FolderModel testFolder;
+ private DataUser.ListUserWithRoles usersWithRoles;
+ private String prefix = "-edit";
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ managerUser = dataUser.createRandomTestUser();
+ nonInvitedUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(managerUser).createPublicRandomSite();
+ inexistentUser = new UserModel("inexistent", "inexistent");
+ usersWithRoles = dataUser.usingUser(managerUser)
+ .addUsersWithRolesToSite(testSite, UserRole.SiteContributor, UserRole.SiteCollaborator, UserRole.SiteConsumer);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.SANITY,
+ description = "Verify site manager is able to rename document and folder created by himself")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerCanRenameContent() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(managerUser).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .createFolder(testFolder).assertThat().existsInRepo()
+ .then().usingResource(testFile)
+ .rename(testFile.getName() + prefix).assertThat().existsInRepo()
+ .when().usingResource(testFile).assertThat().doesNotExistInRepo()
+ .then().usingResource(testFolder)
+ .rename(testFolder.getName() + prefix).assertThat().existsInRepo()
+ .when().usingResource(testFolder).assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify admin user is able to rename document and folder created by himself")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void adminCanRenameContentFromPublicSite() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(managerUser).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .createFolder(testFolder).assertThat().existsInRepo()
+ .then().authenticateUser(dataUser.getAdminUser())
+ .usingResource(testFile)
+ .rename(testFile.getName() + prefix).assertThat().existsInRepo()
+ .when().usingResource(testFile).assertThat().doesNotExistInRepo()
+ .usingResource(testFolder)
+ .rename(testFolder.getName() + prefix).assertThat().existsInRepo()
+ .when().usingResource(testFolder).assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to rename inexistent document")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisObjectNotFoundException.class)
+ public void siteManagerCannotRenameInexistentDocument() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ testFile.setCmisLocation("/fake-folder/test.txt");
+ cmisApi.authenticateUser(managerUser).usingSite(testSite)
+ .then().usingResource(testFile)
+ .rename(testFile.getName() + prefix).assertThat().existsInRepo()
+ .when().usingResource(testFile).assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to rename inexistent folder")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisObjectNotFoundException.class)
+ public void siteManagerCannotRenameInexistentFolder() throws Exception
+ {
+ FolderModel folder = FolderModel.getRandomFolderModel();
+ folder.setCmisLocation("/" + folder.getName() + "/");
+ cmisApi.authenticateUser(managerUser).usingSite(testSite)
+ .then().usingResource(folder)
+ .rename(prefix).assertThat().existsInRepo()
+ .when().usingResource(testFile).assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to rename document with invalid symbols")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisConstraintException.class)
+ public void siteManagerCannotRenameDocumentInvalidSymbols() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(managerUser).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().usingResource(testFile)
+ .rename("/.:?|\\`\\.txt").assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to rename folder with invalid symbols")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisConstraintException.class)
+ public void siteManagerCannotRenameFolderInvalidSymbols() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(managerUser).usingSite(testSite)
+ .createFolder(testFolder).assertThat().existsInRepo()
+ .then().usingResource(testFolder)
+ .rename("/.:?|\\`\\.txt").assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to rename document with empty string")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=IllegalArgumentException.class,
+ expectedExceptionsMessageRegExp="New name must not be empty!*")
+ public void siteManagerCannotRenameDocumentEmptyName() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(managerUser).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().usingResource(testFile)
+ .rename("").assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to rename folder with empty name")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=IllegalArgumentException.class,
+ expectedExceptionsMessageRegExp="New name must not be empty!*")
+ public void siteManagerCannotRenameFolderEmptyName() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(managerUser).usingSite(testSite)
+ .createFolder(testFolder).assertThat().existsInRepo()
+ .then().usingResource(testFolder)
+ .rename("").assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to rename checked out document")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisUpdateConflictException.class)
+ public void siteManagerCannotRenameCheckedOutDocument() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(managerUser).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().checkOut().assertThat().documentIsCheckedOut()
+ .then().usingResource(testFile)
+ .rename(testFile.getName() + prefix).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is able to rename pwc document")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanRenamePwcDocument() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ FileModel renamedPwc = new FileModel("pwc" + prefix + " (Working Copy)");
+ cmisApi.authenticateUser(managerUser).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().checkOut().assertThat().documentIsCheckedOut()
+ .then().usingResource(testFile)
+ .usingPWCDocument().assertThat().existsInRepo()
+ .rename("pwc" + prefix);
+ renamedPwc.setCmisLocation(testFile.getCmisLocation().replace(testFile.getName(), renamedPwc.getName()));
+ cmisApi.usingResource(renamedPwc).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is able to rename document with same name")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanRenameDocumentWithSameName() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(managerUser).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().usingResource(testFile)
+ .rename(testFile.getName()).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is able to rename document with multiple versions")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanRenameDocumentWithMultipleVersions() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(managerUser).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().update("first content").assertThat().documentHasVersion(1.1)
+ .then().update("second content").assertThat().documentHasVersion(1.2)
+ .rename(testFile.getName() + prefix).assertThat().existsInRepo()
+ .and().assertThat().documentHasVersion(1.2);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to rename document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteCollaboratorCanRenameDocumentCreatedByManager() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(managerUser).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .rename(testFile.getName() + prefix).assertThat().existsInRepo()
+ .when().usingResource(testFile).assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to rename folder created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteCollaboratorCanRenameFolderCreatedByManager() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(managerUser).usingSite(testSite)
+ .createFolder(testFolder).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .rename(testFolder.getName() + prefix).assertThat().existsInRepo()
+ .when().usingResource(testFolder).assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is able to rename folder created by collaborator")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanRenameFolderCreatedByCollaborator() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingSite(testSite)
+ .createFolder(testFolder).assertThat().existsInRepo()
+ .then().authenticateUser(managerUser)
+ .rename(testFolder.getName() + prefix).assertThat().existsInRepo()
+ .when().usingResource(testFolder).assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to rename document created by himself")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteCollaboratorCanRenameDocumentCreatedByHimself() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .rename(testFile.getName() + prefix).assertThat().existsInRepo()
+ .when().usingResource(testFile).assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site contributor is not able to rename document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void siteContributorCannotRenameDocumentCreatedByManager() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(managerUser).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .rename(testFile.getName() + prefix).assertThat().existsInRepo()
+ .when().usingResource(testFile).assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site contributor is able to rename document created by himself")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteContributorCanRenameDocumentCreatedByHimself() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .rename(testFile.getName() + prefix).assertThat().existsInRepo()
+ .when().usingResource(testFile).assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site consumer is not able to rename document created by manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void siteConsumerCannotRenameDocumentCreatedByManager() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(managerUser).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .rename(testFile.getName() + prefix).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify non invited user is not able to rename document in public site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void siteConsumerCannotRenameDocumentInPublicSite() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(managerUser).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .rename(testFile.getName() + prefix).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify non invited user is not able to rename document in private site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonInvitedUserCannotRenameDocumentInPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingUser(managerUser).createPrivateRandomSite();
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(managerUser).usingSite(privateSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(nonInvitedUser)
+ .rename(testFile.getName() + prefix).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify non invited user is not able to rename document in moderated site")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonInvitedUserCannotRenameDocumentInModeratedSite() throws Exception
+ {
+ SiteModel moderatedSite = dataSite.usingUser(managerUser).createModeratedRandomSite();
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(managerUser).usingSite(moderatedSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(nonInvitedUser)
+ .rename(testFile.getName() + prefix).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to rename document with same name as another file in same location")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisContentAlreadyExistsException.class,
+ expectedExceptionsMessageRegExp="An object with this name already exists.*")
+ public void siteManagerCannotRenameDocumentWithSameNameFromOtherFile() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ FileModel secondFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(managerUser).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .createFile(secondFile)
+ .then().usingResource(testFile)
+ .rename(secondFile.getName()).assertThat().existsInRepo();
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/RenditionTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/RenditionTests.java
new file mode 100644
index 00000000000..50b3323828f
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/RenditionTests.java
@@ -0,0 +1,177 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.Utility;
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.enums.VersioningState;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+@Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.RENDITIONS})
+public class RenditionTests extends CmisTest
+{
+ private SiteModel testSite;
+ private UserModel testUser, inexistentUser, nonInvitedUser;
+ private DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ nonInvitedUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createPublicRandomSite();
+ inexistentUser = new UserModel("inexistent", "inexistent");
+ usersWithRoles = dataUser.usingUser(testUser)
+ .addUsersWithRolesToSite(testSite, UserRole.SiteContributor, UserRole.SiteCollaborator, UserRole.SiteConsumer);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.RENDITIONS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify admin can get renditions for valid Document object")
+ public void adminShouldGetRenditionsForDocument() throws Exception
+ {
+ FileModel txtModel = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingShared().createFile(txtModel);
+ Utility.sleep(300, 10000, () -> cmisApi.usingResource(txtModel).assertThat().renditionIsAvailable()
+ .assertThat().thumbnailRenditionIsAvailable());
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.RENDITIONS}, expectedExceptions = {CmisObjectNotFoundException.class})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify admin can get renditions for invalid Document object")
+ public void adminCannotGetRenditionsForInvalidDocument() throws Exception
+ {
+ FileModel invalidFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ invalidFile.setCmisLocation("/" + invalidFile.getName() + "/");
+ cmisApi.authenticateUser(dataUser.getAdminUser()).usingShared()
+ .then().usingResource(invalidFile).assertThat().renditionIsAvailable()
+ .assertThat().thumbnailRenditionIsAvailable();
+ }
+
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS, TestGroup.RENDITIONS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify site manager can get renditions for valid Document")
+ public void managerGetRenditionsForDocument() throws Exception
+ {
+ FileModel testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFile(testFile);
+ Utility.sleep(300, 10000, () -> cmisApi.authenticateUser(testUser)
+ .usingResource(testFile).assertThat().renditionIsAvailable()
+ .assertThat().thumbnailRenditionIsAvailable());
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.RENDITIONS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site collaborator can get renditions for valid Document")
+ public void collaboratorGetRenditionsForDocument() throws Exception
+ {
+ FileModel testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFile(testFile);
+ Utility.sleep(300, 10000, () -> cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingResource(testFile).assertThat().renditionIsAvailable()
+ .assertThat().thumbnailRenditionIsAvailable());
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.RENDITIONS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site contributor can get renditions for valid Document")
+ public void contributorGetRenditionsForDocument() throws Exception
+ {
+ FileModel testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFile(testFile);
+ Utility.sleep(300, 10000, () -> cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingResource(testFile).assertThat().renditionIsAvailable()
+ .assertThat().thumbnailRenditionIsAvailable());
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.RENDITIONS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site consumer can get renditions for valid Document")
+ public void consumerGetRenditionsForDocument() throws Exception
+ {
+ FileModel testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFile(testFile);
+ Utility.sleep(300, 10000, () -> cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .usingResource(testFile).assertThat().renditionIsAvailable()
+ .assertThat().thumbnailRenditionIsAvailable());
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.RENDITIONS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager can get renditions for checked out document")
+ public void managerGetRenditionsForCheckedOutDocument() throws Exception
+ {
+ FileModel checkedDoc = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(checkedDoc, VersioningState.CHECKEDOUT).assertThat().documentIsCheckedOut();
+ Utility.sleep(300, 10000, () -> cmisApi.usingResource(checkedDoc)
+ .assertThat().renditionIsAvailable()
+ .assertThat().thumbnailRenditionIsAvailable());
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.RENDITIONS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify non invited user can get renditions in public site")
+ public void nonInvitedUserGetRenditionsInPublicSite() throws Exception
+ {
+ FileModel testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFile(testFile);
+ Utility.sleep(300, 10000, () -> cmisApi.authenticateUser(nonInvitedUser)
+ .usingResource(testFile)
+ .assertThat().renditionIsAvailable()
+ .assertThat().thumbnailRenditionIsAvailable());
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.RENDITIONS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify non invited user cannot get renditions in private site")
+ public void nonInvitedUserCannotGetRenditionsInPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingUser(testUser).createPrivateRandomSite();
+ FileModel privateDoc = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(testUser).usingSite(privateSite)
+ .createFile(privateDoc).assertThat().existsInRepo()
+ .authenticateUser(nonInvitedUser)
+ .usingResource(privateDoc)
+ .assertThat().renditionIsAvailable()
+ .assertThat().thumbnailRenditionIsAvailable();
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.RENDITIONS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify non invited user cannot get renditions in moderated site")
+ public void nonInvitedUserCannotGetRenditionsInModeratedSite() throws Exception
+ {
+ SiteModel moderatedSite = dataSite.usingUser(testUser).createPrivateRandomSite();
+ FileModel moderatedDoc = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(testUser).usingSite(moderatedSite)
+ .createFile(moderatedDoc).assertThat().existsInRepo()
+ .authenticateUser(nonInvitedUser)
+ .usingResource(moderatedDoc)
+ .assertThat().renditionIsAvailable()
+ .assertThat().thumbnailRenditionIsAvailable();
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS, TestGroup.RENDITIONS}, expectedExceptions=CmisUnauthorizedException.class)
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify inexistent user cannot get renditions")
+ public void inexistentUserCannotGetRenditions() throws Exception
+ {
+ FileModel testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, documentContent);
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFile(testFile);
+ cmisApi.authenticateUser(inexistentUser)
+ .usingResource(testFile)
+ .assertThat().renditionIsAvailable()
+ .assertThat().thumbnailRenditionIsAvailable();
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/RepositoryInfoTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/RepositoryInfoTests.java
new file mode 100644
index 00000000000..5af9bcf9384
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/RepositoryInfoTests.java
@@ -0,0 +1,119 @@
+package org.alfresco.cmis;
+
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.report.Bug;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.data.AclCapabilities;
+import org.apache.chemistry.opencmis.commons.data.RepositoryCapabilities;
+import org.apache.chemistry.opencmis.commons.data.RepositoryInfo;
+import org.apache.chemistry.opencmis.commons.enums.BindingType;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisConnectionException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class RepositoryInfoTests extends CmisTest
+{
+ UserModel testUser;
+ UserModel unauthorizedUser;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ unauthorizedUser = dataUser.createRandomTestUser();
+ }
+
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.SANITY, description = "Verify that valid user can get repositories")
+ public void validUserCanGetRepositories() throws Exception
+ {
+ Assert.assertNotNull(cmisApi.authenticateUser(testUser).getSession());
+ }
+
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS}, expectedExceptions = CmisUnauthorizedException.class)
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.SANITY, description = "Verify that valid user with invalid password cannot get repositories")
+ public void unauthorizedUserCannotGetRepositories() throws Exception
+ {
+ unauthorizedUser.setPassword("invalidPass");
+ cmisApi.authenticateUser(unauthorizedUser);
+ }
+
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.SANITY, description = "Verify that valid user can get the repository informations")
+ public void validUserCanGetRepositoryInfo() throws Exception
+ {
+ RepositoryInfo repoInfo = cmisApi.authenticateUser(testUser).getRepositoryInfo();
+ Assert.assertNotNull(repoInfo.getRootFolderId());
+ Assert.assertNotNull(repoInfo.getProductVersion());
+ Assert.assertNotNull(repoInfo.getRootFolderId());
+ Assert.assertNotNull(repoInfo.getId());
+ Assert.assertEquals(repoInfo.getProductName(), String.format("Alfresco %s", serverHealth.getAlfrescoEdition()));
+ Assert.assertEquals(repoInfo.getVendorName(), "Alfresco");
+ RepositoryCapabilities capabilities = repoInfo.getCapabilities();
+ Assert.assertNotNull(capabilities);
+ Assert.assertEquals(capabilities.getContentStreamUpdatesCapability().value(), "anytime", "Verify repository capability: capabilityContentStreamUpdatability");
+ Assert.assertEquals(capabilities.getRenditionsCapability().value(), "read", "Verify repository capability: capabilityRenditions");
+ Assert.assertTrue(capabilities.isGetDescendantsSupported(), "Verify repository capability: capabilityGetDescendants");
+ Assert.assertTrue(capabilities.isGetFolderTreeSupported(), "Verify repository capability: capabilityGetFolderTree");
+ Assert.assertTrue(capabilities.isMultifilingSupported(), "Verify repository capability: capabilityMultifiling");
+ Assert.assertFalse(capabilities.isUnfilingSupported(), "Verify repository capability: capabilityUnfiling");
+ Assert.assertFalse(capabilities.isVersionSpecificFilingSupported(), "Verify repository capability: capabilityVersionSpecificFiling");
+ Assert.assertFalse(capabilities.isPwcSearchableSupported(), "Verify repository capability: capabilityPWCSearchable");
+ Assert.assertTrue(capabilities.isPwcUpdatableSupported(), "Verify repository capability: capabilityPWCUpdatable");
+ Assert.assertFalse(capabilities.isAllVersionsSearchableSupported(), "Verify repository capability: capabilityAllVersionsSearchable");
+ Assert.assertEquals(capabilities.getQueryCapability().value(), "bothcombined", "Verify repository capability: capabilityQuery");
+ Assert.assertEquals(capabilities.getJoinCapability().value(), "none", "Verify repository capability: capabilityJoin");
+ Assert.assertEquals(capabilities.getAclCapability().value(), "manage", "Verify repository capability: capabilityACL");
+ }
+
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.SANITY, description = "Verify that valid user can get Acl Capabilities")
+ public void validUserCanGetAclCapabilities() throws Exception
+ {
+ AclCapabilities aclCapabilities = cmisApi.authenticateUser(testUser).getAclCapabilities();
+ Assert.assertNotNull(aclCapabilities);
+ Assert.assertFalse(aclCapabilities.getPermissions().isEmpty(), "Verify acl capabilities: getPermissions");
+ Assert.assertEquals(aclCapabilities.getSupportedPermissions().value(), "both", "Verify acl capabilities: getSupportedPermissions");
+ Assert.assertEquals(aclCapabilities.getAclPropagation().value(), "propagate", "Verify acl capabilities: getAclPropagation");
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = CmisUnauthorizedException.class)
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION, description = "Verify that invalid user cannot get repositories")
+ public void invalidUserCannotGetRepositories() throws Exception
+ {
+ UserModel invalidUser = UserModel.getRandomUserModel();
+ cmisApi.authenticateUser(invalidUser).getRepositoryInfo();
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisConnectionException.class})
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION, description = "Verify that invalid user cannot get repositories")
+ public void userCannotGetRepositoriesUsingWrongBrowserUrl() throws Exception
+ {
+ String wrongUrlPath = "//alfresco//api//-default-//public//cmis//versions//1.1";
+ cmisApi.authUserUsingBrowserUrlAndBindingType(testUser, wrongUrlPath, BindingType.BROWSER.value()).getRepositoryInfo();
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {IllegalArgumentException.class, CmisRuntimeException.class}, expectedExceptionsMessageRegExp = "Invalid binding type!")
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION, description = "Verify that invalid user cannot get repositories")
+ public void userCannotGetRepositoriesUsingWrongBindingType() throws Exception
+ {
+ String wrongBindingType = BindingType.BROWSER.value() + "w";
+ cmisApi.authUserUsingBrowserUrlAndBindingType(testUser, cmisApi.cmisProperties.envProperty().getFullServerUrl() + cmisApi.cmisProperties.getBasePath(), wrongBindingType).getRepositoryInfo();
+ }
+
+ @Bug(id="REPO-4301")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = CmisUnauthorizedException.class)
+ @TestRail(section = { "cmis-api" }, executionType = ExecutionType.REGRESSION, description = "Verify that disabled user cannot get repositories")
+ public void disabledUserCannotGetRepositories() throws Exception
+ {
+ UserModel disabledUser = dataUser.createRandomTestUser();
+ Assert.assertNotNull(cmisApi.authenticateUser(disabledUser).getRepositoryInfo());
+ dataUser.usingAdmin().disableUser(disabledUser);
+ cmisApi.authenticateUser(disabledUser).getRepositoryInfo();
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/SecondaryTypesTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/SecondaryTypesTests.java
new file mode 100644
index 00000000000..121bd2dab44
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/SecondaryTypesTests.java
@@ -0,0 +1,287 @@
+package org.alfresco.cmis;
+
+import java.util.Date;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.FolderModel;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.apache.commons.lang.time.DateUtils;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class SecondaryTypesTests extends CmisTest
+{
+ SiteModel testSite;
+ UserModel testUser, nonInvitedUser;
+ private DataUser.ListUserWithRoles usersWithRoles;
+ FileModel managerFile;
+ FolderModel managerFolder;
+ String titledAspect = "P:cm:titled";
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ managerFile = FileModel.getRandomFileModel(FileType.MSWORD2007, documentContent);
+ managerFolder = FolderModel.getRandomFolderModel();
+ testUser = dataUser.createRandomTestUser();
+ nonInvitedUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createPublicRandomSite();
+ usersWithRoles = dataUser.usingUser(testUser)
+ .addUsersWithRolesToSite(testSite, UserRole.SiteContributor, UserRole.SiteCollaborator, UserRole.SiteConsumer);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(managerFile)
+ .createFolder(managerFolder);
+ }
+
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify site manager is able to get secondary types for Document")
+ public void userCanGetSecondaryTypesForDocument() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingResource(managerFile)
+ .assertThat().secondaryTypeIsAvailable(titledAspect);
+ }
+
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify site manager is able to get secondary types for Folder")
+ public void userCanGetSecondaryTypesForFolder() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingResource(managerFolder)
+ .assertThat().secondaryTypeIsAvailable(titledAspect);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = {CmisObjectNotFoundException.class})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is NOT able to get secondary types for Folder")
+ public void userCannotGetSecondaryTypesForInvalidObject() throws Exception
+ {
+ FolderModel folder = FolderModel.getRandomFolderModel();
+ folder.setCmisLocation("/" + folder.getName() + "/");
+ cmisApi.authenticateUser(testUser)
+ .usingResource(folder)
+ .assertThat().secondaryTypeIsAvailable(titledAspect);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is NOT able to get invalid secondary type for Folder")
+ public void invalidSecondaryTypeIsNotAvailableForFolder() throws Exception
+ {
+ FolderModel folder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(folder).and().assertThat().existsInRepo()
+ .and().assertThat().secondaryTypeIsNotAvailable(titledAspect + "-fake");
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to get secondary types")
+ public void collaboratorCanGetSecondaryTypesForContent() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingResource(managerFolder)
+ .assertThat().secondaryTypeIsAvailable(titledAspect)
+ .then().usingResource(managerFile)
+ .assertThat().secondaryTypeIsAvailable(titledAspect);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site contributor is able to get secondary types")
+ public void contributorCanGetSecondaryTypesForContent() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingResource(managerFolder)
+ .assertThat().secondaryTypeIsAvailable(titledAspect)
+ .then().usingResource(managerFile)
+ .assertThat().secondaryTypeIsAvailable(titledAspect);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site consumer is able to get secondary types")
+ public void consumerCanGetSecondaryTypesForContent() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .usingResource(managerFolder)
+ .assertThat().secondaryTypeIsAvailable(titledAspect)
+ .then().usingResource(managerFile)
+ .assertThat().secondaryTypeIsAvailable(titledAspect);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify non invited user is able to get secondary types in public site")
+ public void nonInvitedUserCanGetSecondaryTypesForContentInPublicSite() throws Exception
+ {
+ cmisApi.authenticateUser(nonInvitedUser)
+ .usingResource(managerFolder)
+ .assertThat().secondaryTypeIsAvailable(titledAspect)
+ .then().usingResource(managerFile)
+ .assertThat().secondaryTypeIsAvailable(titledAspect);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify non invited user is not able to get secondary types in private site")
+ public void nonInvitedUserCannotGetSecondaryTypesForContentInPrivateSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingUser(testUser).createPrivateRandomSite();
+ FileModel privateDoc = FileModel.getRandomFileModel(FileType.MSPOWERPOINT2007);
+ cmisApi.authenticateUser(testUser).usingSite(privateSite)
+ .createFile(privateDoc)
+ .authenticateUser(nonInvitedUser)
+ .assertThat().secondaryTypeIsAvailable(titledAspect);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify non invited user is not able to get secondary types in moderated site")
+ public void nonInvitedUserCannotGetSecondaryTypesInModeratedSite() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingUser(testUser).createModeratedRandomSite();
+ FileModel privateDoc = FileModel.getRandomFileModel(FileType.MSPOWERPOINT2007);
+ cmisApi.authenticateUser(testUser).usingSite(privateSite)
+ .createFile(privateDoc)
+ .authenticateUser(nonInvitedUser)
+ .assertThat().secondaryTypeIsAvailable(titledAspect);
+ }
+
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify site manager is able to add secondary types for Document")
+ public void managerCanAddSecondaryTypesForDocument() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingResource(managerFile)
+ .addSecondaryTypes("P:cm:dublincore")
+ .assertThat().secondaryTypeIsAvailable("P:cm:dublincore")
+ .assertThat().secondaryTypeIsAvailable(titledAspect)
+ .then().updateProperty("cm:subject", "TAS Subject")
+ .updateProperty("cm:rights", "TAS Rights")
+ .updateProperty("cm:publisher", "TAS Team")
+ .then().assertThat().objectHasProperty("cm:subject", "TAS Subject")
+ .assertThat().objectHasProperty("cm:rights", "TAS Rights")
+ .assertThat().objectHasProperty("cm:publisher", "TAS Team");
+ }
+
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.SANITY,
+ description = "Verify site manager is able to add secondary types for folder")
+ public void managerCanAddSecondaryTypesForFolder() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingResource(managerFolder)
+ .addSecondaryTypes("P:cm:geographic")
+ .assertThat().secondaryTypeIsAvailable("P:cm:geographic")
+ .assertThat().secondaryTypeIsAvailable(titledAspect)
+ .then().updateProperty("cm:longitude", 455.21)
+ .updateProperty("cm:latitude", 101.32)
+ .then().assertThat().objectHasProperty("cm:longitude", 455.21)
+ .assertThat().objectHasProperty("cm:latitude", 101.32);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisObjectNotFoundException.class,
+ expectedExceptionsMessageRegExp="Type 'P:cm:fakeAspect' is unknown!*")
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to add fake secondary type")
+ public void managerCannotAddInexistentSecondaryType() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingResource(managerFolder)
+ .addSecondaryTypes("P:cm:fakeAspect");
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to add twice same secondary type")
+ public void managerCanAddTwiceSameSecondaryType() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingResource(managerFile)
+ .addSecondaryTypes("P:cm:dublincore")
+ .assertThat().secondaryTypeIsAvailable("P:cm:dublincore")
+ .then().addSecondaryTypes("P:cm:dublincore")
+ .assertThat().secondaryTypeIsAvailable("P:cm:dublincore");
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to add secondary types for document created by manager")
+ public void collaboratorCanAddAspectForDocument() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingResource(managerFile)
+ .addSecondaryTypes("P:audio:audio")
+ .assertThat().secondaryTypeIsAvailable("P:audio:audio")
+ .assertThat().secondaryTypeIsAvailable(titledAspect)
+ .then().updateProperty("audio:channelType", "TAS")
+ .updateProperty("audio:trackNumber", 9)
+ .updateProperty("audio:sampleType", "TAS Sample")
+ .then().assertThat().objectHasProperty("audio:channelType", "TAS")
+ .assertThat().objectHasProperty("audio:trackNumber", 9)
+ .assertThat().objectHasProperty("audio:sampleType", "TAS Sample");
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site contributor is able to add secondary types for document created by manager")
+ public void contributorCanAddAspectForDocument() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingResource(managerFile)
+ .addSecondaryTypes("P:dp:restrictable")
+ .assertThat().secondaryTypeIsAvailable("P:dp:restrictable")
+ .assertThat().secondaryTypeIsAvailable(titledAspect)
+ .then().updateProperty("dp:offlineExpiresAfter", 2)
+ .and().assertThat().objectHasProperty("dp:offlineExpiresAfter", 2);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site contributor is able to add secondary types for document created by manager")
+ public void consumerCanAddAspectForDocument() throws Exception
+ {
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer)).usingResource(managerFile)
+ .addSecondaryTypes("P:dp:restrictable")
+ .assertThat().secondaryTypeIsAvailable("P:dp:restrictable")
+ .assertThat().secondaryTypeIsAvailable(titledAspect)
+ .then().updateProperty("dp:offlineExpiresAfter", 2)
+ .and().assertThat().objectHasProperty("dp:offlineExpiresAfter", 2);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is able to add twice same secondary type")
+ public void managerCanAddDateProperty() throws Exception
+ {
+ Date today = new Date();
+ Date tomorow = new Date();
+ tomorow = DateUtils.addDays(tomorow, 1);
+ cmisApi.authenticateUser(testUser).usingResource(managerFile)
+ .addSecondaryTypes("P:cm:effectivity")
+ .assertThat().secondaryTypeIsAvailable("P:cm:effectivity")
+ .then().updateProperty("cm:to", today)
+ .updateProperty("cm:from", tomorow)
+ .and().assertThat().objectHasProperty("cm:to", today)
+ .assertThat().objectHasProperty("cm:from", tomorow);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=IllegalArgumentException.class,
+ expectedExceptionsMessageRegExp="Property 'cm:fake-prop' is not valid for this type or one of the secondary types!*")
+ @TestRail(section = {"cmis-api"}, executionType= ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to update aspect with fake property")
+ public void managerCannotUpdateFakePropertyFromAspect() throws Exception
+ {
+ cmisApi.authenticateUser(testUser).usingResource(managerFile)
+ .addSecondaryTypes("P:cm:dublincore")
+ .assertThat().secondaryTypeIsAvailable("P:cm:dublincore")
+ .assertThat().secondaryTypeIsAvailable(titledAspect)
+ .then().updateProperty("cm:fake-prop", "fake-prop");
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/SetContentTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/SetContentTests.java
new file mode 100644
index 00000000000..7ceada39ae4
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/SetContentTests.java
@@ -0,0 +1,246 @@
+package org.alfresco.cmis;
+
+import org.alfresco.cmis.exception.InvalidCmisObjectException;
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.model.*;
+import org.alfresco.utility.report.Bug;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisContentAlreadyExistsException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUpdateConflictException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * Created by Claudia Agache on 9/28/2016.
+ */
+public class SetContentTests extends CmisTest
+{
+ UserModel siteManager;
+ SiteModel publicSite;
+ FileModel testFile;
+ FolderModel testFolder;
+ private String someContent = "some content";
+ private String secondContent = "second content";
+ private DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ siteManager = dataUser.createRandomTestUser();
+ publicSite = dataSite.usingUser(siteManager).createPublicRandomSite();
+ usersWithRoles = dataUser.addUsersWithRolesToSite(publicSite, UserRole.SiteManager, UserRole.SiteContributor, UserRole.SiteCollaborator, UserRole.SiteConsumer);
+ }
+
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.SANITY,
+ description = "Verify site manager is able to set content to a valid document in DocumentLibrary with CMIS")
+ public void siteManagerSetFileContentForFileCreatedBySelf() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "first content");
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().update("content")
+ .then().setContent(someContent).and().refreshResource()
+ .then().assertThat().contentIs(someContent)
+ .and().assertThat().contentLengthIs(12);
+ }
+
+ @Test(expectedExceptions = InvalidCmisObjectException.class, groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify if exception is thrown when user tries to set content to an invalid document in DocumentLibrary with CMIS")
+ public void siteManagerSetFolderContent() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(siteManager)
+ .usingSite(publicSite)
+ .createFolder(testFolder).setContent(someContent);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisUnauthorizedException.class)
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that inexistent user is not able to set content to a document with CMIS")
+ public void inexistentUserCannotSetFileContent() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .and().assertThat().contentLengthIs(0)
+ .then().authenticateUser(UserModel.getRandomUserModel())
+ .setContent(someContent);
+ }
+
+ @Bug(id="ACE-5614")
+ @Test(groups = { TestGroup.REGRESSION , TestGroup.CMIS})
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is able to set content to a document with no content with overwrite parameter set to false with CMIS")
+ public void siteManagerCanSetContentWithFalseOverwriteToDocWithNoContent() throws Exception
+ {
+ FileModel newFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(newFile).assertThat().existsInRepo()
+ .and().assertThat().contentLengthIs(0)
+ .then().setContent(someContent, false).and()
+ .and().assertThat().contentIs(someContent);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisContentAlreadyExistsException.class)
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to set content to a document with content with overwrite parameter set to false with CMIS")
+ public void siteManagerCanSetContentWithFalseOverwriteToDocWithContent() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, someContent);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .and().assertThat().contentIs(someContent)
+ .then().setContent(secondContent, false);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify unauthorized user is not able to set content to a document")
+ public void unauthorizedUserCannotSetContent() throws Exception
+ {
+ UserModel unauthorizedUser = dataUser.createRandomTestUser();
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, someContent);
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(unauthorizedUser)
+ .setContent(secondContent);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify admin is able to set file content with CMIS")
+ public void adminCanSetFileContent() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "first content");
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(dataUser.getAdminUser())
+ .and().setContent(someContent).and().refreshResource()
+ .then().assertThat().contentIs(someContent)
+ .and().assertThat().contentLengthIs(12);
+ }
+
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.SANITY,
+ description = "Verify site manager is able to set file content for a file created by other user with CMIS")
+ public void managerCanSetFileContentForFileCreatedByOtherUser() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "first content");
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager))
+ .and().setContent(someContent).and().refreshResource()
+ .then().assertThat().contentIs(someContent)
+ .and().assertThat().contentLengthIs(12);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site contributor is not able to set content to a document created by other user with CMIS")
+ public void contributorCannotSetFileContentForFileCreatedByOtherUser() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "first content");
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .then().setContent(someContent);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site contributor is able to set content to a document created by self with CMIS")
+ public void contributorCanSetFileContentForFileCreatedBySelf() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "first content");
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().setContent(someContent).and().refreshResource()
+ .then().assertThat().contentIs(someContent)
+ .and().assertThat().contentLengthIs(12);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to set content to a document created by other user with CMIS")
+ public void collaboratorCanSetFileContentForFileCreatedByOtherUser() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "first content");
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .then().usingResource(testFile)
+ .setContent(someContent).and().refreshResource()
+ .and().assertThat().contentIs(someContent)
+ .assertThat().contentLengthIs(12);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to set content to a document created by self with CMIS")
+ public void collaboratorCanSetFileContentForFileCreatedBySelf() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "first content");
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().setContent(someContent).and().refreshResource()
+ .then().assertThat().contentIs(someContent)
+ .and().assertThat().contentLengthIs(12);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site consumer is not able to set file content with CMIS")
+ public void consumerCannotSetFileContent() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "first content");
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .then().setContent(someContent);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions = CmisUpdateConflictException.class, expectedExceptionsMessageRegExp = "^.*Cannot perform operation since the node.*is locked.$")
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is able to set content to a checked out document with CMIS")
+ public void siteManagerCannotSetContentToCheckedOutFile() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "first content");
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().checkOut().and().assertThat().documentIsCheckedOut()
+ .setContent(someContent);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is able to set content to PWC document version with CMIS")
+ public void siteManagerSetContentToPWCFile() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "first content");
+ cmisApi.authenticateUser(siteManager).usingSite(publicSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().checkOut().and().assertThat().documentIsCheckedOut()
+ .usingPWCDocument().setContent(someContent).and().refreshResource()
+ .then().assertThat().contentIs(someContent)
+ .and().assertThat().contentLengthIs(12);
+ }
+
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ @TestRail(section = {"cmis-api" }, executionType = ExecutionType.REGRESSION,
+ description = "Verify unauthorized user is not able to set content to a document from a private site")
+ public void unauthorizedUserCannotSetContentToPrivateSiteDoc() throws Exception
+ {
+ SiteModel privateSite = dataSite.usingUser(siteManager).createPrivateRandomSite();
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, someContent);
+ cmisApi.authenticateUser(siteManager).usingSite(privateSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingResource(testFile).setContent(secondContent);
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/UpdatePropertiesTests.java b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/UpdatePropertiesTests.java
new file mode 100644
index 00000000000..da87ca47f61
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/java/org/alfresco/cmis/UpdatePropertiesTests.java
@@ -0,0 +1,357 @@
+package org.alfresco.cmis;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.data.RandomData;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.FolderModel;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.report.Bug;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.PropertyIds;
+import org.apache.chemistry.opencmis.commons.enums.VersioningState;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * Created by Claudia Agache on 9/30/2016.
+ */
+public class UpdatePropertiesTests extends CmisTest
+{
+ UserModel testUser;
+ SiteModel testSite;
+ FileModel testFile;
+ FolderModel testFolder;
+ String propertyNameValue;
+ private DataUser.ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createPublicRandomSite();
+ dataContent.deployContentModel("shared-resources/model/tas-model.xml");
+ usersWithRoles = dataUser.usingUser(testUser)
+ .addUsersWithRolesToSite(testSite, UserRole.SiteContributor, UserRole.SiteCollaborator, UserRole.SiteConsumer);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.SANITY,
+ description = "Verify site manager is able to update properties to a valid document in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerUpdatesFileProperties() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ propertyNameValue = RandomData.getRandomAlphanumeric();
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().updateProperty("cmis:name", propertyNameValue)
+ .and().assertThat().contentPropertyHasValue("cmis:name", propertyNameValue)
+ .then().updateProperty("cmis:description", "some description")
+ .and().assertThat().contentPropertyHasValue("cmis:description", "some description");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.SANITY,
+ description = "Verify site manager is able to update properties to a valid folder in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.SANITY, TestGroup.CMIS})
+ public void siteManagerUpdatesFolderProperties() throws Exception
+ {
+ propertyNameValue = RandomData.getRandomAlphanumeric();
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder).assertThat().existsInRepo()
+ .then().updateProperty("cmis:name", propertyNameValue)
+ .and().assertThat().contentPropertyHasValue("cmis:name", propertyNameValue)
+ .then().updateProperty("cmis:description", "some description")
+ .and().assertThat().contentPropertyHasValue("cmis:description", "some description");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify if exception is thrown when user tries to update properties to a non existent document in DocumentLibrary with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisObjectNotFoundException.class)
+ public void siteManagerUpdatesNoneExistentFileProperties() throws Exception
+ {
+ propertyNameValue = RandomData.getRandomAlphanumeric();
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFile(testFile).assertThat().existsInRepo()
+ .then().delete().and().assertThat().doesNotExistInRepo()
+ .then().updateProperty("cmis:name", propertyNameValue);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to update properties with invalid property with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=IllegalArgumentException.class)
+ public void siteManagerCannotUpdateFileWithInvalidProperty() throws Exception
+ {
+ propertyNameValue = RandomData.getRandomAlphanumeric();
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().updateProperty("cmis:fakeProp", propertyNameValue);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify that deleted user is not able to update properties with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisUnauthorizedException.class)
+ public void deletedUserCannotUpdateFileProperties() throws Exception
+ {
+ propertyNameValue = RandomData.getRandomAlphanumeric();
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ UserModel toBeDeleted = dataUser.createRandomTestUser();
+ FolderModel shared = FolderModel.getSharedFolderModel();
+ cmisApi.authenticateUser(toBeDeleted)
+ .usingResource(shared)
+ .createFile(testFile).and().assertThat().existsInRepo();
+ dataUser.deleteUser(toBeDeleted);
+ cmisApi.updateProperty("cmis:name", propertyNameValue);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to update name property while document is checked out with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCannotUpdatePWCDocumentName() throws Exception
+ {
+ propertyNameValue = RandomData.getRandomAlphanumeric();
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().checkOut()
+ .and().assertThat().documentIsCheckedOut()
+ .usingPWCDocument().updateProperty("cmis:name", testFile.getName() + "-edit")
+ .cancelCheckOut()
+ .then().usingResource(testFile)
+ .assertThat().contentPropertyHasValue("cmis:name", testFile.getName());
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is able to update the title and description while document is checked out with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanUpdateCheckOutDocTitleAndDescription() throws Exception
+ {
+ propertyNameValue = RandomData.getRandomAlphanumeric();
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().checkOut().and().assertThat().documentIsCheckedOut()
+ .then().usingPWCDocument()
+ .updateProperty("cmis:description", propertyNameValue)
+ .updateProperty("cm:title", propertyNameValue)
+ .and().assertThat().contentPropertyHasValue("cmis:description", propertyNameValue)
+ .assertThat().contentPropertyHasValue("cm:title", propertyNameValue);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is able to update the title and description for document with version is checked out with CMIS")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanUpdateDocumentWithVersion() throws Exception
+ {
+ propertyNameValue = RandomData.getRandomAlphanumeric();
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite).createFile(testFile).assertThat().existsInRepo()
+ .then().update("first content").update("second content")
+ .updateProperty("cmis:description", propertyNameValue)
+ .updateProperty("cm:title", propertyNameValue)
+ .and().assertThat().contentPropertyHasValue("cmis:description", propertyNameValue)
+ .assertThat().contentPropertyHasValue("cm:title", propertyNameValue);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to update document name with invalid symbols")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisConstraintException.class)
+ public void siteManagerCannotUpdateDocNameInvalidSymbols() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ propertyNameValue = "/.:?|\\`\\";
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().updateProperty("cmis:name", propertyNameValue);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to update folder name with invalid symbols")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisConstraintException.class)
+ public void siteManagerCannotUpdateFolderNameInvalidSymbols() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ propertyNameValue = "/.:?|\\`\\";
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(testFolder).assertThat().existsInRepo()
+ .then().updateProperty("cmis:name", propertyNameValue);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to update document name with empty value")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisRuntimeException.class,
+ expectedExceptionsMessageRegExp="Local name cannot be null or empty.")
+ public void siteManagerCannotUpdateDocNameEmptyValue() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().updateProperty("cmis:name", "");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is not able to update folder name with empty value")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisRuntimeException.class,
+ expectedExceptionsMessageRegExp="Local name cannot be null or empty.")
+ public void siteManagerCannotUpdateFolderNameEmptyValue() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFolder(testFolder).assertThat().existsInRepo()
+ .then().updateProperty("cmis:name", "");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is able to update Integer and Long types with max values")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanUpdateIntAndLongTypesWithMaxValue() throws Exception
+ {
+ FileModel customFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "custom content");
+ Map properties = new HashMap();
+ properties.put(PropertyIds.OBJECT_TYPE_ID, "D:tas:document");
+ properties.put(PropertyIds.NAME, customFile.getName());
+
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(customFile, properties, VersioningState.MAJOR).assertThat().existsInRepo()
+ .then().updateProperty("tas:IntPropertyC", Integer.MAX_VALUE)
+ .and().assertThat().contentPropertyHasValue("tas:IntPropertyC", String.valueOf(Integer.MAX_VALUE))
+ .then().updateProperty("tas:LongPropertyC", Long.MAX_VALUE)
+ .and().assertThat().contentPropertyHasValue("tas:LongPropertyC", String.valueOf(Long.MAX_VALUE));
+ cmisApi.usingResource(customFile).delete().assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager is able to update Integer and Long types with min values")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void siteManagerCanUpdateIntAndLongTypesWithMinValue() throws Exception
+ {
+ FileModel customFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "custom content");
+ Map properties = new HashMap();
+ properties.put(PropertyIds.OBJECT_TYPE_ID, "D:tas:document");
+ properties.put(PropertyIds.NAME, customFile.getName());
+
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(customFile, properties, VersioningState.MAJOR).assertThat().existsInRepo()
+ .then().updateProperty("tas:IntPropertyC", Integer.MIN_VALUE)
+ .and().assertThat().contentPropertyHasValue("tas:IntPropertyC", String.valueOf(Integer.MIN_VALUE))
+ .then().updateProperty("tas:LongPropertyC", Long.MIN_VALUE)
+ .and().assertThat().contentPropertyHasValue("tas:LongPropertyC", String.valueOf(Long.MIN_VALUE));
+ cmisApi.usingResource(customFile).delete().assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to update properties to a valid document created by himself")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorCanUpdateHisOwnFileProperties() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ propertyNameValue = RandomData.getRandomAlphanumeric();
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().updateProperty("cmis:name", propertyNameValue)
+ .and().assertThat().contentPropertyHasValue("cmis:name", propertyNameValue)
+ .then().updateProperty("cmis:description", "some description")
+ .and().assertThat().contentPropertyHasValue("cmis:description", "some description");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to update properties to a valid document created by site manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void collaboratorCanUpdateFilePropertiesCreatedByManager() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ propertyNameValue = RandomData.getRandomAlphanumeric();
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .and().updateProperty("cmis:name", propertyNameValue)
+ .and().assertThat().contentPropertyHasValue("cmis:name", propertyNameValue)
+ .then().updateProperty("cmis:description", "some description")
+ .and().assertThat().contentPropertyHasValue("cmis:description", "some description");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site contributor is able to update properties to a valid document created by himself")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorCanUpdateHisOwnFileProperties() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ propertyNameValue = RandomData.getRandomAlphanumeric();
+ cmisApi.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().updateProperty("cmis:name", propertyNameValue)
+ .and().assertThat().contentPropertyHasValue("cmis:name", propertyNameValue)
+ .then().updateProperty("cmis:description", "some description")
+ .and().assertThat().contentPropertyHasValue("cmis:description", "some description");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site collaborator is able to update properties to a valid document created by site manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS})
+ public void contributorCanUpdateFilePropertiesCreatedByManager() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ propertyNameValue = RandomData.getRandomAlphanumeric();
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .and().updateProperty("cmis:name", propertyNameValue)
+ .and().assertThat().contentPropertyHasValue("cmis:name", propertyNameValue)
+ .then().updateProperty("cmis:description", "some description")
+ .and().assertThat().contentPropertyHasValue("cmis:description", "some description");
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify site consumer is not able to update properties to a valid document created by site manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void consumerCannotUpdateFilePropertiesCreatedByManager() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ propertyNameValue = RandomData.getRandomAlphanumeric();
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .and().updateProperty("cmis:name", propertyNameValue);
+ }
+
+ @Bug(id="REPO-4301")
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify disabled user is not able to update properties")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions=CmisUnauthorizedException.class)
+ public void disabledUserCannotUpdateFileProperties() throws Exception
+ {
+ UserModel disabledUser = dataUser.createRandomTestUser();
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ propertyNameValue = RandomData.getRandomAlphanumeric();
+ cmisApi.authenticateUser(disabledUser).usingShared()
+ .createFile(testFile).assertThat().existsInRepo();
+ dataUser.usingAdmin().disableUser(disabledUser);
+ cmisApi.usingResource(testFile).updateProperty("cmis:name", propertyNameValue);
+ }
+
+ @TestRail(section = {"cmis-api"}, executionType = ExecutionType.REGRESSION,
+ description = "Verify non invited user is not able to update properties to a document created by site manager")
+ @Test(groups = { TestGroup.REGRESSION, TestGroup.CMIS}, expectedExceptions={CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ public void nonInvitedUserCannotUpdateFilePropertiesCreatedByManager() throws Exception
+ {
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ UserModel nonInvitedUser = dataUser.createRandomTestUser();
+ propertyNameValue = RandomData.getRandomAlphanumeric();
+ cmisApi.authenticateUser(testUser).usingSite(testSite)
+ .createFile(testFile).assertThat().existsInRepo()
+ .then().authenticateUser(nonInvitedUser)
+ .and().updateProperty("cmis:name", propertyNameValue);
+ }
+}
diff --git a/packaging/tests/tas-cmis/src/test/resources/alfresco-cmis-context.xml b/packaging/tests/tas-cmis/src/test/resources/alfresco-cmis-context.xml
new file mode 100644
index 00000000000..ecf3d2db4b2
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/resources/alfresco-cmis-context.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packaging/tests/tas-cmis/src/test/resources/cmis-suite.xml b/packaging/tests/tas-cmis/src/test/resources/cmis-suite.xml
new file mode 100644
index 00000000000..46728ee4e4c
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/resources/cmis-suite.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packaging/tests/tas-cmis/src/test/resources/default.properties b/packaging/tests/tas-cmis/src/test/resources/default.properties
new file mode 100644
index 00000000000..9ca9119ba55
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/resources/default.properties
@@ -0,0 +1,76 @@
+# dataprep related
+alfresco.scheme=http
+alfresco.server=localhost
+alfresco.port=8082
+
+# credentials
+admin.user=admin
+admin.password=admin
+
+solrWaitTimeInSeconds=30
+
+# in containers we cannot access directly JMX, so we will use http://jolokia.org agent
+# disabling this we will use direct JMX calls to server
+jmx.useJolokiaAgent=false
+
+# Server Health section
+# in ServerHealth#isServerReachable() - could also be shown.
+# enable this option to view if on server there are tenants or not
+serverHealth.showTenants=true
+
+# set CMIS binding to 'browser' or 'atom'
+cmis.binding=browser
+cmis.basePath=/alfresco/api/-default-/public/cmis/versions/1.1/${cmis.binding}
+
+# TEST MANAGEMENT SECTION - Test Rail
+#
+# (currently supporting Test Rail v5.2.1.3472 integration)
+#
+# Example of configuration:
+# ------------------------------------------------------
+# if testManagement.enabled=true we enabled TestRailExecutorListener (if used in your suite xml file)
+# testManagement.updateTestExecutionResultsOnly=true (this will just update the results of a test: no step will be updated - good for performance)
+# testManagement.endPoint=https://alfresco.testrail.com/
+# testManagement.username=
+# testManagement.apiKey=
+# testManagement.project=
+# testManagement.includeOnlyTestCasesExecuted=true #if you want to include in your run ONLY the test cases that you run, then set this value to false
+# testManagement.rateLimitInSeconds=1 #is the default rate limit after what minimum time, should we upload the next request. http://docs.gurock.com/testrail-api2/introduction #Rate Limit
+# testManagement.suiteId=23 (the id of the Master suite)
+# ------------------------------------------------------
+testManagement.enabled=false
+testManagement.endPoint=
+testManagement.username=
+testManagement.apiKey=
+testManagement.project=7
+testManagement.includeOnlyTestCasesExecuted=true
+testManagement.rateLimitInSeconds=1
+testManagement.testRun=MyTestRunInTestRail
+testManagement.suiteId=12
+
+# The location of the reports path
+reports.path=./target/reports
+
+#
+# Database Section
+# You should provide here the database URL, that can be a differed server as alfresco.
+# https://docs.oracle.com/javase/tutorial/jdbc/basics/connecting.html
+#
+# Current supported db.url:
+#
+# MySQL:
+# db.url = jdbc:mysql://${alfresco.server}:3306/alfresco
+#
+# PostgreSQL:
+# db.url = jdbc:postgresql://:3306/alfresco
+#
+# Oracle:
+# db.url = jdbc:oracle://:3306/alfresco
+#
+# MariaDB:
+# db.url = jdbc:mariadb://:3306/alfresco
+#
+db.url = jdbc:mysql://${alfresco.server}:3306/alfresco
+db.username = alfresco
+db.password = alfresco
diff --git a/packaging/tests/tas-cmis/src/test/resources/log4j.properties b/packaging/tests/tas-cmis/src/test/resources/log4j.properties
new file mode 100644
index 00000000000..00e9b5a114e
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/resources/log4j.properties
@@ -0,0 +1,26 @@
+# Root logger option
+log4j.rootLogger=INFO, file, stdout
+
+# Direct log messages to a log file
+log4j.appender.file=org.apache.log4j.RollingFileAppender
+log4j.appender.file.File=./target/reports/alfresco-tas.log
+log4j.appender.file.MaxBackupIndex=10
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+log4j.appender.file.layout.ConversionPattern=[%t] %d{HH:mm:ss} %-5p %c{1}:%L - %m%n
+
+# Direct log messages to stdout
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=[%t] %d{HH:mm:ss} %-5p %c{1}:%L - %m%n
+
+# TestRail particular log file
+# Direct log messages to a log file
+log4j.appender.testrailLog=org.apache.log4j.RollingFileAppender
+log4j.appender.testrailLog.File=./target/reports/alfresco-testrail.log
+log4j.appender.testrailLog.MaxBackupIndex=10
+log4j.appender.testrailLog.layout=org.apache.log4j.PatternLayout
+log4j.appender.testrailLog.layout.ConversionPattern=%d{HH:mm:ss} %-5p %c{1}:%L - %m%n
+
+log4j.category.testrail=INFO, testrailLog
+log4j.additivity.testrail=false
\ No newline at end of file
diff --git a/packaging/tests/tas-cmis/src/test/resources/shared-resources/model/tas-model.xml b/packaging/tests/tas-cmis/src/test/resources/shared-resources/model/tas-model.xml
new file mode 100644
index 00000000000..892027f9c19
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/resources/shared-resources/model/tas-model.xml
@@ -0,0 +1,151 @@
+
+
+
+
+ Alfresco TAS custom model
+ Bogdan
+ 1.0
+
+
+
+
+
+
+
+
+
+
+
+
+ CMIS TAS Content
+ cm:content
+
+
+ Text
+ d:text
+
+
+ Datetime
+ d:datetime
+
+
+ Integer
+ d:int
+
+
+ Long
+ d:long
+
+
+ Multiply String
+ d:text
+ true
+ true
+
+
+
+
+
+
+ false
+ false
+
+
+ cm:content
+ false
+ false
+
+
+
+
+
+
+ CMIS TAS Folder
+ cm:folder
+
+
+ Text
+ d:text
+
+
+ Datetime
+ d:datetime
+
+
+ Integer
+ d:int
+
+
+ Multiply String
+ d:text
+ true
+ true
+
+
+
+
+
+
+ false
+ false
+
+
+ cm:folder
+ false
+ false
+
+
+
+
+
+
+
+
+ TAS Content Aspect
+
+
+ Aspect Text
+ d:text
+
+
+ Aspect Datetime
+ d:datetime
+
+
+ Aspect Integer
+ d:int
+
+
+ Aspect Multiply String
+ d:text
+ true
+ true
+
+
+
+
+
+ TAS Folder Aspect
+
+
+ Aspect Text
+ d:text
+
+
+ Aspect Datetime
+ d:datetime
+
+
+ Aspect Integer
+ d:int
+
+
+ Aspect Multiply String
+ d:text
+ true
+ true
+
+
+
+
+
\ No newline at end of file
diff --git a/packaging/tests/tas-cmis/src/test/resources/shared-resources/testdata/cmis-checkIn.txt b/packaging/tests/tas-cmis/src/test/resources/shared-resources/testdata/cmis-checkIn.txt
new file mode 100644
index 00000000000..863a223b69e
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/resources/shared-resources/testdata/cmis-checkIn.txt
@@ -0,0 +1 @@
+Sp23xfcYhUBYpsXuPFzn8nVQ
\ No newline at end of file
diff --git a/packaging/tests/tas-cmis/src/test/resources/shared-resources/testdata/cmis-resource b/packaging/tests/tas-cmis/src/test/resources/shared-resources/testdata/cmis-resource
new file mode 100644
index 00000000000..e01d8091533
--- /dev/null
+++ b/packaging/tests/tas-cmis/src/test/resources/shared-resources/testdata/cmis-resource
@@ -0,0 +1 @@
+tas
\ No newline at end of file
diff --git a/packaging/tests/tas-email/pom.xml b/packaging/tests/tas-email/pom.xml
new file mode 100644
index 00000000000..e6ea84e0fbf
--- /dev/null
+++ b/packaging/tests/tas-email/pom.xml
@@ -0,0 +1,66 @@
+
+
+ 4.0.0
+ org.alfresco.tas
+ content-repository-community-email-test
+ content-repository-community-email-test
+ 6.2.2-SNAPSHOT
+ jar
+
+
+ org.alfresco
+ content-repository-community-tas-tests-parent
+ 6.2.2-SNAPSHOT
+ ../pom.xml
+
+
+
+
+ Paul Brodner
+
+ Test Automation Architect
+
+
+
+
+
+ ${project.basedir}/src/test/resources/email-suite.xml
+
+
+
+
+ org.alfresco.tas
+ email
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ ${suiteXmlFile}
+
+
+ --illegal-access=warn
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+
+ test-jar
+
+
+
+
+
+
+
diff --git a/packaging/tests/tas-email/src/test/java/org/alfresco/email/EmailTest.java b/packaging/tests/tas-email/src/test/java/org/alfresco/email/EmailTest.java
new file mode 100644
index 00000000000..2a1a1b4a582
--- /dev/null
+++ b/packaging/tests/tas-email/src/test/java/org/alfresco/email/EmailTest.java
@@ -0,0 +1,100 @@
+package org.alfresco.email;
+
+import java.lang.reflect.Method;
+
+import org.alfresco.email.dsl.ServerConfiguration;
+import org.alfresco.utility.LogFactory;
+import org.alfresco.utility.data.*;
+import org.alfresco.utility.model.*;
+import org.alfresco.utility.network.ServerHealth;
+import org.alfresco.utility.network.TenantConsole;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
+import org.testng.annotations.*;
+
+@ContextConfiguration("classpath:alfresco-email-context.xml")
+public abstract class EmailTest extends AbstractTestNGSpringContextTests
+{
+ private static Logger LOG = LogFactory.getLogger();
+
+ @Autowired
+ ServerHealth serverHealth;
+
+ @Autowired
+ protected ImapWrapper imapProtocol;
+
+ @Autowired
+ protected SmtpWrapper smtpProtocol;
+
+ @Autowired
+ public DataUser dataUser;
+
+ @Autowired
+ public DataGroup dataGroup;
+
+ @Autowired
+ public DataSite dataSite;
+
+ @Autowired
+ public DataContent dataContent;
+
+ @Autowired
+ public DataLink dataLink;
+
+ @Autowired
+ public DataCalendarEvent dataCalendarEvent;
+
+ @Autowired
+ public DataWiki dataWiki;
+
+ @Autowired
+ public TenantConsole tenantConsole;
+
+ protected UserModel adminUser;
+ protected UserModel testUser;
+ protected SiteModel adminSite;
+ protected SiteModel testSite;
+ protected FolderModel testFolder;
+ protected FileModel testFile;
+ protected ContentModel contentModel;
+
+ @BeforeSuite(alwaysRun = true)
+ public void checkServerHealth() throws Exception
+ {
+ super.springTestContextPrepareTestInstance();
+ serverHealth.assertServerIsOnline();
+
+ UserModel anonymousUser = new UserModel("anonymous", DataUser.PASSWORD);
+ if (!dataUser.isUserInRepo(anonymousUser.getUsername()))
+ {
+ dataUser.createUser(anonymousUser);
+ dataGroup.usingUser(anonymousUser).addUserToGroup(GroupModel.getEmailContributorsGroup());
+ }
+
+ String jmxUseJolokiaAgent = System.getProperty("jmx.useJolokiaAgent");
+ if ("true".equals(jmxUseJolokiaAgent))
+ {
+ imapProtocol.assertThat().protocolIsEnabled();
+ smtpProtocol.assertThat().protocolIsEnabled();
+ ServerConfiguration.save(smtpProtocol.withJMX(), smtpProtocol.emailProperties);
+ }
+ else
+ {
+ LOG.warn("*** Jolokia is not used! To use jolokia, please add next system property when running the tests: jmx.useJolokiaAgent=true ***");
+ }
+ }
+
+ @BeforeMethod(alwaysRun=true)
+ public void showStartTestInfo(Method method)
+ {
+ LOG.info(String.format("*** STARTING Test: [%s] ***",method.getName()));
+ }
+
+ @AfterMethod(alwaysRun=true)
+ public void showEndTestInfo(Method method)
+ {
+ LOG.info(String.format("*** ENDING Test: [%s] ***", method.getName()));
+ }
+}
diff --git a/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapCheckFolderTests.java b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapCheckFolderTests.java
new file mode 100644
index 00000000000..d99b21dad7f
--- /dev/null
+++ b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapCheckFolderTests.java
@@ -0,0 +1,189 @@
+package org.alfresco.email.imap;
+
+import org.alfresco.email.EmailTest;
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.model.FolderModel;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import javax.mail.FolderNotFoundException;
+import javax.mail.MessagingException;
+
+public class ImapCheckFolderTests extends EmailTest
+{
+ UserModel managerUser;
+ SiteModel managerTestSite;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ managerUser = dataUser.createRandomTestUser();
+ managerTestSite = dataSite.usingUser(managerUser).createIMAPSite();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Returns the current working directory with admin user")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void adminShouldGetCurrentWorkingDirectory() throws Exception
+ {
+ testUser = dataUser.getAdminUser();
+ testSite = dataSite.usingUser(testUser).createIMAPSite();
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).usingResource(testFolder).assertThat().existsInRepo()
+ .then().assertThat().currentDirectoryIs(testFolder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify in IMAP client current directory/list of directories for site manager")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void siteManagerShouldGetCurrentWorkingDirectory() throws Exception
+ {
+ testFolder = dataContent.usingUser(managerUser).usingSite(managerTestSite).createFolder();
+ imapProtocol.authenticateUser(managerUser).usingSite(managerTestSite).usingResource(testFolder).assertThat().existsInRepo()
+ .then().assertThat().currentDirectoryIs(testFolder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Returns the directories list of the root for site manager")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void siteManagerShouldGetDirectoriesListOfRoot() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ FolderModel alfrescoImap = FolderModel.getRandomFolderModel();
+ alfrescoImap.setName("Alfresco IMAP");
+ FolderModel inbox = FolderModel.getRandomFolderModel();
+ inbox.setName("INBOX");
+ imapProtocol.authenticateUser(testUser).usingRoot()
+ .then().assertThat().contains(alfrescoImap, inbox);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "User finds all its folders for IMAP Sites in Alfresco IMAP > Sites folder")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void userShouldFindAllIMAPSitesFoldersInAlfrescoIMAPFolder() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ SiteModel imapSite1 = dataSite.usingUser(testUser).createIMAPSite();
+ SiteModel imapSite2 = dataSite.usingUser(testUser).createIMAPSite();
+
+ imapProtocol.authenticateUser(testUser).usingSites().assertThat().existsInImap()
+ .then().assertThat().contains(imapSite1, imapSite2);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify in IMAP client current directory/list of directories for COLLABORATOR user - folder created by other user")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void collaboratorShouldGetCurrentWorkingDirectory() throws Exception
+ {
+ UserModel collaborator = dataUser.createRandomTestUser();
+ dataUser.usingUser(managerUser).addUserToSite(collaborator, managerTestSite, UserRole.SiteCollaborator);
+
+ testFolder = dataContent.usingUser(managerUser).usingSite(managerTestSite).createFolder();
+ imapProtocol.authenticateUser(collaborator).usingSite(managerTestSite).usingResource(testFolder).assertThat().existsInRepo()
+ .then().assertThat().currentDirectoryIs(testFolder);
+
+ dataSite.usingUser(collaborator).usingSite(managerTestSite).setIMAPFavorite();
+
+ FolderModel testFolder1 = dataContent.usingUser(managerUser).usingSite(managerTestSite)
+ .usingResource(testFolder).createFolder();
+ FolderModel testFolder2 = dataContent.usingUser(managerUser).usingSite(managerTestSite)
+ .usingResource(testFolder).createFolder();
+
+ imapProtocol.authenticateUser(collaborator).usingSite(managerTestSite)
+ .usingResource(testFolder)
+ .then().assertThat().contains(testFolder1,testFolder2);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify in IMAP client current directory/list of directories for CONTRIBUTOR user - folder created by other user")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void contributorShouldGetCurrentWorkingDirectory() throws Exception
+ {
+ UserModel contributor = dataUser.createRandomTestUser();
+ dataUser.usingUser(managerUser).addUserToSite(contributor, managerTestSite, UserRole.SiteContributor);
+
+ testFolder = dataContent.usingUser(managerUser).usingSite(managerTestSite).createFolder();
+ imapProtocol.authenticateUser(contributor).usingSite(managerTestSite).usingResource(testFolder).assertThat().existsInRepo()
+ .then().assertThat().currentDirectoryIs(testFolder);
+
+ dataSite.usingUser(contributor).usingSite(managerTestSite).setIMAPFavorite();
+
+ FolderModel testFolder1 = dataContent.usingUser(managerUser).usingSite(managerTestSite)
+ .usingResource(testFolder).createFolder();
+ FolderModel testFolder2 = dataContent.usingUser(managerUser).usingSite(managerTestSite)
+ .usingResource(testFolder).createFolder();
+
+ imapProtocol.authenticateUser(contributor).usingSite(managerTestSite)
+ .usingResource(testFolder)
+ .then().assertThat().contains(testFolder1,testFolder2);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify in IMAP client current directory/list of directories for CONSUMER user - folder created by other user")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL })
+ public void consumerShouldGetCurrentWorkingDirectory() throws Exception
+ {
+ UserModel consumer = dataUser.createRandomTestUser();
+ dataUser.usingUser(managerUser).addUserToSite(consumer, managerTestSite, UserRole.SiteConsumer);
+
+ testFolder = dataContent.usingUser(managerUser).usingSite(managerTestSite).createFolder();
+ imapProtocol.authenticateUser(consumer).usingSite(managerTestSite).usingResource(testFolder).assertThat().existsInRepo()
+ .then().assertThat().currentDirectoryIs(testFolder);
+
+ dataSite.usingUser(consumer).usingSite(managerTestSite).setIMAPFavorite();
+
+ FolderModel testFolder1 = dataContent.usingUser(managerUser).usingSite(managerTestSite)
+ .usingResource(testFolder).createFolder();
+ FolderModel testFolder2 = dataContent.usingUser(managerUser).usingSite(managerTestSite)
+ .usingResource(testFolder).createFolder();
+
+ imapProtocol.authenticateUser(consumer).usingSite(managerTestSite)
+ .usingResource(testFolder)
+ .then().assertThat().contains(testFolder1,testFolder2);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify unauthorized is not able to access document library section ( PUBLIC imap SITE)")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL }, expectedExceptions = FolderNotFoundException.class)
+ public void unAuthorizedUserCannotAccessPublicImapSiteDocumentLibrary() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ UserModel unauthorizedUser = dataUser.createRandomTestUser();
+ SiteModel publicImapSite = dataSite.usingUser(testUser).createPublicRandomSite();
+ dataSite.usingUser(unauthorizedUser).usingSite(publicImapSite).setIMAPFavorite();
+
+ imapProtocol.authenticateUser(unauthorizedUser).usingSite(publicImapSite).assertThat().doesNotContain(testFolder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify unauthorized is not able to access document library section ( Moderated imap SITE)")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL }, expectedExceptions = FolderNotFoundException.class)
+ public void unAuthorizedUserCannotAccessModeratedImapSiteDocumentLibrary() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ UserModel unauthorizedUser = dataUser.createRandomTestUser();
+ SiteModel moderatedImapSite = dataSite.usingUser(testUser).createModeratedRandomSite();
+ dataSite.usingUser(unauthorizedUser).usingSite(moderatedImapSite).setIMAPFavorite();
+
+ imapProtocol.authenticateUser(unauthorizedUser).usingSite(moderatedImapSite).assertThat().doesNotContain(testFolder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify unauthorized is not able to access document library section ( Private imap SITE)")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL }, expectedExceptions = MessagingException.class,
+ expectedExceptionsMessageRegExp = ".*Access Denied.*You do not have the appropriate permissions to perform this operation.*")
+ public void unAuthorizedUserCannotAccessPrivateImapSiteDocumentLibrary() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ UserModel unauthorizedUser = dataUser.createRandomTestUser();
+ SiteModel privateImapSite = dataSite.usingUser(testUser).createPrivateRandomSite();
+ dataSite.usingUser(unauthorizedUser).usingSite(privateImapSite).setIMAPFavorite();
+
+ imapProtocol.authenticateUser(unauthorizedUser).usingSite(privateImapSite).assertThat().doesNotContain(testFolder);
+ }
+}
diff --git a/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapConnectionTests.java b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapConnectionTests.java
new file mode 100644
index 00000000000..db73d0a9fcc
--- /dev/null
+++ b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapConnectionTests.java
@@ -0,0 +1,79 @@
+package org.alfresco.email.imap;
+
+import org.alfresco.email.EmailTest;
+import org.alfresco.utility.exception.TestConfigurationException;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * Tests for Connection to Imap
+ *
+ * @author Cristina Axinte
+ *
+ */
+public class ImapConnectionTests extends EmailTest
+{
+ @BeforeClass(alwaysRun=true)
+ public void dataPreparation() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createIMAPSite();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify user can connect successfully to IMAP")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void correctUserConnectsToIMAPSuccessfully() throws Exception
+ {
+ imapProtocol.authenticateUser(testUser).then().assertThat().userIsConnected();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify user fails to connect to IMAP on different port")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY }, expectedExceptions = TestConfigurationException.class)
+ public void userFailsConnectToIMAPOnDifferentPort() throws Exception
+ {
+ imapProtocol.authenticateUser(testUser, 43).then().assertThat().userIsNotConnected();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify user can disconnect successfully from IMAP Server")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void userDisconnectsFromImapServerSuccessfully() throws Exception
+ {
+ imapProtocol.authenticateUser(testUser)
+ .disconnect().then().assertThat().userIsNotConnected();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user fails to connect to IMAP on different host")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE }, expectedExceptions = TestConfigurationException.class)
+ public void userFailsConnectToIMAPOnDifferentHost() throws Exception
+ {
+ imapProtocol.authenticateUser(testUser, "172.29.101.1256").then().assertThat().userIsNotConnected();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify existing user with wrong password fails to connect to IMAP")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE }, expectedExceptions = TestConfigurationException.class,
+ expectedExceptionsMessageRegExp =".*You missed some configuration settings in your tests: User failed to connect to IMAP server LOGIN failed. Invalid login/password$" )
+ public void userFailsConnectToIMAPWithWrongPassword() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ testUser.setPassword("invalid");
+ imapProtocol.authenticateUser(testUser);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify a non existing user fails to connect to IMAP.")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL }, expectedExceptions = TestConfigurationException.class,
+ expectedExceptionsMessageRegExp =".*You missed some configuration settings in your tests: User failed to connect to IMAP server LOGIN failed. Invalid login/password")
+ public void nonExistentUserFailsConnectToIMAP() throws Exception
+ {
+ imapProtocol.authenticateUser(new UserModel("nonExistingUser", "pass"));
+ }
+}
diff --git a/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapCopyFolderTests.java b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapCopyFolderTests.java
new file mode 100644
index 00000000000..d6929edab0b
--- /dev/null
+++ b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapCopyFolderTests.java
@@ -0,0 +1,124 @@
+package org.alfresco.email.imap;
+
+import org.alfresco.dataprep.CMISUtil;
+import org.alfresco.email.EmailTest;
+import org.alfresco.utility.Utility;
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.model.*;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import javax.mail.FolderNotFoundException;
+import javax.mail.MessagingException;
+
+public class ImapCopyFolderTests extends EmailTest
+{
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ adminUser = dataUser.getAdminUser();
+ testUser = dataUser.createRandomTestUser();
+ adminSite = dataSite.usingAdmin().createIMAPSite();
+ testSite = dataSite.usingUser(testUser).createIMAPSite();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify copy non-empty folder to a different location by admin user")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void adminShouldCopyNonEmptyFolder() throws Exception
+ {
+ testFolder = dataContent.usingAdmin().usingSite(adminSite).createFolder();
+ FolderModel copyFolder = dataContent.usingAdmin().usingSite(adminSite).createFolder();
+ FolderModel copiedFolder = testFolder;
+ copiedFolder.setProtocolLocation(Utility.buildPath(copyFolder.getProtocolLocation(), testFolder.getName()));
+ dataContent.usingResource(testFolder).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ imapProtocol.authenticateUser(adminUser).usingSite(adminSite).usingResource(testFolder)
+ .copyTo(copyFolder).then().usingResource(copiedFolder).assertThat().countMessagesIs(1);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify copy folder with Manager")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void siteManagerShouldCopyFolder() throws Exception
+ {
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ FolderModel copyFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ FolderModel copiedFolder = testFolder;
+ copiedFolder.setCmisLocation(Utility.buildPath(copyFolder.getCmisLocation(), testFolder.getName()));
+ copiedFolder.setProtocolLocation(Utility.buildPath(copyFolder.getProtocolLocation(), testFolder.getName()));
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).usingResource(testFolder)
+ .copyTo(copyFolder).then().usingResource(copiedFolder).assertThat().existsInRepo().assertThat().existsInImap();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify copy folder that has been deleted with Manager")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE }, expectedExceptions = FolderNotFoundException.class)
+ public void siteManagerShouldNotCopyFolderThatHasBeenDeleted() throws Exception
+ {
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ FolderModel folderModel = dataContent.usingUser(testUser).usingSite(testSite).usingResource(testFolder).createFolder();
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).usingResource(folderModel).delete()
+ .and().assertThat().doesNotExistInRepo().assertThat().doesNotContain(folderModel)
+ .then().copyTo(testFolder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify copy folder with Contributor user")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void contributorShouldCopyFolder() throws Exception
+ {
+ UserModel contributorUser = dataUser.createRandomTestUser();
+ dataUser.addUserToSite(contributorUser, testSite, UserRole.SiteContributor);
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ FolderModel copyFolder = dataContent.usingUser(contributorUser).usingSite(testSite).createFolder();
+ FolderModel copiedFolder = testFolder;
+ copiedFolder.setProtocolLocation(Utility.buildPath(copyFolder.getProtocolLocation(), testFolder.getName()));
+ dataContent.usingResource(testFolder).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ imapProtocol.authenticateUser(contributorUser).usingSite(testSite).usingResource(testFolder)
+ .copyTo(copyFolder).then().usingResource(copiedFolder).assertThat().countMessagesIs(1);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify copy folder with Collaborator user")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void collaboratorShouldCopyFolder() throws Exception
+ {
+ UserModel collaboratorUser = dataUser.createRandomTestUser();
+ dataUser.addUserToSite(collaboratorUser, testSite, UserRole.SiteCollaborator);
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ FolderModel copyFolder = dataContent.usingUser(collaboratorUser).usingSite(testSite).createFolder();
+ FolderModel copiedFolder = testFolder;
+ copiedFolder.setProtocolLocation(Utility.buildPath(copyFolder.getProtocolLocation(), testFolder.getName()));
+ dataContent.usingResource(testFolder).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ imapProtocol.authenticateUser(collaboratorUser).usingSite(testSite).usingResource(testFolder)
+ .copyTo(copyFolder).then().usingResource(copiedFolder).assertThat().countMessagesIs(1);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that copy folder with Consumer user is not possible")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE }, expectedExceptions = FolderNotFoundException.class)
+ public void consumerShouldNotCopyFolder() throws Exception
+ {
+ UserModel consumerUser = dataUser.createRandomTestUser();
+ dataUser.addUserToSite(consumerUser, testSite, UserRole.SiteConsumer);
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ FolderModel copyFolder = new FolderModel("copyFolder");
+ imapProtocol.authenticateUser(consumerUser).usingSite(testSite).createFolder(copyFolder).usingResource(testFolder)
+ .copyTo(copyFolder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify copy folder to a location for which the user does not have permission")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE }, expectedExceptions = MessagingException.class)
+ public void userCopyFolderToALocationThatHeDoesNotHaveAccess() throws Exception
+ {
+ SiteModel siteModel = dataSite.usingAdmin().createPrivateRandomSite();
+ testFolder = dataContent.usingAdmin().usingSite(testSite).createFolder();
+ FolderModel copyFolder = dataContent.usingAdmin().usingSite(siteModel).createFolder();
+ dataContent.usingResource(testFolder).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ imapProtocol.authenticateUser(testUser).usingResource(testFolder)
+ .copyTo(copyFolder);
+ }
+}
diff --git a/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapCopyMessagesTests.java b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapCopyMessagesTests.java
new file mode 100644
index 00000000000..dbcf7d19176
--- /dev/null
+++ b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapCopyMessagesTests.java
@@ -0,0 +1,111 @@
+package org.alfresco.email.imap;
+
+import javax.mail.MessagingException;
+
+import org.alfresco.dataprep.CMISUtil;
+import org.alfresco.email.EmailTest;
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.testng.SkipException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class ImapCopyMessagesTests extends EmailTest
+{
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createIMAPSite();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify site manager can copy non-empty file via IMAP client to a different location")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void siteManagerShouldCopyNonEmptyFile() throws Exception
+ {
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ FileModel fileModel = dataContent.usingSite(testSite).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).usingResource(fileModel).assertThat().existsInRepo()
+ .and().assertThat().existsInImap()
+ .then().copyMessageTo(testFolder).assertThat().containsMessages(fileModel);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify site manager can copy non-empty files via IMAP client to a different location")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void siteManagerShouldCopyNonEmptyFiles() throws Exception
+ {
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ FileModel fileModel1 = dataContent.usingSite(testSite).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ FileModel fileModel2 = dataContent.usingSite(testSite).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).usingResource(fileModel1).assertThat().existsInRepo()
+ .and().assertThat().existsInImap()
+ .then().usingSite(testSite).copyMessagesTo(testFolder).assertThat().containsMessages(fileModel1, fileModel2);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager can copy empty file via IMAP client to a different location")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void siteManagerShouldCopyEmptyFile() throws Exception
+ {
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ FileModel fileModel = new FileModel("EmptyFile.txt", FileType.TEXT_PLAIN, "");
+ fileModel = dataContent.usingUser(testUser).usingSite(testSite).createContent(fileModel);
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).usingResource(fileModel).assertThat().existsInRepo()
+ .and().assertThat().existsInImap()
+ .then().copyMessageTo(testFolder).assertThat().containsMessages(fileModel);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user can copy file via IMAP client to a location where the message already exists")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void userShouldCopyFileWhereAlreadyExists() throws Exception
+ {
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ FileModel fileModel = new FileModel("CopyFile.txt", FileType.TEXT_PLAIN, "content of copied file");
+ dataContent.usingSite(testSite).usingResource(testFolder).createContent(fileModel);
+ FileModel fileToBeCopied = dataContent.usingSite(testSite).createContent(fileModel);
+
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).usingResource(fileToBeCopied).assertThat().existsInRepo()
+ .and().assertThat().existsInImap()
+ .then().copyMessageTo(testFolder).assertThat().containsMessages(fileToBeCopied);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user cannot copy a file via IMAP client if it was already deleted from repository")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE }, expectedExceptions = MessagingException.class,
+ expectedExceptionsMessageRegExp ="There are no messages to be copied")
+ public void userCannotCopyDeletedFile() throws Exception
+ {
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ FileModel fileModel = dataContent.usingSite(testSite).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).usingResource(fileModel).assertThat().existsInImap();
+ dataContent.usingResource(fileModel).deleteContent();
+ imapProtocol.copyMessageTo(testFolder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user cannot copy file via IMAP client to a location where you don't have permissions")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE }, expectedExceptions = MessagingException.class,
+ expectedExceptionsMessageRegExp = ".*NO APPEND failed. Can't append message - Permission denied.*")
+ public void userCannotCopyFileWhereNoPermissions() throws Exception
+ {
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+
+ UserModel user = dataUser.createRandomTestUser();
+ SiteModel site = dataSite.usingUser(user).createIMAPSite();
+ FileModel file = dataContent.usingUser(user).usingSite(site).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ dataSite.usingUser(user).usingSite(testSite).setIMAPFavorite();
+
+ imapProtocol.authenticateUser(user).usingSite(site).usingResource(file).assertThat().existsInRepo()
+ .and().assertThat().existsInImap()
+ .then().copyMessageTo(testFolder);
+ }
+}
diff --git a/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapCreateFolderTests.java b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapCreateFolderTests.java
new file mode 100644
index 00000000000..e32bc38829d
--- /dev/null
+++ b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapCreateFolderTests.java
@@ -0,0 +1,217 @@
+package org.alfresco.email.imap;
+
+import org.alfresco.email.EmailTest;
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.model.FolderModel;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.report.Bug;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import javax.mail.FolderNotFoundException;
+
+/**
+ * Tests for Create Folder action using IMAP client
+ *
+ * @author Cristina Axinte
+ *
+ */
+public class ImapCreateFolderTests extends EmailTest
+{
+ private UserModel adminUser;
+ private SiteModel imapSite;
+
+ @BeforeClass(alwaysRun=true)
+ public void dataPreparation() throws Exception
+ {
+ adminUser = dataUser.getAdminUser();
+ testUser = dataUser.createRandomTestUser();
+ imapSite = dataSite.usingUser(testUser).createIMAPSite();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify admin can create a folder in Afresco IMAP root folder")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void adminCanCreateFolderInAlfrescoImapRoot() throws Exception
+ {
+ FolderModel folderToCreate = FolderModel.getRandomFolderModel();
+
+ imapProtocol.authenticateUser(adminUser).usingAlfrescoImap().createFolder(folderToCreate)
+ .assertThat().existsInImap()
+ .assertThat().existsInRepo();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify user can create a folder in Afresco IMAP root folder, but it is not displayed in Alfresco Repository")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void userCanCreateFolderInAlfrescoImapRootButNotDisplayedInRepo() throws Exception
+ {
+ FolderModel folderToCreate = FolderModel.getRandomFolderModel();
+
+ imapProtocol.authenticateUser(testUser).usingAlfrescoImap().createFolder(folderToCreate)
+ .assertThat().existsInImap()
+ .assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify admin can create a folder in Sites folder and it will be displayed in Alfresco Repository/Sites")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void adminCanCreateFolderInSitesFolder() throws Exception
+ {
+ FolderModel folderToCreate = FolderModel.getRandomFolderModel();
+
+ imapProtocol.authenticateUser(adminUser)
+ .usingSites().createFolder(folderToCreate)
+ .assertThat().existsInImap()
+ .assertThat().existsInRepo();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify manager can create a folder in IMAP Site > documentLibrary")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void managerCanCreateFolderInIMAPSite() throws Exception
+ {
+ UserModel managerUser = dataUser.createRandomTestUser();
+ dataUser.usingUser(testUser).addUserToSite(managerUser, imapSite, UserRole.SiteManager);
+ FolderModel folderToCreate = FolderModel.getRandomFolderModel();
+
+ imapProtocol.authenticateUser(managerUser)
+ .usingSite(imapSite).createFolder(folderToCreate)
+ .assertThat().existsInImap()
+ .assertThat().existsInRepo();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify manager can create a folder with spaces in name in IMAP Site > documentLibrary")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void managerCanCreateFolderWithSpacesInIMAPSite() throws Exception
+ {
+ UserModel managerUser = dataUser.createRandomTestUser();
+ imapSite = dataSite.usingUser(managerUser).createIMAPSite();
+ FolderModel folderToCreate = new FolderModel("Folder with spaces in name");
+
+ imapProtocol.authenticateUser(managerUser)
+ .usingSite(imapSite).createFolder(folderToCreate)
+ .assertThat().existsInImap()
+ .assertThat().existsInRepo();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify collaborator can create a folder in IMAP Site > documentLibrary")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void collaboratorCanCreateFolderInImapSite() throws Exception
+ {
+ UserModel collaboratorUser = dataUser.createRandomTestUser();
+ dataUser.usingUser(testUser).addUserToSite(collaboratorUser, imapSite, UserRole.SiteCollaborator);
+ FolderModel folderToCreate = FolderModel.getRandomFolderModel();
+
+ imapProtocol.authenticateUser(collaboratorUser)
+ .usingSite(imapSite).createFolder(folderToCreate)
+ .assertThat().existsInImap()
+ .assertThat().existsInRepo();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify contributor can create a folder in IMAP Site > documentLibrary")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void contributorCanCreateFolderInImapSite() throws Exception
+ {
+ UserModel contributorUser = dataUser.createRandomTestUser();
+ dataUser.usingUser(testUser).addUserToSite(contributorUser, imapSite, UserRole.SiteCollaborator);
+ FolderModel folderToCreate = FolderModel.getRandomFolderModel();
+
+ imapProtocol.authenticateUser(contributorUser)
+ .usingSite(imapSite).createFolder(folderToCreate)
+ .assertThat().existsInImap()
+ .assertThat().existsInRepo();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify consumer cannot create a folder in IMAP Site > documentLibrary")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL })
+ public void consumerCannotCreateFolderInImapSite() throws Exception
+ {
+ UserModel consumerUser = dataUser.createRandomTestUser();
+ dataUser.usingUser(testUser).addUserToSite(consumerUser, imapSite, UserRole.SiteConsumer);
+ dataSite.usingUser(consumerUser).usingSite(imapSite).setIMAPFavorite();
+ FolderModel folderToCreate = FolderModel.getRandomFolderModel();
+
+ imapProtocol.authenticateUser(consumerUser).usingSite(imapSite).createFolder(folderToCreate)
+ .and()
+ .assertThat().doesNotExistInRepo()
+ .then().usingSite(imapSite)
+ .assertThat().doesNotContain(folderToCreate);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user can create folder successfully with name that contains special characters")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL })
+ public void userCanCreateFolderWithSpecialCharacters() throws Exception
+ {
+ testSite = dataSite.usingUser(testUser).createIMAPSite();
+ FolderModel folderToCreate = new FolderModel("(a)[b]!#%^");
+
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).createFolder(folderToCreate)
+ .then()
+ .assertThat().existsInImap()
+ .assertThat().existsInRepo();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user can create folder successfully with name that contains symbols")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL })
+ public void userCanCreateFolderWithSymbols() throws Exception
+ {
+ testSite = dataSite.usingUser(testUser).createIMAPSite();
+ FolderModel folderToCreate = new FolderModel("a£¥€$♊♎ ♏ ♐ ♑ ♒ ♓");
+
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).createFolder(folderToCreate)
+ .then()
+ .assertThat().existsInImap()
+ .assertThat().existsInRepo();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user cannot create folder with name omegaΩ_<>./?")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL })
+ public void userCannotCreateFolderWithNameThatContainsRestrictedCharacters() throws Exception
+ {
+ testSite = dataSite.usingUser(testUser).createIMAPSite();
+ FolderModel folderToCreate = new FolderModel("omegaΩ_<>./?");
+
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).createFolder(folderToCreate)
+ .and()
+ .assertThat().doesNotExistInRepo()
+ .then().usingSite(testSite)
+ .assertThat().doesNotContain(folderToCreate);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify create folder using an user and check folder can be view by another user with access to the same location/site")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL })
+ public void verifyUserCanViewTheFolderCreatedByAnotherUser() throws Exception
+ {
+ testSite = dataSite.usingUser(testUser).createIMAPSite();
+ UserModel collaboratorUser = dataUser.createRandomTestUser();
+ dataUser.addUserToSite(collaboratorUser, testSite, UserRole.SiteCollaborator);
+ FolderModel folderToCreate = FolderModel.getRandomFolderModel();
+
+ imapProtocol.authenticateUser(collaboratorUser).usingSite(testSite).createFolder(folderToCreate).disconnect();
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).usingResource(folderToCreate)
+ .assertThat().existsInImap()
+ .assertThat().existsInRepo();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify error is returned for unauthenticated user on creating folder")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL }, expectedExceptions = IllegalStateException.class,
+ expectedExceptionsMessageRegExp = "Not connected")
+ public void verifyErrorIsReturnedForUnauthenticatedUserTryingToCreateFolder() throws Exception
+ {
+ imapProtocol.authenticateUser(testUser).usingSite(imapSite).disconnect().then().createFolder(FolderModel.getRandomFolderModel());
+ }
+}
diff --git a/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapDeleteFolderTests.java b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapDeleteFolderTests.java
new file mode 100644
index 00000000000..9f371779311
--- /dev/null
+++ b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapDeleteFolderTests.java
@@ -0,0 +1,259 @@
+package org.alfresco.email.imap;
+
+import org.alfresco.dataprep.CMISUtil;
+import org.alfresco.email.EmailTest;
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.model.*;
+import org.alfresco.utility.report.Bug;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import javax.mail.FolderNotFoundException;
+
+public class ImapDeleteFolderTests extends EmailTest
+{
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ adminUser = dataUser.getAdminUser();
+ testUser = dataUser.createRandomTestUser();
+ adminSite = dataSite.usingAdmin().createIMAPSite();
+ testSite = dataSite.usingUser(testUser).createIMAPSite();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify admin can delete folder")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void adminShouldDeleteFolder() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ imapProtocol.authenticateUser(adminUser).usingSite(adminSite).createFolder(testFolder)
+ .assertThat().existsInRepo()
+ .assertThat().existsInImap()
+ .delete()
+ .assertThat().doesNotExistInRepo()
+ .usingSite(adminSite).assertThat().doesNotContain(testFolder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify site Manager can delete a folder with a message(file)")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void siteManagerShouldDeleteNonEmptyFolder() throws Exception
+ {
+ UserModel user = dataUser.createRandomTestUser();
+ SiteModel site = dataSite.usingUser(user).createIMAPSite();
+ FolderModel folder = FolderModel.getRandomFolderModel();
+ imapProtocol.authenticateUser(user).usingSite(site).createFolder(folder)
+ .assertThat().existsInImap()
+ .assertThat().existsInRepo();
+ dataContent.usingUser(user).usingSite(site).usingResource(folder).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ imapProtocol.usingSite(site).usingResource(folder).assertThat().countMessagesIs(1)
+ .delete()
+ .assertThat().doesNotExistInRepo()
+ .usingSite(site).assertThat().doesNotContain(folder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that site manager can delete a empty folder")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void siteManagerShouldDeleteFolder() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder)
+ .assertThat().existsInRepo()
+ .assertThat().existsInImap()
+ .delete()
+ .assertThat().doesNotExistInRepo()
+ .usingSite(testSite).assertThat().doesNotContain(testFolder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that site manager can delete a folder that contains collaborator user messages")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE }, enabled = false)//disable since it's failing intermitent
+ public void siteManagerShouldDeleteFolderWithCollaboratorMessages() throws Exception
+ {
+ UserModel collaboratorUser = dataUser.createRandomTestUser();
+ dataUser.usingUser(testUser).addUserToSite(collaboratorUser, testSite, UserRole.SiteCollaborator);
+ testFolder = FolderModel.getRandomFolderModel();
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder)
+ .assertThat().existsInImap()
+ .assertThat().existsInRepo();
+ testFile = dataContent.usingUser(collaboratorUser).usingResource(testFolder).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ imapProtocol.usingSite(testSite).usingResource(testFolder)
+ .assertThat().countMessagesIs(1)
+ .delete()
+ .assertThat().doesNotExistInRepo()
+ .usingSite(testSite).assertThat().doesNotContain(testFolder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that site manager can delete a folder that contains contributor user messages")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE }, enabled = false)//disable since it's failing intermitent
+ public void siteManagerShouldDeleteFolderWithContributorMessages() throws Exception
+ {
+ UserModel contributorUser = dataUser.createRandomTestUser();
+ dataUser.usingUser(testUser).addUserToSite(contributorUser, testSite, UserRole.SiteContributor);
+ testFolder = FolderModel.getRandomFolderModel();
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder)
+ .assertThat().existsInImap()
+ .assertThat().existsInRepo();
+ dataContent.usingUser(contributorUser).usingSite(testSite).usingResource(testFolder).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ imapProtocol.usingSite(testSite).usingResource(testFolder).assertThat().countMessagesIs(1)
+ .delete()
+ .assertThat().doesNotExistInRepo()
+ .usingSite(testSite).assertThat().doesNotContain(testFolder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that an unauthorized user can not delete folder")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE }, expectedExceptions = FolderNotFoundException.class)
+ public void unauthorizedUserShouldNotDeleteFolder() throws Exception
+ {
+ UserModel unauthorizedUser = dataUser.createRandomTestUser();
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ imapProtocol.authenticateUser(unauthorizedUser).usingResource(testFolder).delete();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that site manager can delete a folder that contains consumer user messages")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL })
+ public void siteManagerShouldDeleteFolderWithConsumerMessages() throws Exception
+ {
+ UserModel consumerUser = dataUser.createRandomTestUser();
+ dataUser.usingUser(testUser).addUserToSite(consumerUser, testSite, UserRole.SiteContributor);
+ testFolder = FolderModel.getRandomFolderModel();
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder)
+ .assertThat().existsInImap()
+ .assertThat().existsInRepo();
+ dataContent.usingUser(consumerUser).usingSite(testSite).usingResource(testFolder).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ dataUser.usingUser(testUser).removeUserFromSite(consumerUser, testSite);
+ dataUser.usingUser(testUser).addUserToSite(consumerUser, testSite, UserRole.SiteConsumer);
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).usingResource(testFolder).assertThat().countMessagesIs(1)
+ .delete()
+ .assertThat().doesNotExistInRepo()
+ .usingSite(testSite).assertThat().doesNotContain(testFolder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user cannot delete folder that no longer exists")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL }, expectedExceptions = FolderNotFoundException.class)
+ public void userCannotDeleteFolderThatNoLongerExists() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder)
+ .assertThat().existsInImap()
+ .assertThat().existsInRepo()
+ .delete()
+ .assertThat().doesNotExistInRepo()
+ .usingSite(testSite).assertThat().doesNotContain(testFolder)
+ .usingResource(testFolder)
+ .delete();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify deleting folder that contains messages by COLLABORATOR user")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL })
+ public void collaboratorTriesToDeleteFolderContainingMessagesByCollaborator() throws Exception
+ {
+ UserModel collaboratorUser1 = dataUser.createRandomTestUser();
+ UserModel collaboratorUser2 = dataUser.createRandomTestUser();
+ dataUser.usingUser(testUser).addUserToSite(collaboratorUser1, testSite, UserRole.SiteCollaborator);
+ dataUser.usingUser(testUser).addUserToSite(collaboratorUser2, testSite, UserRole.SiteCollaborator);
+ testFolder = FolderModel.getRandomFolderModel();
+
+ dataSite.usingUser(collaboratorUser1).usingSite(testSite).setIMAPFavorite();
+ imapProtocol.authenticateUser(collaboratorUser1).usingSite(testSite).createFolder(testFolder)
+ .assertThat().existsInImap()
+ .assertThat().existsInRepo()
+ .disconnect();
+ testFile = dataContent.usingUser(collaboratorUser1).usingSite(testSite).usingResource(testFolder).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ dataSite.usingUser(collaboratorUser2).usingSite(testSite).setIMAPFavorite();
+ imapProtocol.authenticateUser(collaboratorUser2).usingSite(testSite).usingResource(testFolder)
+ .delete()
+ .assertThat().existsInRepo()
+ .usingSite(testSite).assertThat().contains(testFolder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify deleting folder that contains messages by CONTRIBUTOR user")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL })
+ public void contributorTriesToDeleteFolderContainingMessagesByContributor() throws Exception
+ {
+ UserModel contributorUser1 = dataUser.createRandomTestUser();
+ UserModel contributorUser2 = dataUser.createRandomTestUser();
+ dataUser.usingUser(testUser).addUserToSite(contributorUser1, testSite, UserRole.SiteContributor);
+ dataUser.usingUser(testUser).addUserToSite(contributorUser2, testSite, UserRole.SiteContributor);
+ testFolder = FolderModel.getRandomFolderModel();
+
+ dataSite.usingUser(contributorUser1).usingSite(testSite).setIMAPFavorite();
+ imapProtocol.authenticateUser(contributorUser1).usingSite(testSite).createFolder(testFolder)
+ .assertThat().existsInImap()
+ .assertThat().existsInRepo()
+ .disconnect();
+ testFile = dataContent.usingUser(contributorUser1).usingSite(testSite).usingResource(testFolder).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ dataSite.usingUser(contributorUser2).usingSite(testSite).setIMAPFavorite();
+ imapProtocol.authenticateUser(contributorUser2).usingSite(testSite).usingResource(testFolder)
+ .delete()
+ .assertThat().existsInRepo()
+ .usingSite(testSite).assertThat().contains(testFolder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify deleting folder that contains messages by CONSUMER user")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL })
+ public void consumerTriesToDeleteFolderContainingMessagesByConsumer() throws Exception
+ {
+ UserModel consumerUser1 = dataUser.createRandomTestUser();
+ UserModel consumerUser2 = dataUser.createRandomTestUser();
+ dataUser.usingUser(testUser).addUserToSite(consumerUser1, testSite, UserRole.SiteCollaborator);
+ dataUser.usingUser(testUser).addUserToSite(consumerUser2, testSite, UserRole.SiteConsumer);
+ testFolder = FolderModel.getRandomFolderModel();
+
+ dataSite.usingUser(consumerUser1).usingSite(testSite).setIMAPFavorite();
+ imapProtocol.authenticateUser(consumerUser1).usingSite(testSite).createFolder(testFolder)
+ .assertThat().existsInImap()
+ .assertThat().existsInRepo()
+ .disconnect();
+ testFile = dataContent.usingUser(consumerUser1).usingSite(testSite).usingResource(testFolder).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ dataUser.usingUser(testUser).removeUserFromSite(consumerUser1, testSite);
+ dataUser.usingUser(testUser).addUserToSite(consumerUser1, testSite, UserRole.SiteConsumer);
+ dataSite.usingUser(consumerUser2).usingSite(testSite).setIMAPFavorite();
+ imapProtocol.authenticateUser(consumerUser2).usingSite(testSite).usingResource(testFolder)
+ .delete()
+ .assertThat().existsInRepo()
+ .usingSite(testSite).assertThat().contains(testFolder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify delete folder from a location where you don't have permission")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL }, expectedExceptions = FolderNotFoundException.class)
+ public void userTriesToDeleteFolderFromALocationToWhichHeDoesNotHavePermissionToDelete() throws Exception
+ {
+ UserModel userModel = dataUser.createRandomTestUser();
+ SiteModel privateSite = dataSite.usingAdmin().createIMAPSite();
+ testFolder = FolderModel.getRandomFolderModel();
+
+ imapProtocol.authenticateUser(dataUser.getAdminUser()).usingSite(privateSite).createFolder(testFolder)
+ .assertThat().existsInImap()
+ .assertThat().existsInRepo()
+ .disconnect();
+
+ dataSite.usingUser(userModel).usingSite(privateSite).setIMAPFavorite();
+ imapProtocol.authenticateUser(userModel).usingSite(testSite).usingResource(testFolder).delete();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify admin cannot delete a open folder")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL }, expectedExceptions = IllegalStateException.class,
+ expectedExceptionsMessageRegExp = "This operation is not allowed on an open folder")
+ public void adminTriesToDeleteOpenFolder() throws Exception
+ {
+ testFolder = FolderModel.getRandomFolderModel();
+ imapProtocol.authenticateUser(adminUser).usingSite(adminSite).createFolder(testFolder)
+ .assertThat().existsInRepo()
+ .assertThat().existsInImap()
+ .attemptToDeleteOpenFolder();
+ }
+}
diff --git a/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapDeleteMessagesTests.java b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapDeleteMessagesTests.java
new file mode 100644
index 00000000000..fe8c70f8736
--- /dev/null
+++ b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapDeleteMessagesTests.java
@@ -0,0 +1,95 @@
+package org.alfresco.email.imap;
+
+import org.alfresco.dataprep.CMISUtil;
+import org.alfresco.email.EmailTest;
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.model.*;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import javax.mail.MessagingException;
+
+public class ImapDeleteMessagesTests extends EmailTest
+{
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createIMAPSite();
+ adminSite = dataSite.usingAdmin().createIMAPSite();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify message can be deleted from IMAP client by admin")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void adminShouldDeleteMessage() throws Exception
+ {
+ testFile = dataContent.usingAdmin().usingSite(adminSite).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ imapProtocol.authenticateUser(dataUser.getAdminUser()).usingSite(adminSite).assertThat().containsMessages(testFile)
+ .and().usingResource(testFile).assertThat().existsInRepo().deleteMessage()
+ .and().assertThat().doesNotContainMessages(testFile)
+ .then().usingResource(testFile).assertThat().doesNotExistInRepo();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify deleting message via IMAP client by user with MANAGER role")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void siteManagerShouldDeleteMessage() throws Exception
+ {
+ testFile = dataContent.usingUser(testUser).usingSite(testSite).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ imapProtocol.authenticateUser(testUser).usingResource(testFile).assertThat().existsInRepo()
+ .and().usingSite(testSite).assertThat().containsMessages(testFile).deleteMessage(testFile.getName())
+ .and().assertThat().doesNotContainMessages(testFile);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify message has been deleted via REPOSITORU by user with MANAGER role")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void siteManagerVerifyMessageHasBeenDeletedFromRepository() throws Exception
+ {
+ testFile = dataContent.usingUser(testUser).usingSite(testSite).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ dataContent.usingUser(testUser).usingResource(testFile).deleteContent();
+ imapProtocol.authenticateUser(testUser).usingResource(testFile).assertThat().doesNotExistInRepo()
+ .and().usingSite(testSite).assertThat().doesNotContainMessages(testFile);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify deleting message via IMAP client by user with CONTRIBUTOR role")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void siteContributorShouldDeleteMessage() throws Exception
+ {
+ UserModel contributorUser = dataUser.createRandomTestUser();
+ dataUser.usingUser(testUser).addUserToSite(contributorUser, testSite, UserRole.SiteContributor);
+ testFile = dataContent.usingUser(contributorUser).usingSite(testSite).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ imapProtocol.authenticateUser(contributorUser).usingResource(testFile).deleteMessage()
+ .usingResource(testFile).assertThat().doesNotExistInRepo()
+ .and().usingSite(testSite).assertThat().doesNotContainMessages(testFile);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify deleting message via IMAP client by user with COLLABORATOR role")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void siteCollaboratorShouldDeleteMessage() throws Exception
+ {
+ UserModel collaboratorUser = dataUser.createRandomTestUser();
+ dataUser.usingUser(testUser).addUserToSite(collaboratorUser, testSite, UserRole.SiteCollaborator);
+ testFile = dataContent.usingUser(collaboratorUser).usingSite(testSite).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ imapProtocol.authenticateUser(collaboratorUser).usingResource(testFile).deleteMessage()
+ .usingResource(testFile).assertThat().doesNotExistInRepo()
+ .and().usingSite(testSite).assertThat().doesNotContainMessages(testFile);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify deleting message via IMAP client by user with CONSUMER role is not permitted")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE }, expectedExceptions = MessagingException.class,
+ expectedExceptionsMessageRegExp = ".*No permission to set DELETED flag")
+ public void siteConsumerShouldNotDeleteMessage() throws Exception
+ {
+ UserModel consumerUser = dataUser.createRandomTestUser();
+ dataUser.usingUser(testUser).addUserToSite(consumerUser, testSite, UserRole.SiteConsumer);
+ testFile = dataContent.usingUser(testUser).usingSite(testSite).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ imapProtocol.authenticateUser(consumerUser).usingResource(testFile).deleteMessage();
+ }
+}
diff --git a/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapMessageFlagsTests.java b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapMessageFlagsTests.java
new file mode 100644
index 00000000000..1cb777664d0
--- /dev/null
+++ b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapMessageFlagsTests.java
@@ -0,0 +1,58 @@
+package org.alfresco.email.imap;
+
+import org.alfresco.dataprep.CMISUtil;
+import org.alfresco.email.EmailTest;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.testng.annotations.Test;
+
+import javax.mail.Flags;
+
+public class ImapMessageFlagsTests extends EmailTest
+{
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify site manager can set flags action to a content(message) through IMAP Client")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void siteManagerShouldSetFlagsToAContent() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createIMAPSite();
+ FileModel fileModel = dataContent.usingUser(testUser).usingSite(testSite).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ imapProtocol.authenticateUser(testUser).usingResource(fileModel).assertThat().existsInRepo()
+ .and().assertThat().existsInImap()
+ .and().withMessage().setAnsweredFlag().setSeenFlag().updateFlags()
+ .then().assertThat().messageContainsFlags(Flags.Flag.ANSWERED, Flags.Flag.SEEN);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager can set flags to a content(message) through IMAP Client")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void siteManagerShouldSetFlagsToContent() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createIMAPSite();
+ FileModel fileModel = dataContent.usingUser(testUser).usingSite(testSite).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ imapProtocol.authenticateUser(testUser).usingResource(fileModel).assertThat().existsInRepo()
+ .and().assertThat().existsInImap()
+ .and().withMessage().setFlags(Flags.Flag.ANSWERED, Flags.Flag.SEEN).updateFlags()
+ .then().assertThat().messageContainsFlags(Flags.Flag.ANSWERED, Flags.Flag.SEEN);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site manager can remove flags from a content(message) through IMAP Client")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void siteManagerShouldRemoveFlagsFromContent() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createIMAPSite();
+ FileModel fileModel = dataContent.usingUser(testUser).usingSite(testSite).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ imapProtocol.authenticateUser(testUser).usingResource(fileModel).assertThat().existsInRepo()
+ .and().assertThat().existsInImap()
+ .and().withMessage().setFlags(Flags.Flag.ANSWERED, Flags.Flag.SEEN).updateFlags()
+ .and().assertThat().messageContainsFlags(Flags.Flag.ANSWERED, Flags.Flag.SEEN)
+ .and().withMessage().removeFlags(Flags.Flag.ANSWERED, Flags.Flag.SEEN).updateFlags()
+ .then().assertThat().messageDoesNotContainFlags(Flags.Flag.ANSWERED, Flags.Flag.SEEN);
+ }
+}
diff --git a/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapMoveFolderTests.java b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapMoveFolderTests.java
new file mode 100644
index 00000000000..0d41f149f07
--- /dev/null
+++ b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapMoveFolderTests.java
@@ -0,0 +1,146 @@
+package org.alfresco.email.imap;
+
+import javax.mail.FolderNotFoundException;
+
+import org.alfresco.dataprep.CMISUtil;
+import org.alfresco.email.EmailTest;
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.model.FolderModel;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.report.Bug;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class ImapMoveFolderTests extends EmailTest
+{
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ adminUser = dataUser.getAdminUser();
+ testUser = dataUser.createRandomTestUser();
+ adminSite = dataSite.usingAdmin().createIMAPSite();
+ testSite = dataSite.usingUser(testUser).createIMAPSite();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify move non-empty folder to a different location by admin user")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void adminShouldMoveNonEmptyFolder() throws Exception
+ {
+ testFolder = dataContent.usingAdmin().usingSite(adminSite).createFolder();
+ FolderModel moveToFolder = dataContent.usingAdmin().usingSite(adminSite).createFolder();
+ dataContent.usingAdmin().usingResource(testFolder).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ imapProtocol.authenticateUser(adminUser).usingSite(adminSite).usingResource(testFolder).moveTo(moveToFolder)
+ .and().usingResource(testFolder).assertThat().doesNotExistInRepo()
+ .then().usingResource(moveToFolder).assertThat().contains(testFolder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify move folder with Manager")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void siteManagerShouldMoveFolder() throws Exception
+ {
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ FolderModel moveToFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).usingResource(testFolder).moveTo(moveToFolder)
+ .and().usingResource(testFolder).assertThat().doesNotExistInRepo()
+ .then().usingResource(moveToFolder).assertThat().contains(testFolder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify move folder at location where the folder already exists is successful")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void userShouldMoveFolderWhereAlreadyExists() throws Exception
+ {
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ FolderModel moveToFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ dataContent.usingUser(testUser).usingSite(testSite)
+ .usingResource(moveToFolder)
+ .createFolder(testFolder);
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).usingResource(testFolder).moveTo(moveToFolder)
+ .and().usingResource(testFolder).assertThat().doesNotExistInRepo()
+ .then().usingResource(moveToFolder).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify move folder with Contributor will create the new folder, but is NOT able to delete the current one")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void siteContributorCannotMoveFolder() throws Exception
+ {
+ UserModel siteContributor = dataUser.createRandomTestUser();
+ dataUser.usingUser(testUser).addUserToSite(siteContributor, testSite, UserRole.SiteContributor);
+ dataSite.usingUser(siteContributor).usingSite(testSite).setIMAPFavorite();
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ FolderModel moveToFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+
+ imapProtocol.authenticateUser(siteContributor).usingSite(testSite).usingResource(testFolder).moveTo(moveToFolder)
+ .usingResource(moveToFolder).assertThat().contains(testFolder)
+ .and().usingResource(testFolder).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify move folder with Collaborator will create the new folder, but is NOT able to delete the current one")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void siteCollaboratorCannotMoveFolder() throws Exception
+ {
+ UserModel siteCollaborator = dataUser.createRandomTestUser();
+ dataUser.usingUser(testUser).addUserToSite(siteCollaborator, testSite, UserRole.SiteContributor);
+ dataSite.usingUser(siteCollaborator).usingSite(testSite).setIMAPFavorite();
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ FolderModel moveToFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+
+ imapProtocol.authenticateUser(siteCollaborator).usingSite(testSite).usingResource(testFolder).moveTo(moveToFolder)
+ .usingResource(moveToFolder).assertThat().contains(testFolder)
+ .and().usingResource(testFolder).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify move folder with Consumer will create the new folder, but is NOT able to delete the current one")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void siteConsumerCannotMoveFolder() throws Exception
+ {
+ UserModel siteConsumer = dataUser.createRandomTestUser();
+ dataUser.usingUser(testUser).addUserToSite(siteConsumer, testSite, UserRole.SiteContributor);
+ dataSite.usingUser(siteConsumer).usingSite(testSite).setIMAPFavorite();
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ FolderModel moveToFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+
+ imapProtocol.authenticateUser(siteConsumer).usingSite(testSite).usingResource(testFolder).moveTo(moveToFolder)
+ .usingResource(moveToFolder).assertThat().contains(testFolder)
+ .and().usingResource(testFolder).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify move folder fails using user that doesn't have permission to the IMAP site")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE }, expectedExceptions = FolderNotFoundException.class)
+ public void unauthorizedUserCannotMoveFolder() throws Exception
+ {
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ FolderModel moveToFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+
+ UserModel unauthorizedUser = dataUser.createRandomTestUser();
+ dataSite.usingUser(unauthorizedUser).usingSite(testSite).setIMAPFavorite();
+
+ imapProtocol.authenticateUser(unauthorizedUser).usingSite(testSite).usingResource(testFolder).moveTo(moveToFolder)
+ .usingResource(moveToFolder).assertThat().doesNotContain(testFolder)
+ .and().usingResource(testFolder).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify move folder with Manager")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL }, expectedExceptions = FolderNotFoundException.class)
+ public void siteManagerShouldNotMoveDeletedFolder() throws Exception
+ {
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ FolderModel moveToFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).usingResource(testFolder)
+ .assertThat().existsInImap()
+ .assertThat().existsInRepo()
+ .delete()
+ .moveTo(moveToFolder);
+ }
+}
diff --git a/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapMoveMessagesTests.java b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapMoveMessagesTests.java
new file mode 100644
index 00000000000..31ee6b0931c
--- /dev/null
+++ b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapMoveMessagesTests.java
@@ -0,0 +1,27 @@
+package org.alfresco.email.imap;
+
+import org.alfresco.dataprep.CMISUtil;
+import org.alfresco.email.EmailTest;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.testng.annotations.Test;
+
+public class ImapMoveMessagesTests extends EmailTest
+{
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify site manager can move message via IMAP client to a different location")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void siteManagerShouldMoveNonEmptyFile() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createIMAPSite();
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ FileModel fileModel = dataContent.usingSite(testSite).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).usingResource(fileModel).assertThat().existsInRepo()
+ .and().assertThat().existsInImap()
+ .then().moveMessageTo(testFolder).assertThat().containsMessages(fileModel)
+ .and().usingSite(testSite).assertThat().doesNotContainMessages(fileModel);
+ }
+}
diff --git a/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapReadMessagesTests.java b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapReadMessagesTests.java
new file mode 100644
index 00000000000..9419f16216e
--- /dev/null
+++ b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapReadMessagesTests.java
@@ -0,0 +1,180 @@
+package org.alfresco.email.imap;
+
+import org.alfresco.dataprep.CMISUtil;
+import org.alfresco.email.EmailTest;
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.RandomData;
+import org.alfresco.utility.model.*;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import javax.mail.Flags;
+import javax.mail.MessagingException;
+import java.io.IOException;
+
+public class ImapReadMessagesTests extends EmailTest
+{
+ @BeforeClass(alwaysRun=true)
+ public void dataPreparation() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createIMAPSite();
+ adminUser = dataUser.getAdminUser();
+ adminSite = dataSite.usingAdmin().createIMAPSite();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify folders created in repository in other folder via IMAP client by admin user")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void adminShouldGetFoldersCreatedInRepositoryViaImap() throws Exception
+ {
+ testFolder = dataContent.usingAdmin().usingSite(testSite).createFolder();
+ FolderModel testFolder1 = FolderModel.getRandomFolderModel();
+ FolderModel testFolder2 = FolderModel.getRandomFolderModel();
+ imapProtocol.authenticateUser(adminUser).usingSite(adminSite).usingResource(testFolder).createFolder(testFolder1)
+ .and().assertThat().existsInRepo()
+ .and().assertThat().existsInImap()
+ .then().usingResource(testFolder).createFolder(testFolder2).assertThat().existsInRepo()
+ .and().assertThat().existsInImap();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify file and its content are displayed via IMAP client when the file is created by site manager")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void siteManagerShouldGetFileAndItsContentsViaImap() throws Exception
+ {
+ FileModel fileModel = dataContent.usingUser(testUser).usingSite(testSite).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).assertThat().containsMessages(fileModel)
+ .and().usingResource(fileModel).assertThat().existsInRepo()
+ .then().assertThat().fileContentIsDisplayed();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify that file content in IMAP client contains creator, title, description, created date, " +
+ "modifier, modified date, size, three links to content folder, to content url, to download url")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void siteManagerShouldVerifyFileContent() throws Exception
+ {
+ FileModel fileModel = dataContent.usingUser(testUser).usingSite(testSite).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).assertThat().containsMessages(fileModel)
+ .and().usingResource(fileModel).assertThat().existsInRepo()
+ .then().assertThat().messageContentMatchesFileModelData(fileModel);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that the admin user can mark a message as read")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void adminCanMarkMessageAsRead() throws Exception
+ {
+ testFile = dataContent.usingUser(adminUser).usingSite(adminSite).createContent(FileModel.getRandomFileModel(FileType.TEXT_PLAIN));
+ imapProtocol.authenticateUser(adminUser).usingResource(testFile).withMessage().setSeenFlag().updateFlags()
+ .then().assertThat().messageContainsFlags(Flags.Flag.SEEN);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that site manager can see wiki pages via IMAP")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void siteManagerCanViewWikiPages() throws Exception
+ {
+ dataWiki.usingUser(testUser).usingSite(testSite).createRandomWiki();
+ imapProtocol.authenticateUser(testUser).usingSiteWikiContainer(testSite).assertThat().countMessagesIs(1);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that collaborator can see files created by self")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void collaboratorCanViewFileCreatedBySelf() throws Exception
+ {
+ UserModel collaboratorUser = dataUser.createRandomTestUser();
+ dataUser.addUserToSite(collaboratorUser, testSite, UserRole.SiteCollaborator);
+ testFile = dataContent.usingUser(collaboratorUser).usingSite(testSite).createContent(FileModel.getRandomFileModel(FileType.TEXT_PLAIN));
+ imapProtocol.authenticateUser(collaboratorUser).usingSite(testSite).assertThat().containsMessages(testFile);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that contributor can see files created by self")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void contributorCanViewFileCreatedBySelf() throws Exception
+ {
+ UserModel contributorUser = dataUser.createRandomTestUser();
+ dataUser.addUserToSite(contributorUser, testSite, UserRole.SiteContributor);
+ testFile = dataContent.usingUser(contributorUser).usingSite(testSite).createContent(FileModel.getRandomFileModel(FileType.TEXT_PLAIN));
+ imapProtocol.authenticateUser(contributorUser).usingSite(testSite).assertThat().containsMessages(testFile);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify file created with spaces in the name is displayed in IMAP client")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void fileWithSpacesInNameIsDisplayedInImap() throws Exception
+ {
+ testFile = dataContent.usingUser(testUser).usingSite(testSite).createContent(new FileModel("name with spaces.txt", FileType.TEXT_PLAIN));
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).assertThat().containsMessages(testFile);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that a file created with name which contains special characters is visible in IMAP")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL })
+ public void userCanViewFileWithSpecialCharactersInNameViaIMAP() throws Exception
+ {
+ testFile = dataContent.usingUser(testUser).usingSite(testSite).createContent(new FileModel("(a)[b]!#%^.txt", FileType.TEXT_PLAIN));
+ imapProtocol.authenticateUser(testUser)
+ .usingSite(testSite).assertThat().containsMessages(testFile)
+ .usingResource(testFile).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that a file created with name which contains symbols is visible in IMAP")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL })
+ public void userCanViewFileWithSymbolsInNameViaIMAP() throws Exception
+ {
+ testFile = dataContent.usingUser(testUser).usingSite(testSite).createContent(new FileModel("a£¥€$♊♎♏♐♑♒♓Ω.txt", FileType.TEXT_PLAIN));
+ imapProtocol.authenticateUser(testUser)
+ .usingSite(testSite).assertThat().containsMessages(testFile)
+ .usingResource(testFile).assertThat().existsInRepo();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that site manager can see links via IMAP")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL })
+ public void siteManagerCanViewLinks() throws Exception
+ {
+ dataLink.usingUser(testUser).usingSite(testSite).createRandomLink();
+ imapProtocol.authenticateUser(testUser).usingSiteLinksContainer(testSite).assertThat().countMessagesIs(1);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that site manager can see calendar events via IMAP")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL })
+ public void siteManagerCanViewCalendarEvents() throws Exception
+ {
+ dataCalendarEvent.usingUser(testUser).usingSite(testSite).createRandomCalendarEvent();
+ imapProtocol.authenticateUser(testUser).usingSiteCalendarContainer(testSite).assertThat().countMessagesIs(1);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that site manager cannot read file via IMAP if it is already deleted from repository")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL }, expectedExceptions = MessagingException.class,
+ expectedExceptionsMessageRegExp = "No message with subject .* has been found")
+ public void siteManagerCannotReadFileInImapIfItWasDeletedFromRepository() throws Exception
+ {
+ testFile = dataContent.usingUser(testUser).usingSite(testSite)
+ .createContent(new FileModel(RandomData.getRandomName("File"), FileType.TEXT_PLAIN));
+ dataContent.usingUser(testUser).usingSite(testSite).usingResource(testFile).deleteContent();
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).usingResource(testFile).assertThat().fileContentIsDisplayed();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that site manager cannot read file via IMAP client if it is locked by an user in repository")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL }, expectedExceptions = IOException.class,
+ expectedExceptionsMessageRegExp = "No content")
+ public void siteManagerCannotReadFileInImapIfItsLocked() throws Exception
+ {
+ String content = RandomData.getRandomAlphanumeric();
+ testFile = dataContent.usingUser(testUser).usingSite(testSite)
+ .createContent(new FileModel(RandomData.getRandomName("File"), FileType.TEXT_PLAIN, content));
+ dataContent.usingUser(testUser).usingSite(testSite).usingResource(testFile).checkOutDocument();
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).usingResource(testFile).assertThat().fileContentIsDisplayed();
+ }
+}
diff --git a/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapRenameFolderTests.java b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapRenameFolderTests.java
new file mode 100644
index 00000000000..c7f3471c087
--- /dev/null
+++ b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapRenameFolderTests.java
@@ -0,0 +1,361 @@
+package org.alfresco.email.imap;
+
+import javax.mail.FolderNotFoundException;
+
+import org.alfresco.email.EmailTest;
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.RandomData;
+import org.alfresco.utility.exception.TestConfigurationException;
+import org.alfresco.utility.model.FolderModel;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.report.Bug;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class ImapRenameFolderTests extends EmailTest
+{
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ adminUser = dataUser.getAdminUser();
+ testUser = dataUser.createRandomTestUser();
+ adminSite = dataSite.usingAdmin().createIMAPSite();
+ testSite = dataSite.usingUser(testUser).createIMAPSite();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify rename folder by admin user")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void adminShouldRenameFolder() throws Exception
+ {
+ testFolder = dataContent.usingAdmin().usingSite(adminSite).createFolder();
+ String newFolderName = RandomData.getRandomName("Folder");
+ imapProtocol.authenticateUser(adminUser).usingSite(adminSite).usingResource(testFolder).rename(newFolderName)
+ .usingSite(adminSite)
+ .assertThat().contains(new FolderModel(newFolderName))
+ .assertThat().doesNotContain(testFolder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify renaming folder by user with MANAGER role")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void siteManagerShouldRenameFolder() throws Exception
+ {
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ String newFolderName = RandomData.getRandomName("Folder");
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).usingResource(testFolder).rename(newFolderName)
+ .usingSite(testSite)
+ .assertThat().contains(new FolderModel(newFolderName))
+ .assertThat().doesNotContain(testFolder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user with MANAGER role is not able to rename an nonexistent folder")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE }, expectedExceptions = FolderNotFoundException.class)
+ public void siteManagerShouldNotRenameNonExistentFolder() throws Exception
+ {
+ String newFolderName = RandomData.getRandomName("Folder");
+
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).usingResource(FolderModel.getRandomFolderModel())
+ .rename(newFolderName)
+ .assertThat().contains(testFolder)
+ .and().assertThat().doesNotContain(new FolderModel(newFolderName));
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user with MANAGER role is able to rename a folder with long name")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void siteManagerShouldRenameFolderWithLongName() throws Exception
+ {
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ String longName = RandomStringUtils.randomAlphabetic(200);
+
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).usingResource(testFolder)
+ .rename(longName)
+ .usingSite(testSite)
+ .assertThat().contains(new FolderModel(longName))
+ .assertThat().doesNotContain(testFolder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify unauthorized user is not able to rename a folder")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL }, expectedExceptions = FolderNotFoundException.class)
+ public void unauthorizedUserShouldNotRenameFolder() throws Exception
+ {
+ UserModel unauthorizedUser = dataUser.createRandomTestUser();
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+
+ dataSite.usingUser(unauthorizedUser).usingSite(testSite).setIMAPFavorite();
+
+ String newFolderName = RandomData.getRandomName("Folder");
+ imapProtocol.authenticateUser(unauthorizedUser).usingResource(testFolder)
+ .rename(newFolderName)
+ .then().assertThat().doesNotExistInRepo()
+ .assertThat().contains(testFolder)
+ .and().assertThat().doesNotContain(new FolderModel(newFolderName));
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify inexistent user is not able to rename a folder")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE }, expectedExceptions = TestConfigurationException.class,
+ expectedExceptionsMessageRegExp = ".*You missed some configuration settings in your tests: User failed to connect to IMAP server LOGIN failed. Invalid login/password$")
+ public void nonexistentUserShouldNotRenameFolder() throws Exception
+ {
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ String newFolderName = RandomData.getRandomName("Folder");
+
+ imapProtocol.authenticateUser(UserModel.getRandomUserModel()).usingResource(testFolder)
+ .rename(newFolderName)
+ .then().assertThat().doesNotExistInRepo()
+ .and().assertThat().contains(testFolder)
+ .and().assertThat().doesNotContain(new FolderModel(newFolderName));
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify disconnected user is not able to rename a folder")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE }, expectedExceptions = IllegalStateException.class,
+ expectedExceptionsMessageRegExp= "Not connected")
+ public void disconnectedUserShouldNotRenameFolder() throws Exception
+ {
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ String newFolderName = RandomData.getRandomName("Folder");
+
+ imapProtocol.authenticateUser(testUser).usingResource(testFolder).assertThat().existsInImap().then()
+ .disconnect().usingResource(testFolder)
+ .rename(newFolderName)
+ .then().assertThat().doesNotExistInRepo()
+ .and().assertThat().contains(testFolder)
+ .and().assertThat().doesNotContain(new FolderModel(newFolderName));
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify renaming folder by user with COLLABORATOR role - folder created by self")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void collaboratorShouldRenameFolderCreatedBySelf() throws Exception
+ {
+ UserModel collaboratorUser = dataUser.usingAdmin().createRandomTestUser();
+ dataUser.usingUser(testUser).addUserToSite(collaboratorUser, testSite, UserRole.SiteCollaborator);
+
+ dataSite.usingUser(collaboratorUser).usingSite(testSite).setIMAPFavorite();
+
+ testFolder = dataContent.usingUser(collaboratorUser).usingSite(testSite).createFolder();
+ String newFolderName = RandomData.getRandomName("Folder");
+ imapProtocol.authenticateUser(collaboratorUser).usingSite(testSite).usingResource(testFolder)
+ .rename(newFolderName)
+ .usingSite(testSite)
+ .assertThat().contains(new FolderModel(newFolderName))
+ .assertThat().doesNotContain(testFolder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user with COLLABORATOR role is not able to rename a folder created by other user")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void collaboratorShouldNotRenameFolderCreatedByOtherUser() throws Exception
+ {
+ UserModel collaboratorUser = dataUser.usingAdmin().createRandomTestUser();
+ dataUser.usingUser(testUser).addUserToSite(collaboratorUser, testSite, UserRole.SiteCollaborator);
+
+ dataSite.usingUser(collaboratorUser).usingSite(testSite).setIMAPFavorite();
+
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ String newFolderName = RandomData.getRandomName("Folder");
+ imapProtocol.authenticateUser(collaboratorUser).usingResource(testFolder).rename(newFolderName)
+ .usingSite(testSite)
+ .assertThat().contains(testFolder)
+ .assertThat().doesNotContain(new FolderModel(newFolderName));
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user with CONTRIBUTOR role is able to rename a folder created by self")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void contributorShouldRenameFolderCreatedBySelf() throws Exception
+ {
+ UserModel contributorUser = dataUser.usingAdmin().createRandomTestUser();
+ dataUser.usingUser(testUser).addUserToSite(contributorUser, testSite, UserRole.SiteContributor);
+
+ dataSite.usingUser(contributorUser).usingSite(testSite).setIMAPFavorite();
+
+ testFolder = dataContent.usingUser(contributorUser).usingSite(testSite).createFolder();
+ String newFolderName = RandomData.getRandomName("Folder");
+ imapProtocol.authenticateUser(contributorUser).usingSite(testSite).usingResource(testFolder)
+ .rename(newFolderName)
+ .usingSite(testSite)
+ .assertThat().contains(new FolderModel(newFolderName))
+ .assertThat().doesNotContain(testFolder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user with CONTRIBUTOR role is NOT able to rename a folder created by other user")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void contributorShouldNotRenameFolderCreatedByOtherUser() throws Exception
+ {
+ UserModel contributorUser = dataUser.usingAdmin().createRandomTestUser();
+ dataUser.usingUser(testUser).addUserToSite(contributorUser, testSite, UserRole.SiteContributor);
+
+ dataSite.usingUser(contributorUser).usingSite(testSite).setIMAPFavorite();
+
+ FolderModel testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ String newFolderName = RandomData.getRandomName("Folder");
+ imapProtocol.authenticateUser(contributorUser).usingSite(testSite).usingResource(testFolder)
+ .rename(newFolderName).usingSite(testSite).then().assertThat().contains(testFolder)
+ .and().assertThat().doesNotContain(new FolderModel(newFolderName));
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user with CONSUMER role is not able to rename a folder created by other user")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL })
+ public void consumerShouldNotRenameFolderCreatedByOtherUser() throws Exception
+ {
+ UserModel consumer = dataUser.createRandomTestUser();
+ dataUser.usingUser(testUser).addUserToSite(consumer, testSite, UserRole.SiteConsumer);
+
+ dataSite.usingUser(consumer).usingSite(testSite).setIMAPFavorite();
+
+ FolderModel testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ String newFolderName = RandomData.getRandomName("Folder");
+ imapProtocol.authenticateUser(consumer).usingSite(testSite).usingResource(testFolder)
+ .rename(newFolderName).usingSite(testSite).then()
+ .assertThat().contains(testFolder)
+ .and().assertThat().doesNotContain(new FolderModel(newFolderName));
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify renaming folder fails when it was deleted by another user")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL }, expectedExceptions = FolderNotFoundException.class)
+ public void userCannotRenameFolderDeletedByAnotherUser() throws Exception
+ {
+ UserModel contributorUser = dataUser.usingAdmin().createRandomTestUser();
+ dataUser.usingUser(testUser).addUserToSite(contributorUser, testSite, UserRole.SiteContributor);
+ FolderModel testFolder = FolderModel.getRandomFolderModel();
+
+ dataSite.usingUser(contributorUser).usingSite(testSite).setIMAPFavorite();
+ imapProtocol.authenticateUser(contributorUser).usingSite(testSite).createFolder(testFolder)
+ .assertThat().existsInRepo()
+ .assertThat().existsInImap()
+ .delete().disconnect();
+
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).usingResource(testFolder).rename("deletedFolderRename");
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user can rename folder to a name that contains white spaces")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL })
+ public void userCanRenameFolderToAFolderThatContainsWhiteSpaces() throws Exception
+ {
+ FolderModel testFolder = FolderModel.getRandomFolderModel();
+
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder)
+ .and()
+ .assertThat().existsInRepo()
+ .assertThat().existsInImap()
+ .rename("folder with name that contains spaces")
+ .then().usingSite(testSite)
+ .assertThat().contains(new FolderModel("folder with name that contains spaces"))
+ .assertThat().doesNotContain(testFolder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user can rename folder successfully with name that contains special characters")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL })
+ public void userCanRenameFolderWithSpecialCharacters() throws Exception
+ {
+ FolderModel testFolder = FolderModel.getRandomFolderModel();
+
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder)
+ .and()
+ .assertThat().existsInRepo()
+ .assertThat().existsInImap()
+ .rename("(a)[b]!#%^")
+ .then().usingSite(testSite)
+ .assertThat().contains(new FolderModel("(a)[b]!#%^"))
+ .assertThat().doesNotContain(testFolder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user can rename folder successfully with name that contains symbols")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL })
+ public void userCanRenameFolderWithSymbols() throws Exception
+ {
+ FolderModel testFolder = FolderModel.getRandomFolderModel();
+
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder)
+ .and()
+ .assertThat().existsInRepo()
+ .assertThat().existsInImap()
+ .rename("a£¥€$♊♎ ♏ ♐ ♑ ♒ ♓")
+ .then().usingSite(testSite)
+ .assertThat().contains(new FolderModel("a£¥€$♊♎ ♏ ♐ ♑ ♒ ♓"))
+ .assertThat().doesNotContain(testFolder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user cannot create folder with name omegaΩ_<>./?")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL })
+ public void userCannotRenameFolderWithNameThatContainsRestrictedCharacters() throws Exception
+ {
+ FolderModel testFolder = FolderModel.getRandomFolderModel();
+
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder)
+ .and()
+ .assertThat().existsInRepo()
+ .assertThat().existsInImap()
+ .rename("omegaΩ_<>./?")
+ .then().usingSite(testSite)
+ .assertThat().contains(testFolder)
+ .assertThat().doesNotContain(new FolderModel("omegaΩ_<>./?"));
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify renaming folder fails when it was renamed by another user")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL }, expectedExceptions = FolderNotFoundException.class)
+ public void userCannotRenameFolderRenamedByAnotherUser() throws Exception
+ {
+ UserModel contributorUser = dataUser.usingAdmin().createRandomTestUser();
+ dataUser.usingUser(testUser).addUserToSite(contributorUser, testSite, UserRole.SiteContributor);
+ FolderModel testFolder = FolderModel.getRandomFolderModel();
+
+ dataSite.usingUser(contributorUser).usingSite(testSite).setIMAPFavorite();
+ imapProtocol.authenticateUser(contributorUser).usingSite(testSite).createFolder(testFolder)
+ .assertThat().existsInRepo()
+ .assertThat().existsInImap()
+ .rename("folderRenamedByUser").disconnect();
+
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).usingResource(testFolder).rename("deletedFolderRename");
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify a site folder cannot be renamed via IMAP client")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL })
+ public void verifyASiteFolderCannotBeRenamedViaImap() throws Exception
+ {
+ SiteModel siteModel = dataSite.usingUser(testUser).createIMAPSite();
+
+ imapProtocol.authenticateUser(testUser).usingSiteRoot(siteModel).rename("new site name")
+ .and()
+ .assertThat().doesNotExistInRepo()
+ .then().usingSites()
+ .assertThat().doesNotContain(new FolderModel("new site name"));
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify renaming folder by changing the case")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL })
+ public void verifyFolderCanBeRenamedByChangingTheCase() throws Exception
+ {
+ FolderModel testFolder = FolderModel.getRandomFolderModel();
+
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).createFolder(testFolder)
+ .and()
+ .assertThat().existsInRepo()
+ .assertThat().existsInImap()
+ .rename(testFolder.getName().toUpperCase())
+ .then().usingSite(testSite)
+ .assertThat().contains(new FolderModel(testFolder.getName().toUpperCase()))
+ .assertThat().doesNotContain(testFolder);
+ }
+}
diff --git a/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapRenameMessagesTests.java b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapRenameMessagesTests.java
new file mode 100644
index 00000000000..55e3384f1fc
--- /dev/null
+++ b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapRenameMessagesTests.java
@@ -0,0 +1,34 @@
+package org.alfresco.email.imap;
+
+import org.alfresco.dataprep.CMISUtil;
+import org.alfresco.email.EmailTest;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class ImapRenameMessagesTests extends EmailTest
+{
+ @BeforeClass(alwaysRun=true)
+ public void dataPreparation() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createIMAPSite();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify the renamed file from repository is still preset in IMAP client with the old name for site manager")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void siteManagerShouldVerifyFileContentForRenamedFileViaImap() throws Exception
+ {
+ testFile = dataContent.usingUser(testUser).usingSite(testSite).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
+ FileModel renamedFile = testFile;
+ renamedFile.setName(FileModel.getRandomFileModel(FileType.TEXT_PLAIN).getName());
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).usingResource(testFile).assertThat().existsInRepo()
+ .and().assertThat().existsInImap()
+ .then().renameMessageTo(renamedFile).assertThat().messageContentMatchesFileModelData(testFile);
+ }
+}
diff --git a/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapSearchMessagesTests.java b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapSearchMessagesTests.java
new file mode 100644
index 00000000000..dd743909498
--- /dev/null
+++ b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapSearchMessagesTests.java
@@ -0,0 +1,118 @@
+package org.alfresco.email.imap;
+
+import org.alfresco.email.EmailTest;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.testng.annotations.Test;
+
+/**
+ * Tests for Search for Messages in IMAP client
+ *
+ * @author Cristina Axinte
+ *
+ */
+public class ImapSearchMessagesTests extends EmailTest
+{
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify that no results are returned when searching for a message name term with no match")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void noResultsReturnedWhenSearchingForNotExistingMessage() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createIMAPSite();
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ String fileName1="File-new1";
+ FileModel fileModel1 = dataContent.usingUser(testUser).usingSite(testSite).usingResource(testFolder)
+ .createContent(new FileModel(fileName1, fileName1, fileName1 + "description", FileType.TEXT_PLAIN, fileName1 + "content"));
+ String fileName2="File2";
+ FileModel fileModel2 = dataContent.usingUser(testUser).usingSite(testSite).usingResource(testFolder)
+ .createContent(new FileModel(fileName2, fileName2, fileName2 + "description", FileType.TEXT_PLAIN, fileName2 + "content"));
+
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).usingResource(testFolder)
+ .searchSubjectFor("new").assertThat().resultsContainMessage(fileModel1)
+ .assertThat().resultsDoNotContainMessage(fileModel2);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.SANITY,
+ description = "Verify that searched message is returned when searching for full message name")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.SANITY })
+ public void searchedMessageIsReturnedWhenSearchingForFullMessageName() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createIMAPSite();
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ String fileName1="File-new1";
+ FileModel fileModel1 = dataContent.usingUser(testUser).usingSite(testSite).usingResource(testFolder)
+ .createContent(new FileModel(fileName1, fileName1, fileName1 + "description", FileType.TEXT_PLAIN, fileName1 + "content"));
+ String fileName2="File2";
+ FileModel fileModel2 = dataContent.usingUser(testUser).usingSite(testSite).usingResource(testFolder)
+ .createContent(new FileModel(fileName2, fileName2, fileName2 + "description", FileType.TEXT_PLAIN, fileName2 + "content"));
+
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).usingResource(testFolder)
+ .searchSubjectFor("File2").assertThat().resultsContainMessage(fileModel2)
+ .assertThat().resultsDoNotContainMessage(fileModel1);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that search results are returned for search term containing white spaces")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void siteManagerVerifySearchResultsForWhiteSpaces() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createIMAPSite();
+ String fileName1="File new";
+ FileModel fileModel1 = dataContent.usingUser(testUser).usingSite(testSite)
+ .createContent(new FileModel(fileName1, fileName1, fileName1 + "description", FileType.TEXT_PLAIN, fileName1 + "content"));
+ String fileName2="File new1";
+ FileModel fileModel2 = dataContent.usingSite(testSite)
+ .createContent(new FileModel(fileName2, fileName2, fileName2 + "description", FileType.TEXT_PLAIN, fileName2 + "content"));
+
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).searchSubjectFor("File new")
+ .assertThat().resultsContainMessage(fileModel1, fileModel2);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that search results are returned for search term containing wildcards")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void siteManagerVerifySearchResultsForWildcards() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createIMAPSite();
+ String fileName1="File new 1";
+ FileModel fileModel1 = dataContent.usingUser(testUser).usingSite(testSite)
+ .createContent(new FileModel(fileName1, fileName1, fileName1 + "description", FileType.TEXT_PLAIN, fileName1 + "content"));
+ String fileName2="File presentation 2";
+ FileModel fileModel2 = dataContent.usingSite(testSite)
+ .createContent(new FileModel(fileName2, fileName2, fileName2 + "description", FileType.TEXT_PLAIN, fileName2 + "content"));
+
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).searchSubjectWithWildcardsFor("File.*1.*")
+ .assertThat().resultsContainMessage(fileModel1)
+ .assertThat().resultsDoNotContainMessage(fileModel2);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that search results are returned for search term containing special characters")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void siteManagerVerifySearchResultsForSpecialCharacters() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createIMAPSite();
+ String fileName1="File@#$%^&()-_=+-[]{};'";
+ FileModel fileModel1 = dataContent.usingUser(testUser).usingSite(testSite)
+ .createContent(new FileModel(fileName1, fileName1, fileName1 + "description", FileType.TEXT_PLAIN, fileName1 + "content"));
+ String fileName2="File";
+ FileModel fileModel2 = dataContent.usingSite(testSite)
+ .createContent(new FileModel(fileName2, fileName2, fileName2 + "description", FileType.TEXT_PLAIN, fileName2 + "content"));
+
+ imapProtocol.authenticateUser(testUser).usingSite(testSite)
+ .searchSubjectFor("=").assertThat().resultsContainMessage(fileModel1).assertThat().resultsDoNotContainMessage(fileModel2)
+ .searchSubjectFor("@").assertThat().resultsContainMessage(fileModel1).assertThat().resultsDoNotContainMessage(fileModel2)
+ .searchSubjectFor("#").assertThat().resultsContainMessage(fileModel1).assertThat().resultsDoNotContainMessage(fileModel2)
+ .searchSubjectFor("$").assertThat().resultsContainMessage(fileModel1).assertThat().resultsDoNotContainMessage(fileModel2)
+ .searchSubjectFor("@#").assertThat().resultsContainMessage(fileModel1).assertThat().resultsDoNotContainMessage(fileModel2)
+ .searchSubjectFor("[]").assertThat().resultsContainMessage(fileModel1).assertThat().resultsDoNotContainMessage(fileModel2);
+ }
+}
diff --git a/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapSitesTests.java b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapSitesTests.java
new file mode 100644
index 00000000000..6522185eabd
--- /dev/null
+++ b/packaging/tests/tas-email/src/test/java/org/alfresco/email/imap/ImapSitesTests.java
@@ -0,0 +1,81 @@
+package org.alfresco.email.imap;
+
+import org.alfresco.email.EmailTest;
+import org.alfresco.utility.model.FolderModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import javax.mail.FolderNotFoundException;
+import javax.mail.MessagingException;
+
+public class ImapSitesTests extends EmailTest
+{
+ @BeforeClass(alwaysRun=true)
+ public void dataPreparation() throws Exception
+ {
+ testUser = dataUser.createRandomTestUser();
+ testSite = dataSite.usingUser(testUser).createIMAPSite();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that site manager can unsubscribe from a folder")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void siteManagerCanUnSubscribeFromAFolder() throws Exception
+ {
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).assertThat().isSubscribed()
+ .usingResource(testFolder).assertThat().isSubscribed()
+ .unsubscribe().assertThat().isNotSubscribed()
+ .usingSite(testSite).assertThat().isSubscribed();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that site manager is subscribed to folders created by self")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE })
+ public void siteManagerIsSubscribedToFoldersCreatedBySelf() throws Exception
+ {
+ testFolder = new FolderModel("newFolder");
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).assertThat().isSubscribed()
+ .createFolder(testFolder).assertThat().existsInRepo().assertThat().existsInImap()
+ .assertThat().isSubscribed();
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that operations on a private site are not permitted")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE }, expectedExceptions = MessagingException.class,
+ expectedExceptionsMessageRegExp = ".* Access Denied.*You do not have the appropriate permissions to perform this operation.*")
+ public void verifyOperationsOnPrivateSiteAreNotPermitted() throws Exception
+ {
+ adminUser = dataUser.getAdminUser();
+ adminSite = dataSite.usingAdmin().createPrivateRandomSite();
+ testFolder = dataContent.usingAdmin().usingSite(adminSite).createFolder();
+ dataSite.usingUser(testUser).usingSite(testSite).setIMAPFavorite();
+ imapProtocol.authenticateUser(testUser).usingSite(adminSite).assertThat().contains(testFolder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that operations on a moderated site are not permitted")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.CORE }, expectedExceptions = FolderNotFoundException.class)
+ public void verifyOperationsOnModeratedSiteAreNotPermitted() throws Exception
+ {
+ adminUser = dataUser.getAdminUser();
+ adminSite = dataSite.usingAdmin().createModeratedRandomSite();
+ testFolder = dataContent.usingAdmin().usingSite(adminSite).createFolder();
+ dataSite.usingUser(testUser).usingSite(testSite).setIMAPFavorite();
+ imapProtocol.authenticateUser(testUser).usingSite(adminSite).assertThat().contains(testFolder);
+ }
+
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.IMAP }, executionType = ExecutionType.REGRESSION,
+ description = "Verify site cannot be accessed in IMAP client if it is no longer an IMAP site or marked as IMAP favorite")
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.IMAP, TestGroup.FULL }, expectedExceptions = FolderNotFoundException.class)
+ public void userCannotAccessSiteThatIsNoLongerAnImapSiteOrMarkedAsImapFavorite() throws Exception
+ {
+ testFolder = dataContent.usingUser(testUser).usingSite(testSite).createFolder();
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).assertThat().contains(testFolder);
+ dataSite.usingUser(testUser).usingSite(testSite).unsetIMAPFavorite();
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).assertThat().contains(testFolder);
+ }
+}
diff --git a/packaging/tests/tas-email/src/test/resources/alfresco-email-context.xml b/packaging/tests/tas-email/src/test/resources/alfresco-email-context.xml
new file mode 100644
index 00000000000..d6a5817e9c4
--- /dev/null
+++ b/packaging/tests/tas-email/src/test/resources/alfresco-email-context.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packaging/tests/tas-email/src/test/resources/default.properties b/packaging/tests/tas-email/src/test/resources/default.properties
new file mode 100644
index 00000000000..6dd13d4b3da
--- /dev/null
+++ b/packaging/tests/tas-email/src/test/resources/default.properties
@@ -0,0 +1,97 @@
+# dataprep related
+alfresco.scheme=http
+alfresco.server=localhost
+alfresco.port=8082
+
+# credentials
+admin.user=admin
+admin.password=admin
+
+# in containers we cannot access directly JMX, so we will use http://jolokia.org agent
+# disabling this we will use direct JMX calls to server
+jmx.useJolokiaAgent=false
+
+# Server Health section
+# in ServerHealth#isServerReachable() - could also be shown.
+# enable this option to view if on server there are tenants or not
+serverHealth.showTenants=true
+
+# IMAP Service settings from admin console
+imap.server=${alfresco.server}
+imap.port=143
+imaps.port=993
+
+# Inbound Email settings from admin console
+smtp.server=${alfresco.server}
+smtp.port=25
+smtp.authentication.enabled=true
+smtp.tsl.enabled=false
+
+# Outbound Email settings from admin console
+mail.encoding=UTF-8
+mail.from.default=alfresco.cloud@gmail.com
+mail.from.enabled=true
+mail.host=smtp.gmail.com
+mail.password=eiWei6vieiWei6vieiWei6vieiWei6vi
+mail.port=465
+mail.protocol=smtps
+mail.smtp.auth=true
+mail.smtp.debug=false
+mail.smtp.starttls.enable=true
+mail.smtp.timeout=30000
+mail.smtps.auth=true
+mail.smtps.starttls.enable=true
+mail.username=alfresco.cloud@gmail.com
+
+# TEST MANAGEMENT SECTION - Test Rail
+#
+# (currently supporting Test Rail v5.2.1.3472 integration)
+#
+# Example of configuration:
+# ------------------------------------------------------
+# if testManagement.enabled=true we enabled TestRailExecutorListener (if used in your suite xml file)
+# testManagement.updateTestExecutionResultsOnly=true (this will just update the results of a test: no step will be updated - good for performance)
+# testManagement.endPoint=https://alfresco.testrail.com/
+# testManagement.username=
+# testManagement.apiKey=
+# testManagement.project=
+# testManagement.includeOnlyTestCasesExecuted=true #if you want to include in your run ONLY the test cases that you run, then set this value to false
+# testManagement.rateLimitInSeconds=1 #is the default rate limit after what minimum time, should we upload the next request. http://docs.gurock.com/testrail-api2/introduction #Rate Limit
+# testManagement.suiteId=23 (the id of the Master suite)
+# ------------------------------------------------------
+testManagement.enabled=false
+testManagement.endPoint=
+testManagement.username=
+testManagement.apiKey=
+testManagement.project=7
+testManagement.includeOnlyTestCasesExecuted=true
+testManagement.rateLimitInSeconds=1
+testManagement.testRun=MyTestRunInTestRail
+testManagement.suiteId=12
+
+# The location of the reports path
+reports.path=./target/reports
+
+#
+# Database Section
+# You should provide here the database URL, that can be a differed server as alfresco.
+# https://docs.oracle.com/javase/tutorial/jdbc/basics/connecting.html
+#
+# Current supported db.url:
+#
+# MySQL:
+# db.url = jdbc:mysql://${alfresco.server}:3306/alfresco
+#
+# PostgreSQL:
+# db.url = jdbc:postgresql://:3306/alfresco
+#
+# Oracle:
+# db.url = jdbc:oracle://:3306/alfresco
+#
+# MariaDB:
+# db.url = jdbc:mariadb://:3306/alfresco
+#
+db.url = jdbc:mysql://${alfresco.server}:3306/alfresco
+db.username = alfresco
+db.password = alfresco
diff --git a/packaging/tests/tas-email/src/test/resources/email-suite.xml b/packaging/tests/tas-email/src/test/resources/email-suite.xml
new file mode 100644
index 00000000000..ecb87f6d2d9
--- /dev/null
+++ b/packaging/tests/tas-email/src/test/resources/email-suite.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packaging/tests/tas-email/src/test/resources/log4j.properties b/packaging/tests/tas-email/src/test/resources/log4j.properties
new file mode 100644
index 00000000000..00e9b5a114e
--- /dev/null
+++ b/packaging/tests/tas-email/src/test/resources/log4j.properties
@@ -0,0 +1,26 @@
+# Root logger option
+log4j.rootLogger=INFO, file, stdout
+
+# Direct log messages to a log file
+log4j.appender.file=org.apache.log4j.RollingFileAppender
+log4j.appender.file.File=./target/reports/alfresco-tas.log
+log4j.appender.file.MaxBackupIndex=10
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+log4j.appender.file.layout.ConversionPattern=[%t] %d{HH:mm:ss} %-5p %c{1}:%L - %m%n
+
+# Direct log messages to stdout
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=[%t] %d{HH:mm:ss} %-5p %c{1}:%L - %m%n
+
+# TestRail particular log file
+# Direct log messages to a log file
+log4j.appender.testrailLog=org.apache.log4j.RollingFileAppender
+log4j.appender.testrailLog.File=./target/reports/alfresco-testrail.log
+log4j.appender.testrailLog.MaxBackupIndex=10
+log4j.appender.testrailLog.layout=org.apache.log4j.PatternLayout
+log4j.appender.testrailLog.layout.ConversionPattern=%d{HH:mm:ss} %-5p %c{1}:%L - %m%n
+
+log4j.category.testrail=INFO, testrailLog
+log4j.additivity.testrail=false
\ No newline at end of file
diff --git a/packaging/tests/tas-email/src/test/resources/shared-resources/email-runner-suite.xml b/packaging/tests/tas-email/src/test/resources/shared-resources/email-runner-suite.xml
new file mode 100644
index 00000000000..0ff426e2c8b
--- /dev/null
+++ b/packaging/tests/tas-email/src/test/resources/shared-resources/email-runner-suite.xml
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packaging/tests/tas-email/src/test/resources/shared-resources/email-sanity-suite.xml b/packaging/tests/tas-email/src/test/resources/shared-resources/email-sanity-suite.xml
new file mode 100644
index 00000000000..d8831e31310
--- /dev/null
+++ b/packaging/tests/tas-email/src/test/resources/shared-resources/email-sanity-suite.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packaging/tests/tas-email/src/test/resources/shared-resources/email-suites.xml b/packaging/tests/tas-email/src/test/resources/shared-resources/email-suites.xml
new file mode 100644
index 00000000000..0afc400acc4
--- /dev/null
+++ b/packaging/tests/tas-email/src/test/resources/shared-resources/email-suites.xml
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packaging/tests/tas-email/src/test/resources/shared-resources/tas-email-sanity-suite.xml b/packaging/tests/tas-email/src/test/resources/shared-resources/tas-email-sanity-suite.xml
new file mode 100644
index 00000000000..e900cfb97d1
--- /dev/null
+++ b/packaging/tests/tas-email/src/test/resources/shared-resources/tas-email-sanity-suite.xml
@@ -0,0 +1,143 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packaging/tests/tas-email/src/test/resources/shared-resources/testCount.xml b/packaging/tests/tas-email/src/test/resources/shared-resources/testCount.xml
new file mode 100644
index 00000000000..2e0aaaac54e
--- /dev/null
+++ b/packaging/tests/tas-email/src/test/resources/shared-resources/testCount.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packaging/tests/tas-email/src/test/resources/shared-resources/testdata/imap-input-data.xml b/packaging/tests/tas-email/src/test/resources/shared-resources/testdata/imap-input-data.xml
new file mode 100644
index 00000000000..53bf3f49555
--- /dev/null
+++ b/packaging/tests/tas-email/src/test/resources/shared-resources/testdata/imap-input-data.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ /Sites/site1/documentLibrary
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packaging/tests/tas-email/src/test/resources/shared-resources/testdata/imap-resource b/packaging/tests/tas-email/src/test/resources/shared-resources/testdata/imap-resource
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/packaging/tests/tas-integration/pom.xml b/packaging/tests/tas-integration/pom.xml
new file mode 100644
index 00000000000..5eaa878833d
--- /dev/null
+++ b/packaging/tests/tas-integration/pom.xml
@@ -0,0 +1,134 @@
+
+
+ 4.0.0
+ org.alfresco.tas
+ content-repository-community-integration-test
+ content-repository-community-integration-test
+ 6.2.2-SNAPSHOT
+ jar
+
+
+ org.alfresco
+ content-repository-community-tas-tests-parent
+ 6.2.2-SNAPSHOT
+ ../pom.xml
+
+
+
+
+ Paul Brodner
+
+ Test Automation Architect
+
+
+
+
+
+ ${project.basedir}/src/test/resources/integration-suite.xml
+ 2.5.9
+ 1.6.2
+
+
+
+
+ org.alfresco.tas
+ utility
+ test
+
+
+
+ io.rest-assured
+ rest-assured
+ test
+
+
+
+ javax.mail
+ javax.mail-api
+ ${dependency.javax.mail.version}
+ test
+
+
+
+ com.sun.mail
+ javax.mail
+ ${dependency.javax.mail.version}
+
+
+
+ org.codehaus.groovy
+ groovy
+ ${dependency.groovy.version}
+
+
+
+
+ org.alfresco.tas
+ ftp
+ test
+
+
+
+
+ org.alfresco.tas
+ restapi
+ test
+
+
+
+
+ org.alfresco.tas
+ cmis
+ test
+
+
+
+
+ org.alfresco.tas
+ email
+ test
+
+
+
+
+ org.alfresco.tas
+ webdav
+ test
+
+
+
+ com.jayway.jsonpath
+ json-path
+ 2.4.0
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ ${suiteXmlFile}
+
+
+ --illegal-access=warn
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+
+ test-jar
+
+
+
+
+
+
+
diff --git a/packaging/tests/tas-integration/src/test/java/org/alfresco/tas/integration/IntegrationCoreTests.java b/packaging/tests/tas-integration/src/test/java/org/alfresco/tas/integration/IntegrationCoreTests.java
new file mode 100644
index 00000000000..7f211292c14
--- /dev/null
+++ b/packaging/tests/tas-integration/src/test/java/org/alfresco/tas/integration/IntegrationCoreTests.java
@@ -0,0 +1,1494 @@
+package org.alfresco.tas.integration;
+
+import static org.alfresco.utility.report.log.Step.STEP;
+
+import javax.mail.FolderNotFoundException;
+
+import org.alfresco.rest.model.RestCommentModel;
+import org.alfresco.rest.model.RestDeploymentModel;
+import org.alfresco.rest.model.RestDeploymentModelsCollection;
+import org.alfresco.rest.model.RestErrorModel;
+import org.alfresco.rest.model.RestPersonFavoritesModel;
+import org.alfresco.rest.model.RestPersonFavoritesModelsCollection;
+import org.alfresco.rest.model.RestRatingModel;
+import org.alfresco.utility.Utility;
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.RandomData;
+import org.alfresco.utility.model.*;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.springframework.http.HttpStatus;
+import org.testng.annotations.Test;
+
+import junit.framework.Assert;
+
+/**
+ * Created by Claudia Agache on 12/13/2016.
+ */
+public class IntegrationCoreTests extends IntegrationTest
+{
+ UserModel testUser1, testUser2;
+ SiteModel testSitePublic, testSiteModerated, testSitePrivate, secondPublicSite;
+ FolderModel testFolder1, testFolder2, parentFolder1;
+ private String renamePrefix = "edited-";
+ FileModel testFile1, testFile2, childDoc1, childDoc2, childDoc3, childDoc4, childDoc5;
+ RestRatingModel returnedRatingModel;
+ RestPersonFavoritesModel restPersonFavoritesModel;
+ private String newContent = "new TAS content";
+
+ /**
+ * Scenario 22
+ * 1. Using CMIS create 2 test users: u1 and u2
+ * 2. U1 creates a public test site and U2 a public test site using CMIS
+ * 3. U1 creates a folder with a file in his public site's document library using WebDav
+ * 4. U1 tries to move his folder to U2 public site using IMAP
+ * 5. Verify folder with file is not moved. U1 is not authorized to access the public site
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.CORE }, expectedExceptions = FolderNotFoundException.class)
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user is not able to move a folder with a file to a public site if he is not a member of that site.")
+ public void moveFolderWithFileToPublicSiteByUninvitedUser() throws Exception
+ {
+ STEP("1. Using CMIS create 2 test users: u1 and u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates a public test site and U2 a public test site using CMIS");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+ secondPublicSite = dataSite.usingUser(testUser2).createIMAPSite();
+
+ STEP("3. U1 creates a folder with a file in public site's document library using WebDav");
+ testFolder1 = FolderModel.getRandomFolderModel();
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ webDavProtocol.authenticateUser(testUser1).usingSite(testSitePublic)
+ .createFolder(testFolder1).assertThat().existsInWebdav()
+ .usingResource(testFolder1).createFile(testFile1).assertThat().existsInRepo();
+
+ STEP("4. U1 tries to move his folder to U2 public site using IMAP. 5. Verify folder with file is not moved. U1 is not authorized to access the U2 public site");
+ FolderModel destination = new FolderModel(Utility.buildPath("Sites", secondPublicSite.getId(), "documentLibrary"));
+ destination.setProtocolLocation(imapProtocol.authenticateUser(testUser2).usingSite(secondPublicSite).getLastResourceWithoutPrefix());
+ imapProtocol.authenticateUser(testUser1)
+ .usingResource(testFolder1).moveTo(destination)
+ .assertThat().doesNotExistInRepo();
+ }
+
+ /**
+ * Scenario 23
+ * 1. Using CMIS create 1 test user: u1
+ * 2. U1 creates a public test site
+ * 3. U1 creates a folder (parentFolder) inside public site's document library using WebDav
+ * 4. Inside parentFolder create 4 files using CMIS, WebDAV, FTP
+ * 5. Inside parentFolder create 1 subfolder using IMAP
+ * 6. Delete parentFolder using CMIS
+ * 7. Verify folder is deleted along with all its children
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.CORE })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user is able to delete parent folder along with all its children using CMIS.")
+ public void deleteFolderWithChildrenUsingCMIS() throws Exception
+ {
+ STEP("1. Using CMIS create 1 test user: u1");
+ testUser1 = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates a public test site using CMIS");
+ testSitePublic = dataSite.usingUser(testUser1).createIMAPSite();
+
+ STEP("3. U1 creates a folder (parentFolder) inside public site's document library using WebDav");
+ FolderModel parentFolder = FolderModel.getRandomFolderModel();
+ webDavProtocol.authenticateUser(testUser1)
+ .usingSite(testSitePublic).createFolder(parentFolder)
+ .assertThat().existsInWebdav()
+ .and().assertThat().existsInRepo();
+
+ STEP("4. Inside parentFolder create 4 files using CMIS, WebDAV, FTP");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ FileModel testFile2 = FileModel.getRandomFileModel(FileType.MSWORD);
+ FileModel testFile3 = FileModel.getRandomFileModel(FileType.HTML);
+ FileModel testFile4 = FileModel.getRandomFileModel(FileType.EXE);
+ cmisAPI.authenticateUser(testUser1).usingResource(parentFolder)
+ .createFile(testFile1).assertThat().existsInRepo();
+ webDavProtocol.usingResource(parentFolder).createFile(testFile2)
+ .assertThat().existsInWebdav().and()
+ .assertThat().existsInRepo();
+ cmisAPI.authenticateUser(testUser1).usingResource(parentFolder).createFile(testFile3)
+ .assertThat().existsInRepo();
+ ftpProtocol.authenticateUser(testUser1).usingResource(parentFolder).createFile(testFile4)
+ .assertThat().existsInFtp().and()
+ .assertThat().existsInRepo();
+
+ STEP("5. Inside parentFolder create 1 subfolder using IMAP");
+ testFolder1 = FolderModel.getRandomFolderModel();
+ imapProtocol.authenticateUser(testUser1)
+ .usingResource(parentFolder).createFolder(testFolder1)
+ .assertThat().existsInImap().and()
+ .assertThat().existsInRepo();
+
+ STEP("6. Delete parentFolder using CMIS 7. Verify folder is deleted along with all its children");
+ cmisAPI.usingResource(parentFolder).deleteFolderTree().and().assertThat().doesNotExistInRepo()
+ .usingResource(testFolder1).assertThat().doesNotExistInRepo()
+ .usingResource(testFile1).assertThat().doesNotExistInRepo()
+ .usingResource(testFile2).assertThat().doesNotExistInRepo()
+ .usingResource(testFile3).assertThat().doesNotExistInRepo()
+ .usingResource(testFile4).assertThat().doesNotExistInRepo();
+ }
+
+ /**
+ * Scenario 24
+ * 1. Using CMIS create 1 test user: u1
+ * 2. U1 creates a public test site
+ * 3. U1 creates a folder (parentFolder) inside public site's document library using IMAP
+ * 4. Inside parentFolder create 4 files using CMIS, WebDAV, FTP
+ * 5. Inside parentFolder create 1 subfolder using WebDAV
+ * 6. Delete parentFolder using WebDAV
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.CORE })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user is able to delete parent folder along with all its children using WebDAV.")
+ public void deleteFolderWithChildrenUsingWebDAV() throws Exception
+ {
+ STEP("1. Using CMIS create 1 test user: u1");
+ testUser1 = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates a public test site using CMIS");
+ testSitePublic = dataSite.usingUser(testUser1).createIMAPSite();
+
+ STEP("3. U1 creates a folder (parentFolder) inside public site's document library using IMAP");
+ FolderModel parentFolder = FolderModel.getRandomFolderModel();
+ imapProtocol.authenticateUser(testUser1)
+ .usingSite(testSitePublic).createFolder(parentFolder)
+ .assertThat().existsInImap().and()
+ .assertThat().existsInRepo();
+
+ STEP("4. Inside parentFolder create 4 files using CMIS, WebDAV, FTP");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ FileModel testFile2 = FileModel.getRandomFileModel(FileType.MSWORD);
+ FileModel testFile3 = FileModel.getRandomFileModel(FileType.HTML);
+ FileModel testFile4 = FileModel.getRandomFileModel(FileType.EXE);
+ cmisAPI.authenticateUser(testUser1).usingResource(parentFolder)
+ .createFile(testFile1).assertThat().existsInRepo();
+ webDavProtocol.authenticateUser(testUser1).usingResource(parentFolder).createFile(testFile2)
+ .assertThat().existsInWebdav().and()
+ .assertThat().existsInRepo();
+ ftpProtocol.authenticateUser(testUser1).usingResource(parentFolder).createFile(testFile4)
+ .assertThat().existsInFtp().and()
+ .assertThat().existsInRepo();
+
+ STEP("5. Inside parentFolder create 1 subfolder using WebDAV");
+ testFolder1 = FolderModel.getRandomFolderModel();
+ webDavProtocol.usingResource(parentFolder).createFolder(testFolder1)
+ .assertThat().existsInWebdav()
+ .and().assertThat().existsInRepo();
+
+ STEP("6. Delete parentFolder using WebDAV 7. Verify folder is deleted along with all its children");
+ webDavProtocol.usingResource(parentFolder).delete().and().assertThat().doesNotExistInRepo()
+ .usingResource(testFolder1).assertThat().doesNotExistInRepo()
+ .usingResource(testFile1).assertThat().doesNotExistInRepo()
+ .usingResource(testFile2).assertThat().doesNotExistInRepo()
+ .usingResource(testFile3).assertThat().doesNotExistInRepo()
+ .usingResource(testFile4).assertThat().doesNotExistInRepo();
+ }
+
+ /**
+ * Scenario 25
+ * 1. Using CMIS create 2 test users: u1 and u2
+ * 2. U1 creates a public test site and adds u2 as manager to his site using CMIS
+ * 3. U1 creates a folder (parentFolder) inside public site's document library using CMIS
+ * 4. U1 creates a subfolder1 and a file1 inside parentFolder using FTP
+ * 5. U1 creates a subfolder2 and a file2 inside subfolder1 using CMIS
+ * 6. U2 creates a subfolder3 and a file3 using WebDAV
+ * 7. U2 deletes parentFolder using FTP
+ * 8. Verify folder is deleted along with all its children
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.CORE})
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user is able to delete parent folder along with all its children using FTP.")
+ public void deleteFolderWithChildrenUsingFTP() throws Exception
+ {
+ STEP("1. Using CMIS create 2 test users: u1 and u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates a public test site using CMIS and adds u2 as manager to his site using REST");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+ dataUser.usingUser(testUser1).addUserToSite(testUser2, testSitePublic, UserRole.SiteManager);
+ testUser2.setUserRole(UserRole.SiteManager);
+
+ STEP("3. U1 creates a folder (parentFolder) inside public site's document library using CMIS");
+ FolderModel parentFolder = FolderModel.getRandomFolderModel();
+ cmisAPI.authenticateUser(testUser1)
+ .usingSite(testSitePublic).createFolder(parentFolder)
+ .assertThat().existsInRepo();
+
+ STEP("4. U1 creates a subfolder1 and a file1 inside parentFolder using FTP");
+ FolderModel subFolder1 = FolderModel.getRandomFolderModel();
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+
+ ftpProtocol.authenticateUser(testUser1)
+ .usingResource(parentFolder).createFolder(subFolder1)
+ .assertThat().existsInRepo()
+ .assertThat().existsInFtp()
+ .usingResource(parentFolder).createFile(testFile1)
+ .assertThat().existsInRepo()
+ .assertThat().existsInFtp();
+
+ STEP("5. U1 creates a subfolder2 and a file2 inside subfolder1 using CMIS");
+ FolderModel subFolder2 = FolderModel.getRandomFolderModel();
+ FileModel testFile2 = FileModel.getRandomFileModel(FileType.MSWORD);
+
+ cmisAPI.authenticateUser(testUser1).usingResource(subFolder1)
+ .createFolder(subFolder2)
+ .assertThat().existsInRepo()
+ .createFile(testFile2)
+ .assertThat().existsInRepo();
+
+ STEP("6. U2 creates a subfolder3 and a file3 using WebDAV");
+ FolderModel subFolder3 = FolderModel.getRandomFolderModel();
+ FileModel testFile3 = FileModel.getRandomFileModel(FileType.HTML);
+
+ webDavProtocol.authenticateUser(testUser2).usingResource(subFolder2)
+ .createFolder(subFolder3)
+ .assertThat().existsInWebdav()
+ .assertThat().existsInRepo()
+ .createFile(testFile3)
+ .assertThat().existsInWebdav()
+ .assertThat().existsInRepo();
+
+ STEP("7. U2 deletes parentFolder using FTP");
+ ftpProtocol.authenticateUser(testUser2)
+ .usingResource(parentFolder).assertThat().existsInFtp()
+ .then().delete()
+ .assertThat().doesNotExistInRepo().and()
+ .assertThat().doesNotExistInFtp()
+ .usingResource(subFolder1)
+ .assertThat().doesNotExistInRepo().and()
+ .assertThat().doesNotExistInFtp()
+ .usingResource(subFolder2)
+ .assertThat().doesNotExistInRepo().and()
+ .assertThat().doesNotExistInFtp()
+ .usingResource(subFolder3)
+ .assertThat().doesNotExistInRepo().and()
+ .assertThat().doesNotExistInFtp()
+ .usingResource(testFile1)
+ .assertThat().doesNotExistInRepo().and()
+ .assertThat().doesNotExistInFtp()
+ .usingResource(testFile2)
+ .assertThat().doesNotExistInRepo().and()
+ .assertThat().doesNotExistInFtp()
+ .usingResource(testFile3)
+ .assertThat().doesNotExistInRepo().and()
+ .assertThat().doesNotExistInFtp();
+ }
+
+ /**
+ * Scenario 28
+ * 1. Using CMIS create one test user: U1
+ * 2. Using CMIS U1 creates a public test site
+ * 3. Using CMIS, WebDAV and FTP U1 creates multiple files and folders in parent folder
+ * 4. Using CMIS, U1 checks out a document from parent folder
+ * 5. Using CMIS, U1 deletes parent folder (deleteTree)
+ * 6. Using WebDAV, U1 verifies that parent folder and all children are NOT present in Repo and WebDAV
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.CORE})
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION, description = "Verify deletion of a parentFolder with checkedout file using CMIS.")
+ public void deleteParentFolderWithCheckoutFileInUsingCMIS() throws Exception
+ {
+ STEP("1. Using CMIS create one test user: U1");
+ testUser1 = dataUser.createRandomTestUser();
+
+ STEP("2. Using CMIS U1 creates a public test site");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("3. Using CMIS, WebDAV and FTP U1 creates multiple files and folders in parent folder");
+ FileModel cmisTestFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file 1 content");
+ FileModel webdavTestFile = FileModel.getRandomFileModel(FileType.HTML, "file 2 content");
+ FileModel ftpTestFile = FileModel.getRandomFileModel(FileType.MSWORD, "file 4 content");
+
+ testFolder1 = FolderModel.getRandomFolderModel();
+ cmisAPI.authenticateUser(testUser1).usingSite(testSitePublic).createFolder(testFolder1).assertThat().existsInRepo();
+ cmisAPI.authenticateUser(testUser1).usingResource(testFolder1).createFile(cmisTestFile)
+ .assertThat().existsInRepo();
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFolder1).createFile(webdavTestFile)
+ .assertThat().existsInWebdav().assertThat().existsInRepo();
+ ftpProtocol.authenticateUser(testUser1).usingResource(testFolder1).createFile(ftpTestFile)
+ .assertThat().existsInFtp().assertThat().existsInRepo();
+
+ FolderModel cmisTestFolder = FolderModel.getRandomFolderModel();
+ FolderModel webdavTestFolder = FolderModel.getRandomFolderModel();
+ FolderModel ftpTestFolder = FolderModel.getRandomFolderModel();
+
+ cmisAPI.usingResource(testFolder1).createFolder(cmisTestFolder)
+ .assertThat().existsInRepo();
+ webDavProtocol.usingResource(testFolder1).createFolder(webdavTestFolder)
+ .assertThat().existsInWebdav().assertThat().existsInRepo();
+ ftpProtocol.usingResource(testFolder1).createFolder(ftpTestFolder)
+ .assertThat().existsInFtp().assertThat().existsInRepo();
+
+ cmisAPI.usingResource(testFolder1).assertThat()
+ .hasChildren(cmisTestFile, webdavTestFile, ftpTestFile, cmisTestFolder, webdavTestFolder, ftpTestFolder);
+
+ STEP("Step 4: Using CMIS, U1 checks out a document from parent folder");
+ cmisAPI.usingResource(webdavTestFile).checkOut().assertThat().documentIsCheckedOut();
+
+ STEP("Step 5: Using CMIS, U1 deletes parent folder (deleteTree)");
+
+ cmisAPI.usingResource(testFolder1).deleteFolderTree()
+ .assertThat().doesNotExistInRepo();
+ STEP("Step 6. Using WebDAV, U1 verifies that parent folder and all children are not present");
+ webDavProtocol.usingResource(testFolder1).assertThat().doesNotExistInRepo().assertThat().doesNotExistInWebdav()
+ .and().usingResource(cmisTestFile).assertThat().doesNotExistInRepo().assertThat().doesNotExistInWebdav()
+ .and().usingResource(webdavTestFile).assertThat().doesNotExistInRepo().assertThat().doesNotExistInWebdav()
+ .and().usingResource(ftpTestFile).assertThat().doesNotExistInRepo().assertThat().doesNotExistInWebdav()
+ .and().usingResource(cmisTestFolder).assertThat().doesNotExistInRepo().assertThat().doesNotExistInWebdav()
+ .and().usingResource(webdavTestFolder).assertThat().doesNotExistInRepo().assertThat().doesNotExistInWebdav()
+ .and().usingResource(ftpTestFolder).assertThat().doesNotExistInRepo().assertThat().doesNotExistInWebdav();
+ }
+
+ /**
+ * Scenario 29
+ * 1. Using CMIS create one test user: U1
+ * 2. Using CMIS U1 creates a public test site
+ * 3. Using FTP U1 creates a parent folder in public site's document library
+ * 4. Using CMIS, WebDAV and FTP U1 creates multiple files and folders in parent folder
+ * 5. Using CMIS, U1 checks out a document from parent folder
+ * 6. Using WebDAV, U1 deletes parent folder (deleteFolder)
+ * 7. Using FTP, U1 verifies that parent folder and all children are NOT present in Repo and FTP
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.CORE})
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION, description = "Verify deletion of a parentFolder with checkedout file using WebDAV.")
+ public void deleteParentFolderWithCheckoutFileInUsingWebDAV() throws Exception
+ {
+ STEP("1. Using CMIS create one test user: U1");
+ testUser1 = dataUser.createRandomTestUser();
+
+ STEP("2. Using CMIS U1 creates a public test site");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("3. Using FTP U1 creates a parent folder");
+ testFolder1 = FolderModel.getRandomFolderModel();
+ ftpProtocol.authenticateUser(testUser1).usingSite(testSitePublic).createFolder(testFolder1).assertThat().existsInRepo();
+
+ STEP("4. Using CMIS, WebDAV and FTP U1 creates multiple files and folders in parent folder");
+ FileModel cmisTestFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file 1 content");
+ FileModel webdavTestFile = FileModel.getRandomFileModel(FileType.HTML, "file 2 content");
+ FileModel ftpTestFile = FileModel.getRandomFileModel(FileType.MSWORD, "file 4 content");
+
+ cmisAPI.authenticateUser(testUser1).usingResource(testFolder1).createFile(cmisTestFile)
+ .assertThat().existsInRepo();
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFolder1).createFile(webdavTestFile)
+ .assertThat().existsInWebdav().assertThat().existsInRepo();
+ ftpProtocol.usingResource(testFolder1).createFile(ftpTestFile)
+ .assertThat().existsInFtp().assertThat().existsInRepo();
+
+ FolderModel cmisTestFolder = FolderModel.getRandomFolderModel();
+ FolderModel webdavTestFolder = FolderModel.getRandomFolderModel();
+
+ cmisAPI.usingResource(testFolder1).createFolder(cmisTestFolder)
+ .assertThat().existsInRepo();
+ webDavProtocol.usingResource(testFolder1).createFolder(webdavTestFolder).assertThat().existsInWebdav()
+ .and().assertThat().existsInRepo();
+
+ cmisAPI.usingResource(testFolder1).assertThat().hasChildren(cmisTestFile, webdavTestFile, ftpTestFile, cmisTestFolder, webdavTestFolder);
+
+ STEP("Step 5: Using CMIS, U1 checks out a document from parent folder");
+ cmisAPI.usingResource(cmisTestFile).checkOut().assertThat().documentIsCheckedOut();
+
+ STEP("Step 6: Using WebDAV, U1 deletes parent folder (deleteFolder)");
+ webDavProtocol.usingResource(testFolder1).assertThat().existsInRepo().and().assertThat().existsInWebdav()
+ .and().assertThat().hasFiles(cmisTestFile, webdavTestFile, ftpTestFile)
+ .and().assertThat().hasFolders(cmisTestFolder, webdavTestFolder)
+ .then().usingResource(testFolder1).delete()
+ .assertThat().doesNotExistInWebdav().assertThat().doesNotExistInRepo();
+
+ STEP("Step 7. Using FTP, U1 verifies that parent folder and all children are not present");
+ ftpProtocol.usingResource(testFolder1).assertThat().doesNotExistInRepo().assertThat().doesNotExistInFtp()
+ .and().usingResource(cmisTestFile).assertThat().doesNotExistInRepo().assertThat().doesNotExistInFtp()
+ .and().usingResource(webdavTestFile).assertThat().doesNotExistInRepo().assertThat().doesNotExistInFtp()
+ .and().usingResource(ftpTestFile).assertThat().doesNotExistInRepo().assertThat().doesNotExistInFtp()
+ .and().usingResource(cmisTestFolder).assertThat().doesNotExistInRepo().assertThat().doesNotExistInFtp()
+ .and().usingResource(webdavTestFolder).assertThat().doesNotExistInRepo().assertThat().doesNotExistInFtp();
+ }
+
+ /**
+ * Scenario 30
+ * 1. Using CMIS create one test user: U1
+ * 2. Using CMIS U1 creates a public test site
+ * 3. Using WebDAV U1 creates a parent folder in public site's document library
+ * 4. Using CMIS, WebDAV and FTP U1 creates multiple files and folders in parent folder
+ * 5. Using CMIS, U1 checks out a document from parent folder
+ * 6. Using FTP, U1 deletes parent folder (deleteDirectory)
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.CORE})
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT}, executionType = ExecutionType.REGRESSION, description = "Verify deletion of a parentFolder with checkedout file using FTP.")
+ public void deleteParentFolderWithCheckoutFileInUsingFTP() throws Exception
+ {
+ STEP("1. Using CMIS create one test user: U1");
+ testUser1 = dataUser.createRandomTestUser();
+
+ STEP("2. Using CMIS U1 creates a public test site");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("3. Using WebDAV U1 creates a parent folder");
+ testFolder1 = FolderModel.getRandomFolderModel();
+ webDavProtocol.authenticateUser(testUser1).usingSite(testSitePublic).createFolder(testFolder1).assertThat().existsInRepo().assertThat()
+ .existsInWebdav();
+
+ STEP("4. Using CMIS, WebDAV and FTP U1 creates multiple files and folders in parent folder");
+ FileModel cmisTestFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file 1 content");
+ FileModel webdavTestFile = FileModel.getRandomFileModel(FileType.HTML, "file 2 content");
+
+ cmisAPI.authenticateUser(testUser1).usingResource(testFolder1).createFile(cmisTestFile)
+ .assertThat().existsInRepo();
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFolder1).createFile(webdavTestFile)
+ .assertThat().existsInWebdav().assertThat().existsInRepo();
+
+ FolderModel cmisTestFolder = FolderModel.getRandomFolderModel();
+ FolderModel webdavTestFolder = FolderModel.getRandomFolderModel();
+ FolderModel ftpTestFolder = FolderModel.getRandomFolderModel();
+
+ cmisAPI.usingResource(testFolder1).createFolder(cmisTestFolder)
+ .assertThat().existsInRepo();
+ webDavProtocol.usingResource(testFolder1).createFolder(webdavTestFolder)
+ .assertThat().existsInWebdav().assertThat().existsInRepo();
+ ftpProtocol.authenticateUser(testUser1).usingResource(testFolder1).createFolder(ftpTestFolder)
+ .assertThat().existsInFtp().assertThat().existsInRepo();
+
+ cmisAPI.usingResource(testFolder1).assertThat()
+ .hasChildren(cmisTestFile, webdavTestFile, cmisTestFolder, webdavTestFolder, ftpTestFolder);
+
+ STEP("Step 5: Using CMIS, U1 checks out a document from parent folder");
+ cmisAPI.usingResource(webdavTestFile).checkOut().assertThat().documentIsCheckedOut();
+
+ STEP("Step 6: Using FTP, U1 deletes parent folder (deleteDirectory)");
+ ftpProtocol.usingResource(testFolder1).delete()
+ .and().assertThat().doesNotExistInFtp().and().assertThat().doesNotExistInRepo();
+ }
+
+ /**
+ * Scenario 32 - Document updates
+ *
+ * 1. Using CMIS create 2 test users: U1 and U2
+ * 2. Using CMIS and RestAPI U1 creates a public test site and U2 user is added with collaborator role
+ * 3. Using WebDAV U1 creates a folder in his public site's document library
+ * 4. Using WebDAV U1 creates a document inside the above folder
+ * 5. Using RestAPI U2 adds the document to favorites
+ * 6. Using CMIS U1 adds content to document
+ * 7. Using WebDAV U2 validates document's content
+ * 8. Using WebDAV U2 updates content from document
+ * 9. Using CMIS U2 validates document's content
+ * 10. Using WebDAV U1 deletes the file
+ * 11. Using RestAPI U1 deletes the folder
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.CORE })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user with collaborator role can update document content in a public site.")
+ public void usersCanUpdateDocumentContentInsideAPublicSite() throws Exception
+ {
+ String originalContent = "originalContent";
+ String updatedContent = "updatedContent";
+ testFolder1 = FolderModel.getRandomFolderModel();
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+
+ STEP("1. Using CMIS create 2 test users: U1 and U2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("2. Using CMIS and RestAPI U1 creates a public test site and U2 user is added with collaborator role");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+ testUser2.setUserRole(UserRole.SiteCollaborator);
+ restAPI.authenticateUser(testUser1).withCoreAPI().usingSite(testSitePublic).addPerson(testUser2);
+
+ STEP("3. Using WebDAV U1 creates a folder in his public site's document library");
+ webDavProtocol.authenticateUser(testUser1).usingSite(testSitePublic).createFolder(testFolder1)
+ .and().assertThat().existsInRepo();
+
+ STEP("4. Using WebDAV U1 creates a document inside the above folder");
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFolder1).createFile(testFile1)
+ .and().assertThat().existsInWebdav()
+ .and().assertThat().existsInRepo();
+
+ STEP("5. Using RestAPI U2 adds the document to favorites");
+ restAPI.authenticateUser(testUser2).withCoreAPI().usingAuthUser().addFolderToFavorites(testFolder1);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("6. Using CMIS U1 adds content to document");
+ cmisAPI.authenticateUser(testUser1).usingResource(testFile1)
+ .and().assertThat().existsInRepo()
+ .and().update(originalContent);
+
+ STEP("7. Using WebDAV U2 validates document's content");
+ webDavProtocol.authenticateUser(testUser2).usingResource(testFile1).assertThat().contentIs(originalContent);
+
+ STEP("8. Using WebDAV U2 updates content from document");
+ webDavProtocol.usingUser(testUser2).usingResource(testFile1)
+ .assertThat().existsInRepo()
+ .and().update(updatedContent);
+
+ STEP("9. Using CMIS U2 validates document's content");
+ cmisAPI.authenticateUser(testUser2).usingResource(testFile1).assertThat().contentIs(updatedContent);
+
+ STEP("10. Using WebDAV U1 deletes the file");
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFile1).delete()
+ .and().assertThat().doesNotExistInRepo();
+
+ STEP("11. Using WebDAV U1 deletes the folder");
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFolder1).delete()
+ .and().assertThat().doesNotExistInRepo();
+ }
+
+ /**
+ * Scenario 33 - Document likes
+ *
+ * 1. Using CMIS create 2 test users: U1 and U2
+ * 2. Using RestAPI U1 creates a public test site and U2 user is added with contributor role
+ * 3. Using WebDAV U1 creates a folder in his public site's document library
+ * 4. Using WebDAV U1 creates a document1 inside the above folder
+ * 5. Using WebDAV U2 creates a document2 inside folder
+ * 6. Using RestAPI U2 likes document1
+ * 7. Using RestAPI U1 likes document2
+ * 8. Using RestAPI U1 dislikes document2
+ * 9. Using RestAPI U2 add to favorites document1
+ * 10. Using CMIS U1 delete document1
+ * 11. Using CMIS U2 delete the folder
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.CORE }, expectedExceptions = {CmisPermissionDeniedException.class, CmisUnauthorizedException.class} )
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user with contributor role can like/favorite a document in a public site.")
+ public void usersCanLikeADocumentInPublicSite() throws Exception
+ {
+ STEP("1. Using CMIS create 2 test users: U1 and U2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("2. Using RestAPI U1 creates a public test site and U2 user is added with contributor role");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+ testUser2.setUserRole(UserRole.SiteContributor);
+ restAPI.authenticateUser(testUser1).withCoreAPI().usingSite(testSitePublic).addPerson(testUser2);
+
+ STEP("3. Using WebDAV U1 creates a folder in his public site's document library");
+ testFolder1 = FolderModel.getRandomFolderModel();
+ webDavProtocol.authenticateUser(testUser1).usingSite(testSitePublic)
+ .createFolder(testFolder1).assertThat().existsInWebdav()
+ .and().assertThat().existsInRepo();
+
+ STEP("4. Using WebDAV U1 creates a document1 inside the above folder");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ webDavProtocol.usingResource(testFolder1).createFile(testFile1)
+ .assertThat().existsInRepo()
+ .and().assertThat().existsInWebdav();
+
+ STEP("5. Using WebDAV U2 creates a document2 inside folder");
+ testFile2 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ webDavProtocol.authenticateUser(testUser2)
+ .usingResource(testFolder1).createFile(testFile2).assertThat().existsInRepo()
+ .and().assertThat().existsInWebdav();
+
+ STEP("6. Using RestAPI U2 likes document1");
+ RestRatingModel returnedRatingModel = restAPI.authenticateUser(testUser2).withCoreAPI().usingResource(testFile1).likeDocument();
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ returnedRatingModel.assertThat().field("myRating").is("true")
+ .and().field("id").is("likes").and().field("aggregate").isNotEmpty();
+
+ STEP("7. Using RestAPI U1 likes document2");
+ returnedRatingModel = restAPI.authenticateUser(testUser1).withCoreAPI().usingResource(testFile2).likeDocument();
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ returnedRatingModel.assertThat().field("myRating").is("true")
+ .and().field("id").is("likes").and().field("aggregate").isNotEmpty();
+
+ STEP("8. Using RestAPI U1 dislikes document2");
+ restAPI.authenticateUser(testUser1).withCoreAPI().usingResource(testFile2).deleteLikeRating();
+ restAPI.assertStatusCodeIs(HttpStatus.NO_CONTENT);
+
+ STEP("9. Using RestAPI U2 add to favorites document1");
+ RestPersonFavoritesModel restPersonFavoritesModel = restAPI.authenticateUser(testUser2).withCoreAPI().usingAuthUser().addFileToFavorites(testFile1);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ restPersonFavoritesModel.assertThat().field("targetGuid").is(testFile1.getNodeRefWithoutVersion());
+
+ STEP("10. Using CMIS U1 delete document1");
+ cmisAPI.authenticateUser(testUser1).usingResource(testFile1).delete()
+ .and().assertThat().doesNotExistInRepo();
+
+ restAPI.withCoreAPI().usingResource(testFile1).getLikeRating();
+ restAPI.assertStatusCodeIs(HttpStatus.NOT_FOUND).assertLastError()
+ .containsSummary(String.format(RestErrorModel.ENTITY_NOT_FOUND, testFile1.getNodeRef()));
+
+ RestPersonFavoritesModelsCollection userFavorites = restAPI.withCoreAPI().usingAuthUser().getFavorites();
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ userFavorites.assertThat().entriesListIsEmpty().and().paginationField("totalItems").is("0");
+
+ STEP("11. Using CMIS U2 delete the folder. With Contributor role, U2 does not have permission to delete files/folders created by others.");
+ cmisAPI.authenticateUser(testUser2).usingResource(testFolder1).assertThat().doesNotHaveFile(testFile1)
+ .and().assertThat().hasFiles(testFile2)
+ .and().usingResource(testFile2).delete()
+ .and().usingResource(testFolder1).delete();
+ }
+
+ /**
+ * Scenario 34 - Document ratings
+ *
+ * 1. Using CMIS create 2 test users: U1 and U2
+ * 2. Using RestAPI U1 creates a public test site and U2 user is added with collaborator role
+ * 3. Using CMIS U1 creates a new folder in site
+ * 4. Using WebDAV U2 creates file1 in public site document library
+ * 5. Using WebDAV U1 creates a file2 in public site document library
+ * 6. Using RestAPI U2 rates with 5 stars file2
+ * 7. Using RestAPI U1 rates with 1 star file1
+ * 8. Using RestAPI U2 likes file1
+ * 9. Using RestAPI U2 removes the rating of 5 stars for file2
+ * 10. Using WebDAV U1 delete file1. Using RestAPI get ratings of file1.
+ * 11. Using WebDAV U1 delete the folder
+ */
+
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.CORE })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user with collaborator role can rate a document in a public site.")
+ public void usersCanRateADocumentInPublicSite() throws Exception
+ {
+ RestRatingModel returnedRatingModel;
+
+ STEP("1. Using CMIS create 2 test users: U1 and U2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("2. Using RestAPI U1 creates a public test site and U2 user is added with collaborator role");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+ testUser2.setUserRole(UserRole.SiteCollaborator);
+ restAPI.authenticateUser(testUser1).withCoreAPI().usingSite(testSitePublic).addPerson(testUser2);
+
+ STEP("3. Using CMIS U1 creates a new folder in site");
+ testFolder1 = FolderModel.getRandomFolderModel();
+ cmisAPI.authenticateUser(testUser1).usingSite(testSitePublic)
+ .createFolder(testFolder1).assertThat().existsInRepo();
+
+ STEP("4. Using WebDAV U2 creates file1 in public site document library");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ webDavProtocol.authenticateUser(testUser2).usingResource(testFolder1)
+ .createFile(testFile1).assertThat().existsInRepo()
+ .and().assertThat().existsInWebdav();
+
+ STEP("5. Using WebDAV U1 creates a file2 in public site document library");
+ testFile2 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ webDavProtocol.authenticateUser(testUser1).usingSite(testSitePublic)
+ .usingResource(testFolder1).createFile(testFile2).assertThat().existsInRepo();
+
+ STEP("6. Using RestAPI U2 rates with 5 stars file2");
+ returnedRatingModel = restAPI.authenticateUser(testUser2).withCoreAPI().usingResource(testFile2)
+ .rateStarsToDocument(5);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ returnedRatingModel.assertThat().field("myRating").is("5").and().field("id").is("fiveStar").and().field("aggregate").isNotEmpty();
+
+ STEP("7. Using RestAPI U1 rates with 1 star file1");
+ returnedRatingModel = restAPI.authenticateUser(testUser1).withCoreAPI().usingResource(testFile1)
+ .rateStarsToDocument(1);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ returnedRatingModel.assertThat().field("myRating").is("1").and().field("id").is("fiveStar").and().field("aggregate").isNotEmpty();
+
+ STEP("8. Using RestAPI U2 likes file1");
+ returnedRatingModel = restAPI.authenticateUser(testUser2).withCoreAPI().usingResource(testFile1)
+ .likeDocument();
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ returnedRatingModel.assertThat().field("myRating").is("true").and().field("id").is("likes").and().field("aggregate").isNotEmpty();
+
+ STEP("9. Using RestAPI U2 removes the rating of 5 stars for file2");
+ restAPI.authenticateUser(testUser2).withCoreAPI().usingResource(testFile2).deleteFiveStarRating();
+ restAPI.assertStatusCodeIs(HttpStatus.NO_CONTENT);
+
+ returnedRatingModel = restAPI.withCoreAPI().usingResource(testFile2).getFiveStarRating();
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ returnedRatingModel.getAggregate().assertThat().field("numberOfRatings").is("0");
+
+ STEP("10. Using WebDAV U1 delete file1. Using RestAPI get ratings of file1.");
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFile1).delete()
+ .and().assertThat().doesNotExistInRepo()
+ .and().assertThat().doesNotExistInWebdav();
+
+ restAPI.withCoreAPI().usingResource(testFile1).getLikeRating();
+ restAPI.assertStatusCodeIs(HttpStatus.NOT_FOUND).assertLastError()
+ .containsSummary(String.format(RestErrorModel.ENTITY_NOT_FOUND, testFile1.getNodeRef()));
+
+ restAPI.withCoreAPI().usingResource(testFile1).getFiveStarRating();
+ restAPI.assertStatusCodeIs(HttpStatus.NOT_FOUND).assertLastError()
+ .containsSummary(String.format(RestErrorModel.ENTITY_NOT_FOUND, testFile1.getNodeRef()));
+
+ STEP("11. Using WebDAV U1 delete the folder");
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFolder1).assertThat().hasFiles(testFile2)
+ .and().usingResource(testFolder1).delete()
+ .and().assertThat().doesNotExistInRepo();
+ }
+
+ /**
+ * Scenario 35
+ * 1. Using CMIS create 2 test user: U1 and U2
+ * 2. Using CMIS U1 creates a public test site
+ * 3. Using FTP U1 creates a folder in public site's document library: folder1
+ * 4. Using WebDAV U1 creates inside folder1 a new folder: folder2
+ * 5. Using WebDAV U1 creates inside folder2 a new folder: folder3
+ * 6. Using CMIS U1 creates inside folder1 a new file: file1
+ * 7. Using WebDAV U1 creates inside folder2 a new file: file2
+ * 8. Using FTP U1 creates inside folder3 a new file: file3
+ * 9. Using WebDAV U1 deletes file1
+ * 10. Using IMAP U1 deletes file2
+ * 11. Using WebDAV U1 updates content of file3
+ * 12. Using RestAPI U1 adds a comment to file3
+ * 13. Using RestAPI U1 likes file3 and user U2 rates file3
+ * 14. Using CMIS U1 deletes file3
+ */
+
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.CORE })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "File handling - perform actions: create, delete, add comment, like and rate, update file content ")
+ public void fileHandlingCreateUpdateContentDeleteLikeAndRate() throws Exception
+ {
+ STEP("1. Using CMIS create 1 test user: U1 and U2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates a public test site using CMIS");
+ testSitePublic = dataSite.usingUser(testUser1).createIMAPSite();
+
+ STEP("3. Using FTP U1 creates folder: folder1");
+ FolderModel folder1 = FolderModel.getRandomFolderModel();
+ ftpProtocol.authenticateUser(testUser1).usingSite(testSitePublic).createFolder(folder1)
+ .assertThat().existsInRepo();
+
+ STEP("4. Using WebDAV U1 creates folder2 inside folder1");
+ FolderModel folder2 = FolderModel.getRandomFolderModel();
+ webDavProtocol.authenticateUser(testUser1).usingResource(folder1).createFolder(folder2);
+
+ STEP("5. Using webDAV U1 creates folder3 inside folder2");
+ FolderModel folder3 = FolderModel.getRandomFolderModel();
+ webDavProtocol.authenticateUser(testUser1).usingResource(folder2).createFolder(folder3);
+
+ STEP("6. Using CMIS U1 creates file1 inside folder1");
+ FileModel file1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file 1 content");
+ cmisAPI.authenticateUser(testUser1).usingResource(folder1).createFile(file1)
+ .assertThat().existsInRepo();
+
+ STEP("7. Using webDAV U1 creates file2 inside folder2");
+ FileModel file2 = FileModel.getRandomFileModel(FileType.HTML, "file 2 content");
+ webDavProtocol.authenticateUser(testUser1).usingResource(folder2).createFile(file2)
+ .assertThat().existsInWebdav().assertThat().existsInRepo();
+
+ STEP("8. Using FTP U1 creates file3 inside folder3");
+ FileModel file3 = FileModel.getRandomFileModel(FileType.MSWORD, "file 3 content");
+ ftpProtocol.authenticateUser(testUser1).usingResource(folder3).createFile(file3)
+ .assertThat().existsInRepo();
+
+ STEP("9. Using webDAV U1 deletes file1");
+ webDavProtocol.authenticateUser(testUser1).usingResource(file1).delete()
+ .assertThat().doesNotExistInRepo().and().assertThat().doesNotExistInWebdav();
+
+ STEP("10. Using IMAP U1 deletes file2");
+ imapProtocol.authenticateUser(testUser1).usingResource(file2).deleteMessage()
+ .and().usingResource(file2).assertThat().doesNotExistInRepo();
+
+ STEP("11. Using WebDAV U1 update content of file3");
+ webDavProtocol.authenticateUser(testUser1)
+ .usingResource(file3).assertThat().existsInRepo()
+ .update(newContent).assertThat().contentIs(newContent);
+
+ STEP("12. Using RestAPI U1 adds a comment to file3");
+ String comment = RandomData.getRandomName("comment1");
+ file3.setNodeRef(dataContent.usingUser(testUser1).usingSite(testSitePublic)
+ .usingResource(folder3).usingResource(file3).getNodeRef());
+ RestCommentModel commentModel = restAPI.authenticateUser(testUser1).withCoreAPI()
+ .usingResource(file3).addComment(comment);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+ commentModel.assertThat().field("content").isNotEmpty()
+ .and().field("content").is(comment);
+
+ STEP("13. Using RestAPI U1 likes file3 and user U2 rates file3");
+ returnedRatingModel = restAPI.authenticateUser(testUser1).withCoreAPI().usingResource(file3).likeDocument();
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+ returnedRatingModel.assertThat().field("myRating").is("true").and().field("id").is("likes").and().field("aggregate").isNotEmpty();
+
+ returnedRatingModel = restAPI.authenticateUser(testUser2).withCoreAPI()
+ .usingResource(file3).rateStarsToDocument(5);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+ returnedRatingModel.assertThat().field("myRating").is("5").and().field("id").is("fiveStar").and().field("aggregate").isNotEmpty();
+
+ STEP("14. Using CMIS U1 deletes file3");
+ cmisAPI.authenticateUser(testUser1).usingResource(file3).delete()
+ .assertThat().doesNotExistInRepo();
+ }
+
+ /**
+ * Scenario 37
+ * 1. Using CMIS creates 2 users: U1 and U
+ * 2. U1 creates a public test site using CMIS
+ * 3. Using CMIS U1 creates folder: folder1
+ * 4. Using WebDAV U1 creates folder2 and folder3 inside folder1
+ * 5. Using FTP U1 creates file1 inside folder1
+ * 6. Using CMIS U1 copies file1 to folder2
+ * 7. Using WebDAV U1 update content of file1 from folder2
+ * 8. Using FTP U1 tries to move file1 from folder2 to folder1
+ * 9. Using WebDAV U1 updates content of file1 from folder1
+ * 10. Using RestAPI U1 adds file1 to favorites
+ * 11. Using RestAPI U1 likes file1 and U2 user rates file1
+ * 12. Using CMIS U1 moves file1 from folder1 to folder3
+ * 13. Using CMIS/RestAPI U1 checks that content, favorites and ratings are kept
+ */
+
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.CORE })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "File handling - perform actions: copy, move, add/update content, favorites, like and rate")
+ public void fileHandlingCopyMoveAddUpdateContentFavoritesLikeAndRate() throws Exception
+ {
+ STEP("1. Using CMIS creates 2 users: U1 and U2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates a public test site using CMIS");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("3. Using CMIS U1 creates folder: folder1");
+ FolderModel folder1 = FolderModel.getRandomFolderModel();
+ cmisAPI.authenticateUser(testUser1).usingSite(testSitePublic).createFolder(folder1)
+ .assertThat().existsInRepo();
+
+ STEP("4. Using WebDAV U1 creates folder2 and folder3 inside folder1");
+ FolderModel folder2 = FolderModel.getRandomFolderModel();
+ FolderModel folder3 = FolderModel.getRandomFolderModel();
+ webDavProtocol.authenticateUser(testUser1)
+ .usingResource(folder1).createFolder(folder2).and().assertThat().existsInWebdav()
+ .usingResource(folder1).createFolder(folder3).and().assertThat().existsInWebdav();
+
+ STEP("5. Using FTP U1 creates file1 inside folder1");
+ FileModel file1 = FileModel.getRandomFileModel(FileType.MSWORD2007, "tasTesting");
+ ftpProtocol.authenticateUser(testUser1).usingResource(folder1).createFile(file1)
+ .assertThat().existsInRepo();
+
+ STEP("6. Using CMIS U1 copies file1 to folder2");
+ FileModel copiedFile = new FileModel(file1);
+ cmisAPI.authenticateUser(testUser1).usingResource(file1).copyTo(folder2);
+ copiedFile.setCmisLocation(cmisAPI.getLastResource());
+ cmisAPI.usingResource(folder2).assertThat().hasFiles(file1);
+
+ STEP("7. Using WebDAV U1 update content of file1 from folder2");
+ webDavProtocol.usingResource(copiedFile).assertThat().existsInRepo()
+ .update(newContent).assertThat().contentIs(newContent);
+
+ STEP("8. Using FTP U1 tries to move file1 from folder2 to folder1");
+ ftpProtocol.authenticateUser(testUser1)
+ .usingResource(copiedFile).moveTo(folder1).assertThat().existsInRepo();
+ Assert.assertTrue(ftpProtocol.usingResource(folder1).getFiles().size() == 1);
+
+ STEP("9. Using WebDAV U1 updates content of file1 from folder1");
+ webDavProtocol.usingResource(file1).update("content folder1")
+ .assertThat().contentIs("content folder1");
+
+ STEP("10. Using RestAPI U1 adds file1 to favorites");
+ file1.setNodeRef(dataContent.usingUser(testUser1).usingSite(testSitePublic)
+ .usingResource(folder1).usingResource(file1).getNodeRef());
+
+ restPersonFavoritesModel = restAPI.authenticateUser(testUser1).withCoreAPI()
+ .usingAuthUser().addFileToFavorites(file1);
+ restAPI.assertStatusCodeIs(org.springframework.http.HttpStatus.CREATED);
+ restPersonFavoritesModel.assertThat().field("targetGuid").is(file1.getNodeRefWithoutVersion());
+
+ STEP("11. Using RestAPI U1 likes file1 and U2 user rates file1");
+ returnedRatingModel = restAPI.authenticateUser(testUser1).withCoreAPI()
+ .usingResource(file1).likeDocument();
+ restAPI.assertStatusCodeIs(org.springframework.http.HttpStatus.CREATED);
+ returnedRatingModel.assertThat().field("myRating").is("true").and().field("id").is("likes")
+ .and().field("aggregate").isNotEmpty();
+
+ returnedRatingModel = restAPI.authenticateUser(testUser2).withCoreAPI()
+ .usingResource(file1).rateStarsToDocument(5);
+ restAPI.assertStatusCodeIs(org.springframework.http.HttpStatus.CREATED);
+ returnedRatingModel.assertThat().field("myRating").is("5").and().field("id").is("fiveStar")
+ .and().field("aggregate").isNotEmpty();
+
+ STEP("12. Using CMIS U1 moves file1 from folder1 to folder3");
+ cmisAPI.usingSite(testSitePublic).usingResource(file1).moveTo(folder3)
+ .and().assertThat().existsInRepo();
+
+ STEP("13. Using CMIS/RestAPI U1 checks that content, favorites and ratings are kept");
+ returnedRatingModel.assertThat().field("myRating").is("5").and().field("id").is("fiveStar")
+ .and().field("aggregate").isNotEmpty();
+ restPersonFavoritesModel.assertThat().field("targetGuid").is(file1.getNodeRefWithoutVersion());
+ }
+
+ /**
+ * Scenario 38
+ * 1. Using CMIS create one test user: U1
+ * 2. Using CMIS U1 creates a new document in Share
+ * 3. Using WebDAV U1 creates a new document in User Home
+ * 4. Using WebDAV U1 updates both documents
+ * 5. Verify if only first document's version is increased using CMIS
+ * 6. Verify if content is updated using WebDav
+ * 7. Verify if the size of the document is increased
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.CORE })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION, description = "Verify document versioning after appending content using WebDAV.")
+ public void checkDocumentVersionAfterAppendingContent() throws Exception
+ {
+ STEP("1. Using CMIS create one test user: U1");
+ testUser1 = dataUser.createRandomTestUser();
+
+ STEP("2. Using CMIS U1 creates a new document in Share");
+ FileModel cmisTestFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file 1 content");
+ cmisAPI.authenticateUser(testUser1)
+ .usingShared().createFile(cmisTestFile)
+ .assertThat().existsInRepo();
+
+ STEP("3. Using WebDAV U1 creates a new document in User Home");
+ FileModel webDAVTestFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file 2 content");
+ webDavProtocol.authenticateUser(testUser1)
+ .usingUserHome().createFile(webDAVTestFile)
+ .assertThat().existsInWebdav().and()
+ .assertThat().existsInRepo();
+
+ STEP("4. Using WebDAV U1 updates both documents");
+ webDavProtocol.usingResource(cmisTestFile).update("cmis file content")
+ .usingResource(webDAVTestFile).update("WebDAV file content");
+
+ STEP("5. Verify if only first document's version is increased using CMIS");
+ cmisAPI.usingResource(cmisTestFile).assertThat().documentHasVersion(1.1)
+ .usingResource(webDAVTestFile).assertThat().documentHasVersion(1.0);
+
+ STEP("6. Verify if content is updated using WebDav");
+ webDavProtocol.authenticateUser(testUser1)
+ .usingResource(cmisTestFile).assertThat().contentIs("cmis file content")
+ .usingResource(webDAVTestFile).assertThat().contentIs("WebDAV file content");
+
+ STEP("7. Verify if the size of the document is increased");
+ cmisAPI.usingResource(cmisTestFile).assertThat().contentLengthIs(17)
+ .usingResource(webDAVTestFile).assertThat().contentLengthIs(19);
+ }
+
+ /**
+ * Scenario 40
+ * 1. Using CMIS create test user: U1
+ * 2. U1 creates a private test site using CMIS
+ * 3. Using WebDAV U1 creates a folder
+ * 4. Using WebDAV U1 creates a file inside the folder
+ * 5. Using CMIS, check out the document
+ * 6. Using CMIS verify if PWC is created
+ * 7. Using CMIS check in document with content
+ * 8. Using CMIS verify that version does not increase
+ * 9. Using CMIS verify new content is added to document
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.CORE })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Verify increased version and new content of a file that was check out then check in.")
+ public void verifyIncreasedVersionAndNewContentOfCheckInDocument() throws Exception
+ {
+ STEP("Step 1. Using CMIS create test user: U1");
+ testUser1 = dataUser.createRandomTestUser();
+
+ STEP("Step 2. U1 creates a private test site using CMIS");
+ testSitePublic = dataSite.usingUser(testUser1).createPrivateRandomSite();
+
+ STEP("Step 3. Using WebDAV U1 creates a folder");
+ FolderModel folder = FolderModel.getRandomFolderModel();
+ webDavProtocol.authenticateUser(testUser1).usingSite(testSitePublic).createFolder(folder);
+
+ STEP("Step 4. Using WebDAV U1 creates a file inside the folder");
+ FileModel file = FileModel.getRandomFileModel(FileType.XML, "file content");
+ webDavProtocol.authenticateUser(testUser1).usingResource(folder).createFile(file)
+ .assertThat().existsInWebdav().assertThat().existsInRepo();
+
+ STEP("Step 5: Using CMIS, check out the document and verify document version");
+ cmisAPI.authenticateUser(testUser1).usingResource(file).checkOut()
+ .assertThat().documentIsCheckedOut();
+
+ STEP("Step 6: Using CMIS verify if PWC is created");
+ FileModel filePWC = cmisAPI.usingResource(file).withCMISUtil().getPWCFileModel();
+ cmisAPI.usingResource(filePWC).assertThat().existsInRepo();
+
+ STEP("Step 7: Using CMIS check in document with content");
+ String newContent = "new major content";
+ cmisAPI.usingResource(folder).assertThat().folderHasCheckedOutDocument(file);
+ cmisAPI.usingResource(file).prepareDocumentForCheckIn()
+ .withMajorVersion()
+ .withContent(newContent)
+ .checkIn().refreshResource()
+ .and().assertThat().documentIsNotCheckedOut();
+
+ STEP("Step 8: Using CMIS verify that version does not increase");
+ cmisAPI.usingResource(file).assertThat().documentHasVersion(1.0);
+
+ STEP("Step 9: Using CMIS verify new content is added to document");
+ cmisAPI.usingResource(file).assertThat().contentIs(newContent);
+ }
+
+ /**
+ * Scenario 41
+ * 1. Using CMIS create test user: U1
+ * 2. U1 creates a private test site using CMIS
+ * 3. Using WebDAV U1 creates a folder
+ * 4. Using WebDAV U1 creates a file inside the folder
+ * 5. Using CMIS, check out the document
+ * 6. Using CMIS verify if PWC is created
+ * 7. Using CMIS, cancel check out
+ * 8. Using CMIS, verify original document has version 1.0
+ * 9. Using CMIS, verify original document has same content
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.CORE })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Verify that version and the content of a file are not changed if the checkout is canceled.")
+ public void verifyVersionAndContentOfACanceledCheckoutDocument() throws Exception
+ {
+ STEP("Step 1. Using CMIS create test user: U1");
+ testUser1 = dataUser.createRandomTestUser();
+
+ STEP("Step 2. U1 creates a private test site using CMIS");
+ testSitePublic = dataSite.usingUser(testUser1).createPrivateRandomSite();
+
+ STEP("Step 3. Using WebDAV U1 creates a folder");
+ FolderModel folder = FolderModel.getRandomFolderModel();
+ webDavProtocol.authenticateUser(testUser1).usingSite(testSitePublic).createFolder(folder);
+
+ STEP("Step 4. Using WebDAV U1 creates a file inside the folder");
+ FileModel file = FileModel.getRandomFileModel(FileType.XML, "file content");
+ webDavProtocol.authenticateUser(testUser1).usingResource(folder).createFile(file)
+ .assertThat().existsInWebdav().assertThat().existsInRepo();
+
+ STEP("Step 5: Using CMIS, check out the document");
+ cmisAPI.authenticateUser(testUser1).usingResource(file).checkOut();
+
+ STEP("Step 6: Using CMIS verify if PWC is created");
+ FileModel filePWC = cmisAPI.usingResource(file).withCMISUtil().getPWCFileModel();
+ cmisAPI.usingResource(filePWC).assertThat().existsInRepo();
+
+ STEP("Step 7: Using CMIS, cancel check out");
+ cmisAPI.usingResource(file).cancelCheckOut().then()
+ .assertThat().documentIsNotCheckedOut();
+
+ STEP("Step 8: Using CMIS, verify original document has version 1.0");
+ cmisAPI.usingResource(file).assertThat().isNotPrivateWorkingCopy()
+ .then().assertThat().documentHasVersion(1.0);
+
+ STEP("Step 9: Using CMIS, verify original document has same content");
+ cmisAPI.usingResource(file).assertThat().contentIs("file content");
+ }
+
+ /**
+ * Scenario 42
+ * 1. Using CMIS create one test user: U1
+ * 2. Using CMIS U1 creates a file: file
+ * 3. Using WebDAV U1 renames file and verify if the new document exists
+ * 4. Using FTP verify old document does not exists
+ */
+
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.CORE })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Edit document name and verify document with new name")
+ public void renameDocument() throws Exception
+ {
+ STEP("1. Using CMIS create test user: U1");
+ testUser1 = dataUser.createRandomTestUser();
+
+ STEP("2. Using CMIS U1 creates file");
+ FileModel file = FileModel.getRandomFileModel(FileType.PDF, "file content");
+ cmisAPI.authenticateUser(testUser1).usingUserHome().createFile(file)
+ .assertThat().existsInRepo();
+
+ STEP("3. Using WebDAV U1 renames file and verify if the new document exists");
+ FileModel oldFile = new FileModel(file);
+ webDavProtocol.authenticateUser(testUser1).usingResource(file).rename(renamePrefix + file.getName())
+ .and().assertThat().existsInRepo().and().assertThat().existsInWebdav();
+
+ STEP("4. Using FTP verify old document does not exists");
+ ftpProtocol.authenticateUser(testUser1).usingResource(oldFile)
+ .assertThat().doesNotExistInRepo()
+ .and().assertThat().doesNotExistInFtp();
+ }
+
+ /**
+ * Scenario 43
+ * 1. Using CMIS create test user: U1
+ * 2. Using WebDAV U1 creates a file using shared
+ * 3. Using webDAV append content to document
+ * 4. Using CMIS, verify original document has version 1.0
+ * 5. Using CMIS delete document
+ * 6. Using WebDAV, verify document is deleted
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.CORE })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Delete document after append content and verify document version.")
+ public void deleteDocumentAfterAppendContent() throws Exception
+ {
+ STEP("Step 1. Using CMIS create test user: U1");
+ testUser1 = dataUser.createRandomTestUser();
+
+ STEP("Step 2. Using WebDAV U1 creates a file using shared");
+ FileModel file = FileModel.getRandomFileModel(FileType.XML, "file content");
+ webDavProtocol.authenticateUser(testUser1).usingUserHome().createFile(file)
+ .assertThat().existsInRepo();
+
+ STEP("Step 3. Using webDAV append content to document");
+ String newContentToAppend = " - append this text to the file";
+ webDavProtocol.authenticateUser(testUser1).usingResource(file).assertThat().contentIs("file content")
+ .then().update(file.getContent() + newContentToAppend)
+ .assertThat().contentIs(file.getContent() + newContentToAppend);
+
+ STEP("Step 4: Using CMIS, verify original document has version 1.0");
+ cmisAPI.authenticateUser(testUser1).usingResource(file).assertThat().isNotPrivateWorkingCopy()
+ .then().assertThat().documentHasVersion(1.0);
+
+ STEP("Step 4: Using CMIS, delete document");
+ cmisAPI.usingResource(file).assertThat().existsInRepo().delete();
+
+ STEP("Step 5: Using WebDAV, verify document is deleted");
+ webDavProtocol.authenticateUser(testUser1).usingResource(file).assertThat().doesNotExistInWebdav()
+ .and().assertThat().doesNotExistInRepo();
+ }
+
+ /**
+ * Scenario 44
+ * 1. Using CMIS create one test user: U1
+ * 2. Using CMIS U1 creates a public test site
+ * 3. Using WebDAV U1 creates a new file in User Home
+ * 4. Using WebDAV U1 creates another file in public site document library.
+ * 5. Using CMIS U1 creates a relationship between documents
+ * 6. Verify if relationship is created
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.CORE })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION, description = "Verify if relationship is created between 2 items using CMIS.")
+ public void checkRelationshipBetween2Files() throws Exception
+ {
+ STEP("1. Using CMIS create one test user: U1");
+ testUser1 = dataUser.createRandomTestUser();
+
+ STEP("2. Using CMIS U1 creates a public test site");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("3. Using WebDAV U1 creates a new file in User Home");
+ FileModel sourceFile= FileModel.getRandomFileModel(FileType.PDF, "file content");
+ webDavProtocol.authenticateUser(testUser1).usingUserHome()
+ .createFile(sourceFile).assertThat().existsInRepo();
+
+ STEP("4. Using WebDAV U1 creates another file in public site document library.");
+ FileModel targetFile= FileModel.getRandomFileModel(FileType.PDF, "file content");
+ webDavProtocol.authenticateUser(testUser1).usingSite(testSitePublic)
+ .createFile(targetFile).assertThat().existsInRepo();
+
+ STEP("5. Using CMIS U1 creates a relationship between documents. 6. Verify if relationship is created");
+ cmisAPI.authenticateUser(testUser1).usingResource(sourceFile).createRelationshipWith(targetFile)
+ .assertThat().objectHasRelationshipWith(targetFile);
+ }
+
+ /**
+ * Scenario 46
+ * 1. Using CMIS create one test user: U1
+ * 2. Using CMIS U1 creates an imap test site
+ * 3. Using CMIS U1 creates cmisFolder in Shared
+ * 4. Using IMAP U1 creates parentFolder in private site document library.
+ * 5. Using FTP U1 creates a subfolder in parentFolder
+ * 6. Using WebDAV U1 creates a webdavFolder in User Home
+ * 7. Using WebDAV U1 creates a document in parentFolder
+ * 8. Using CMIS U1 adds document to cmisFolder, subfolder, webdavFolder
+ * 9. Using WebDAV verify document is present in all folders
+ * 10. Using CMIS U1 removes document from subFolder
+ * 11. Using WebDAV verify document is not present in subFolder
+ * 12. Using FTP U1 deletes original document from parentFolder
+ * 13. Using CMIS verify document does not exist
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.CORE })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION, description = "Verify parents list for an object using CMIS.")
+ public void addAndRemoveDocumentFromFolders() throws Exception
+ {
+ STEP("1. Using CMIS create one test user: U1");
+ testUser1 = dataUser.createRandomTestUser();
+
+ STEP("2. Using CMIS U1 creates an imap test site");
+ testSitePublic = dataSite.usingUser(testUser1).createIMAPSite();
+
+ STEP("3. Using CMIS U1 creates cmisFolder in Shared");
+ FolderModel cmisFolder = FolderModel.getRandomFolderModel();
+ cmisAPI.authenticateUser(testUser1)
+ .usingShared().createFolder(cmisFolder)
+ .assertThat().existsInRepo();
+
+ STEP("4. Using IMAP U1 creates parentFolder in private site document library.");
+ FolderModel parentFolder = FolderModel.getRandomFolderModel();
+ imapProtocol.authenticateUser(testUser1)
+ .usingSite(testSitePublic).createFolder(parentFolder)
+ .assertThat().existsInRepo();
+
+ STEP("5. Using FTP U1 creates a subfolder in parentFolder");
+ FolderModel subFolder = FolderModel.getRandomFolderModel();
+ ftpProtocol.authenticateUser(testUser1)
+ .usingResource(parentFolder).createFolder(subFolder)
+ .assertThat().existsInRepo();
+
+ STEP("6. Using WebDAV U1 creates a webdavFolder in User Home");
+ FolderModel webdavFolder = FolderModel.getRandomFolderModel();
+ webDavProtocol.authenticateUser(testUser1)
+ .usingUserHome().createFolder(webdavFolder)
+ .assertThat().existsInRepo();
+
+ STEP("7. Using WebDAV U1 creates a document in parentFolder");
+ testFile1= FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file content");
+ webDavProtocol.authenticateUser(testUser1)
+ .usingResource(parentFolder).createFile(testFile1)
+ .assertThat().existsInRepo();
+
+ STEP("8. Using CMIS U1 adds document to cmisFolder, subfolder, webdavFolder");
+ cmisAPI.usingResource(testFile1)
+ .addDocumentToFolder(cmisFolder, true).assertThat().hasParents(parentFolder.getName(), cmisFolder.getName())
+ .addDocumentToFolder(subFolder, true).assertThat().hasParents(parentFolder.getName(), cmisFolder.getName(), subFolder.getName())
+ .addDocumentToFolder(webdavFolder, true).assertThat().hasParents(parentFolder.getName(), cmisFolder.getName(), subFolder.getName(), webdavFolder.getName());
+
+ STEP("9. Using WebDAV verify document is present in all folders");
+ FileModel fileAddedInCMISFolder = new FileModel(testFile1.getName(), testFile1.getTitle(), testFile1.getDescription(), testFile1.getFileType(), testFile1.getContent());
+ fileAddedInCMISFolder.setCmisLocation(Utility.buildPath(cmisFolder.getCmisLocation(), testFile1.getName()));
+
+ FileModel fileAddedInSubFolder = new FileModel(testFile1.getName(), testFile1.getTitle(), testFile1.getDescription(), testFile1.getFileType(), testFile1.getContent());
+ fileAddedInSubFolder.setCmisLocation(Utility.buildPath(subFolder.getCmisLocation(), testFile1.getName()));
+
+ FileModel fileAddedInWebDAVFolder = new FileModel(testFile1.getName(), testFile1.getTitle(), testFile1.getDescription(), testFile1.getFileType(), testFile1.getContent());
+ fileAddedInWebDAVFolder.setCmisLocation(Utility.buildPath(webdavFolder.getCmisLocation(), testFile1.getName()));
+
+ webDavProtocol.usingResource(fileAddedInCMISFolder).assertThat().existsInWebdav()
+ .usingResource(fileAddedInSubFolder).assertThat().existsInWebdav()
+ .usingResource(fileAddedInWebDAVFolder).assertThat().existsInWebdav();
+
+ STEP("10. Using CMIS U1 removes document from subFolder");
+ cmisAPI.usingResource(testFile1).removeDocumentFromFolder(subFolder)
+ .assertThat().hasParents(parentFolder.getName(), cmisFolder.getName(), webdavFolder.getName());
+
+ STEP("11. Using WebDAV verify document is not present in subFolder");
+ webDavProtocol.usingResource(testFile1).assertThat().existsInWebdav()
+ .usingResource(fileAddedInCMISFolder).assertThat().existsInWebdav()
+ .usingResource(fileAddedInSubFolder).assertThat().doesNotExistInWebdav()
+ .usingResource(fileAddedInWebDAVFolder).assertThat().existsInWebdav();
+
+ STEP("12. Using FTP U1 deletes original document from parentFolder");
+ ftpProtocol.usingResource(testFile1).delete().assertThat().doesNotExistInFtp();
+
+ STEP("13. Using CMIS verify document does not exist");
+ cmisAPI.usingResource(fileAddedInCMISFolder).assertThat().doesNotExistInRepo()
+ .usingResource(fileAddedInWebDAVFolder).assertThat().doesNotExistInRepo();
+ }
+
+ /**
+ * Scenario 47 - Delete many documents
+ *
+ * 1. Using CMIS create test user: U1
+ * 2. Using CMIS U1 creates a public test site
+ * 3. Using CMIS and WebDAV U1 creates parentFolder1, doc1 and doc2 in document library
+ * 4. Using WebDAV and FTP U1 creates inside parentFolder1: childDoc1 to childDoc5
+ * 5. Using IMAP bulk delete doc1 and doc2
+ * 6. Using CMIS verify that doc1 and doc2 are deleted
+ * 7. Using IMAP delete childDoc1 to childDoc4
+ * 8. Using WebDAV and FTP verify if docs are deleted from their folders
+ */
+
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.CORE })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT}, executionType = ExecutionType.REGRESSION,
+ description = "Verify users can delete many documents in a public site using different protocols.")
+ public void usersCanDeleteManyDocuments() throws Exception
+ {
+ FolderModel parentFolder1 = FolderModel.getRandomFolderModel();
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ testFile2 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ FileModel childDoc1, childDoc2, childDoc3, childDoc4, childDoc5;
+ childDoc1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ childDoc2 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ childDoc3 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ childDoc4 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ childDoc5 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+
+ STEP("1. Using CMIS create test user: U1");
+ testUser1 = dataUser.createRandomTestUser();
+
+ STEP("2. Using CMIS U1 creates a public test site");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("3. Using CMIS and WebDAV U1 creates parentFolder1, doc1 and doc2 in document library");
+ cmisAPI.authenticateUser(testUser1).usingSite(testSitePublic).createFolder(parentFolder1)
+ .and().assertThat().existsInRepo();
+
+ webDavProtocol.authenticateUser(testUser1).usingSite(testSitePublic).createFile(testFile1)
+ .and().createFile(testFile2);
+
+ STEP("4. Using WebDAV and FTP U1 creates inside parentFolder1: childDoc1 to childDoc5");
+ webDavProtocol.authenticateUser(testUser1).usingResource(parentFolder1)
+ .createFile(childDoc1).and().createFile(childDoc2);
+
+ ftpProtocol.authenticateUser(testUser1).usingResource(parentFolder1)
+ .createFile(childDoc3).and().createFile(childDoc4).and().createFile(childDoc5);
+
+ STEP("5. Using IMAP bulk delete doc1 and doc2");
+ imapProtocol.authenticateUser(testUser1).usingSite(testSitePublic).deleteMessage(testFile1.getName(), testFile2.getName()).assertThat().doesNotContainMessages(testFile1, testFile2);
+ Utility.waitToLoopTime(10);
+
+ STEP("6. Using CMIS verify that doc1 and doc2 are deleted");
+ cmisAPI.authenticateUser(testUser1)
+ .usingResource(testFile1).assertThat().doesNotExistInRepo()
+ .and().usingResource(testFile2).assertThat().doesNotExistInRepo();
+
+ STEP("7. Using IMAP delete childDoc1 to childDoc4");
+ imapProtocol.authenticateUser(testUser1).usingResource(parentFolder1).deleteMessage(childDoc1.getName(), childDoc2.getName(), childDoc3.getName(), childDoc4.getName())
+ .assertThat().doesNotContainMessages(childDoc1, childDoc2, childDoc3, childDoc4);
+ Utility.waitToLoopTime(10);
+
+ STEP("8. Using WebDAV and FTP verify if docs are deleted from their folders");
+ webDavProtocol.authenticateUser(testUser1).usingResource(parentFolder1).assertThat().hasFiles(childDoc5)
+ .and().usingResource(childDoc1).assertThat().doesNotExistInRepo()
+ .and().usingResource(childDoc2).assertThat().doesNotExistInRepo();
+
+ ftpProtocol.authenticateUser(testUser1).usingResource(childDoc3)
+ .assertThat().doesNotExistInRepo()
+ .and().usingResource(childDoc4).assertThat().doesNotExistInRepo();
+ }
+
+ /**
+ * Scenario 48 - Move folder in another folder
+ *
+ * 1. Using CMIS create user u1 and public site
+ * 2. Using WebDAV U1 creates folder1 and folder2
+ * 3. Using WebDAV U1 creates doc1 in folder1
+ * 4. Using FTP U1 moves folder1 in folder2
+ * 5. Using WebDAV verify that folder1 is not in the original location and is present in folder2
+ * 6. Using CMIS verify if doc1 is still present in folder1
+ */
+
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.CORE })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION, description = "Verify user is able to move a non empty folder to another folder from the same site.")
+ public void moveFolderInAnotherFolder() throws Exception
+ {
+ testFolder1 = FolderModel.getRandomFolderModel();
+ testFolder2 = FolderModel.getRandomFolderModel();
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+
+ STEP("1. Using CMIS create user u1 and public site");
+ testUser1 = dataUser.createRandomTestUser();
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("2. Using WebDAV U1 creates folder1 and folder2");
+ webDavProtocol.authenticateUser(testUser1).usingSite(testSitePublic)
+ .createFolder(testFolder1)
+ .and().assertThat().existsInRepo().and().assertThat().existsInWebdav()
+ .then().createFolder(testFolder2)
+ .and().assertThat().existsInRepo().and().assertThat().existsInWebdav();
+
+ STEP("3. Using WebDAV U1 creates doc1 in folder1");
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFolder1).createFile(testFile1)
+ .and().assertThat().existsInRepo().and().assertThat().existsInWebdav()
+ .and().usingResource(testFolder1).assertThat().hasFiles(testFile1);
+
+ STEP("4. Using FTP U1 moves folder1 in folder2");
+ ftpProtocol.authenticateUser(testUser1)
+ .usingResource(testFolder1).moveTo(testFolder2)
+ .assertThat().existsInRepo()
+ .then().usingResource(testFolder1).assertThat().doesNotExistInRepo();
+
+ STEP("5. Using WebDAV verify that folder1 is not in the original location and is present in folder2");
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFolder1).assertThat().doesNotExistInRepo()
+ .and().usingResource(testFolder2).assertThat().hasFolders(testFolder1);
+
+ STEP("6. Using CMIS verify if doc1 is still present in folder1");
+ FolderModel newTestFolder1 = new FolderModel(testFolder1.getName(), testFolder1.getTitle(), testFolder1.getDescription());
+ newTestFolder1.setCmisLocation(Utility.buildPath(testFolder2.getCmisLocation(), testFolder1.getName()));
+
+ FileModel newTestFile1 = new FileModel(testFile1.getName(), testFile1.getTitle(), testFile1.getDescription(), testFile1.getFileType(), testFile1.getContent());
+ newTestFile1.setCmisLocation(Utility.buildPath(newTestFolder1.getCmisLocation(), testFile1.getName()));
+
+ cmisAPI.authenticateUser(testUser1).usingResource(newTestFolder1)
+ .assertThat().existsInRepo()
+ .assertThat().hasFiles(newTestFile1);
+ }
+
+ /**
+ * Scenario 49 - Copy folder in another folder
+ *
+ * 1. Using CMIS create user u1 and public site
+ * 2. Using CMIS U1 creates folder1 and folder2
+ * 3. Using WebDAV U1 creates doc1 in folder1
+ * 4. Using WebDAV U1 copies folder1 in folder2
+ * 5. Using FTP verify that folder1 is in the original location and contains doc1
+ * 6. Using WebDAV verify that folder1 is in folder2 and contains doc1
+ */
+
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.CORE })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION, description = "Verify user is able to copy non empty folder to another folder in the same site.")
+ public void copyFolderInAnotherFolder() throws Exception
+ {
+ testFolder1 = FolderModel.getRandomFolderModel();
+ testFolder2 = FolderModel.getRandomFolderModel();
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+
+ STEP("1. Using CMIS create user u1 and public site");
+ testUser1 = dataUser.createUser(RandomStringUtils.randomAlphanumeric(20));
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("2. Using CMIS U1 creates folder1 and folder2");
+ cmisAPI.authenticateUser(testUser1).usingSite(testSitePublic)
+ .createFolder(testFolder1).and().assertThat().existsInRepo().and()
+ .createFolder(testFolder2).and().assertThat().existsInRepo();
+
+ STEP("3. Using WebDAV U1 creates doc1 in folder1");
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFolder1)
+ .createFile(testFile1).and().assertThat().existsInRepo()
+ .and().assertThat().existsInWebdav();
+
+ STEP("4. Using WebDAV U1 copies folder1 in folder2");
+ testFolder2.setProtocolLocation(webDavProtocol.getPrefixSpace() + testFolder2.getCmisLocation());
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFolder1).copyTo(testFolder2)
+ .assertThat().existsInRepo()
+ .then().usingResource(testFolder1).assertThat().existsInRepo();
+
+ STEP("5. Using FTP verify that folder1 is in the original location and contains doc1");
+ ftpProtocol.authenticateUser(testUser1).usingResource(testFolder1)
+ .assertThat().existsInRepo()
+ .and().assertThat().existsInFtp()
+ .and().assertThat().hasFiles(testFile1);
+
+ STEP("6. Using WebDAV verify that folder1 is in folder2 and contains doc1");
+ FolderModel newTestFolder1 = new FolderModel(testFolder1.getName(), testFolder1.getTitle(), testFolder1.getDescription());
+ newTestFolder1.setCmisLocation(Utility.buildPath(testFolder2.getCmisLocation(), testFolder1.getName()));
+
+ FileModel newTestFile1 = new FileModel(testFile1.getName(), testFile1.getTitle(), testFile1.getDescription(), testFile1.getFileType(), testFile1.getContent());
+ newTestFile1.setCmisLocation(Utility.buildPath(newTestFolder1.getCmisLocation(), testFile1.getName()));
+
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFolder2)
+ .assertThat().hasFolders(newTestFolder1)
+ .and().usingResource(newTestFolder1)
+ .assertThat().existsInRepo().and().assertThat().existsInWebdav()
+ .and().assertThat().hasFiles(newTestFile1);
+ }
+
+ /**
+ * Scenario 50 - Rename site
+ *
+ * 1. Using CMIS create one test user: U1
+ * 2. Using CMIS U1 creates a moderated site
+ * 3. Using WebDAV U1 creates a folder in the moderated site document library
+ * 4. Using CMIS U1 tries to rename site
+ * 5. Verify that a site cannot be renamed
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.CORE }, expectedExceptions = CmisRuntimeException.class, expectedExceptionsMessageRegExp = "^.*Sites can not be renamed.$")
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION, description = "Verify sites cannot be renamed using CMIS.")
+ public void renameSite() throws Exception
+ {
+ STEP("1. Using CMIS create one test user: U1");
+ testUser1 = dataUser.createRandomTestUser();
+
+ STEP("2. Using CMIS U1 creates a moderated site");
+ testSiteModerated = dataSite.usingUser(testUser1).createModeratedRandomSite();
+
+ STEP("3. Using WebDAV U1 creates a folder in the moderated site document library");
+ testFolder1 = FolderModel.getRandomFolderModel();
+ webDavProtocol.authenticateUser(testUser1)
+ .usingSite(testSiteModerated).createFolder(testFolder1)
+ .assertThat().existsInWebdav()
+ .assertThat().existsInRepo();
+
+ STEP("4. Using CMIS U1 tries to rename site 5. Verify that a site cannot be renamed");
+ FolderModel siteFolder = new FolderModel(String.format("/Sites/%s", testSiteModerated.getId()));
+ cmisAPI.authenticateUser(testUser1).usingResource(siteFolder).rename("renamedSite");
+ }
+}
diff --git a/packaging/tests/tas-integration/src/test/java/org/alfresco/tas/integration/IntegrationFullTests.java b/packaging/tests/tas-integration/src/test/java/org/alfresco/tas/integration/IntegrationFullTests.java
new file mode 100644
index 00000000000..529c5ef412d
--- /dev/null
+++ b/packaging/tests/tas-integration/src/test/java/org/alfresco/tas/integration/IntegrationFullTests.java
@@ -0,0 +1,1800 @@
+package org.alfresco.tas.integration;
+
+import static org.alfresco.utility.report.log.Step.STEP;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.equalTo;
+
+import io.restassured.RestAssured;
+import java.io.File;
+
+import javax.json.JsonObject;
+import javax.mail.Flags;
+import javax.mail.MessagingException;
+
+import org.alfresco.dataprep.CMISUtil;
+import org.alfresco.dataprep.SiteService.Visibility;
+import org.alfresco.rest.core.JsonBodyGenerator;
+import org.alfresco.rest.core.RestRequest;
+import org.alfresco.rest.core.RestResponse;
+import org.alfresco.rest.model.RestCommentModel;
+import org.alfresco.rest.model.RestErrorModel;
+import org.alfresco.rest.model.RestItemModelsCollection;
+import org.alfresco.rest.model.RestNetworkModelsCollection;
+import org.alfresco.rest.model.RestPreferenceModel;
+import org.alfresco.rest.model.RestPreferenceModelsCollection;
+import org.alfresco.rest.model.RestProcessDefinitionModelsCollection;
+import org.alfresco.rest.model.RestProcessModel;
+import org.alfresco.rest.model.RestProcessVariableCollection;
+import org.alfresco.rest.model.RestProcessVariableModel;
+import org.alfresco.rest.model.RestTaskModel;
+import org.alfresco.rest.model.RestTaskModelsCollection;
+import org.alfresco.utility.Utility;
+import org.alfresco.utility.constants.PreferenceName;
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.RandomData;
+import org.alfresco.utility.model.*;
+import org.alfresco.utility.report.Bug;
+import org.alfresco.utility.report.Bug.Status;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
+import org.apache.commons.net.ftp.FTPReply;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.testng.Assert;
+import org.testng.SkipException;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * Created by Claudia Agache on 2/7/2017.
+ */
+public class IntegrationFullTests extends IntegrationTest
+{
+ private UserModel admin, testUser1, testUser2, userToAssign;
+ private SiteModel publicSite, moderatedSite, privateSite;
+ private FileModel testFile1, testFile2;
+ private FolderModel parentFolder;
+ private RestTaskModelsCollection processTasks;
+ private RestProcessModel processModel;
+ private RestItemModelsCollection taskItems;
+ private TaskModel taskModel;
+ private RestTaskModel restTaskModel;
+
+ @BeforeClass(alwaysRun = true)
+ public void setup() throws Exception
+ {
+ admin = dataUser.getAdminUser();
+ }
+
+ /**
+ * Scenario
+ * 1. Using CMIS create test user testUser
+ * 2. Using CMIS create public IMAP site testSite
+ * 3. Using CMIS create file testFile in testSite document library
+ * 4. Using IMAP delete testFile
+ * 5. Using CMIS try to rename testFile
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL }, expectedExceptions = CmisObjectNotFoundException.class)
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Verify the file cannot be renamed in repository if it is deleted from IMAP client")
+ public void verifyFileCannotBeRenamedInRepoIfItWasAlreadyDeletedViaIMAP() throws Exception
+ {
+ UserModel testUser = dataUser.createRandomTestUser();
+ SiteModel testSite = dataSite.usingUser(testUser).createIMAPSite();
+ FileModel testFile = dataContent.usingUser(testUser).usingSite(testSite).createContent(FileModel.getRandomFileModel(FileType.TEXT_PLAIN));
+ imapProtocol.authenticateUser(testUser).usingSite(testSite).usingResource(testFile).deleteMessage();
+ cmisAPI.authenticateUser(testUser).usingSite(testSite).usingResource(testFile).rename("new file name");
+ }
+
+ /**
+ * Scenario 51
+ * 1. Using CMIS create a test user: u1
+ * 2. U1 creates a private site using CMIS
+ * 3. U1 creates a folder in site's document library using WebDAV
+ * 4. U1 uploads a document with size > x MB in folder1 using FTP
+ * 5. Verify file is present in folder1 using WebDAV
+ * 6. Verify size of the document from folder1 is exact as the size of the uploaded document CMIS
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Verify a 1MB file is uploaded in a private site")
+ public void userShouldUploadFileInPrivateSite() throws Exception
+ {
+ STEP("1. Using CMIS create a test user: u1");
+ testUser1 = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates a private site using CMIS");
+ privateSite = dataSite.usingUser(testUser1).createPrivateRandomSite();
+
+ STEP("3. U1 creates a folder in site's document library using WebDav");
+ parentFolder = FolderModel.getRandomFolderModel();
+ webDavProtocol.authenticateUser(testUser1)
+ .usingSite(privateSite).createFolder(parentFolder)
+ .assertThat().existsInWebdav();
+
+ STEP("4. U1 uploads a document with size > x MB in folder1 using FTP");
+ File fileForUpload = Utility.getTestResourceFile("shared-resources/testdata/flower.jpg");
+ ftpProtocol.authenticateUser(testUser1)
+ .usingResource(parentFolder).uploadFile(fileForUpload)
+ .assertThat().existsInRepo()
+ .and().assertThat().existsInFtp();
+ testFile1 = new FileModel(fileForUpload.getName());
+ testFile1.setCmisLocation(ftpProtocol.getLastResourceWithoutPrefix());
+
+ STEP("5. Verify file is present in folder1 using WebDAV");
+ webDavProtocol.authenticateUser(testUser1).usingResource(parentFolder).assertThat().hasFiles(testFile1);
+
+ STEP("6. Verify size of the document from folder1 is exact as the size of the uploaded document CMIS");
+ cmisAPI.authenticateUser(testUser1)
+ .usingResource(testFile1).assertThat().contentLengthIs(fileForUpload.length());
+ }
+
+ /**
+ * Scenario 52
+ * 1. Using CMIS create 2 test users: u1 and u2
+ * 2. U1 creates a private site using CMIS
+ * 3. U1 creates 2 documents in his site using WebDAV
+ * 4. U1 creates a new task with the documents created above and assigns the task to U2 using REST
+ * 5. Verify that U2 doesn't have access to te documents attached to the task using FTP
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.WORKFLOW }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user is not able to access files from a private site, even if they are attached to a task assigned to him.")
+ public void assigneeCantAccessFilesFromPrivateSiteIfHeIsNotAMember() throws Exception
+ {
+ STEP("1. Using CMIS create 2 test users: u1 and u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates a private site using CMIS");
+ privateSite = dataSite.usingUser(testUser1).createPrivateRandomSite();
+
+ STEP("3. U1 creates 2 documents in his site using WebDav");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ testFile2 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file2 content");
+ webDavProtocol.authenticateUser(testUser1).usingSite(privateSite)
+ .createFile(testFile1)
+ .assertThat().existsInWebdav()
+ .assertThat().existsInRepo()
+ .createFile(testFile2)
+ .assertThat().existsInWebdav()
+ .assertThat().existsInRepo();
+
+ STEP("4. U1 creates a new task with the documents created above and assigns the task to U2 using REST");
+ processModel = restAPI.authenticateUser(testUser1).withWorkflowAPI()
+ .addProcess("activitiAdhoc", testUser2, false, CMISUtil.Priority.Normal);
+ restAPI.withWorkflowAPI().usingProcess(processModel).addProcessItem(testFile1);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+ restAPI.withWorkflowAPI().usingProcess(processModel).addProcessItem(testFile2);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("5. Verify that U2 doesn't have access to te documents attached to the task using FTP");
+ ftpProtocol.authenticateUser(testUser2)
+ .usingResource(testFile1).assertThat().hasReplyCode(FTPReply.FILE_UNAVAILABLE).and().assertThat().doesNotExistInFtp()
+ .usingResource(testFile2).assertThat().hasReplyCode(FTPReply.FILE_UNAVAILABLE).and().assertThat().doesNotExistInFtp();
+ }
+
+ /**
+ * Scenario 53
+ * 1. Using CMIS create 2 test users: u1 and u2
+ * 2. U1 creates a moderated site using CMIS
+ * 3. U1 creates 2 documents in his site using WebDAV
+ * 4. U1 creates a new task with the documents created above and assigns the task to U2 using REST
+ * 5. Verify that U2 doesn't have access to te documents attached to the task using WebDav
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL }, expectedExceptionsMessageRegExp = "^Access is denied.$")
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.WORKFLOW }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user is not able to access files from a moderated site, even if they are attached to a task assigned to him.")
+ public void assigneeCantAccessFilesFromModeratedSiteIfHeIsNotAMember() throws Exception
+ {
+ STEP("1. Using CMIS create 2 test users: u1 and u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates a moderated site using CMIS");
+ moderatedSite = dataSite.usingUser(testUser1).createModeratedRandomSite();
+
+ STEP("3. U1 creates 2 documents in his site using WebDAV");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ testFile2 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file2 content");
+ webDavProtocol.authenticateUser(testUser1).usingSite(moderatedSite)
+ .createFile(testFile1)
+ .assertThat().existsInWebdav()
+ .assertThat().existsInRepo()
+ .createFile(testFile2)
+ .assertThat().existsInWebdav()
+ .assertThat().existsInRepo();
+
+ STEP("4. U1 creates a new task with the documents created above and assigns the task to U2 using REST");
+ processModel = restAPI.authenticateUser(testUser1).withWorkflowAPI()
+ .addProcess("activitiAdhoc", testUser2, false, CMISUtil.Priority.Normal);
+ restAPI.withWorkflowAPI().usingProcess(processModel).addProcessItem(testFile1);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+ restAPI.withWorkflowAPI().usingProcess(processModel).addProcessItem(testFile2);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("5. Verify that U2 doesn't have access to te documents attached to the task using WebDav");
+ webDavProtocol.authenticateUser(testUser2)
+ .usingResource(testFile1).assertThat().doesNotExistInWebdav()
+ .usingResource(testFile2).assertThat().doesNotExistInWebdav();
+ }
+
+ /**
+ * Scenario 54
+ * 1. Using CMIS create 2 test users: u1 and u2
+ * 2. U1 creates a public site using CMIS
+ * 3. U1 creates 2 documents in his site using CMIS
+ * 4. U1 creates a new task with the documents created above and assigns the task to U2 using REST
+ * 5. Verify that U2 have access to te documents attached to the task using WebDAV
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.WORKFLOW }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user is able to access files from a public site, even if they are attached to a task assigned to him.")
+ public void assigneeCanAccessFilesFromPublicSiteIfHeIsNotAMember() throws Exception
+ {
+ STEP("1. Using CMIS create 2 test users: u1 and u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates a public site using CMIS");
+ publicSite = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("3. U1 creates 2 documents in his site using CMIS");
+ testFile1 = FileModel.getRandomFileModel(FileType.MSWORD, "file1 content");
+ testFile2 = FileModel.getRandomFileModel(FileType.MSWORD, "file2 content");
+ cmisAPI.authenticateUser(testUser1).usingSite(publicSite)
+ .createFile(testFile1)
+ .assertThat().existsInRepo()
+ .usingSite(publicSite).createFile(testFile2)
+ .assertThat().existsInRepo();
+
+ STEP("4. U1 creates a new task with the documents created above and assigns the task to U2 using REST");
+ processModel = restAPI.authenticateUser(testUser1).withWorkflowAPI()
+ .addProcess("activitiAdhoc", testUser2, false, CMISUtil.Priority.Normal);
+ testFile1.setNodeRef(dataContent.usingResource(testFile1).getNodeRef());
+ restAPI.withWorkflowAPI().usingProcess(processModel).addProcessItem(testFile1);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+ testFile2.setNodeRef(dataContent.usingResource(testFile2).getNodeRef());
+ restAPI.withWorkflowAPI().usingProcess(processModel).addProcessItem(testFile2);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("5. Verify that U2 have access to te documents attached to the task using WebDAV");
+ webDavProtocol.authenticateUser(testUser2)
+ .usingSite(publicSite).assertThat().hasFiles(testFile1, testFile2);
+ }
+
+ /**
+ * Scenario 55
+ * 1. Using CMIS create 2 test users: u1 and u2
+ * 2. U1 creates 2 documents in User Home with CMIS
+ * 3. U1 creates a new task with the documents created above and assigns the task to U2 using REST
+ * 4. Verify that U2 doesn't have access to te documents attached to the task using CMIS
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL }, expectedExceptions = {CmisPermissionDeniedException.class, CmisUnauthorizedException.class})
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.WORKFLOW }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user is not able to access files from another user User Home repo, even if they are attached to a task assigned to him.")
+ public void assigneeCantAccessFilesFromAnotherUserHome() throws Exception
+ {
+ STEP("1. Using CMIS create 2 test users: u1 and u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates 2 documents in User Home with CMIS");
+ testFile1 = FileModel.getRandomFileModel(FileType.MSWORD, "file1 content");
+ testFile2 = FileModel.getRandomFileModel(FileType.MSWORD, "file2 content");
+
+ cmisAPI.authenticateUser(testUser1).usingUserHome()
+ .createFile(testFile1)
+ .assertThat().existsInRepo()
+ .createFile(testFile2)
+ .assertThat().existsInRepo();
+
+ STEP("3. U1 creates a new task with the documents created above and assigns the task to U2 using REST");
+ processModel = restAPI.authenticateUser(testUser1).withWorkflowAPI()
+ .addProcess("activitiAdhoc", testUser2, false, CMISUtil.Priority.Normal);
+ restAPI.withWorkflowAPI().usingProcess(processModel).addProcessItem(testFile1);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+ restAPI.withWorkflowAPI().usingProcess(processModel).addProcessItem(testFile2);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("4. Verify that U2 doesn't have access to te documents attached to the task using CMIS");
+ cmisAPI.authenticateUser(testUser2)
+ .usingResource(testFile1).assertThat().doesNotExistInRepo();
+ }
+
+ /**
+ * Scenario 56
+ * 1. Using CMIS create 2 test users: u1 and u2
+ * 2. U1 creates document1 in a public site using CMIS
+ * 3. U2 is added to that public site with manager role using REST
+ * 4. U2 opens the document and renames it to document2 using WebDAV
+ * 5. Verify that U1 can't delete anymore document1 using FTP
+ * 6. U1 deletes document2 using WebDAV
+ * 7. Verify U2 can't update document2 using WebDAV
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Check that user can't delete/update a file that is renamed/deleted by another user.")
+ public void deleteFileAfterItIsRenamedByAnotherUser() throws Exception
+ {
+ STEP("1. Using CMIS create 2 test users: u1 and u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates document1 in a public site using CMIS");
+ publicSite = dataSite.usingUser(testUser1).createPublicRandomSite();
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ cmisAPI.authenticateUser(testUser1).usingSite(publicSite)
+ .createFile(testFile1).assertThat().existsInRepo();
+
+ STEP("3. U2 is added to that public site with manager role using REST");
+ testUser2.setUserRole(UserRole.SiteManager);
+ restAPI.authenticateUser(testUser1).withCoreAPI()
+ .usingSite(publicSite).addPerson(testUser2);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("4. U2 opens the document and renames it to document2 using WebDAV");
+ FileModel oldFile = new FileModel(testFile1);
+ webDavProtocol.authenticateUser(testUser2)
+ .usingResource(testFile1).rename("new" + testFile1.getName())
+ .assertThat().existsInRepo();
+
+ STEP("5. Verify that U1 can't delete anymore document1 using FTP");
+ ftpProtocol.authenticateUser(testUser1)
+ .usingResource(oldFile).delete()
+ .assertThat().hasReplyCode(550);
+
+ STEP("6. U1 deletes document2 using WebDAV");
+ webDavProtocol.authenticateUser(testUser1)
+ .usingResource(testFile1).delete()
+ .assertThat().doesNotExistInWebdav()
+ .assertThat().doesNotExistInRepo();
+
+ STEP("7. Verify U2 can't update document2 using WebDAV");
+ webDavProtocol.authenticateUser(testUser2)
+ .usingResource(testFile1).update("file2 content")
+ .assertThat().hasStatus(404);
+ }
+
+ /**
+ * Scenario 57
+ * 1. Using CMIS create 2 test users: u1 and u2
+ * 2. U1 creates document1 in a public site using FTP
+ * 3. U2 is added to that public site with manager role using REST
+ * 4. U1 adds comment to document1 using REST
+ * 5. U2 gets document1 comments using REST
+ * 6. U1 renames document1 using CMIS
+ * 7. U2 deletes comment using REST
+ * 8. Verify U1 cannot get comment using REST
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT, TestGroup.COMMENTS }, executionType = ExecutionType.REGRESSION,
+ description = "Check that user can't get a comment that is deleted by another user.")
+ public void getCommentAfterItIsDeleted() throws Exception
+ {
+ STEP("1. Using CMIS create 2 test users: u1 and u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates document1 in a public site using FTP");
+ publicSite = dataSite.usingUser(testUser1).createPublicRandomSite();
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ ftpProtocol.authenticateUser(testUser1).usingSite(publicSite).createFile(testFile1).assertThat().existsInRepo();
+
+ STEP("3. U2 is added to that public site with manager role using REST");
+ testUser2.setUserRole(UserRole.SiteManager);
+ restAPI.authenticateUser(testUser1).withCoreAPI()
+ .usingSite(publicSite).addPerson(testUser2);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("4. U1 adds comment to document1 using REST");
+ RestCommentModel user1Comment = restAPI.authenticateUser(testUser1).withCoreAPI().usingResource(testFile1).addComment("user1 comment");
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("5. U2 gets document1 comments using REST");
+ restAPI.authenticateUser(testUser2).withCoreAPI().usingResource(testFile1).getNodeComments()
+ .assertThat().entriesListContains("content", "user1 comment");
+
+ STEP("6. U1 renames document1 using CMIS");
+ cmisAPI.authenticateUser(testUser1).usingResource(testFile1).rename("new" + testFile1.getName())
+ .assertThat().existsInRepo()
+ .assertThat().contentPropertyHasValue("cmis:name", "new" + testFile1.getName())
+ .usingResource(testFile1).assertThat().doesNotExistInRepo();
+
+ STEP("7. U2 deletes comment using REST");
+ restAPI.withCoreAPI().usingResource(testFile1).deleteComment(user1Comment);
+ restAPI.assertStatusCodeIs(HttpStatus.NO_CONTENT);
+
+ STEP("8. Verify U1 cannot get comment using REST");
+ restAPI.authenticateUser(testUser1).withCoreAPI().usingResource(testFile1).getNodeComments()
+ .assertThat().entriesListIsEmpty();
+ }
+
+ /**
+ * Scenario 59
+ * 1. Using CMIS create one test user: u1
+ * 2. U1 creates a public site using CMIS
+ * 3. Admin creates a folder with a document (doc1.txt) in the public site using WebDAV
+ * 4. Admin renames document1 (doc1-edited.txt) using WebDAV
+ * 5. U1 tries to move doc1.txt to another location using IMAP
+ * 6. Verify that document is not moved (catch Exceptions)
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL }, expectedExceptions = MessagingException.class)
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user is not able to move a renamed file using its initial name.")
+ public void moveRenamedFileUsingInitialFilename() throws Exception
+ {
+ STEP("1. Using CMIS create one test user: u1");
+ testUser1 = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates a public site using CMIS");
+ publicSite = dataSite.usingUser(testUser1).createIMAPSite();
+
+ STEP("3. Admin creates a folder with a document (doc1.txt) in the public site using WebDav");
+ parentFolder = FolderModel.getRandomFolderModel();
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file 1 content");
+
+ webDavProtocol.authenticateUser(admin)
+ .usingSite(publicSite).createFolder(parentFolder)
+ .assertThat().existsInWebdav()
+ .usingResource(parentFolder).createFile(testFile1)
+ .assertThat().existsInWebdav();
+
+ STEP("4. Admin renames document1 (doc1-edited.txt) using WebDAV");
+ FileModel oldFile = new FileModel(testFile1);
+ webDavProtocol.authenticateUser(admin)
+ .usingResource(testFile1).rename("new" + testFile1.getName())
+ .assertThat().existsInRepo();
+
+ STEP("5. U1 tries to move doc1.txt to another location using IMAP");
+ FolderModel destination = new FolderModel(Utility.buildPath("Sites", publicSite.getId(), "documentLibrary"));
+ destination.setProtocolLocation(imapProtocol.authenticateUser(testUser1).usingSite(publicSite).getLastResourceWithoutPrefix());
+ imapProtocol.usingResource(oldFile).moveMessageTo(destination);
+ }
+
+ /**
+ * Scenario 61
+ * 1. Using CMIS create an user and a site.
+ * 2. Using FTP create two folders.
+ * 3. Using CMIS create documents in folder1: a-childDoc1, childDoc11, child21.
+ * 4. Using CMIS create documents in folder2: childDoc112, childDoc2, achild2.
+ * 5. Using IMAP client flag content 'childDoc112'.
+ * 6. Using IMAP find documents after search term 'child'.
+ * 7. Using IMAP find documents after search term '.*child2.*'.
+ * 8. Using IMAP find documents after search term 'childa'. No results should be displayed.
+ * 9. Using IMAP find documents after search term 'child*2'.
+ * 10. Using IMAP verify that 'childDoc112' is flagged.
+ *
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL})
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Find files and flag files.")
+ public void findFilesAndFlagFiles() throws Exception
+ {
+ STEP("1. Using CMIS create an user and a site.");
+ UserModel testUser = dataUser.createRandomTestUser();
+ SiteModel testSitePublic = dataSite.usingUser(testUser).createIMAPSite();
+
+ STEP("2. Using FTP create two folders.");
+ FolderModel folder1 = FolderModel.getRandomFolderModel();
+ FolderModel folder2 = FolderModel.getRandomFolderModel();
+
+ ftpProtocol.authenticateUser(testUser).usingSite(testSitePublic).createFolder(folder1).and().createFolder(folder2);
+
+ STEP("3. Using CMIS create documents in folder1: a-childDoc1, childDoc11, child21.");
+
+ FileModel file11 = dataContent.usingUser(testUser).usingSite(testSitePublic).usingResource(folder1)
+ .createContent(new FileModel("a-childDoc1", FileType.TEXT_PLAIN, "content"));
+ FileModel file12 = dataContent.usingUser(testUser).usingSite(testSitePublic).usingResource(folder1)
+ .createContent(new FileModel("childDoc11", FileType.TEXT_PLAIN, "content"));
+ FileModel file13 = dataContent.usingUser(testUser).usingSite(testSitePublic).usingResource(folder1)
+ .createContent(new FileModel("child21", FileType.TEXT_PLAIN, "content"));
+
+ STEP("4. Using CMIS create documents in folder2: childDoc112, childDoc2, achild2.");
+
+ FileModel file21 = dataContent.usingUser(testUser).usingSite(testSitePublic).usingResource(folder2)
+ .createContent(new FileModel("childDoc112", FileType.TEXT_PLAIN, "content"));
+ FileModel file22 = dataContent.usingUser(testUser).usingSite(testSitePublic).usingResource(folder2)
+ .createContent(new FileModel("childDoc2", FileType.TEXT_PLAIN, "content"));
+ FileModel file23 = dataContent.usingUser(testUser).usingSite(testSitePublic).usingResource(folder2)
+ .createContent(new FileModel("achild2", FileType.TEXT_PLAIN, "content"));
+
+ STEP("5. Using IMAP client flag content 'childDoc112'.");
+ imapProtocol.authenticateUser(testUser).usingResource(file21).withMessage().setFlags(Flags.Flag.ANSWERED, Flags.Flag.SEEN).updateFlags();
+
+ STEP("6. Using IMAP find documents after search term 'child'.");
+ imapProtocol.usingResource(folder1).searchSubjectFor("child")
+ .assertThat().resultsContainMessage(file11,file12,file13)
+ .usingResource(folder2).searchSubjectFor("child")
+ .assertThat().resultsContainMessage(file21,file22,file23);
+
+ STEP("7. Using IMAP find documents after search term '.*child2.*'.");
+ imapProtocol.usingResource(folder2).searchSubjectWithWildcardsFor(".*child2.*")
+ .assertThat().resultsContainMessage(file23)
+ .assertThat().resultsDoNotContainMessage(file21,file22);
+
+ STEP("8. Using IMAP find documents after search term 'childa'. No results should be displayed.");
+ imapProtocol.usingResource(folder1).searchSubjectFor("childa")
+ .assertThat().resultsDoNotContainMessage(file11,file12,file13)
+ .usingResource(folder2).searchSubjectFor("childa")
+ .assertThat().resultsDoNotContainMessage(file21,file22,file23);
+
+ STEP("9. Using IMAP find documents after search term 'child*2'.");
+ imapProtocol.usingResource(folder1).searchSubjectWithWildcardsFor("child.*2.*")
+ .assertThat().resultsContainMessage(file13)
+ .assertThat().resultsDoNotContainMessage(file11,file12)
+ .usingResource(folder2).searchSubjectWithWildcardsFor("child.*2.*")
+ .assertThat().resultsContainMessage(file21,file22)
+ .assertThat().resultsDoNotContainMessage(file23);
+
+ STEP("10. Using IMAP verify that 'childDoc112' is flagged.");
+ imapProtocol.usingResource(file21)
+ .assertThat().messageContainsFlags(Flags.Flag.ANSWERED, Flags.Flag.SEEN);
+ }
+
+ /**
+ * Scenario 62
+ * 1. Using CMIS create two test users: u1 and userToAssign
+ * 2. U1 creates a public site using CMIS: publicSite
+ * 3. U1 creates a document in public site using WebDAV: documentTest
+ * 4. U1 creates a new task with the documents created above and assigns the task to userToAssign using REST
+ * 5. Verify that userToAssign receives the task using REST
+ * 6. U1 adds items to task using REST
+ * 7. U1 removes items from task using REST
+ * 8. userToAssign gets the list of the updated items using REST
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.WORKFLOW }, executionType = ExecutionType.REGRESSION,
+ description = "Verify assigner user is able to add and remove items from task.")
+ public void assignerIsAbleToAddAndRemoveItemsFromTask() throws Exception
+ {
+ STEP("1. Using CMIS create two test users: u1 and userToAssign");
+ testUser1 = dataUser.createRandomTestUser();
+ UserModel userToAssign = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates a public site using CMIS: publicSite");
+ publicSite = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("3. U1 creates a document in public site using WebDAV: documentTest");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ webDavProtocol.authenticateUser(testUser1).usingSite(publicSite)
+ .createFile(testFile1)
+ .assertThat().webDavWrapper()
+ .assertThat().existsInRepo();
+
+ STEP("4. U1 creates a new task with the documents created above and assigns the task to userToAssign using REST");
+ processModel = restAPI.authenticateUser(testUser1).withWorkflowAPI()
+ .addProcess("activitiAdhoc", userToAssign, false, CMISUtil.Priority.Normal);
+ processTasks = restAPI.authenticateUser(userToAssign).withWorkflowAPI()
+ .usingProcess(processModel)
+ .getProcessTasks();
+ restAPI.withWorkflowAPI().usingTask(processTasks.getTaskModelByAssignee(userToAssign))
+ .addTaskItem(testFile1);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("5. Verify that userToAssign receives the task using REST");
+ processTasks = restAPI.authenticateUser(userToAssign).withWorkflowAPI().usingProcess(processModel)
+ .getProcessTasks();
+ processTasks.assertThat().entriesListContains("assignee", userToAssign.getUsername())
+ .and().entriesListContains("state", "claimed")
+ .and().paginationField("count").is("1");
+
+ STEP("6. U1 adds items to task using REST");
+ testFile2 = dataContent.usingSite(publicSite).createContent(CMISUtil.DocumentType.HTML);
+ FileModel testFile3 = dataContent.usingSite(publicSite).createContent(CMISUtil.DocumentType.PDF);
+ taskItems = restAPI.authenticateUser(testUser1).withWorkflowAPI()
+ .usingTask(processTasks.getTaskModelByAssignee(userToAssign))
+ .addTaskItems(testFile2, testFile3);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("7. U1 removes items from task using REST");
+ restAPI.authenticateUser(testUser1).withWorkflowAPI().usingTask(processTasks.getTaskModelByAssignee(userToAssign))
+ .deleteTaskItem(taskItems.getEntries().get(0).onModel());
+ restAPI.assertStatusCodeIs(HttpStatus.NO_CONTENT);
+
+ STEP("8. userToAssign gets the list of the updated items using REST");
+ restAPI.authenticateUser(userToAssign).withWorkflowAPI().usingTask(processTasks.getTaskModelByAssignee(userToAssign))
+ .getTaskItems()
+ .assertThat().entriesListContains("name", testFile1.getName())
+ .assertThat().entriesListContains("name", testFile3.getName())
+ .and().paginationField("count").is("2");
+ }
+
+ /**
+ * Scenario 63
+ * 1. Using CMIS create two test users: u1 and userToAssign
+ * 2. U1 creates a public site using CMIS: publicSite
+ * 3. U1 creates a document in public site using webDAV: documentTest
+ * 4. U1 creates a new task with the documents created above and assigns the task to userToAssign using REST
+ * 5. Verify that userToAssign receives the task using REST
+ * 6. userToAssign adds items to task using REST
+ * 7. userToAssign removes items from task using REST
+ * 8. u1 gets the list of the updated items using REST
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.WORKFLOW }, executionType = ExecutionType.REGRESSION,
+ description = "Verify assignee user is to add and remove items from task.")
+ public void assigneeIsAbleToAddAndRemoveItemsFromTask() throws Exception
+ {
+ STEP("1. Using CMIS create two test users: u1 and userToAssign");
+ testUser1 = dataUser.createRandomTestUser();
+ UserModel userToAssign = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates a public site using CMIS: publicSite");
+ publicSite = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("3. U1 creates a document in public site using webDAV: documentTest");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ webDavProtocol.authenticateUser(testUser1).usingSite(publicSite)
+ .createFile(testFile1)
+ .assertThat().existsInWebdav()
+ .assertThat().existsInRepo();
+
+ STEP("4. U1 creates a new task with the documents created above and assigns the task to userToAssign using REST");
+ processModel = restAPI.authenticateUser(testUser1).withWorkflowAPI()
+ .addProcess("activitiAdhoc", userToAssign, false, CMISUtil.Priority.Normal);
+ processTasks = restAPI.authenticateUser(userToAssign).withWorkflowAPI()
+ .usingProcess(processModel)
+ .getProcessTasks();
+ restAPI.withWorkflowAPI().usingTask(processTasks.getTaskModelByAssignee(userToAssign))
+ .addTaskItem(testFile1);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("5. Verify that userToAssign receives the task using REST");
+ processTasks = restAPI.authenticateUser(userToAssign).withWorkflowAPI().usingProcess(processModel)
+ .getProcessTasks();
+ processTasks.assertThat().entriesListContains("assignee", userToAssign.getUsername())
+ .and().entriesListContains("state", "claimed")
+ .and().paginationField("count").is("1");
+
+ STEP("6. userToAssign adds items to task using REST");
+ testFile2 = dataContent.usingSite(publicSite).createContent(CMISUtil.DocumentType.HTML);
+ FileModel testFile3 = dataContent.usingSite(publicSite).createContent(CMISUtil.DocumentType.PDF);
+
+ taskItems = restAPI.withWorkflowAPI().usingTask(processTasks.getTaskModelByAssignee(userToAssign))
+ .addTaskItems(testFile2, testFile3);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("7. userToAssign removes items from task using REST");
+ restAPI.withWorkflowAPI().usingTask(processTasks.getTaskModelByAssignee(userToAssign))
+ .deleteTaskItem(taskItems.getEntries().get(1).onModel());
+ restAPI.assertStatusCodeIs(HttpStatus.NO_CONTENT);
+
+ STEP("8. U1 gets the list of the updated items using REST");
+ restAPI.authenticateUser(testUser1).withWorkflowAPI().usingTask(processTasks.getTaskModelByAssignee(userToAssign))
+ .getTaskItems()
+ .assertThat().entriesListContains("name", testFile2.getName())
+ .assertThat().entriesListContains("name", testFile1.getName())
+ .and().paginationField("count").is("2");
+ }
+
+ /**
+ * Scenario 66
+ * 1. Using CMIS create two test users: u1 and userToAssign
+ * 2. U1 creates a public site using CMIS: publicSite
+ * 3. U1 creates a document in public site using webDavProtocol: documentTest
+ * 4. U1 creates a new task with the documents created above and assigns the task to userToAssign using REST
+ * 5. Verify that userToAssign receives the task using REST
+ * 6. Status is changed by userToAssign using REST
+ * 7. U1 gets the modified values from the task using REST
+ * 8. userToAssign marks the task as 'Resolved' using REST
+ * 9. U1 receives the task using REST
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.WORKFLOW }, executionType = ExecutionType.REGRESSION,
+ description = "Verify assignee user is able to update task.")
+ public void assigneeIsAbleToUpdateTask() throws Exception
+ {
+ STEP("1. Using CMIS create two test users: u1 and userToAssign");
+ testUser1 = dataUser.createRandomTestUser();
+ userToAssign = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates a public site using CMIS: publicSite");
+ publicSite = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("3. U1 creates a document in public site using webDavProtocol: documentTest");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ webDavProtocol.authenticateUser(testUser1).usingSite(publicSite).createFile(testFile1).assertThat().existsInRepo();
+
+ STEP("4. U1 creates a new task with the documents created above and assigns the task to userToAssign using REST");
+ processModel = restAPI.authenticateUser(testUser1).withWorkflowAPI()
+ .addProcess("activitiAdhoc", userToAssign, false, CMISUtil.Priority.Normal);
+ restAPI.withWorkflowAPI().usingProcess(processModel).addProcessItem(testFile1);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("5. Verify that userToAssign receives the task using REST");
+ taskModel = restAPI.authenticateUser(userToAssign).withWorkflowAPI().usingProcess(processModel).getProcessTasks()
+ .getTaskModelByAssignee(userToAssign)
+ .assertThat().field("assignee").is(userToAssign.getUsername());
+
+ STEP("6. Status is changed by userToAssign using REST");
+ restTaskModel = restAPI.authenticateUser(userToAssign).withParams("select=state").withWorkflowAPI().usingTask(taskModel)
+ .updateTask("claimed");
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+
+ restTaskModel.assertThat().field("id").is(taskModel.getId())
+ .and().field("state").is("claimed");
+
+ STEP("7. U1 gets the modified values from the task using REST");
+ restAPI.authenticateUser(testUser1).withWorkflowAPI().usingTask(restTaskModel).getTask()
+ .assertThat().field("id").is(taskModel.getId())
+ .and().field("state").is("claimed");
+
+ STEP("8. userToAssign marks the task as 'Resolved' using REST");
+ restTaskModel = restAPI.authenticateUser(userToAssign).withParams("select=state").withWorkflowAPI().usingTask(taskModel)
+ .updateTask("completed");
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ restTaskModel.assertThat().field("id").is(taskModel.getId())
+ .and().field("state").is("completed")
+ .and().field("assignee").is(userToAssign.getUsername());
+
+ STEP("9. U1 receives the task using REST");
+ restAPI.authenticateUser(testUser1).withWorkflowAPI().usingTask(restTaskModel).getTask()
+ .assertThat().field("state").is("completed");
+ }
+
+ /**
+ * Scenario 67
+ * 1. Using CMIS create two test users: U1 and userToAssign
+ * 2. U1 creates a public site using CMIS: publicSite
+ * 3. U1 creates a document in public site using webDavProtocol: documentTest
+ * 4. U1 creates a new task with the documents created above and assigns the task to userToAssign using REST
+ * 5. Verify that userToAssign receives the task using REST
+ * 6. Status is changed by U1 using REST
+ * 7. userToAssign gets the modified values from the task using REST
+ * 8. userToAssign marks the task as 'Resolved' using REST
+ * 9. U1 receives the task using REST
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.WORKFLOW }, executionType = ExecutionType.REGRESSION,
+ description = "Verify assigner user is able to update task.")
+ public void assignerIsAbleToUpdateTask() throws Exception
+ {
+ STEP("1. Using CMIS create two test users: u1 and userToAssign");
+ testUser1 = dataUser.createRandomTestUser();
+ userToAssign = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates a public site using CMIS: publicSite");
+ publicSite = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("3. U1 creates a document in public site using webDavProtocol: documentTest");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ webDavProtocol.authenticateUser(testUser1).usingSite(publicSite).createFile(testFile1).assertThat().existsInRepo();
+
+ STEP("4. U1 creates a new task with the documents created above and assigns the task to userToAssign using REST");
+ processModel = restAPI.authenticateUser(testUser1).withWorkflowAPI()
+ .addProcess("activitiAdhoc", userToAssign, false, CMISUtil.Priority.Normal);
+ restAPI.withWorkflowAPI().usingProcess(processModel).addProcessItem(testFile1);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("5. Verify that userToAssign receives the task using REST");
+ taskModel = restAPI.authenticateUser(userToAssign).withWorkflowAPI().usingProcess(processModel).getProcessTasks().getEntryByIndex(0)
+ .assertThat().field("assignee").is(userToAssign.getUsername());
+
+ STEP("6. Status is changed by U1 using REST");
+ JsonObject inputJson = JsonBodyGenerator.defineJSON().add("state", "delegated").add("assignee", userToAssign.getUsername()).build();
+ restTaskModel = restAPI.authenticateUser(testUser1).withParams("select=state,assignee").withWorkflowAPI().usingTask(taskModel)
+ .updateTask(inputJson);
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+
+ restTaskModel.assertThat().field("id").is(taskModel.getId())
+ .and().field("state").is("delegated")
+ .and().field("owner").is(testUser1.getUsername())
+ .and().field("assignee").is(userToAssign.getUsername());
+
+ STEP("7. userToAssign gets the modified values from the task using REST");
+ restAPI.authenticateUser(userToAssign).withWorkflowAPI().usingProcess(processModel).getProcessTasks().getTaskModelByAssignee(userToAssign)
+ .assertThat().field("id").is(taskModel.getId())
+ .and().field("state").is("delegated");
+
+ STEP("8. userToAssign marks the task as 'Resolved' using REST");
+ restTaskModel = restAPI.withParams("select=state").withWorkflowAPI().usingTask(taskModel).updateTask("resolved");
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ restTaskModel.assertThat().field("id").is(taskModel.getId())
+ .and().field("state").is("resolved");
+
+ STEP("9. U1 receives the task using REST");
+ restAPI.authenticateUser(testUser1).withWorkflowAPI().usingProcess(processModel).getProcessTasks().getEntryByIndex(0)
+ .assertThat().field("state").is("resolved")
+ .assertThat().field("id").is(taskModel.getId())
+ .assertThat().field("assignee").is(testUser1.getUsername());
+ }
+
+ /**
+ * Scenario 68
+ * 1. Using CMIS create two test users: u1 and userToAssign
+ * 2. U1 creates a public site using CMIS: publicSite
+ * 3. U1 creates a document in public site using webDavProtocol: documentTest
+ * 4. U1 creates a new task with the documents created above and assigns the task to userToAssign using REST
+ * 5. Verify that userToAssign receives the task using REST
+ * 6. U1 cancels workflow using REST
+ * 7. Verify task is no longer present for userToAssign
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.WORKFLOW }, executionType = ExecutionType.REGRESSION,
+ description = "Verify assigner user is able to cancel an workflow.")
+ public void assignerIsAbleToCancelWorkflow() throws Exception
+ {
+ STEP("1. Using CMIS create two test users: u1 and userToAssign");
+ testUser1 = dataUser.createRandomTestUser();
+ userToAssign = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates a public site using CMIS: publicSite");
+ publicSite = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("3. U1 creates a document in public site using webDavProtocol: documentTest");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ webDavProtocol.authenticateUser(testUser1).usingSite(publicSite).createFile(testFile1).assertThat().existsInRepo();
+
+ STEP("4. U1 creates a new task with the documents created above and assigns the task to userToAssign using REST");
+ processModel = restAPI.authenticateUser(testUser1).withWorkflowAPI().addProcess("activitiAdhoc", userToAssign, false, CMISUtil.Priority.Normal);
+ restAPI.withWorkflowAPI().usingProcess(processModel).addProcessItem(testFile1);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ restAPI.withWorkflowAPI().getProcesses()
+// due changing to java 11 the id changed
+// .assertThat().entriesListContains("processDefinitionId", WorkflowService.WorkflowType.NewTask.getId())
+ .assertThat().entriesListContains("startActivityId", "start")
+ .and().paginationField("count").is("1");
+
+ STEP("5. Verify that userToAssign receives the task using REST");
+ restAPI.authenticateUser(userToAssign).withWorkflowAPI().usingProcess(processModel).getProcessTasks()
+ .getTaskModelByAssignee(userToAssign)
+ .assertThat().field("assignee").is(userToAssign.getUsername());
+
+ STEP("6. U1 cancels workflow using REST");
+ Assert.assertTrue(dataWorkflow.usingUser(testUser1).cancelProcess(processModel), "User is able to cancel the workflow");
+
+ restAPI.withWorkflowAPI().getProcesses().assertThat()
+ .entriesListDoesNotContain("id", processModel.getId())
+ .and().paginationField("count").is("0");
+
+ STEP("7. Verify task is no longer present for userToAssign: MyTasks");
+ restAPI.authenticateUser(userToAssign).withWorkflowAPI().getProcesses().assertThat()
+ .entriesListDoesNotContain("id", processModel.getId());
+ }
+
+ /**
+ * Scenario 69
+ * 1. Using CMIS create two test users: u1 and userToAssign
+ * 2. U1 creates a public site using CMIS: publicSite
+ * 3. U1 creates a document in public site using webDavProtocol: documentTest
+ * 4. U1 creates a new task with the documents created above and assigns the task to userToAssign using REST
+ * 5. Verify that userToAssign receives the task using REST
+ * 6. userToAssign is not able to cancel workflow using REST
+ * 7. Verify U1 still has the workflow
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.WORKFLOW }, executionType = ExecutionType.REGRESSION,
+ description = "Verify assignee user is able to cancel an workflow.")
+ public void assigneeIsNotAbleToCancelWorkflow() throws Exception
+ {
+ STEP("1. Using CMIS create two test users: u1 and userToAssign");
+ testUser1 = dataUser.createRandomTestUser();
+ userToAssign = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates a public site using CMIS: publicSite");
+ publicSite = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("3. U1 creates a document in public site using webDavProtocol: documentTest");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ webDavProtocol.authenticateUser(testUser1).usingSite(publicSite).createFile(testFile1).assertThat().existsInRepo();
+
+ STEP("4. U1 creates a new task with the documents created above and assigns the task to userToAssign using REST");
+ processModel = restAPI.authenticateUser(testUser1).withWorkflowAPI().addProcess("activitiAdhoc", userToAssign, false, CMISUtil.Priority.Normal);
+ restAPI.withWorkflowAPI().usingProcess(processModel).addProcessItem(testFile1);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ restAPI.withWorkflowAPI().getProcesses()
+ .assertThat().entriesListContains("startActivityId", "start")
+ .and().paginationField("count").is("1");
+
+ STEP("5. Verify that userToAssign receives the task using REST");
+ restAPI.authenticateUser(userToAssign).withWorkflowAPI().usingProcess(processModel).getProcessTasks()
+ .getTaskModelByAssignee(userToAssign)
+ .assertThat().field("assignee").is(userToAssign.getUsername());
+
+ STEP("6. userToAssign is not able to cancel workflow using REST");
+ Assert.assertFalse(dataWorkflow.usingUser(userToAssign).cancelProcess(processModel), "User is unable to cancel workflow.");
+
+ restAPI.withWorkflowAPI().getProcesses().assertThat()
+ .entriesListContains("id", processModel.getId())
+ .and().paginationField("count").is("1");
+
+ STEP("7. Verify U1 still has the workflow");
+ restAPI.authenticateUser(userToAssign).withWorkflowAPI().getProcesses().assertThat()
+ .entriesListContains("id", processModel.getId())
+ .and().paginationField("count").is("1");
+ }
+
+ /**
+ * Scenario 70
+ * 1. Using CMIS create two test users: u1 and userToAssign
+ * 2. U1 creates a public site using CMIS: publicSite
+ * 3. U1 creates a document in public site using webDavProtocol: documentTest
+ * 4. U1 creates a new task with the documents created above and assigns the task to userToAssign using REST
+ * 5. Verify that userToAssign receives the task using REST
+ * 6. U1 renames the document using webDAV
+ * 7. Verify renamed document with users: U1 and userToAssign using RestAPI
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.WORKFLOW }, executionType = ExecutionType.REGRESSION,
+ description = "Verify assigner user is able to rename items from a task.")
+ public void assignerIsAbleToRenameItemsFromTask() throws Exception
+ {
+ STEP("1. Using CMIS create two test users: u1 and userToAssign");
+ testUser1 = dataUser.createRandomTestUser();
+ userToAssign = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates a public site using CMIS: publicSite");
+ publicSite = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("3. U1 creates a document in public site using webDavProtocol: documentTest");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ webDavProtocol.authenticateUser(testUser1).usingSite(publicSite).createFile(testFile1).assertThat().existsInRepo();
+
+ STEP("4. U1 creates a new task with the documents created above and assigns the task to userToAssign using REST");
+ processModel = restAPI.authenticateUser(testUser1).withWorkflowAPI()
+ .addProcess("activitiAdhoc", userToAssign, false, CMISUtil.Priority.Normal);
+ restAPI.withWorkflowAPI().usingProcess(processModel).addProcessItem(testFile1);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("5. Verify that userToAssign receives the task using REST");
+ taskModel = restAPI.authenticateUser(userToAssign).withWorkflowAPI().usingProcess(processModel).getProcessTasks()
+ .getTaskModelByAssignee(userToAssign)
+ .assertThat().field("assignee").is(userToAssign.getUsername());
+
+ STEP("6. U1 renames the document using webDAV");
+ FileModel originalFileModel = new FileModel(testFile1);
+ webDavProtocol.authenticateUser(testUser1).usingSite(publicSite)
+ .usingResource(testFile1).and().assertThat().existsInRepo()
+ .when().rename(testFile1.getName() + "-edit").assertThat().existsInRepo()
+ .and().assertThat().hasStatus(org.apache.commons.httpclient.HttpStatus.SC_CREATED)
+ .then().usingSite(publicSite).usingResource(originalFileModel).assertThat().doesNotExistInRepo();
+
+ STEP("7. Verify renamed document with users: U1 and userToAssign using RestAPI");
+ processTasks = restAPI.authenticateUser(testUser1).withWorkflowAPI().usingProcess(processModel)
+ .getProcessTasks();
+ restAPI.withWorkflowAPI().usingTask(processTasks.getTaskModelByAssignee(userToAssign))
+ .getTaskItems()
+ .assertThat().entriesListContains("name", testFile1.getName()+ "-edit")
+ .assertThat().entriesListDoesNotContain("name", originalFileModel.getName())
+ .and().paginationField("count").is("1");
+
+ processTasks = restAPI.authenticateUser(userToAssign).withWorkflowAPI().usingProcess(processModel)
+ .getProcessTasks();
+ restAPI.authenticateUser(userToAssign).withWorkflowAPI().usingTask(processTasks.getTaskModelByAssignee(userToAssign))
+ .getTaskItems()
+ .assertThat().entriesListContains("name", testFile1.getName()+ "-edit")
+ .assertThat().entriesListDoesNotContain("name", originalFileModel.getName())
+ .and().paginationField("count").is("1");
+ }
+
+ /**
+ * Scenario 71
+ * 1. Using CMIS create two test users: u1 and userToAssign
+ * 2. U1 creates a public site using CMIS: publicSite
+ * 3. U1 creates a document in public site using webDavProtocol: documentTest
+ * 4. U1 creates a new task with the documents created above and assigns the task to userToAssign using REST
+ * 5. Verify that userToAssign receives the task using REST
+ * 6. U1 deletes the document using webDAV
+ * 7. Verify no documents are present with users: U1 and userToAssign using RestAPI
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.WORKFLOW }, executionType = ExecutionType.REGRESSION,
+ description = "Verify assigner user is able to delete items from a task.")
+ public void assignerIsAbleToDeleteItemsFromTask() throws Exception
+ {
+ STEP("1. Using CMIS create two test users: u1 and userToAssign");
+ testUser1 = dataUser.createRandomTestUser();
+ userToAssign = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates a public site using CMIS: publicSite");
+ publicSite = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("3. U1 creates a document in public site using webDavProtocol: documentTest");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ webDavProtocol.authenticateUser(testUser1).usingSite(publicSite).createFile(testFile1).assertThat().existsInRepo();
+
+ STEP("4. U1 creates a new task with the documents created above and assigns the task to userToAssign using REST");
+ processModel = restAPI.authenticateUser(testUser1).withWorkflowAPI()
+ .addProcess("activitiAdhoc", userToAssign, false, CMISUtil.Priority.Normal);
+ restAPI.withWorkflowAPI().usingProcess(processModel).addProcessItem(testFile1);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("5. Verify that userToAssign receives the task using REST");
+ taskModel = restAPI.authenticateUser(userToAssign).withWorkflowAPI().usingProcess(processModel).getProcessTasks()
+ .getTaskModelByAssignee(userToAssign)
+ .assertThat().field("assignee").is(userToAssign.getUsername());
+
+ STEP("6. U1 deletes the document using webDAV");
+ webDavProtocol.authenticateUser(testUser1).usingSite(publicSite)
+ .usingResource(testFile1).delete()
+ .assertThat().hasStatus(org.apache.commons.httpclient.HttpStatus.SC_OK)
+ .and().assertThat().doesNotExistInRepo()
+ .and().assertThat().doesNotExistInWebdav()
+ .and().assertThat().hasStatus(org.apache.commons.httpclient.HttpStatus.SC_NOT_FOUND);
+
+ STEP("7. Verify no documents are present with users: U1 and userToAssign using RestAPI");
+ processTasks = restAPI.authenticateUser(testUser1).withWorkflowAPI().usingProcess(processModel)
+ .getProcessTasks();
+ restAPI.withWorkflowAPI().usingTask(processTasks.getTaskModelByAssignee(userToAssign)).getTaskItems().assertThat()
+ .entriesListDoesNotContain("name", testFile1.getName()).and()
+ .paginationField("count").is("0");
+
+ processTasks = restAPI.authenticateUser(userToAssign).withWorkflowAPI().usingProcess(processModel).getProcessTasks();
+ restAPI.authenticateUser(userToAssign).withWorkflowAPI().usingTask(processTasks.getTaskModelByAssignee(userToAssign)).getTaskItems().assertThat()
+ .entriesListDoesNotContain("name", testFile1.getName()).and()
+ .paginationField("count").is("0");
+ }
+
+
+ /**
+ * Scenario 72
+ * 1. Using CMIS create 1 test user: u1
+ * 2. U1 creates folder1 in a public site using IMAP
+ * 3. U1 creates file with special symbols in its name using FTP inside the public site
+ * 4. U1 adds some special characters in document content using CMIS
+ * 5. U1 renames document to a different name using special chars using FTP
+ * 6. U1 copy document to the folder created above using IMAP
+ * 7. U1 deletes document from initial location using CMIS
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user is able to create, rename, update content, delete a file with special symbols in its name.")
+ public void userIsAbleToDoCRUDActionsOnFileWithSpecialName() throws Exception
+ {
+ STEP("1. Using CMIS create 1 test user: u1");
+ testUser1 = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates folder1 in a public site using IMAP");
+ publicSite = dataSite.usingUser(testUser1).createIMAPSite();
+ parentFolder = FolderModel.getRandomFolderModel();
+
+ imapProtocol.authenticateUser(testUser1)
+ .usingSite(publicSite).createFolder(parentFolder)
+ .assertThat().existsInImap().and()
+ .assertThat().existsInRepo();
+
+ STEP("3. U1 creates file with special symbols in its name using FTP inside the public site");
+ String fileName = RandomData.getRandomAlphanumeric();
+ testFile1 = new FileModel(fileName + "\ufeff\u6768\u6728\u91d1.doc");
+ ftpProtocol.authenticateUser(testUser1)
+ .then().usingSite(publicSite)
+ .createFile(testFile1).and().assertThat().existsInRepo()
+ .and().assertThat().existsInFtp();
+
+ STEP("4. U1 adds some special characters in document content using CMIS");
+ cmisAPI.authenticateUser(testUser1).usingResource(testFile1).update("!@#$%^&()-_+={}[].,")
+ .assertThat().contentIs("!@#$%^&()-_+={}[].,");
+
+ STEP("5. U1 renames document to a different name using special chars using FTP");
+ ftpProtocol.usingResource(testFile1).rename(fileName + "!@#$%^&()-_+={}[].,")
+ .assertThat().existsInRepo();
+
+ testFile2 = new FileModel(testFile1);
+ STEP("6. U1 copy document to the folder created above using IMAP");
+ imapProtocol.authenticateUser(testUser1).usingSite(publicSite)
+ .usingResource(testFile1)
+ .assertThat().existsInRepo()
+ .assertThat().existsInImap()
+ .copyMessageTo(parentFolder)
+ .assertThat().containsMessages(testFile1);
+
+ STEP("7. U1 deletes document from initial location using CMIS");
+ cmisAPI.usingResource(testFile2).delete().assertThat().doesNotExistInRepo()
+ .usingResource(parentFolder).assertThat().hasFiles(testFile1);
+ }
+
+ /**
+ * Scenario 75
+ * 1. Using CMIS create 3 test users: u1, u2 and u3
+ * 2. U1 creates document1 in a public site using WebDAV
+ * 3. U1 adds U3 to his site as Site manager using REST
+ * 4. Check that U2 is not able to update document using FTP.
+ * 5. Check that U3 is able to update document using WebDAV.
+ * 6. U1 changes site visibility to moderated using REST
+ * 7. Check that U2 is not able to update document using FTP.
+ * 8. Check that U3 is able to update document WebDAV.
+ * 9. U1 changes site visibility to private using REST
+ * 10. Check that U2 is not able to update document using FTP.
+ * 11. Check that U3 is able to update document WebDAV.
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Verify users ability to update files when site visibility is changed.")
+ public void updateFileByRegularUserAndSiteMemberWhenSiteVisibilityIsChanged() throws Exception
+ {
+ STEP("1. Using CMIS create 3 test users: u1, u2 and u3");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+ UserModel testUser3 = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates document1 in a public site using WebDAV");
+ publicSite = dataSite.usingUser(testUser1).createPublicRandomSite();
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ webDavProtocol.authenticateUser(testUser1)
+ .usingSite(publicSite).createFile(testFile1)
+ .assertThat().existsInRepo();
+
+ STEP("3. U1 adds U3 to his site as Site manager using REST");
+ testUser3.setUserRole(UserRole.SiteManager);
+ restAPI.authenticateUser(testUser1).withCoreAPI()
+ .usingSite(publicSite).addPerson(testUser3);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("4. Check that U2 is able to update document using FTP.");
+ ftpProtocol.authenticateUser(testUser2).usingResource(testFile1).update("u2 update when site visibility is public")
+ .assertThat().contentIs("file1 content");
+
+ STEP("5. Check that U3 is able to update document using WebDav.");
+ webDavProtocol.authenticateUser(testUser3).usingResource(testFile1).update("u3 update when site visibility is public")
+ .assertThat().contentIs("u3 update when site visibility is public");
+
+ STEP("6. U1 changes site visibility to moderated using REST");
+ dataSite.usingUser(testUser1).updateSiteVisibility(publicSite, Visibility.MODERATED);
+
+ STEP("7. Check that U2 is not able to update document using FTP.");
+ ftpProtocol.authenticateUser(testUser2).usingResource(testFile1).update("u2 update when site visibility is moderated")
+ .assertThat().hasReplyCode(FTPReply.ACTION_ABORTED);
+
+ STEP("8. Check that U3 is able to update document WebDAV.");
+ webDavProtocol.authenticateUser(testUser3).usingResource(testFile1).update("u3 update when site visibility is moderated")
+ .assertThat().contentIs("u3 update when site visibility is moderated");
+
+ STEP("9. U1 changes site visibility to private using REST");
+ dataSite.usingUser(testUser1).updateSiteVisibility(publicSite, Visibility.PRIVATE);
+
+ STEP("10. Check that U2 is not able to update document using FTP.");
+ ftpProtocol.authenticateUser(testUser2).usingResource(testFile1).update("u2 update when site visibility is private")
+ .assertThat().hasReplyCode(FTPReply.ACTION_ABORTED);
+
+ STEP("11. Check that U3 is able to update document WebDAV.");
+ webDavProtocol.authenticateUser(testUser3).usingResource(testFile1).update("u3 update when site visibility is private")
+ .assertThat().contentIs("u3 update when site visibility is private");
+ }
+
+ /**
+ * Scenario 89
+ * 1. Using CMIS create 2 test users: u1 and u2
+ * 2. U1 creates document1 in a public site using FTP
+ * 3. U1 creates a New Task with the document created above and assigns it to U2 using REST
+ * 4. U2 updates the task as resolved using REST
+ * 5. U1 deletes the task process using REST. Assert that process is deleted successfully among with its tasks.
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.WORKFLOW }, executionType = ExecutionType.REGRESSION,
+ description = "Verify initiator is able to delete a process after its task is updated by assignee as resolved.")
+ public void deleteWorkflowByInitiator() throws Exception
+ {
+ STEP("1. Using CMIS create 2 test users: u1 and u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates document1 in a public site using FTP");
+ publicSite = dataSite.usingUser(testUser1).createPublicRandomSite();
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ ftpProtocol.authenticateUser(testUser1).usingSite(publicSite).createFile(testFile1).assertThat().existsInRepo();
+
+ STEP("3. U1 creates a New Task with the document created above and assigns it to U2 using REST");
+ processModel = restAPI.authenticateUser(testUser1).withWorkflowAPI()
+ .addProcess("activitiAdhoc", testUser2, false, CMISUtil.Priority.Normal);
+ restAPI.withWorkflowAPI().usingProcess(processModel).addProcessItem(testFile1);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("4. U2 updates the task as Done using REST");
+ processTasks = restAPI.authenticateUser(testUser2).withWorkflowAPI().usingProcess(processModel).getProcessTasks();
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+
+ RestTaskModel processTask = processTasks.getTaskModelByAssignee(testUser2);
+
+ restAPI.withParams("select=state").withWorkflowAPI().usingTask(processTask).updateTask("resolved");
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+
+ STEP("5. U1 deletes the task process using REST. Assert that process is deleted successfully among with its tasks.");
+ restAPI.authenticateUser(testUser1).withWorkflowAPI().usingProcess(processModel).deleteProcess();
+ restAPI.assertStatusCodeIs(HttpStatus.NO_CONTENT);
+ restAPI.withWorkflowAPI().getProcesses().assertThat().entriesListDoesNotContain("id", processModel.getId());
+ restAPI.withWorkflowAPI().getTasks().assertThat().entriesListDoesNotContain("id", processTask.getId());
+ }
+
+ /**
+ * Scenario 90
+ * 1. Using CMIS create 2 test users: u1 and u2
+ * 2. U1 creates document1 in a public site using WebDAV
+ * 3. U1 creates a New Task with the document created above and assigns it to U2 using REST
+ * 4. U2 updates the task as resolved using REST
+ * 5. U1 updates the task as completed using REST
+ * 6. U2 deletes the task process using REST. Assert that process is not deleted.
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.WORKFLOW }, executionType = ExecutionType.REGRESSION,
+ description = "Verify assignee is not able to delete a process after its task is completed.")
+ public void deleteWorkflowByAssignee() throws Exception
+ {
+ STEP("1. Using CMIS create 2 test users: u1 and u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates document1 in a public site using WebDAV");
+ publicSite = dataSite.usingUser(testUser1).createPublicRandomSite();
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ webDavProtocol.authenticateUser(testUser1).usingSite(publicSite).createFile(testFile1).assertThat().existsInRepo();
+
+ STEP("3. U1 creates a New Task with the document created above and assigns it to U2 using REST");
+ processModel = restAPI.authenticateUser(testUser1).withWorkflowAPI()
+ .addProcess("activitiAdhoc", testUser2, false, CMISUtil.Priority.Normal);
+ restAPI.withWorkflowAPI().usingProcess(processModel).addProcessItem(testFile1);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("4. U2 updates the task as resolved using REST");
+ processTasks = restAPI.authenticateUser(testUser2).withWorkflowAPI().usingProcess(processModel).getProcessTasks();
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+
+ RestTaskModel processTask = processTasks.getTaskModelByAssignee(testUser2);
+
+ restAPI.withParams("select=state").withWorkflowAPI().usingTask(processTask).updateTask("resolved");
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+
+ STEP("5. U1 updates the task as completed using REST");
+ restAPI.authenticateUser(testUser1).withParams("select=state").withWorkflowAPI().usingTask(processTask).updateTask("completed");
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+
+ STEP("6. U2 deletes the task process using REST. Assert that process is not deleted. ");
+ restAPI.authenticateUser(testUser2).withWorkflowAPI().usingProcess(processModel).deleteProcess();
+ restAPI.assertStatusCodeIs(HttpStatus.FORBIDDEN)
+ .assertLastError().containsSummary(String.format(RestErrorModel.ACCESS_INFORMATION_NOT_ALLOWED, processModel.getId()));
+ }
+
+ /**
+ * Scenario 91
+ * 1. Using CMIS create 2 test users: u1 and u2
+ * 2. U1 creates document1 in a public site using CMIS
+ * 3. U1 creates a New Task with the document created above and assigns it to U2 using REST
+ * 4. U1 deletes the task process using REST. Assert that process is deleted.
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.WORKFLOW }, executionType = ExecutionType.REGRESSION,
+ description = "Verify initiator is able to delete a process even if its task is not completed.")
+ public void deleteWorkflowWithoutCompletingIt() throws Exception
+ {
+ STEP("1. Using CMIS create 2 test users: u1 and u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates document1 in a public site using CMIS");
+ publicSite = dataSite.usingUser(testUser1).createPublicRandomSite();
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ cmisAPI.authenticateUser(testUser1).usingSite(publicSite).createFile(testFile1).assertThat().existsInRepo();
+
+ STEP("3. U1 creates a New Task with the document created above and assigns it to U2 using REST");
+ processModel = restAPI.authenticateUser(testUser1).withWorkflowAPI()
+ .addProcess("activitiAdhoc", testUser2, false, CMISUtil.Priority.Normal);
+ restAPI.withWorkflowAPI().usingProcess(processModel).addProcessItem(testFile1);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("4. U1 deletes the task process using REST. Assert that process is deleted.");
+ restAPI.withWorkflowAPI().usingProcess(processModel).deleteProcess();
+ restAPI.assertStatusCodeIs(HttpStatus.NO_CONTENT);
+ restAPI.withWorkflowAPI().getProcesses().assertThat().entriesListDoesNotContain("id", processModel.getId());
+ }
+
+ /**
+ * Scenario 94
+ * 1. Using CMIS create one test user: u1
+ * 2. Using FTP create file in unauthorized folder (Data Dictionary)
+ * 3. Verify that document is not created
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT}, executionType = ExecutionType.REGRESSION,
+ description = "Verify that document is not created in unauthorized folder (Data Dictonary)")
+ public void createUserMakeUnathorizedAction() throws Exception
+ {
+ STEP("1. Using CMIS creates one test user: u1");
+ testUser1 = dataUser.createRandomTestUser();
+
+ STEP("2. Using FTP create file in unauthorized folder (Data Dictionary). 3. Verify that document is not created");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+
+ ftpProtocol.authenticateUser(testUser1)
+ .changeWorkingDirectory(ftpProtocol.getDataDictionaryPath())
+ .assertThat().currentFolderIs(ftpProtocol.getDataDictionaryPath())
+ .createFile(testFile1).assertThat().doesNotExistInFtp();
+ }
+
+ /**
+ * Scenario 95
+ * 1. Using CMIS create 2 test users: u1 and u2
+ * 2. U1 creates 2 documents in User Homes using CMIS
+ * 3. U1 verifies the list of available process definitions using REST
+ * 4. U1 creates a workflow of type "activitiAdhoc" with the documents created above and assign it to u2 using REST
+ * 5. U1 adds a new process variable using REST
+ * 6. U2 gets the process variables using REST
+ * 7. U2 closes the task using REST
+ * 8. Verify that user2 doesn't have access to the documents attached to the task using FTP
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.WORKFLOW}, executionType = ExecutionType.REGRESSION,
+ description = "Verify assignee user is able to get a process variable added by another user.")
+ public void createWorkflowProcessWithNewProcessVariable() throws Exception
+ {
+ STEP("1. Using CMIS create 2 test users: u1 and u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates 2 documents in User Homes using CMIS");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ testFile2 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file2 content");
+ cmisAPI.authenticateUser(testUser1).usingUserHome()
+ .createFile(testFile1).assertThat().existsInRepo()
+ .createFile(testFile2).assertThat().existsInRepo();
+
+ STEP("3. U1 verifies the list of available process definitions using REST");
+ RestProcessDefinitionModelsCollection procDefinitions = restAPI.authenticateUser(testUser1).withWorkflowAPI().getAllProcessDefinitions();
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ procDefinitions.assertThat().entriesListContains("key", "activitiAdhoc");
+
+ STEP("4. U1 creates a workflow of type 'activitiAdhoc' with the documents created above and assign it to u2 using REST");
+ processModel = restAPI.authenticateUser(testUser1).withWorkflowAPI()
+ .addProcess("activitiAdhoc", testUser2, false, CMISUtil.Priority.Normal);
+ restAPI.withWorkflowAPI().usingProcess(processModel).addProcessItem(testFile1);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+ restAPI.withWorkflowAPI().usingProcess(processModel).addProcessItem(testFile2);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("5. U1 adds a new process variable using REST");
+ RestProcessVariableModel variableModel = RestProcessVariableModel.getRandomProcessVariableModel("d:text");
+
+ RestProcessVariableModel processVariable = restAPI.withWorkflowAPI().usingProcess(processModel).addProcessVariable(variableModel);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+ processVariable.assertThat().field("name").is(variableModel.getName())
+ .and().field("type").is(variableModel.getType())
+ .and().field("value").is(variableModel.getValue());
+
+ STEP("6. U2 gets the process variables using REST");
+ RestProcessVariableCollection processVariables = restAPI.authenticateUser(testUser2).withWorkflowAPI().usingProcess(processModel).getProcessVariables();
+ processVariables.getProcessVariableByName(processVariable.getName())
+ .assertThat().field("type").is(processVariable.getType())
+ .assertThat().field("value").is(processVariable.getValue());
+
+ processVariables.getProcessVariableByName("bpm_assignee")
+ .assertThat().field("type").is("cm:person")
+ .assertThat().field("value").is(testUser2.getUsername());
+
+ processVariables.getProcessVariableByName("bpm_priority")
+ .assertThat().field("type").is("d:int")
+ .assertThat().field("value").is(CMISUtil.Priority.Normal.getLevel());
+
+ processVariables.getProcessVariableByName("bpm_sendEMailNotifications")
+ .assertThat().field("type").is("d:boolean")
+ .assertThat().field("value").is(false);
+
+ processVariables.getProcessVariableByName("initiator")
+ .assertThat().field("type").is("d:noderef")
+ .assertThat().field("value").is(testUser1.getUsername());
+
+ processVariables.getProcessVariableByName("bpm_percentComplete")
+ .assertThat().field("type").is("d:int")
+ .assertThat().field("value").is(0);
+
+ STEP("7. U2 closes the task using REST");
+ RestTaskModel processTask = restAPI.withWorkflowAPI().usingProcess(processModel).getProcessTasks().getTaskModelByAssignee(testUser2);
+ restAPI.withParams("select=state").withWorkflowAPI().usingTask(processTask).updateTask("completed");
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+
+ STEP("8. Verify that user2 doesn't have access to the documents attached to the task using FTP");
+ ftpProtocol.authenticateUser(testUser2)
+ .usingResource(testFile1).assertThat().hasReplyCode(FTPReply.FILE_UNAVAILABLE).and().assertThat().doesNotExistInFtp()
+ .usingResource(testFile2).assertThat().hasReplyCode(FTPReply.FILE_UNAVAILABLE).and().assertThat().doesNotExistInFtp();
+ }
+
+ /**
+ * Scenario 96
+ * 1. Using CMIS create 2 test users: u1 and u2.
+ * 2. U1 creates 2 documents in User Homes using CMIS
+ * 3. U1 verifies the list of available process definitions using REST
+ * 4. U1 creates a workflow of type 'activitiReview' with the documents created above and assign it to u2 using REST
+ * 5. U1 adds a new process variable using REST
+ * 6. U2 gets the process variables using REST
+ * 7. U2 closes the task using REST
+ * 8. U1 deletes the new added process variable
+ * 9. U1 starts new 'activitiReview' process. Verify the process doesn't have the process variable added above.
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.WORKFLOW}, executionType = ExecutionType.REGRESSION,
+ description = "Verify process variable is process specific, not process definition.")
+ public void createWorkflowProcessAndDeleteProcessVariable() throws Exception
+ {
+ STEP("1. Using CMIS create 2 test users: u1 and u2.");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates 2 documents in User Homes using CMIS");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ testFile2 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file2 content");
+ cmisAPI.authenticateUser(testUser1).usingUserHome()
+ .createFile(testFile1).assertThat().existsInRepo()
+ .createFile(testFile2).assertThat().existsInRepo();
+
+ STEP("3. U1 verifies the list of available process definitions using REST");
+ RestProcessDefinitionModelsCollection procDefinitions = restAPI.authenticateUser(testUser1).withWorkflowAPI().getAllProcessDefinitions();
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ procDefinitions.assertThat().entriesListContains("key", "activitiReview");
+
+
+ STEP("4. U1 creates a workflow of type 'activitiParallelGroupReview' with the documents created above and assign it to u2 using REST");
+ processModel = restAPI.authenticateUser(testUser1).withWorkflowAPI()
+ .addProcess("activitiReview", testUser2, false, CMISUtil.Priority.Normal);
+ restAPI.withWorkflowAPI().usingProcess(processModel).addProcessItem(testFile1);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+ restAPI.withWorkflowAPI().usingProcess(processModel).addProcessItem(testFile2);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("5. U1 adds a new process variable using REST");
+ RestProcessVariableModel variableModel = RestProcessVariableModel.getRandomProcessVariableModel("d:text");
+
+ RestProcessVariableModel processVariable = restAPI.withWorkflowAPI().usingProcess(processModel).addProcessVariable(variableModel);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+ processVariable.assertThat().field("name").is(variableModel.getName())
+ .and().field("type").is(variableModel.getType())
+ .and().field("value").is(variableModel.getValue());
+
+ STEP("6. U2 gets the process variables using REST");
+ RestProcessVariableCollection processVariables = restAPI.authenticateUser(testUser2).withWorkflowAPI().usingProcess(processModel).getProcessVariables();
+ processVariables.getProcessVariableByName(processVariable.getName())
+ .assertThat().field("type").is(processVariable.getType())
+ .assertThat().field("value").is(processVariable.getValue());
+
+ processVariables.getProcessVariableByName("bpm_assignee")
+ .assertThat().field("type").is("cm:person")
+ .assertThat().field("value").is(testUser2.getUsername());
+
+ processVariables.getProcessVariableByName("bpm_priority")
+ .assertThat().field("type").is("d:int")
+ .assertThat().field("value").is(CMISUtil.Priority.Normal.getLevel());
+
+ processVariables.getProcessVariableByName("bpm_sendEMailNotifications")
+ .assertThat().field("type").is("d:boolean")
+ .assertThat().field("value").is(false);
+
+ processVariables.getProcessVariableByName("initiator")
+ .assertThat().field("type").is("d:noderef")
+ .assertThat().field("value").is(testUser1.getUsername());
+
+ processVariables.getProcessVariableByName("wf_reviewOutcome")
+ .assertThat().field("type").is("d:text")
+ .assertThat().field("value").is("Reject");
+
+ STEP("7. U2 closes the task using REST");
+ RestTaskModel processTask = restAPI.withWorkflowAPI().usingProcess(processModel).getProcessTasks().getTaskModelByAssignee(testUser2);
+ restAPI.withParams("select=state").withWorkflowAPI().usingTask(processTask).updateTask("completed");
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+
+ STEP("8. U1 deletes the new added process variable");
+ restAPI.authenticateUser(testUser1).withWorkflowAPI().usingProcess(processModel).deleteProcessVariable(processVariable);
+ restAPI.assertStatusCodeIs(HttpStatus.NO_CONTENT);
+
+ STEP("9. U1 starts new 'activitiReview' process. Verify the process doesn't have the process variable added above.");
+ processModel = restAPI.withWorkflowAPI().addProcess("activitiReview", testUser2, false, CMISUtil.Priority.Normal);
+ restAPI.withWorkflowAPI().usingProcess(processModel).getProcessVariables().assertThat()
+ .entriesListDoesNotContain("name", processVariable.getName());
+ }
+
+ /**
+ * Scenario 97
+ * 1. Using CMIS create 2 public sites: s1, s2.
+ * 2. Using CMIS create test users: u1 and u2.
+ * 3. Using RestAPI add u1 to s1 and s2, u2 to s2.
+ * 4. Using RestAPI add all sites to favorites for every user.
+ * 5. Using RestAPI get preferences and check that favorited sites are listed.
+ * 6. Using RestAPI, u1 removes site1 from favorites, u2 removes site2 from favorites.
+ * 7. Using RestAPI get preferences and check that favorited sites are listed. Removed sites are not listed.
+ * 8. Using FTP U1 creates file1 in s1 document library and adds it to favorites using RestAPI. Same for u2 and s2
+ * 9. Using RestAPI U1 and U2 get preferences. Files added to favorites are listed.
+ * 10. Using WebDAV rename file1 and file2.
+ * 11. Using RestAPI U1 and U2 get preferences. Files renamed are listed.
+ * 12. Using FTP delete files.
+ * 13. Using CMIS delete site1.
+ * 14. Using RestAPI get preferences. Files and sites deleted are not listed anymore as favorites.
+ */
+
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL})
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.PREFERENCES }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user can get preferences of sites and documents which were updated or deleted")
+ @Bug(id = "ACE-5769")
+ public void getUserPreferencesForSitesAndFiles() throws Exception
+ {
+ RestPreferenceModelsCollection restPreferenceModelsCollection;
+
+ STEP("1. Using CMIS create 2 public sites: s1, s2.");
+ SiteModel testSitePublic1 = dataSite.usingUser(testUser1).createPublicRandomSite();
+ SiteModel testSitePublic2 = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("2. Using CMIS create test users: u1 and u2.");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("3. Using RestAPI add u1 to s1 and s2, u2 to s2.");
+ dataUser.addUserToSite(testUser1, testSitePublic1, UserRole.SiteManager);
+ dataUser.addUserToSite(testUser1, testSitePublic2, UserRole.SiteCollaborator);
+ dataUser.addUserToSite(testUser2, testSitePublic2, UserRole.SiteManager);
+
+ STEP("4. Using RestAPI add all sites to favorites for every user.");
+ restAPI.authenticateUser(testUser1).withCoreAPI().usingAuthUser().addSiteToFavorites(testSitePublic1);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+ restAPI.withCoreAPI().usingAuthUser().addSiteToFavorites(testSitePublic2);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ restAPI.authenticateUser(testUser2).withCoreAPI().usingAuthUser().addSiteToFavorites(testSitePublic1);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+ restAPI.withCoreAPI().usingAuthUser().addSiteToFavorites(testSitePublic2);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("5. Using RestAPI get preferences and check that favorited sites are listed.");
+ restPreferenceModelsCollection = restAPI.authenticateUser(testUser1).withCoreAPI().usingAuthUser().getPersonPreferences();
+ restPreferenceModelsCollection.assertThat().paginationField("count").is("4");
+ restPreferenceModelsCollection.assertThat().entriesListIsNotEmpty()
+ .and().entriesListContains("id", String.format(PreferenceName.EXT_SITES_FAVORITES_PREFIX.toString(), testSitePublic1.getId()))
+ .and().entriesListContains("id", String.format(PreferenceName.SITES_FAVORITES_PREFIX.toString(), testSitePublic1.getId()))
+ .and().entriesListContains("id", String.format(PreferenceName.EXT_SITES_FAVORITES_PREFIX.toString(), testSitePublic2.getId()))
+ .and().entriesListContains("id", String.format(PreferenceName.SITES_FAVORITES_PREFIX.toString(), testSitePublic2.getId()))
+ .and().entriesListContains("value", "true");
+
+ restPreferenceModelsCollection = restAPI.authenticateUser(testUser2).withCoreAPI().usingAuthUser().getPersonPreferences();
+ restPreferenceModelsCollection.assertThat().paginationField("count").is("4");
+ restPreferenceModelsCollection.assertThat().entriesListIsNotEmpty()
+ .and().entriesListContains("id", String.format(PreferenceName.EXT_SITES_FAVORITES_PREFIX.toString(), testSitePublic1.getId()))
+ .and().entriesListContains("id", String.format(PreferenceName.SITES_FAVORITES_PREFIX.toString(), testSitePublic1.getId()))
+ .and().entriesListContains("id", String.format(PreferenceName.EXT_SITES_FAVORITES_PREFIX.toString(), testSitePublic2.getId()))
+ .and().entriesListContains("id", String.format(PreferenceName.SITES_FAVORITES_PREFIX.toString(), testSitePublic2.getId()))
+ .and().entriesListContains("value", "true");
+
+ STEP("6. Using RestAPI, u1 removes site1 from favorites, u2 removes site2 from favorites.");
+ restAPI.authenticateUser(testUser1).withCoreAPI().usingAuthUser().removeFavoriteSite(testSitePublic1);
+ restAPI.assertStatusCodeIs(HttpStatus.NO_CONTENT);
+
+ restAPI.authenticateUser(testUser2).withCoreAPI().usingAuthUser().removeFavoriteSite(testSitePublic2);
+ restAPI.assertStatusCodeIs(HttpStatus.NO_CONTENT);
+
+ STEP("7. Using RestAPI get preferences and check that favorited sites are listed. Removed sites are not listed.");
+ restPreferenceModelsCollection = restAPI.authenticateUser(testUser1).withCoreAPI().usingAuthUser().getPersonPreferences();
+ restPreferenceModelsCollection.assertThat().paginationField("count").is("3");
+ restPreferenceModelsCollection.assertThat().entriesListIsNotEmpty()
+ .and().entriesListContains("id", String.format(PreferenceName.EXT_SITES_FAVORITES_PREFIX.toString(), testSitePublic2.getId()))
+ .and().entriesListContains("id", String.format(PreferenceName.SITES_FAVORITES_PREFIX.toString(), testSitePublic2.getId()))
+ .and().entriesListContains("value", "true");
+
+ restPreferenceModelsCollection = restAPI.authenticateUser(testUser2).withCoreAPI().usingAuthUser().getPersonPreferences();
+ restPreferenceModelsCollection.assertThat().paginationField("count").is("3");
+ restPreferenceModelsCollection.assertThat().entriesListIsNotEmpty()
+ .and().entriesListContains("id", String.format(PreferenceName.EXT_SITES_FAVORITES_PREFIX.toString(), testSitePublic1.getId()))
+ .and().entriesListContains("id", String.format(PreferenceName.SITES_FAVORITES_PREFIX.toString(), testSitePublic1.getId()))
+ .and().entriesListContains("value", "true");
+
+ STEP("8. Using FTP U1 creates file1 in s1 document library and adds it to favorites using RestAPI. Same for u2 and s2");
+ FileModel file1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ FileModel file2 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+
+ ftpProtocol.authenticateUser(testUser1).usingSite(testSitePublic1).createFile(file1);
+ restAPI.authenticateUser(testUser1).withCoreAPI().usingAuthUser().addFileToFavorites(file1);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ ftpProtocol.authenticateUser(testUser2).usingSite(testSitePublic2).createFile(file2);
+ restAPI.authenticateUser(testUser2).withCoreAPI().usingAuthUser().addFileToFavorites(file2);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("9. Using RestAPI U1 and U2 get preferences. Files added to favorites are listed.");
+ restPreferenceModelsCollection = restAPI.authenticateUser(testUser1).withCoreAPI().usingAuthUser().getPersonPreferences();
+ restPreferenceModelsCollection.assertThat().paginationField("count").is("5");
+ restPreferenceModelsCollection.assertThat().entriesListIsNotEmpty()
+ .and().entriesListContains("id", String.format(PreferenceName.EXT_SITES_FAVORITES_PREFIX.toString(), testSitePublic2.getId()))
+ .and().entriesListContains("id", String.format(PreferenceName.SITES_FAVORITES_PREFIX.toString(), testSitePublic2.getId()))
+ .and().entriesListContains("id", "org.alfresco.ext.documents.favourites.workspace://SpacesStore/" + file1.getNodeRef() +".createdAt")
+ .and().entriesListContains("value", "workspace://SpacesStore/" + file1.getNodeRef())
+ .and().entriesListContains("value", "true");
+
+ restPreferenceModelsCollection = restAPI.authenticateUser(testUser2).withCoreAPI().usingAuthUser().getPersonPreferences();
+ restPreferenceModelsCollection.assertThat().paginationField("count").is("5");
+ restPreferenceModelsCollection.assertThat().entriesListIsNotEmpty()
+ .and().entriesListContains("id", String.format(PreferenceName.EXT_SITES_FAVORITES_PREFIX.toString(), testSitePublic1.getId()))
+ .and().entriesListContains("id", String.format(PreferenceName.SITES_FAVORITES_PREFIX.toString(), testSitePublic1.getId()))
+ .and().entriesListContains("id", "org.alfresco.ext.documents.favourites.workspace://SpacesStore/" + file2.getNodeRef() +".createdAt")
+ .and().entriesListContains("value", "workspace://SpacesStore/" + file2.getNodeRef())
+ .and().entriesListContains("value", "true");
+
+ STEP("10. Using WebDAV rename file1 and file2.");
+ webDavProtocol.authenticateUser(testUser1).usingResource(file1).rename(file1.getName()+ "-updated-file1");
+ webDavProtocol.authenticateUser(testUser2).usingResource(file2).rename(file2.getName()+ "-updated-file2");
+
+ STEP("11. Using RestAPI U1 and U2 get preferences. Files renamed are listed.");
+ restPreferenceModelsCollection = restAPI.authenticateUser(testUser1).withCoreAPI().usingAuthUser().getPersonPreferences();
+ restPreferenceModelsCollection.assertThat().paginationField("count").is("5");
+ restPreferenceModelsCollection.assertThat().entriesListIsNotEmpty()
+ .and().entriesListContains("id", String.format(PreferenceName.EXT_SITES_FAVORITES_PREFIX.toString(), testSitePublic2.getId()))
+ .and().entriesListContains("id", String.format(PreferenceName.SITES_FAVORITES_PREFIX.toString(), testSitePublic2.getId()))
+ .and().entriesListContains("id", "org.alfresco.ext.documents.favourites.workspace://SpacesStore/" + file1.getNodeRef() +".createdAt")
+ .and().entriesListContains("value", "workspace://SpacesStore/" + file1.getNodeRef())
+ .and().entriesListContains("value", "true");
+
+ restPreferenceModelsCollection = restAPI.authenticateUser(testUser2).withCoreAPI().usingAuthUser().getPersonPreferences();
+ restPreferenceModelsCollection.assertThat().paginationField("count").is("5");
+ restPreferenceModelsCollection.assertThat().entriesListIsNotEmpty()
+ .and().entriesListContains("id", String.format(PreferenceName.EXT_SITES_FAVORITES_PREFIX.toString(), testSitePublic1.getId()))
+ .and().entriesListContains("id", String.format(PreferenceName.SITES_FAVORITES_PREFIX.toString(), testSitePublic1.getId()))
+ .and().entriesListContains("id", "org.alfresco.ext.documents.favourites.workspace://SpacesStore/" + file2.getNodeRef() +".createdAt")
+ .and().entriesListContains("value", "workspace://SpacesStore/" + file2.getNodeRef())
+ .and().entriesListContains("value", "true");
+
+ STEP("12. Using FTP delete files.");
+ ftpProtocol.authenticateUser(testUser1).usingResource(file1).delete();
+ ftpProtocol.authenticateUser(testUser2).usingResource(file2).delete();
+
+ STEP("13. Using CMIS delete site1.");
+ dataSite.usingUser(admin).deleteSite(testSitePublic1);
+
+ STEP("14. Using RestAPI get preferences. Files and sites deleted are not listed anymore as favorites.");
+ restPreferenceModelsCollection = restAPI.authenticateUser(testUser1).withCoreAPI().usingAuthUser().getPersonPreferences();
+ restPreferenceModelsCollection.assertThat().paginationField("count").is("2");
+ restPreferenceModelsCollection.assertThat().entriesListIsNotEmpty()
+ .and().entriesListContains("id", String.format(PreferenceName.EXT_SITES_FAVORITES_PREFIX.toString(), testSitePublic2.getId()))
+ .and().entriesListContains("id", String.format(PreferenceName.SITES_FAVORITES_PREFIX.toString(), testSitePublic2.getId()))
+ .and().entriesListDoesNotContain("id", "org.alfresco.ext.documents.favourites.workspace://SpacesStore/" + file1.getNodeRef() +".createdAt")
+ .and().entriesListDoesNotContain("value", "workspace://SpacesStore/" + file1.getNodeRef())
+ .and().entriesListContains("value", "true");
+
+ restPreferenceModelsCollection = restAPI.authenticateUser(testUser2).withCoreAPI().usingAuthUser().getPersonPreferences();
+ restPreferenceModelsCollection.assertThat().paginationField("count").is("2");
+ restPreferenceModelsCollection.assertThat().entriesListIsNotEmpty()
+ .and().entriesListDoesNotContain("id", String.format(PreferenceName.EXT_SITES_FAVORITES_PREFIX.toString(), testSitePublic1.getId()))
+ .and().entriesListDoesNotContain("id", String.format(PreferenceName.SITES_FAVORITES_PREFIX.toString(), testSitePublic1.getId()))
+ .and().entriesListDoesNotContain("id", "org.alfresco.ext.documents.favourites.workspace://SpacesStore/" + file2.getNodeRef() +".createdAt")
+ .and().entriesListDoesNotContain("value", "workspace://SpacesStore/" + file2.getNodeRef())
+ .and().entriesListContains("value", "true");
+ }
+
+ /**
+ * Scenario 101
+ * 1. Using CMIS create test users: u1 and u2
+ * 2. U1 creates public test site U1 creates a public test site using CMIS
+ * 3. U1 adds U2 as site member with manager role using RestAPI
+ * 4. U2 adds site to favorites using RestAPI
+ * 5. U2 gets preference 'org.alfresco.ext.sites.favourites.testsite.createdAt' using RestAPI
+ * 6. U2 remove site from favorites using RestAPI
+ * 7. U2 gets preference 'org.alfresco.ext.sites.favourites.testsite.createdAt' using RestAPI
+ * 8. U2 creates file1 in test site's document library using FTP
+ * 9. U2 gets preference 'org.alfresco.ext.documents.favourites.workspace://SpacesStore/.createdAt' using RestAPI
+ * 10. U2 removes file1 from favorites using RestAPI
+ * 11. U2 gets preference 'org.alfresco.share.documents.favourite' using RestAPI
+ * 12. U2 renames file1 to file-updated with WebDAV
+ * 13. U2 gets preference 'org.alfresco.ext.documents.favourites.workspace://SpacesStore/.createdAt' using RestAPI
+ * 14. U2 deletes file-updated with CMIS
+ * 15. U2 gets preference 'org.alfresco.ext.documents.favourites.workspace://SpacesStore/.createdAt' using RestAPI
+ * 16. U2 adds site to favorites with RestAPI and U1 deletes site1 with CMIS
+ * 17. U2 gets preference 'org.alfresco.ext.sites.favourites.site1.createdAt' using RestAPI
+ */
+ @Bug(id = "ACE-5769")
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL})
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.PREFERENCES }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user can get preference of sites and documents which were updated or deleted")
+ public void getPreferenceForSiteAndFiles() throws Exception
+ {
+ STEP("1. Using CMIS create 2 test users: u1 and u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates public test site U1 creates a public test site using CMIS");
+ SiteModel testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("3. U1 adds U2 as site member with manager role using RestAPI");
+ dataUser.usingUser(testUser1).addUserToSite(testUser2, testSitePublic, UserRole.SiteManager);
+ testUser2.setUserRole(UserRole.SiteManager);
+
+ STEP("4. U2 adds site to favorites using RestAPI");
+ restAPI.authenticateUser(testUser2).withCoreAPI().usingAuthUser().addSiteToFavorites(testSitePublic);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("5. U2 gets preference 'org.alfresco.ext.sites.favourites.testsite.createdAt' using RestAPI");
+ restAPI.authenticateUser(testUser2).withCoreAPI().usingAuthUser().getPersonPreferenceInformation(String.format(PreferenceName.SITES_FAVORITES_PREFIX.toString(), testSitePublic.getId()));
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+
+ STEP("6. U2 remove site from favorites using RestAPI");
+ restAPI.authenticateUser(testUser2).withCoreAPI().usingAuthUser().removeFavoriteSite(testSitePublic);
+ restAPI.assertStatusCodeIs(HttpStatus.NO_CONTENT);
+
+ STEP("7. U2 gets preference 'org.alfresco.ext.sites.favourites.testsite.createdAt' using RestAPI");
+ restAPI.authenticateUser(testUser2).withCoreAPI().usingAuthUser().getPersonPreferenceInformation(String.format(PreferenceName.SITES_FAVORITES_PREFIX.toString(), testSitePublic.getId()));
+ restAPI.assertStatusCodeIs(HttpStatus.NOT_FOUND);
+
+ STEP("8. U2 creates file1 in test site's document library using FTP and adds it to favorites using RestAPI");
+ FileModel file1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ ftpProtocol.authenticateUser(testUser2).usingSite(testSitePublic).createFile(file1);
+ restAPI.authenticateUser(testUser2).withCoreAPI().usingAuthUser().addFileToFavorites(file1);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("9. U2 gets preference 'org.alfresco.ext.documents.favourites.workspace://SpacesStore/.createdAt' using RestAPI");
+ RestPreferenceModel preference = restAPI.authenticateUser(testUser2).withCoreAPI().usingAuthUser().getPersonPreferenceInformation(PreferenceName.DOCUMENTS_FAVORITES_PREFIX.toString());
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ preference.assertThat().field("value").is("workspace://SpacesStore/" + file1.getNodeRefWithoutVersion());
+
+ STEP("10. U2 removes file1 from favorites using RestAPI");
+ restAPI.authenticateUser(testUser2).withCoreAPI().usingAuthUser().deleteFileFromFavorites(file1);
+ restAPI.assertStatusCodeIs(HttpStatus.NO_CONTENT);
+
+ STEP("11. U2 gets preference 'org.alfresco.share.documents.favourite' using RestAPI");
+ preference = restAPI.authenticateUser(testUser2).withCoreAPI().usingAuthUser().getPersonPreferenceInformation(PreferenceName.DOCUMENTS_FAVORITES_PREFIX.toString());
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ preference.assertThat().field("value").isNull();
+
+ STEP("12. U2 adds file1 to favorites using RestAPI and renames file1 to file-updated with WebDAV");
+ restAPI.authenticateUser(testUser2).withCoreAPI().usingAuthUser().addFileToFavorites(file1);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+ webDavProtocol.authenticateUser(testUser2).usingResource(file1).rename(file1.getName()+ "-updated");
+
+ STEP("13. U2 gets preference 'org.alfresco.ext.documents.favourites.workspace://SpacesStore/.createdAt' using RestAPI");
+ preference = restAPI.authenticateUser(testUser2).withCoreAPI().usingAuthUser().getPersonPreferenceInformation(PreferenceName.DOCUMENTS_FAVORITES_PREFIX.toString());
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ preference.assertThat().field("value").is("workspace://SpacesStore/" + file1.getNodeRefWithoutVersion());
+
+ STEP("14. U2 adds file1 to favorites using RestAPI and deletes file-updated with CMIS");
+ restAPI.authenticateUser(testUser2).withCoreAPI().usingAuthUser().addFileToFavorites(file1);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+ cmisAPI.authenticateUser(testUser2).usingResource(file1).delete();
+
+ STEP("15. U2 gets preference 'org.alfresco.ext.documents.favourites.workspace://SpacesStore/.createdAt' using RestAPI");
+ preference = restAPI.authenticateUser(testUser2).withCoreAPI().usingAuthUser().getPersonPreferenceInformation(PreferenceName.DOCUMENTS_FAVORITES_PREFIX.toString());
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ preference.assertThat().field("value").isNull();
+
+ STEP("16. U2 adds site to favorites with RestAPI and U1 deletes site1 with CMIS");
+ restAPI.authenticateUser(testUser2).withCoreAPI().usingAuthUser().addSiteToFavorites(testSitePublic);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+ dataSite.usingUser(testUser1).deleteSite(testSitePublic);
+
+ STEP("17. U2 gets preference 'org.alfresco.ext.sites.favourites.site1.createdAt' using RestAPI");
+ preference = restAPI.authenticateUser(testUser2).withCoreAPI().usingAuthUser().getPersonPreferenceInformation(String.format(PreferenceName.SITES_FAVORITES_PREFIX.toString(), testSitePublic.getId()));
+ restAPI.assertStatusCodeIs(HttpStatus.NOT_FOUND);
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ preference.assertThat().field("value").isNull();
+ }
+
+ @Bug(id = "REPO-2419", status = Status.FIXED)
+ @Test(groups = { TestGroup.PROTOCOLS, TestGroup.WEBDAV, TestGroup.FULL })
+ @TestRail(section = { TestGroup.PROTOCOLS, TestGroup.WEBDAV }, executionType = ExecutionType.REGRESSION, description = "Verify that the version of a new file uploaded through WebDAV is 1.0 with the real content size.")
+ public void uploadedFileThroughWebdavHasFirstVersion() throws Exception
+ {
+ UserModel managerUser = dataUser.createRandomTestUser();
+ SiteModel testSite = dataSite.usingUser(managerUser).createPublicRandomSite();
+
+ STEP("0. Verify versionable aspect is set for all contents using webscript");
+ String fileCreationWebScript = "alfresco/s/api/classes/cm_content";
+
+ RestAssured.basePath = "";
+ restAPI.configureRequestSpec().setBasePath(RestAssured.basePath);
+ RestRequest request = RestRequest.simpleRequest(HttpMethod.GET, fileCreationWebScript);
+ RestResponse response = restAPI.authenticateUser(admin).process(request);
+ Assert.assertEquals(response.getResponse().getStatusCode(), HttpStatus.OK.value());
+ try
+ {
+ response.assertThat().body(containsString("cm:versionable"));
+ response.assertThat().body("defaultAspects.'cm:versionable'.title", equalTo("Versionable"));
+ }
+ catch(AssertionError ae)
+ {
+ throw new SkipException("Skipping this test because the versionable aspect is not applied. Please add "
+ + "the versionable aspect to all content in contentModel.xml and run the test again.");
+ }
+
+ STEP("1. Upload a local file on a new folder using WebDAV protocol");
+ FolderModel folder = dataContent.usingUser(managerUser).usingSite(testSite).createFolder();
+ File fileToUpload = Utility.getTestResourceFile("shared-resources/testdata/nonemptyupload.txt");
+ webDavProtocol.authenticateUser(managerUser).usingSite(testSite).usingResource(folder).uploadFile(fileToUpload);
+ FileModel file = new FileModel(fileToUpload.getName());
+
+ STEP("2. Verify version is exactly 1.0 and the size is the same as the local file");
+ dataContent.usingResource(file).assertContentVersionIs("1.0");
+ dataContent.usingResource(file).assertContentSizeIs(19);
+ }
+}
diff --git a/packaging/tests/tas-integration/src/test/java/org/alfresco/tas/integration/IntegrationFullTests1.java b/packaging/tests/tas-integration/src/test/java/org/alfresco/tas/integration/IntegrationFullTests1.java
new file mode 100644
index 00000000000..c606dc17cf6
--- /dev/null
+++ b/packaging/tests/tas-integration/src/test/java/org/alfresco/tas/integration/IntegrationFullTests1.java
@@ -0,0 +1,477 @@
+package org.alfresco.tas.integration;
+
+import static org.alfresco.utility.report.log.Step.STEP;
+
+import io.restassured.RestAssured;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.alfresco.dataprep.SiteService.Visibility;
+import org.alfresco.rest.core.RestRequest;
+import org.alfresco.rest.core.RestResponse;
+import org.alfresco.rest.model.RestSiteContainerModel;
+import org.alfresco.rest.model.RestSiteContainerModelsCollection;
+import org.alfresco.rest.model.RestSiteEntry;
+import org.alfresco.rest.model.RestSiteMemberModelsCollection;
+import org.alfresco.rest.model.RestSiteMembershipRequestModel;
+import org.alfresco.rest.model.RestTagModel;
+import org.alfresco.rest.model.RestTaskModel;
+import org.alfresco.utility.Utility;
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.RandomData;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.FolderModel;
+import org.alfresco.utility.model.GroupModel;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class IntegrationFullTests1 extends IntegrationTest
+{
+ UserModel testUser1, testUser2, testUser3;
+ SiteModel testSitePublic, testSiteModerated;
+
+ /**
+ * Scenario 87
+ * 1. Using RestApi Admin user creates a new group1
+ * 2. Using CMIS create test users: U1, U2 and U3
+ * 3. Using RestApi add users U2 and U3 to group1
+ * 4. U1 creates public test site1 using CMIS
+ * 5. U1 creates file1 using CMIS, WebDav, FTP
+ * 6. U1 apply Acl permission in the new documents for testGroup with role Site Consumer using CMIS
+ * 7. Get permissions for U2 using CMIS
+ * 8. U2 edits files created with CMIS, WebDav, FTP using WebDav
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Verify document permissions are added for a group of users")
+ public void addDocumentPermissionsForGroupOfUsers() throws Exception
+ {
+ STEP("1. Using RestApi Admin user creates a new group1");
+ GroupModel group1 = dataGroup.createRandomGroup();
+
+ STEP("2. Using CMIS create test users: U1, U2 and U3");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+ testUser3 = dataUser.createRandomTestUser();
+
+ STEP("3. Using RestApi add users U2 and U3 to group1");
+ dataGroup.usingUser(testUser2).addUserToGroup(group1);
+ dataGroup.usingUser(testUser3).addUserToGroup(group1);
+
+ STEP("4. U1 creates public test site1 using CMIS");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("5. U1 creates file1 using CMIS, WebDav, FTP");
+ FileModel cmisFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisAPI.authenticateUser(testUser1).usingSite(testSitePublic).createFile(cmisFile);
+ FileModel webDavFile = FileModel.getRandomFileModel(FileType.HTML);
+ webDavProtocol.authenticateUser(testUser1).usingSite(testSitePublic).createFile(webDavFile);
+ FileModel ftpFile = FileModel.getRandomFileModel(FileType.XML);
+ ftpProtocol.authenticateUser(testUser1).usingSite(testSitePublic).createFile(ftpFile);
+
+ STEP("6. U1 apply Acl permission in the new documents for testGroup with role Site Consumer using CMIS");
+ cmisAPI.usingResource(cmisFile).addAcl(group1, UserRole.SiteConsumer);
+ cmisAPI.usingResource(webDavFile).addAcl(group1, UserRole.SiteConsumer);
+ cmisAPI.usingResource(ftpFile).addAcl(group1, UserRole.SiteConsumer);
+
+ STEP("7. Get permissions for U2 using CMIS");
+ cmisAPI.usingResource(cmisFile).assertThat().permissionIsSetForGrup(group1, UserRole.SiteConsumer);
+ cmisAPI.usingResource(webDavFile).assertThat().permissionIsSetForGrup(group1, UserRole.SiteConsumer);
+ cmisAPI.usingResource(ftpFile).assertThat().permissionIsSetForGrup(group1, UserRole.SiteConsumer);
+
+ STEP("8. U2 edits files created with CMIS, WebDav, FTP using WebDav");
+ String newContent = "new content";
+ webDavProtocol.authenticateUser(testUser2)
+ .usingResource(cmisFile).update(newContent)
+ .assertThat().hasStatus(org.apache.commons.httpclient.HttpStatus.SC_FORBIDDEN)
+ .usingResource(webDavFile).update(newContent)
+ .assertThat().hasStatus(org.apache.commons.httpclient.HttpStatus.SC_FORBIDDEN)
+ .usingResource(ftpFile).update(newContent)
+ .assertThat().hasStatus(org.apache.commons.httpclient.HttpStatus.SC_FORBIDDEN);
+ }
+
+ /**
+ * Scenario 88
+ * 1. Using RestApi Admin user creates a new group1
+ * 2. Using CMIS create test users: U1, U2 and U3
+ * 3. Using RestApi add users U2 and U3 to group1
+ * 4. U1 creates public test site1 using CMIS
+ * 5. U1 creates folder1 using CMIS, WebDav, FTP
+ * 6. U1 apply Acl permission in the new folders for testGroup with role Site Consumer using CMIS
+ * 7. Get permissions for U2 using CMIS
+ * 8. U2 edits folders created with CMIS, WebDav, FTP using WebDav
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Verify folder permissions are added for a group of users")
+ public void addFolderPermissionsForGroupOfUsers() throws Exception
+ {
+ STEP("1. Using RestApi Admin user creates a new group1");
+ GroupModel group1 = dataGroup.createRandomGroup();
+
+ STEP("2. Using CMIS create test users: U1, U2 and U3");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+ testUser3 = dataUser.createRandomTestUser();
+
+ STEP("3. Using RestApi add users U2 and U3 to group1");
+ dataGroup.usingUser(testUser2).addUserToGroup(group1);
+ dataGroup.usingUser(testUser3).addUserToGroup(group1);
+
+ STEP("4. U1 creates public test site1 using CMIS");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("5. U1 creates folders using CMIS, WebDav, FTP");
+ FolderModel cmisFolder = FolderModel.getRandomFolderModel();
+ cmisAPI.authenticateUser(testUser1).usingSite(testSitePublic).createFolder(cmisFolder);
+ FolderModel webDavFolder = FolderModel.getRandomFolderModel();
+ webDavProtocol.authenticateUser(testUser1).usingSite(testSitePublic).createFolder(webDavFolder);
+ FolderModel ftpFolder = FolderModel.getRandomFolderModel();
+ ftpProtocol.authenticateUser(testUser1).usingSite(testSitePublic).createFolder(ftpFolder);
+
+ STEP("6. U1 apply Acl permission in the new folders for testGroup with role Site Consumer using CMIS");
+ cmisAPI.usingResource(cmisFolder).addAcl(group1, UserRole.SiteConsumer);
+ cmisAPI.usingResource(webDavFolder).addAcl(group1, UserRole.SiteConsumer);
+ cmisAPI.usingResource(ftpFolder).addAcl(group1, UserRole.SiteConsumer);
+
+ STEP("7. Get permissions for U2 using CMIS");
+ cmisAPI.usingResource(cmisFolder).assertThat().permissionIsSetForGrup(group1, UserRole.SiteConsumer);
+ cmisAPI.usingResource(webDavFolder).assertThat().permissionIsSetForGrup(group1, UserRole.SiteConsumer);
+ cmisAPI.usingResource(ftpFolder).assertThat().permissionIsSetForGrup(group1, UserRole.SiteConsumer);
+
+ STEP("8. U2 edits folders created with CMIS, WebDav, FTP using WebDav");
+ String newName = "newName";
+ webDavProtocol.authenticateUser(testUser2)
+ .usingResource(cmisFolder).rename(newName)
+ .assertThat().hasStatus(org.apache.commons.httpclient.HttpStatus.SC_FORBIDDEN)
+ .usingResource(webDavFolder).rename(newName)
+ .assertThat().hasStatus(org.apache.commons.httpclient.HttpStatus.SC_FORBIDDEN)
+ .usingResource(ftpFolder).rename(newName)
+ .assertThat().hasStatus(org.apache.commons.httpclient.HttpStatus.SC_FORBIDDEN);
+ }
+
+ /**
+ * Scenario 102
+ * 1. Using CMIS create test users: U1 and U2
+ * 2. U1 creates moderated test site1 using CMIS
+ * 3. U2 creates site membership request to site1 with RestAPI
+ * 4. U2 gets site membership request, check new message using RestAPI
+ * 5. U2 updates site membership request with a new message using RestAPI
+ * 6. U2 gets site membership request, check new message using RestAPI
+ * 7. U1 changes site visibility to private site using RestAPI
+ * 8. U2 updates site membership request with a new message using RestAPI
+ * 9. U2 gets site membership request, check new message using RestAPI
+ * 10. U1 change site visibility to moderated site RestAPI
+ * 11. U2 gets site membership request, check new message using RestAPI
+ * 12. U2 updates site membership request with a new message using RestAPI
+ * 13. U2 get site membership request, check new message using RestAPI
+ * 14. U1 user1 changes site visibility to public using RestAPI
+ * 15. U2 updates site membership request with a new message with RestAPI
+ * 16. U2 gets site membership request, check new message using RestAPI
+ * 17. U1 changes site visibility to moderated site RestAPI");
+ * 18. U2 gets site membership request, check new message using RestAPI");
+ * 19. U2 updates new site membership request using RestAPI
+ * 20. U1 approves site membership using RestAPI
+ * 21. U2 gets site membership request - no request using RestAPI
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.SITES }, executionType = ExecutionType.REGRESSION,
+ description = "Verify user can update or not site membership request when site visibility is updated")
+ public void updateSiteMembershipRequestWhenSiteVisibilityIsUpdated() throws Exception
+ {
+ STEP("1. Using CMIS create 2 test users: U1 and U2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates moderated test site1 using CMIS");
+ testSiteModerated = dataSite.usingUser(testUser1).createModeratedRandomSite();
+
+ STEP("3. U2 creates site membership request to site1 with RestAPI");
+ restAPI.authenticateUser(testUser2).withCoreAPI().usingMe().addSiteMembershipRequest("Please add me 1", testSiteModerated, "Request1");
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("4. U2 gets site membership request, check new message using RestAPI");
+ RestSiteMembershipRequestModel request = restAPI.withCoreAPI().usingMe().getSiteMembershipRequest(testSiteModerated);
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ request.assertThat().field("message").is("Please add me 1");
+
+ STEP("5. U2 updates site membership request with a new message using RestAPI");
+ request = restAPI.withCoreAPI().usingMe().updateSiteMembershipRequest(testSiteModerated, "Please add me 2");
+ request.assertThat().field("message").is("Please add me 2");
+
+ STEP("6. U2 gets site membership request, check new message using RestAPI");
+ request = restAPI.withCoreAPI().usingMe().getSiteMembershipRequest(testSiteModerated);
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ request.assertThat().field("message").is("Please add me 2");
+
+ STEP("7. U1 changes site visibility to private site using RestAPI");
+ dataSite.usingUser(testUser1).updateSiteVisibility(testSiteModerated, Visibility.PRIVATE);
+
+ STEP("8. U2 updates site membership request with a new message using RestAPI");
+ restAPI.withCoreAPI().usingMe().updateSiteMembershipRequest(testSiteModerated, "Please add me 2");
+ restAPI.assertStatusCodeIs(HttpStatus.NOT_FOUND);
+
+ STEP("9. U2 gets site membership request, check new message using RestAPI");
+ restAPI.withCoreAPI().usingMe().getSiteMembershipRequest(testSiteModerated);
+ restAPI.assertStatusCodeIs(HttpStatus.NOT_FOUND);
+
+ STEP("10. U1 change site visibility to moderated site RestAPI");
+ dataSite.usingUser(testUser1).updateSiteVisibility(testSiteModerated, Visibility.MODERATED);
+
+ STEP("11. U2 gets site membership request, check new message using RestAPI");
+ request = restAPI.withCoreAPI().usingMe().getSiteMembershipRequest(testSiteModerated);
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ request.assertThat().field("message").is("Please add me 2");
+
+ STEP("12. U2 updates site membership request with a new message using RestAPI");
+ request = restAPI.withCoreAPI().usingMe().updateSiteMembershipRequest(testSiteModerated, "Please add me 3");
+ request.assertThat().field("message").is("Please add me 3");
+
+ STEP("13. U2 get site membership request, check new message using RestAPI");
+ request = restAPI.withCoreAPI().usingMe().getSiteMembershipRequest(testSiteModerated);
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ request.assertThat().field("message").is("Please add me 3");
+
+ STEP("14. U1 user1 changes site visibility to public using RestAPI");
+ dataSite.usingUser(testUser1).updateSiteVisibility(testSiteModerated, Visibility.PUBLIC);
+
+ STEP("15. U2 updates site membership request with a new message with RestAPI");
+ restAPI.withCoreAPI().usingMe().updateSiteMembershipRequest(testSiteModerated, "Please add me 4");
+ restAPI.assertStatusCodeIs(HttpStatus.NOT_FOUND);
+
+ STEP("16. U2 gets site membership request, check new message using RestAPI");
+ restAPI.withCoreAPI().usingMe().getSiteMembershipRequest(testSiteModerated);
+ restAPI.assertStatusCodeIs(HttpStatus.NOT_FOUND);
+
+ STEP("17. U1 changes site visibility to moderated site RestAPI");
+ dataSite.usingUser(testUser1).updateSiteVisibility(testSiteModerated, Visibility.MODERATED);
+
+ STEP("18. U2 gets site membership request, check new message using RestAPI");
+ request = restAPI.withCoreAPI().usingMe().getSiteMembershipRequest(testSiteModerated);
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ request.assertThat().field("message").is("Please add me 3");
+
+ STEP("19. U2 updates new site membership request using RestAPI");
+ request = restAPI.withCoreAPI().usingMe().updateSiteMembershipRequest(testSiteModerated, "Please add me 5");
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ request.assertThat().field("message").is("Please add me 5");
+
+ STEP("20. U1 approves site membership using RestAPI");
+ RestTaskModel taskModel = restAPI.withWorkflowAPI().getTasks().getTaskModelByDescription(testSiteModerated);
+ workflow.approveSiteMembershipRequest(testUser1.getUsername(), testUser1.getPassword(), taskModel.getId(), true, "Approve");
+
+ STEP("21. U2 gets site membership request - no request using RestAPI");
+ restAPI.withCoreAPI().usingMe().getSiteMembershipRequest(testSiteModerated);
+ restAPI.assertStatusCodeIs(HttpStatus.NOT_FOUND);
+ RestSiteEntry site= restAPI.withCoreAPI().usingMe().getSiteMembership(testSiteModerated);
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ site.assertThat().field("id").is(testSiteModerated.getId())
+ .and().field("role").isNotEmpty();
+ }
+
+ /**
+ * Scenario 104
+ * 1. Using CMIS create test user A1
+ * 2. A1 creates public test site1 using CMIS
+ * 3. Using CMIS create test user U1
+ * 4. A1 adds U1 to site1 as site manager using RestAPI
+ * 5. A1 get site members using RestAPI
+ * 6. Using CMIS create test user U2
+ * 7. A1 adds U2 to site1 as site collaborator using RestAPI
+ * 8. A1 get site members using RestAPI
+ * 9. Using CMIS create test user U3
+ * 10. A1 add U3 to site1 as site contributor using RestAPI
+ * 11. A1 get site members using RestAPI
+ * 12. Using CMIS create test user U4
+ * 13. A1 add U4 to site1 as site consumer using RestAPI
+ * 14. A1 get site members using RestAPI
+ * 15. Using CMIS delete test user U1
+ * 16. A1 get site members using RestAPI
+ * 17. Using CMIS delete test user U2
+ * 18. A1 get site members using RestAPI
+ * 19. Using CMIS delete test user U3
+ * 20. A1 get site members using RestAPI
+ * 21. Using CMIS delete test user U4
+ * 22. A1 get site members using RestAPI
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.SITES }, executionType = ExecutionType.REGRESSION,
+ description = "Verify get site members when users are added to site or deleted")
+ public void getSiteMembersWhenUsersAreAddedOrDeleted() throws Exception
+ {
+ STEP("1. Using CMIS create test user A1");
+ UserModel testUser = dataUser.createRandomTestUser();
+
+ STEP("2. A1 creates public test site1 using CMIS");
+ testSitePublic = dataSite.usingUser(testUser).createPublicRandomSite();
+
+ STEP("3. Using CMIS create test user U1");
+ UserModel user1 = dataUser.createRandomTestUser();
+
+ STEP("4. A1 adds U1 to site1 as site manager using RestAPI");
+ user1.setUserRole(UserRole.SiteManager);
+ restAPI.authenticateUser(testUser).withCoreAPI().usingSite(testSitePublic).addPerson(user1);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("5. A1 get site members using RestAPI");
+ RestSiteMemberModelsCollection members = restAPI.authenticateUser(testUser).withCoreAPI().usingSite(testSitePublic).getSiteMembers();
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ members.assertThat().paginationField("count").is("2");
+ members.assertThat().entriesListContains("id", user1.getUsername())
+ .and().entriesListContains("role", UserRole.SiteManager.toString());
+
+ STEP("6. Using CMIS create test user U2");
+ UserModel user2 = dataUser.createRandomTestUser();
+
+ STEP("7. A1 adds U2 to site1 as site collaborator using RestAPI");
+ user2.setUserRole(UserRole.SiteCollaborator);
+ restAPI.authenticateUser(testUser).withCoreAPI().usingSite(testSitePublic).addPerson(user2);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("8. A1 get site members using RestAPI");
+ members = restAPI.authenticateUser(testUser).withCoreAPI().usingSite(testSitePublic).getSiteMembers();
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ members.assertThat().paginationField("count").is("3");
+ members.assertThat().entriesListContains("id", user2.getUsername())
+ .and().entriesListContains("role", UserRole.SiteCollaborator.toString());
+
+ STEP("9. Using CMIS create test user U3");
+ UserModel user3 = dataUser.createRandomTestUser();
+
+ STEP("10. A1 add U3 to site1 as site contributor using RestAPI");
+ user3.setUserRole(UserRole.SiteContributor);
+ restAPI.authenticateUser(testUser).withCoreAPI().usingSite(testSitePublic).addPerson(user3);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("11. A1 get site members using RestAPI");
+ members = restAPI.authenticateUser(testUser).withCoreAPI().usingSite(testSitePublic).getSiteMembers();
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ members.assertThat().paginationField("count").is("4");
+ members.assertThat().entriesListContains("id", user3.getUsername())
+ .and().entriesListContains("role", UserRole.SiteContributor.toString());
+
+ STEP("12. Using CMIS create test user U4");
+ UserModel user4 = dataUser.createRandomTestUser();
+
+ STEP("13. A1 add U4 to site1 as site consumer using RestAPI");
+ user4.setUserRole(UserRole.SiteConsumer);
+ restAPI.authenticateUser(testUser).withCoreAPI().usingSite(testSitePublic).addPerson(user4);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("14. A1 get site members using RestAPI");
+ members = restAPI.authenticateUser(testUser).withCoreAPI().usingSite(testSitePublic).getSiteMembers();
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ members.assertThat().paginationField("count").is("5");
+ members.assertThat().entriesListContains("id", user4.getUsername())
+ .and().entriesListContains("role", UserRole.SiteConsumer.toString());
+
+ STEP("15. Using CMIS delete test user U1");
+ dataUser.deleteUser(user1);
+
+ STEP("16. A1 get site members using RestAPI");
+ members = restAPI.authenticateUser(testUser).withCoreAPI().usingSite(testSitePublic).getSiteMembers();
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ members.assertThat().paginationField("count").is("4");
+ members.assertThat().entriesListDoesNotContain("id", user1.getUsername());
+
+ STEP("17. Using CMIS delete test user U2");
+ dataUser.deleteUser(user2);
+
+ STEP("18. A1 get site members using RestAPI");
+ members = restAPI.authenticateUser(testUser).withCoreAPI().usingSite(testSitePublic).getSiteMembers();
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ members.assertThat().paginationField("count").is("3");
+ members.assertThat().entriesListDoesNotContain("id", user2.getUsername());
+
+ STEP("19. Using CMIS delete test user U3");
+ dataUser.deleteUser(user3);
+
+ STEP("20. A1 get site members using RestAPI");
+ members = restAPI.authenticateUser(testUser).withCoreAPI().usingSite(testSitePublic).getSiteMembers();
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ members.assertThat().paginationField("count").is("2");
+ members.assertThat().entriesListDoesNotContain("id", user3.getUsername());
+
+ STEP("21. Using CMIS delete test user U4");
+ dataUser.deleteUser(user4);
+
+ STEP("22. A1 get site members using RestAPI");
+ members = restAPI.authenticateUser(testUser).withCoreAPI().usingSite(testSitePublic).getSiteMembers();
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ members.assertThat().paginationField("count").is("1");
+ members.assertThat().entriesListDoesNotContain("id", user4.getUsername());
+ }
+
+ /**
+ * Scenario 105
+ * 1. Using CMIS create test user U1
+ * 2. U1 creates public test site1 using CMIS
+ * 3. U1 creates file1 using Webdav
+ * 4. U1 updates file1 properties using CMIS
+ * 5. U1 gets file1 properties using CMIS
+ * 6. U1 renames file1 using Webdav
+ * 7. U1 updates file1 content using FTP
+ * 8. U1 adds tags to file1 using RestAPI
+ * 9. U1 updates file1 properties using CMIS
+ * 10. U1 gets file1 properties using CMIS
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Verify file properties with file properties are updated")
+ public void checkFilePropertiesWhenFileIsUpdated() throws Exception
+ {
+ STEP("1. Using CMIS create test user U1");
+ UserModel testUser = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates public test site1 using CMIS");
+ testSitePublic = dataSite.usingUser(testUser).createPublicRandomSite();
+
+ STEP("3. U1 creates file1 using Webdav");
+ FileModel file1 = FileModel.getRandomFileModel(FileType.MSWORD2007);
+ file1.setContent("content1");
+ webDavProtocol.authenticateUser(testUser).usingSite(testSitePublic).createFile(file1);
+
+ STEP("4. U1 updates file1 properties using CMIS");
+ String newDescription = "New-" + file1.getDescription();
+ String newTitle = "New title-" +file1.getTitle();
+ cmisAPI.authenticateUser(testUser).usingSite(testSitePublic).usingResource(file1).updateProperty("cmis:description", newDescription)
+ .updateProperty("cm:title", newTitle);
+
+ STEP("5. U1 gets file1 properties using CMIS");
+ cmisAPI.authenticateUser(testUser).usingResource(file1).assertThat().contentPropertyHasValue("cmis:description", newDescription)
+ .assertThat().contentPropertyHasValue("cm:title", newTitle);
+
+ STEP("6. U1 renames file1 using Webdav");
+ String newName = "Edited-" + file1.getName();
+ webDavProtocol.authenticateUser(testUser).usingSite(testSitePublic).usingResource(file1).rename(newName);
+
+ STEP("7. U1 updates file1 content using FTP");
+ String newContent = "New " + file1.getContent();
+ ftpProtocol.authenticateUser(testUser).usingSite(testSitePublic).usingResource(file1).update(newContent)
+ .assertThat().contentIs(newContent);
+
+ STEP("8. U1 adds tags to file1 using RestAPI");
+ String newTag = RandomData.getRandomName("tag");
+ RestTagModel tag = restAPI.authenticateUser(testUser).withCoreAPI().usingResource(file1).addTag(newTag);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("9. U1 updates file1 properties using CMIS");
+ newTitle = "New title2-" + file1.getTitle();
+ cmisAPI.authenticateUser(testUser).usingSite(testSitePublic).usingResource(file1).updateProperty("cm:title", newTitle);
+
+ STEP("10. U1 gets file1 properties using CMIS");
+ cmisAPI.authenticateUser(testUser).usingResource(file1).assertThat().contentPropertyHasValue("cmis:description", newDescription)
+ .assertThat().contentPropertyHasValue("cm:title", newTitle)
+ .assertThat().contentPropertyHasValue("cmis:name", newName)
+ .assertThat().contentPropertyHasValue("cm:taggable", tag.getId())
+ .assertThat().contentIs(newContent);
+ }
+}
diff --git a/packaging/tests/tas-integration/src/test/java/org/alfresco/tas/integration/IntegrationFullTestsBulk2.java b/packaging/tests/tas-integration/src/test/java/org/alfresco/tas/integration/IntegrationFullTestsBulk2.java
new file mode 100644
index 00000000000..74d12a06410
--- /dev/null
+++ b/packaging/tests/tas-integration/src/test/java/org/alfresco/tas/integration/IntegrationFullTestsBulk2.java
@@ -0,0 +1,490 @@
+package org.alfresco.tas.integration;
+
+import static org.alfresco.utility.report.log.Step.STEP;
+
+import org.alfresco.rest.model.RestErrorModel;
+import org.alfresco.rest.model.RestTagModel;
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser.ListUserWithRoles;
+import org.alfresco.utility.exception.DataPreparationException;
+import org.alfresco.utility.model.*;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.springframework.http.HttpStatus;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class IntegrationFullTestsBulk2 extends IntegrationTest
+{
+ private UserModel testUser1;
+ private SiteModel testSitePublic;
+ private FolderModel testFolder1, testFolder2;
+ private FileModel wordFile, testFile;
+ private ListUserWithRoles usersWithRoles;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ testUser1 = dataUser.createRandomTestUser();
+
+ wordFile = FileModel.getRandomFileModel(FileType.MSWORD2007, "tasTesting");
+ }
+
+ @BeforeMethod(alwaysRun = true)
+ public void setup() throws DataPreparationException {
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+ testFolder1 = FolderModel.getRandomFolderModel();
+ testFolder2 = FolderModel.getRandomFolderModel();
+ testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "testContent");
+ }
+
+ /**
+ * Scenario 73
+ * 1. Create file1 using ftp
+ * 2. Open document for edit using CMIS
+ * 3. Try to edit document using Webdav while checked-out with CMIS
+ * 4. Copy document to testFolder2 with ftp
+ * 5. Update document from folder2, check its content is updated with Webdav
+ * 6. Update document with WebDAV - should fail since document is checked out
+ *
+ * @throws Exception
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Edit checked out document using several protocols")
+ public void updateFileUsingDifferentProtocolsWhileDocumentIsCheckedOut() throws Exception
+ {
+ STEP("1. Create testFile1 using ftp");
+ ftpProtocol.authenticateUser(testUser1).usingSite(testSitePublic).createFolder(testFolder1)
+ .usingResource(testFolder1).createFile(wordFile)
+ .assertThat().contentIs("tasTesting");
+
+ STEP("2. Open document for edit using CMIS");
+ cmisAPI.authenticateUser(testUser1).usingResource(wordFile).checkOut();
+ FileModel wordFilePWC = cmisAPI.usingResource(wordFile).withCMISUtil().getPWCFileModel();
+
+ STEP("3. Try to edit document using Webdav while checked-out with CMIS - content should be updated");
+ webDavProtocol.authenticateUser(testUser1).usingResource(wordFilePWC).update("update")
+ .and().assertThat().contentIs("update");
+
+ STEP("4. Copy document to testFolder2 with ftp");
+ FileModel copiedWordFile = new FileModel(wordFile);
+ ftpProtocol.usingSite(testSitePublic).createFolder(testFolder2)
+ .usingResource(wordFile).copyTo(testFolder2);
+ copiedWordFile.setCmisLocation(ftpProtocol.getLastResourceWithoutPrefix());
+ ftpProtocol.usingResource(testFolder1).assertThat().hasFiles(wordFile)
+ .and().usingResource(testFolder2).assertThat().hasFiles(copiedWordFile);
+
+ STEP("5. Update document from folder2, check its content is updated with Webdav");
+ webDavProtocol.usingResource(copiedWordFile).update("Step5")
+ .and().assertThat().contentIs("Step5");
+
+ STEP("6. Update document with WebDAV");
+ webDavProtocol.authenticateUser(testUser1).usingResource(wordFile).update("WebDAVUpdate");
+ }
+
+ /**
+ * Scenario 84
+ * 1. Create folder1 with webdav
+ * 2. Upload new file, file1 with ftp
+ * 3. Set content for file1 with cmis
+ * 4. CheckOut file1 with cmis
+ * 5. Try to edit file while checked-out with ftp
+ * 6. Cancel checkout with cmis
+ * 7. Try again to edit file with ftp
+ * 8. Edit file content using webDav
+ * 9. Get content using cmis, validate it
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL } )
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Update checked out document")
+ public void updateCheckedOutFile() throws Exception
+ {
+ STEP("1. Create folder1 with webdav");
+ webDavProtocol.authenticateUser(testUser1).usingSite(testSitePublic).createFolder(testFolder1).and().assertThat().existsInRepo();
+
+ STEP("2. Upload new file, file1 with ftp");
+ ftpProtocol.authenticateUser(testUser1).usingResource(testFolder1).createFile(testFile)
+ .and().assertThat().existsInRepo().and().assertThat().existsInFtp();
+
+ STEP("3. Set content for file1 with cmis");
+ cmisAPI.authenticateUser(testUser1).usingResource(testFile).update("cmisUpdate")
+ .and().assertThat().contentIs("testContentcmisUpdate");
+
+ STEP("4. CheckOut file1 with cmis");
+ cmisAPI.usingResource(testFile).checkOut();
+
+ STEP("5. Try to edit file while checked-out with ftp - content should not be updated since file is checked out");
+ ftpProtocol.usingResource(testFile).update("ftpUpdate")
+ .and().assertThat().contentIs("testContentcmisUpdate");
+
+ STEP("6. Cancel checkout with cmis");
+ cmisAPI.usingResource(testFile).cancelCheckOut();
+
+ STEP("7. Try again to edit file with ftp");
+ ftpProtocol.usingResource(testFile).update("ftpUpdate")
+ .and().assertThat().contentIs("ftpUpdate");
+
+ STEP("8. Edit file content using webDav");
+ webDavProtocol.usingResource(testFile).update("webdavUpdate").and().assertThat().contentIs("webdavUpdate");
+
+ STEP("9. Get content using cmis, validate it");
+ cmisAPI.usingResource(testFile).assertThat().contentIs("webdavUpdate");
+ }
+
+ /**
+ * 1. Create folder1 with cmis
+ * 2. Add new file with webdav
+ * 3. Open file with Manager, add some content, save with webdav
+ * 4. Open file with Consumer, add some content, save with ftp
+ * 5. Open file with Contributor, delete some content, save with webdav
+ * 6. Open file with Collaborator, add some content, save with WebDAV
+ * 7. Open file with Consumer, delete some content, save with webdav
+ * 8. Open file with Manager, add new content, save with cmis
+ * 9. Open file with Collaborator, delete content that Manager added with ftp
+ * 10. Open file with Manager, add new content with webdav
+ * 11. Delete all content with admin using FTP
+ * 12. Delete file with cmis
+ * 13. Check file is deleted with WebDAV
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Update file with different user roles and protocols")
+ public void updateFileWithDifferentRolesUsingDifferentProtocols() throws Exception
+ {
+ usersWithRoles = dataUser.addUsersWithRolesToSite(testSitePublic, UserRole.SiteManager, UserRole.SiteCollaborator, UserRole.SiteConsumer,
+ UserRole.SiteContributor);
+
+ STEP("1. Create folder1 with cmis");
+ cmisAPI.authenticateUser(testUser1).usingSite(testSitePublic).createFolder(testFolder1).and().assertThat().existsInRepo();
+
+ STEP("2. Add new file with webdav");
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFolder1).createFile(testFile).and().assertThat().existsInRepo();
+
+ STEP("3. Open file with Manager, add some content, save with webdav");
+ webDavProtocol.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager)).usingResource(testFile).update("webdavUpdate")
+ .and().assertThat().contentIs("webdavUpdate");
+
+ STEP("4. Open file with Consumer, add some content, save with ftp");
+ ftpProtocol.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .usingResource(testFile).update("ftpUpdate").and().assertThat().contentIs("webdavUpdate");
+
+ STEP("5. Open file with Contributor, delete some content, save with webdav");
+ webDavProtocol.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingResource(testFile).update("webdavUpdate").and().assertThat().contentIs("webdavUpdate");
+
+ STEP("6. Open file with Collaborator, add some content, save with WebDAV");
+ webDavProtocol.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingResource(testFile).update("webdavUpdate2").and().assertThat().contentIs("webdavUpdate2");
+
+ STEP("7. Open file with Consumer, delete some content, save with webdav");
+ webDavProtocol.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer))
+ .usingResource(testFile).update("webdavUpdate3").and().assertThat().contentIs("webdavUpdate2");
+
+ STEP("8. Open file with Manager, add new content, save with cmis");
+ cmisAPI.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager))
+ .usingResource(testFile).update("cmisUpdate").and().assertThat().contentIs("webdavUpdate2cmisUpdate");
+
+ STEP("9. Open file with Collaborator, delete content that Manager added with ftp");
+ ftpProtocol.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingResource(testFile).update("ftpUpdate").and().assertThat().contentIs("ftpUpdate");
+
+ STEP("10. Open file with Contributor, add new page with webdav");
+ webDavProtocol.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager))
+ .usingResource(testFile).update("webdavUpdate").and().assertThat().contentIs("webdavUpdate");
+
+ STEP("11. Delete all content with admin using FTP");
+ ftpProtocol.authenticateUser(dataUser.getAdminUser())
+ .usingResource(testFile).update("").and().assertThat().contentIs("");
+
+ STEP("12. Delete file with cmis");
+ cmisAPI.usingResource(testFile).delete().and().assertThat().doesNotExistInRepo();
+
+ STEP("13. Check file is deleted with WebDAV");
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFile).assertThat().doesNotExistInWebdav();
+ }
+
+ /**
+ * 1. Add file1 to document library with ftp
+ * 2. Update file content with WebDAV
+ * 3. Add a minor change to a document with cmis
+ * 4. Add a change with webdav, check document version with cmis
+ * 5. Add a major change to a document with cmis
+ * 6. Delete document last version with cmis
+ * 7. Try to edit previous version with cmis
+ * 8. Update content with ftp, check version
+ * 9. Check document content with WebDAV
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Check document versioning")
+ public void documentVersioningTest() throws Exception
+ {
+ STEP("1. Add file1 to document library with ftp");
+ ftpProtocol.authenticateUser(testUser1).usingSite(testSitePublic).createFile(testFile).and().assertThat().existsInRepo();
+
+ STEP("2. Update file content with WebDAV");
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFile).update("WebDAVUpdate").and().assertThat().contentIs("WebDAVUpdate");
+
+ STEP("3. Add a minor change to a document with cmis");
+ cmisAPI.authenticateUser(testUser1).usingResource(testFile).update("cmisUpdate")
+ .then().assertThat().documentHasVersion(1.1).and().assertThat().contentIs("WebDAVUpdatecmisUpdate");
+
+ STEP("4. Check document version with webdav");
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFile).update("webdavUpdate");
+ cmisAPI.assertThat().documentHasVersion(1.2);
+
+ STEP("5. Add a major change to a document with cmis");
+ cmisAPI.authenticateUser(testUser1).usingResource(testFile).checkOut().prepareDocumentForCheckIn().withMajorVersion().checkIn()
+ .and().assertThat().documentHasVersion(2.0);
+
+ STEP("6. Delete document last version with cmis");
+ cmisAPI.usingResource(testFile).deleteAllVersions(false).and().assertThat().documentHasVersion(1.2);
+
+ STEP("7. Try to edit previous version with cmis");
+ cmisAPI.authenticateUser(testUser1).usingResource(testFile).update("cmisUpdate")
+ .then().assertThat().documentHasVersion(1.3).and().assertThat().contentIs("webdavUpdatecmisUpdate");
+
+ STEP("8. Update content with ftp, check version");
+ ftpProtocol.usingResource(testFile).update("ftpUpdate");
+ cmisAPI.assertThat().documentHasVersion(1.4);
+
+ STEP("9. Check document content with WebDAV");
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFile).assertThat().contentIs("ftpUpdate");
+ }
+
+ /**
+ * Scenario 82
+ * 1. Create user1, user2
+ * 2. User1 creates site1 and invites user2 as manager
+ * 3. User1 adds document1 and tag1 to doc
+ * 4. User2 gets tags and verifies tag1 appears
+ * 5. User2 delete tag1
+ * 6. User1 tries to update tag1
+ * 7. User1 add new tag tag2
+ * 8. User2 verifies tag2 appears and tag1 is not in the list
+ * 9. User2 deletes document1
+ * 10. User1 tries to delete tag2
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, description = "Check negative scenarios for tags")
+ public void tagsNegativeScenariosTest() throws Exception
+ {
+ STEP("1. Create user1, user2");
+ UserModel user1 = dataUser.createRandomTestUser();
+ UserModel user2 = dataUser.createRandomTestUser();
+ user2.setUserRole(UserRole.SiteManager);
+
+ STEP("2. User1 creates site1 and invites user2 as manager");
+ SiteModel site = dataSite.usingUser(user1).createPublicRandomSite();
+ restAPI.authenticateUser(user1).withCoreAPI().usingSite(site).addPerson(user2);
+
+ STEP("3. User1 adds document1 and tag1 to doc");
+ dataContent.usingUser(user1).usingSite(site).createContent(testFile);
+ RestTagModel tag = restAPI.withCoreAPI().usingResource(testFile).addTag("tag1");
+ restAPI.withCoreAPI().usingResource(testFile).getNodeTags().assertThat().entriesListContains("tag", "tag1");
+
+ STEP("4. User2 gets tags and verifies tag1 appears");
+ restAPI.authenticateUser(user2).withCoreAPI().usingResource(testFile).getNodeTags().assertThat().entriesListContains("tag", "tag1");
+
+ STEP("5. User2 delete tag1");
+ restAPI.withCoreAPI().usingResource(testFile).deleteTag(tag);
+ restAPI.withCoreAPI().usingResource(testFile).getNodeTags().assertThat().entriesListDoesNotContain("tag", "tag1");
+
+ STEP("6. User1 tries to update tag1");
+ restAPI.authenticateUser(user2).withCoreAPI().usingTag(tag).update("updatedTag");
+ restAPI.assertStatusCodeIs(HttpStatus.FORBIDDEN)
+ .assertLastError().containsSummary(RestErrorModel.PERMISSION_WAS_DENIED)
+ .containsErrorKey(RestErrorModel.PERMISSION_DENIED_ERRORKEY);
+
+ STEP("7. User1 add new tag tag2");
+ tag = restAPI.authenticateUser(user1).withCoreAPI().usingResource(testFile).addTag("tag2");
+ restAPI.withCoreAPI().usingResource(testFile).getNodeTags().assertThat().entriesListContains("tag", "tag2");
+
+ STEP("8. User2 verifies tag2 appears and tag1 is not in the list");
+ restAPI.authenticateUser(user2).withCoreAPI().usingResource(testFile).getNodeTags()
+ .assertThat().entriesListDoesNotContain("tag", "tag1")
+ .assertThat().entriesListContains("tag", "tag2");
+
+ STEP("9. User2 deletes document1");
+ dataContent.usingUser(user2).usingResource(testFile).deleteContent();
+
+ STEP("10. User1 tries to delete tag2");
+ restAPI.authenticateUser(user1).withCoreAPI().usingResource(testFile).deleteTag(tag);
+ restAPI.assertStatusCodeIs(HttpStatus.NOT_FOUND)
+ .assertLastError().containsSummary(String.format(RestErrorModel.ENTITY_NOT_FOUND, testFile.getNodeRefWithoutVersion()))
+ .containsErrorKey(RestErrorModel.ENTITY_NOT_FOUND_ERRORKEY);
+ }
+
+ /**
+ * Scenario 83
+ * 1. Create user1, user2
+ * 2. User1 creates site1 and invites user2 as manager with rest api
+ * 3. User1 adds document1 with webdav
+ * 4. User2 reads the document1 with ftp
+ * 5. User1 update document1 with WebDAV
+ * 6. User2 update the document1 with WebDAV
+ * 7. User1 deletes the document1 with ftp
+ * 8. Verify user2 cannot update document1 with cmis
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL }, expectedExceptions = CmisObjectNotFoundException.class, expectedExceptionsMessageRegExp = ".*Object not found:.*")
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION, description = "Negative scenarios for update document")
+ public void fileUpdateNegativeScenariosTest() throws Exception
+ {
+ STEP("1. Create user1, user2");
+ UserModel user1 = dataUser.createRandomTestUser();
+ UserModel user2 = dataUser.createRandomTestUser();
+ user2.setUserRole(UserRole.SiteManager);
+
+ STEP("2. User1 creates site1 and invites user2 as manager with rest api");
+ SiteModel site = dataSite.usingUser(user1).createPublicRandomSite();
+ restAPI.authenticateUser(user1).withCoreAPI().usingSite(site).addPerson(user2);
+
+ STEP("3. User1 adds document1 with webdav");
+ webDavProtocol.authenticateUser(user1).usingSite(site).createFile(testFile).and().assertThat().existsInRepo();
+
+ STEP("4. User2 reads the document1 with ftp");
+ ftpProtocol.authenticateUser(user2).usingResource(testFile).assertThat().contentIs("testContent");
+
+ STEP("5. User1 update document1 with WebDAV");
+ webDavProtocol.authenticateUser(user1).usingResource(testFile).update("WebDAVUpdate1").assertThat().contentIs("WebDAVUpdate1");
+
+ STEP("6. User2 update the document1 with WebDAV");
+ webDavProtocol.authenticateUser(user2).usingResource(testFile).update("WebDAVUpdate2").assertThat().contentIs("WebDAVUpdate2");
+
+ STEP("7. User1 deletes the document1 with ftp");
+ ftpProtocol.authenticateUser(user1).usingResource(testFile).delete().assertThat().doesNotExistInFtp().assertThat().doesNotExistInRepo();
+
+ STEP("8. Verify user2 cannot update document1 with cmis");
+ cmisAPI.authenticateUser(user2).usingResource(testFile).update("cmisUpdate");
+ }
+
+ /**
+ * Scenario 85
+ * 1. Upload file with CMIS
+ * 2. Add some content with ftp
+ * 3. Add a minor change to document, 1.2 with cmis
+ * 4. Add a major change to document, 2.0 with cmis
+ * 5. Add a minor change to document, 2.1 with cmis
+ * 6. Delete version 2.0 with cmis with cmis
+ * 7. Get document version with cmis
+ * 8. Try to edit version 2.0 with cmis
+ * 9. Delete version 2.1 with cmis
+ * 10. Get document version with cmis
+ * 11. Try to edit version 2.0 with cmis
+ * 12. Check document content with ftp
+ * 13. Check document version with cmis
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "File versioning test scenarios")
+ public void fileVersioningScenariosTest() throws Exception
+ {
+ STEP("1. Upload file with CMIS");
+ cmisAPI.authenticateUser(testUser1).usingSite(testSitePublic).createFile(testFile).and().assertThat().existsInRepo();
+
+ STEP("2. Add some content with ftp ");
+ ftpProtocol.authenticateUser(testUser1).usingResource(testFile).update("ftpUpdate").and().assertThat().contentIs("ftpUpdate");
+
+ STEP("3. Add a minor change to document, 1.1 with cmis");
+ cmisAPI.usingResource(testFile).checkOut().prepareDocumentForCheckIn().withContent("cmisUpdate")
+ .withMinorVersion().checkIn().refreshResource().and().assertThat().documentHasVersion(1.2);
+
+ STEP("4. Add a major change to document, 2.0 with cmis");
+ cmisAPI.usingResource(testFile).checkOut().prepareDocumentForCheckIn().withContent("cmisUpdate")
+ .withMajorVersion().checkIn().and().assertThat().documentHasVersion(2.0);
+
+ STEP("5. Add a minor change to document, 2.1 with cmis");
+ cmisAPI.usingResource(testFile).checkOut().prepareDocumentForCheckIn().withContent("cmisUpdate")
+ .withMinorVersion().checkIn().and().assertThat().documentHasVersion(2.1);
+
+ STEP("6. Delete version 2.0 with cmis with cmis");
+ cmisAPI.usingResource(testFile).deleteAllVersions(false);
+
+ STEP("7. Get document version with cmis");
+ cmisAPI.usingResource(testFile).assertThat().documentHasVersion(2.0);
+
+ STEP("8. Try to edit version 2.0 with cmis");
+ cmisAPI.usingResource(testFile).update("cmisUpdate").and().assertThat().contentIs("cmisUpdatecmisUpdate")
+ .and().assertThat().documentHasVersion(2.1);
+
+ STEP("9. Delete version 2.1 with cmis");
+ cmisAPI.usingResource(testFile).deleteAllVersions(false);
+
+ STEP("10. Get document version with cmis");
+ cmisAPI.usingResource(testFile).assertThat().documentHasVersion(2.0);
+
+ STEP("11. Try to edit version 2.0 with cmis");
+ cmisAPI.usingResource(testFile).update("cmisUpdate").and().assertThat().contentIs("cmisUpdatecmisUpdate")
+ .and().assertThat().documentHasVersion(2.1);
+
+ STEP("12. Update and check document content with ftp");
+ ftpProtocol.authenticateUser(testUser1).usingResource(testFile).update("ftpUpdate").assertThat().contentIs("ftpUpdate");
+
+ STEP("13. Check document version with cmis");
+ cmisAPI.usingResource(testFile).assertThat().documentHasVersion(2.2);
+ }
+
+ /**
+ * 1. Upload file with cmis
+ * 2. Add some content with WebDAV
+ * 3. Add a minor change to document, 1.2 with cmis
+ * 4. Add a major change to document, 2.0 with cmis
+ * 5. Add a minor change to document, 2.1 with cmis
+ * 6. Delete version 2.1 with cmis
+ * 7. Try to edit the last version (which is now 2.0) with webdav
+ * 8. Check version with CMIS
+ * 9. Add new major change, version 3.0 with cmis
+ * 10. Delete previous version with cmis
+ * 11. Delete document with ftp
+ * 12. Check document version with cmis
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL }, expectedExceptionsMessageRegExp = ".*Version Series not found.*",
+ expectedExceptions = CmisObjectNotFoundException.class)
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "File versioning additional test scenarios")
+ public void fileVersioningNegativeScenariosTest() throws Exception
+ {
+ STEP("1. Upload file with cmis");
+ cmisAPI.authenticateUser(testUser1).usingSite(testSitePublic).createFile(testFile).and().assertThat().existsInRepo();
+
+ STEP("2. Add some content with WebDAV");
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFile).update("WebDAVUpdate").and().assertThat().contentIs("WebDAVUpdate");
+
+ STEP("3. Add a minor change to document, 1.2 with cmis");
+ cmisAPI.usingResource(testFile).checkOut().prepareDocumentForCheckIn().withContent("cmisUpdate")
+ .withMinorVersion().checkIn().refreshResource().and().assertThat().documentHasVersion(1.2);
+
+ STEP("4. Add a major change to document, 2.0 with cmis");
+ cmisAPI.usingResource(testFile).checkOut().prepareDocumentForCheckIn().withContent("cmisUpdate")
+ .withMajorVersion().checkIn().and().assertThat().documentHasVersion(2.0);
+
+ STEP("5. Add a minor change to document, 2.1 with cmis");
+ cmisAPI.usingResource(testFile).checkOut().prepareDocumentForCheckIn().withContent("cmisUpdate")
+ .withMinorVersion().checkIn().refreshResource().and().assertThat().documentHasVersion(2.1);
+
+ STEP("6. Delete version 2.1 with cmis");
+ cmisAPI.usingResource(testFile).deleteAllVersions(false).assertThat().documentHasVersion(2.0);
+
+ STEP("7. Try to edit the last version (which is now 2.0) with webdav");
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFile).update("webdavUpdate");
+
+ STEP("8. Check version with CMIS");
+ cmisAPI.usingResource(testFile).assertThat().documentHasVersion(2.1);
+
+ STEP("9. Add new major change, version 3.0 with cmis");
+ cmisAPI.usingResource(testFile).checkOut().prepareDocumentForCheckIn().withContent("cmisUpdate")
+ .withMajorVersion().checkIn().and().assertThat().documentHasVersion(3.0);
+
+ STEP("10. Delete previous version with cmis");
+ cmisAPI.usingResource(testFile).deleteAllVersions(false).assertThat().documentHasVersion(2.1);
+
+ STEP("11. Delete document with ftp");
+ ftpProtocol.authenticateUser(testUser1).usingResource(testFile).delete().assertThat().doesNotExistInRepo();
+
+ STEP("12. Check document version with cmis - should fail");
+ cmisAPI.usingResource(testFile).assertThat().documentHasVersion(2.1);
+ }
+}
\ No newline at end of file
diff --git a/packaging/tests/tas-integration/src/test/java/org/alfresco/tas/integration/IntegrationFullTestsBulk3.java b/packaging/tests/tas-integration/src/test/java/org/alfresco/tas/integration/IntegrationFullTestsBulk3.java
new file mode 100644
index 00000000000..5a855da02de
--- /dev/null
+++ b/packaging/tests/tas-integration/src/test/java/org/alfresco/tas/integration/IntegrationFullTestsBulk3.java
@@ -0,0 +1,433 @@
+package org.alfresco.tas.integration;
+
+import static org.alfresco.utility.report.log.Step.STEP;
+
+import org.alfresco.rest.model.RestCommentModelsCollection;
+import org.alfresco.rest.model.RestErrorModel;
+import org.alfresco.utility.Utility;
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser.ListUserWithRoles;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.FolderModel;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.springframework.http.HttpStatus;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class IntegrationFullTestsBulk3 extends IntegrationTest
+{
+ private UserModel testUser1, testUser2;
+ private SiteModel publicSite, moderatedSite, privateSite;
+ private RestCommentModelsCollection comments;
+ private FileModel testFile1, testFile2, wordFile ;
+ private ListUserWithRoles usersWithRoles;
+ private FolderModel testFolder1;
+
+ @BeforeClass(alwaysRun = true)
+ public void dataPreparation() throws Exception
+ {
+ testUser1 = dataUser.createRandomTestUser();
+ testFolder1 = FolderModel.getRandomFolderModel();
+ publicSite = dataSite.usingUser(testUser1).createPublicRandomSite();
+ }
+
+ /**
+ * Scenario 64
+ * 1. Create folder1 with WEBDAV
+ * 2. Create wordFile inside folder1 with CMIS
+ * 3. Delete wordFile content with CMIS
+ * 4. Update content using Collaborator role with CMIS
+ * 5. Append content using Manager role with WebDAV
+ * 6. Delete content that Manager added using Collaborator role with CMIS
+ * 7. Rename wordFile with WebDAV
+ * 9. Delete wordFile with WEBDAV
+ *
+ * @throws Exception
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "File handling using several protocols")
+ public void fileHandlingWithCollaboratorRole() throws Exception
+ {
+ String contentCollaborator = "content added by Collaborator";
+ publicSite = dataSite.usingUser(testUser1).createPublicRandomSite();
+ usersWithRoles = dataUser.addUsersWithRolesToSite(publicSite, UserRole.SiteCollaborator);
+ wordFile = FileModel.getRandomFileModel(FileType.MSWORD2007, "tasTesting");
+
+ STEP("1. Create folder1 with webdav");
+ webDavProtocol.authenticateUser(testUser1).usingSite(publicSite).createFolder(testFolder1).and().assertThat().existsInRepo();
+
+ STEP("2. Create testFile1 inside folder1 using CMIS");
+ cmisAPI.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator)).usingSite(publicSite).usingResource(testFolder1).createFile(wordFile)
+ .assertThat().existsInRepo();
+
+ STEP("3. Delete wordFile content with WebDAV");
+ cmisAPI.authenticateUser(testUser1).usingResource(wordFile).deleteContent();
+
+ STEP("4. Update content using Collaborator role with CMIS");
+ cmisAPI.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingResource(wordFile).update(contentCollaborator)
+ .assertThat().contentIs(contentCollaborator);
+
+ STEP("5. Append content using Manager role with WebDAV");
+ webDavProtocol.authenticateUser(testUser1).usingResource(wordFile).update("content added by Manager").assertThat().contentIs("content added by Manager");
+
+ STEP("6. Delete content that Manager added using Collaborator role with CMIS");
+ cmisAPI.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
+ .usingResource(wordFile).deleteAllVersions(false)
+ .and().assertThat().documentHasVersion(1.2);
+
+ STEP("7. Rename wordFile with FTP");
+ ftpProtocol.authenticateUser(testUser1).usingResource(wordFile).rename("renamedFile.docx");
+
+ STEP("8. Delete file with WEBDAV");
+ webDavProtocol.authenticateUser(testUser1).usingResource(wordFile).delete()
+ .assertThat().doesNotExistInRepo();
+ }
+
+ /**
+ * Scenario 65
+ * 1. Create folder1 with WEBDAV
+ * 2. Create wordFile inside folder1 with CMIS
+ * 3. Delete wordFile content with CMIS
+ * 4. Update content using Contributor role with CMIS
+ * 5. Append content using Manager role with WebDAV
+ * 6. Delete content that Manager added using Collaborator role with CMIS
+ * 7. Rename wordFile with WEBDAV
+ * 8. Delete wordFile with FTP
+ *
+ * @throws Exception
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "File handling using several protocols")
+ public void fileHandlingWithContributorRole() throws Exception
+ {
+ String contentContributor = "content added by Contributor";
+ publicSite = dataSite.usingUser(testUser1).createPublicRandomSite();
+ usersWithRoles = dataUser.addUsersWithRolesToSite(publicSite, UserRole.SiteContributor);
+ wordFile = FileModel.getRandomFileModel(FileType.MSWORD2007, "tasTesting");
+
+ STEP("1. Create folder1 with webdav");
+ webDavProtocol.authenticateUser(testUser1).usingSite(publicSite).createFolder(testFolder1).and().assertThat().existsInRepo();
+
+ STEP("2. Create testFile1 inside folder1 using CMIS");
+ cmisAPI.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingResource(testFolder1).createFile(wordFile)
+ .assertThat().existsInRepo();
+
+ STEP("3. Delete wordFile content with CMIS");
+ cmisAPI.authenticateUser(testUser1).usingResource(wordFile).deleteContent();
+
+ STEP("4. Update content using Contributor role with CMIS");
+ cmisAPI.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingResource(wordFile).update(contentContributor)
+ .assertThat().contentIs(contentContributor);
+
+ STEP("5. Append content using Manager role with WebDAV");
+ webDavProtocol.authenticateUser(testUser1)
+ .usingResource(wordFile).update("content added by Manager")
+ .assertThat().contentIs("content added by Manager");
+
+ STEP("6. Delete content that Manager added using Contributor role with CMIS");
+ cmisAPI.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor))
+ .usingResource(wordFile).deleteAllVersions(false)
+ .and().assertThat().documentHasVersion(1.2);
+
+ STEP("7. Rename wordFile with WebDAV");
+ webDavProtocol.authenticateUser(testUser1).usingResource(wordFile).rename("renamedFile.docx");
+
+ STEP("8. Delete file with FTP");
+ ftpProtocol.authenticateUser(testUser1).usingResource(wordFile).delete().assertThat().doesNotExistInRepo();
+ }
+
+ /**
+ * Scenario 76
+ * 1. Using CMIS create two users: u1 and u2
+ * 2. U1 creates a public site using CMIS
+ * 3. U1 creates testFile1 in public site's document library using FTP
+ * 4. U1 adds comment1 for testFile1 using REST API
+ * 5. U2 gets comment1 using REST API
+ * 6. U1 updates testFile1 using WEBDAV
+ * 7. U2 gets comment1 using REST API
+ * 8. U1 deletes testFile1 using WebDAV
+ * 9. U2 can not get comment1 using REST API
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT, TestGroup.COMMENTS }, executionType = ExecutionType.REGRESSION,
+ description = "Verify comment is deleted .")
+ public void negativeScenarioWithComments() throws Exception
+ {
+ STEP("* 1. Using CMIS create two users: u1 and u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("* 2. U1 creates a public site using CMIS");
+ publicSite = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("* 3. U1 creates a file in public site's document library using FTP");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ ftpProtocol.authenticateUser(testUser1).usingSite(publicSite).createFile(testFile1).then().assertThat().existsInRepo();
+
+ STEP("* 4. U1 adds comment1 for testFile1 using REST API");
+ String newComment = "This is a new comment added by " + testUser1.getUsername();
+ restAPI.authenticateUser(testUser1).withCoreAPI().usingResource(testFile1).addComment(newComment).assertThat().field("content").isNotEmpty().and().field("content").is(newComment);
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+
+ STEP("* 5. U2 gets comment1 using REST API");
+ comments = restAPI.authenticateUser(testUser2).withCoreAPI().usingResource(testFile1).getNodeComments();
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ comments.assertThat().entriesListContains("content", newComment);
+
+ STEP("* 6. U1 updates testFile1 using WEBDAV");
+ String newContent = "This is new content added by " + testUser1.getUsername();
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFile1).update(newContent).and().assertThat().contentIs(newContent);
+
+ STEP("* 7. U2 gets comment1 using REST API");
+ comments = restAPI.authenticateUser(testUser2).withCoreAPI().usingResource(testFile1).getNodeComments();
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ comments.assertThat().entriesListContains("content", newComment);
+
+ STEP("* 8. U1 deletes testFile1 using WebDAV");
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFile1).delete().and().assertThat().doesNotExistInRepo();
+
+ STEP("* 9. U2 can not get comment1 using REST API");
+ comments = restAPI.authenticateUser(testUser2).withCoreAPI().usingResource(testFile1).getNodeComments();
+ restAPI.assertStatusCodeIs(HttpStatus.NOT_FOUND).assertLastError().containsSummary(String.format(RestErrorModel.ENTITY_NOT_FOUND, testFile1.getNodeRef()));
+ }
+
+ /**
+ * Scenario 77
+ * 1. Using CMIS create two users: u1 and u2
+ * 2. U1 creates a public site using CMIS
+ * 3. U1 creates a file in public site's document library using FTP
+ * 4. U1 applyAcl(permission) for U2 with role Site Manager to the document using CMIS
+ * 5. U2 edits the document using FTP
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Verify manager permission to a document in a public site - is able to edit document.")
+ public void addManagerPermissionToADocumentFromPublicSite() throws Exception
+ {
+ STEP("* 1. Using CMIS create two users: u1 and u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("* 2. U1 creates a public site using CMIS");
+ publicSite = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("* 3. U1 creates a file in public site's document library using FTP");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ ftpProtocol.authenticateUser(testUser1).usingSite(publicSite).createFile(testFile1).then().assertThat().existsInRepo();
+
+ STEP("* 4. U1 applyAcl(permission) for U2 with role Site Manager to the document using CMIS");
+ cmisAPI.authenticateUser(testUser1).usingResource(testFile1).addAcl(testUser2, UserRole.SiteManager).then().assertThat().permissionIsSetForUser(testUser2, UserRole.SiteManager);
+
+ STEP("* 5. U2 edits the document using FTP");
+ ftpProtocol.authenticateUser(testUser2).usingSite(publicSite).usingResource(testFile1).update("new Content").assertThat().contentIs("new Content");
+ }
+
+ /**
+ * Scenario 78
+ * 1. Using CMIS create two users: u1 and u2
+ * 2. U1 creates a public site using CMIS
+ * 3. U1 creates a file in public site's document library using FTP
+ * 4. U1 applyAcl(permission) for U2 with role Site Collaborator to the document using CMIS
+ * 5. U2 edits the document using FTP
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Verify collaborator permission to a document in a public site - is able to edit document.")
+ public void addCollaboratorPermissionToADocumentFromPublicSite() throws Exception
+ {
+ STEP("* 1. Using CMIS create two users: u1 and u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("* 2. U1 creates a public site using CMIS");
+ publicSite = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("* 3. U1 creates a file in public site's document library using FTP");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ ftpProtocol.authenticateUser(testUser1).usingSite(publicSite).createFile(testFile1).then().assertThat().existsInRepo();
+
+ STEP("* 4. U1 applyAcl(permission) for U2 with role Site Manager to the document using CMIS");
+ cmisAPI.authenticateUser(testUser1).usingResource(testFile1).addAcl(testUser2, UserRole.SiteCollaborator).then().assertThat().permissionIsSetForUser(testUser2, UserRole.SiteCollaborator);
+
+ STEP("* 5. U2 edits the document using FTP");
+ ftpProtocol.authenticateUser(testUser2).usingSite(publicSite).usingResource(testFile1).update("new Content").assertThat().contentIs("new Content");
+ }
+
+ /**
+ * Scenario 79
+ * 1. Using CMIS create two users: u1 and u2
+ * 2. U1 creates a public site using CMIS
+ * 3. U1 creates a file in public site's document library using FTP
+ * 4. U1 applyAcl(permission) for U2 with role Site Contributor to the document using CMIS
+ * 5. U2 edits the document using FTP
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Verify contributor permission to a document in a public site - is not able to edit document.")
+ public void addContributorPermissionToADocumentFromPublicSite() throws Exception
+ {
+ STEP("* 1. Using CMIS create two users: u1 and u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("* 2. U1 creates a public site using CMIS");
+ publicSite = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("* 3. U1 creates a file in public site's document library using FTP");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ ftpProtocol.authenticateUser(testUser1).usingSite(publicSite).createFile(testFile1).then().assertThat().existsInRepo();
+
+ STEP("* 4. U1 applyAcl(permission) for U2 with role Site Manager to the document using CMIS");
+ cmisAPI.authenticateUser(testUser1).usingResource(testFile1).addAcl(testUser2, UserRole.SiteContributor).then().assertThat().permissionIsSetForUser(testUser2, UserRole.SiteContributor);
+
+ STEP("* 5. U2 edits the document using FTP");
+ ftpProtocol.authenticateUser(testUser2).usingSite(publicSite).usingResource(testFile1).update("new Content");
+ ftpProtocol.authenticateUser(testUser1).usingSite(publicSite).usingResource(testFile1).assertThat().contentIs("file1 content");
+ }
+
+ /**
+ * Scenario 80
+ * 1. Using CMIS create two users: u1 and u2
+ * 2. U1 creates a public site using CMIS
+ * 3. U1 creates a file in public site's document library using FTP
+ * 4. U1 applyAcl(permission) for U2 with role Site Consumer to the document using CMIS
+ * 5. U2 edits the document using FTP
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Verify consumer permission to a document in a public site - is not able to edit document.")
+ public void addConsumerPermissionToADocumentFromPublicSite() throws Exception
+ {
+ STEP("* 1. Using CMIS create two users: u1 and u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("* 2. U1 creates a public site using CMIS");
+ publicSite = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("* 3. U1 creates a file in public site's document library using FTP");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ ftpProtocol.authenticateUser(testUser1).usingSite(publicSite).createFile(testFile1).then().assertThat().existsInRepo();
+
+ STEP("* 4. U1 applyAcl(permission) for U2 with role Site Manager to the document using CMIS");
+ cmisAPI.authenticateUser(testUser1).usingResource(testFile1).addAcl(testUser2, UserRole.SiteConsumer).then().assertThat().permissionIsSetForUser(testUser2, UserRole.SiteConsumer);
+
+ STEP("* 5. U2 edits the document using FTP");
+ ftpProtocol.authenticateUser(testUser2).usingSite(publicSite).usingResource(testFile1).update("new Content");
+ ftpProtocol.authenticateUser(testUser1).usingSite(publicSite).usingResource(testFile1).assertThat().contentIs("file1 content");
+ }
+
+ /**
+ * Scenario 107
+ * 1. Using CMIS create two users: u1 and u2
+ * 2. U1 creates a moderated site using CMIS
+ * 3. U1 creates a file in moderated site's document library using FTP
+ * 4. U1 applyAcl(permission) for U2 with role Site Manager to the document using CMIS
+ * 5. U2 edits the document using FTP
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Verify manager permission to a document in a moderated site - is not able to edit document.")
+ public void addManagerPermissionToADocumentFromModeratedSite() throws Exception
+ {
+ STEP("* 1. Using CMIS create two users: u1 and u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("* 2. U1 creates a moderated site using CMIS");
+ moderatedSite = dataSite.usingUser(testUser1).createModeratedRandomSite();
+
+ STEP("* 3. U1 creates a file in moderated site's document library using FTP");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ ftpProtocol.authenticateUser(testUser1).usingSite(moderatedSite).createFile(testFile1).then().assertThat().existsInRepo();
+
+ STEP("* 4. U1 applyAcl(permission) for U2 with role Site Manager to the document using CMIS");
+ cmisAPI.authenticateUser(testUser1).usingResource(testFile1).addAcl(testUser2, UserRole.SiteManager).then().assertThat().permissionIsSetForUser(testUser2, UserRole.SiteManager);
+
+ STEP("* 5. U2 edits the document using FTP");
+ ftpProtocol.authenticateUser(testUser2).usingSite(moderatedSite).usingResource(testFile1).update("new Content");
+ ftpProtocol.authenticateUser(testUser1).usingSite(moderatedSite).usingResource(testFile1).assertThat().contentIs("file1 content");
+ }
+
+ /**
+ * Scenario 108
+ * 1. Using CMIS create two users: u1 and u2
+ * 2. U1 creates a private site using CMIS
+ * 3. U1 creates a file in private site's document library using FTP
+ * 4. U1 applyAcl(permission) for U2 with role Site Manager to the document using CMIS
+ * 5. U2 edits the document using FTP
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.REGRESSION,
+ description = "Verify manager permission to a document in a private site - is not able to edit document.")
+ public void addManagerPermissionToADocumentFromPrivateSite() throws Exception
+ {
+ STEP("* 1. Using CMIS create two users: u1 and u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("* 2. U1 creates a private site using CMIS");
+ privateSite = dataSite.usingUser(testUser1).createPrivateRandomSite();
+
+ STEP("* 3. U1 creates a file in private site's document library using FTP");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ ftpProtocol.authenticateUser(testUser1).usingSite(privateSite).createFile(testFile1).then().assertThat().existsInRepo();
+
+ STEP("* 4. U1 applyAcl(permission) for U2 with role Site Manager to the document using CMIS");
+ cmisAPI.authenticateUser(testUser1).usingResource(testFile1).addAcl(testUser2, UserRole.SiteManager).then().assertThat().permissionIsSetForUser(testUser2, UserRole.SiteManager);
+
+ STEP("* 5. U2 edits the document using FTP");
+ ftpProtocol.authenticateUser(testUser2).usingSite(privateSite).usingResource(testFile1).update("new Content");
+ ftpProtocol.authenticateUser(testUser1).usingSite(privateSite).usingResource(testFile1).assertThat().contentIs("file1 content");
+ }
+
+ /**
+ * Scenario 60
+ * 1. Using CMIS creates one test user: u1
+ * 2. U1 creates testFile1 in public site using FTP
+ * 3. U1 creates testFile2 in public site using FTP
+ * 4. U1 updates testFile2 using FTP
+ * 5. Compare created date with modified date
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT}, executionType = ExecutionType.REGRESSION, description = "Compare Modified Date")
+ public void manageModificationTimeOfFile() throws Exception
+ {
+ STEP("1. Using CMIS creates one test user: u1");
+ testUser1 = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates testFile1 in a public site using FTP");
+ publicSite = dataSite.usingUser(testUser1).createPublicRandomSite();
+ testFile1 = new FileModel("testFile1", FileType.TEXT_PLAIN);
+ ftpProtocol.authenticateUser(testUser1).usingSite(publicSite).createFile(testFile1).assertThat().existsInRepo();
+ String modifiedDate1 = ftpProtocol.getModificationTime();
+
+ STEP("3. U1 creates testFile2 in a public site using FTP");
+ publicSite = dataSite.usingUser(testUser1).createPublicRandomSite();
+ testFile2 = new FileModel("testFile1", FileType.TEXT_PLAIN);
+ Utility.waitToLoopTime(2);
+ ftpProtocol.usingSite(publicSite).createFile(testFile2).assertThat().existsInRepo();
+ String modifiedDate2 = ftpProtocol.getModificationTime();
+ Utility.waitToLoopTime(2, "Waiting for update");
+
+ STEP("4. U1 updates testFile2 in a public site using FTP");
+ ftpProtocol.update("test update").assertThat().contentIs("test update");
+ String updatedDate2 = ftpProtocol.getModificationTime();
+
+ STEP("5. Compare created date with modified date");
+ Assert.assertNotEquals(modifiedDate1, modifiedDate2, "Updated and modified dates are equal");
+ Assert.assertNotEquals(modifiedDate2, updatedDate2, "Modified and updated dates are equal");
+ }
+
+}
\ No newline at end of file
diff --git a/packaging/tests/tas-integration/src/test/java/org/alfresco/tas/integration/IntegrationSanityTests.java b/packaging/tests/tas-integration/src/test/java/org/alfresco/tas/integration/IntegrationSanityTests.java
new file mode 100644
index 00000000000..50b74af19d8
--- /dev/null
+++ b/packaging/tests/tas-integration/src/test/java/org/alfresco/tas/integration/IntegrationSanityTests.java
@@ -0,0 +1,1109 @@
+package org.alfresco.tas.integration;
+
+import static org.alfresco.utility.report.log.Step.STEP;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.mail.MessagingException;
+
+import org.alfresco.rest.model.RestCommentModel;
+import org.alfresco.rest.model.RestErrorModel;
+import org.alfresco.rest.model.RestTagModel;
+import org.alfresco.utility.Utility;
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.RandomData;
+import org.alfresco.utility.model.*;
+import org.alfresco.utility.report.Bug;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.springframework.http.HttpStatus;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * Created by Claudia Agache on 10/25/2016.
+ */
+public class IntegrationSanityTests extends IntegrationTest
+{
+ UserModel testUser1, testUser2, testUser3;
+ SiteModel testSitePublic, testSiteModerated, testSitePrivate, secondTestSitePublic;
+ FolderModel testFolder1, testFolder2, testFolder3;
+ FileModel testFile1, testFile2, testFile3, testFile4;
+ RestCommentModel comment;
+
+ /**
+ * Scenario 1
+ * 1. Using CMIS create two test users: u1, u2
+ * 2. U1 creates a test site using CMIS
+ * 3. Using REST API add u2 as member with Collaborator role
+ * 4. U2 creates one folder F1 using WEBDAV
+ * 5. U2 creates one file in F1 using WebDAV
+ * 6. U2 adds a comment to file using REST API
+ * 7. U1 gets comments using REST API
+ * 8. U1 updates the file content using WEBDAV. Assert with CMIS that content is updated
+ * 9. U1 updates comment using REST API
+ * 10. U2 gets comments using REST API
+ * 11. U2 deletes comment using REST API
+ * 12. U1 deletes file using FTP. Assert with CMIS that file doesn't exist in repository
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.SANITY })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT, TestGroup.COMMENTS }, executionType = ExecutionType.SANITY,
+ description = "Verify two new users are able to manage comments on the same file.")
+ public void usersAreAbleToManageComments() throws Exception
+ {
+ STEP("* 1. Using CMIS create two test users: u1, u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("* 2. U1 creates a test site using CMIS");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("* 3. Using REST API add u2 as member with Collaborator role");
+ testUser2.setUserRole(UserRole.SiteCollaborator);
+ restAPI.authenticateUser(testUser1).withCoreAPI().usingSite(testSitePublic).addPerson(testUser2);
+
+ STEP("* 4. U2 creates one folder F1 using WEBDAV");
+ testFolder1 = FolderModel.getRandomFolderModel();
+ webDavProtocol.authenticateUser(testUser2).usingSite(testSitePublic).createFolder(testFolder1).and().assertThat().existsInWebdav();
+
+ STEP("* 5. U2 creates one file in F1 using WebDAV");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ webDavProtocol.authenticateUser(testUser2).usingResource(testFolder1).createFile(testFile1).and().assertThat().existsInWebdav();
+
+ STEP("* 6. U2 adds a comment to file using REST API");
+ comment = restAPI.authenticateUser(testUser2).withCoreAPI().usingResource(testFile1).addComment("U2 comment");
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+ comment.assertThat().field("content").is("U2 comment");
+
+ STEP("* 7. U1 gets comments using REST API");
+ restAPI.authenticateUser(testUser1).withCoreAPI()
+ .usingResource(testFile1).getNodeComments()
+ .assertThat().entriesListContains("content", "U2 comment");
+
+ STEP("* 8. U1 updates the file content using WEBDAV. Assert with CMIS that content is updated");
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFile1).update("file content");
+ cmisAPI.authenticateUser(testUser1).usingResource(testFile1).assertThat().contentIs("file content");
+
+ STEP("* 9. U1 updates comment using REST API");
+ comment = restAPI.withCoreAPI().usingResource(testFile1).updateComment(comment, "U1 updated comment");
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ comment.assertThat().field("content").is("U1 updated comment");
+
+ STEP("* 10. U2 gets comments using REST API");
+ restAPI.authenticateUser(testUser2).withCoreAPI()
+ .usingResource(testFile1).getNodeComments()
+ .assertThat().entriesListContains("content", "U1 updated comment");
+
+ STEP("* 11. U2 deletes comment using REST API");
+ restAPI.withCoreAPI().usingResource(testFile1).deleteComment(comment);
+ restAPI.assertStatusCodeIs(HttpStatus.NO_CONTENT);
+
+ STEP("* 12. U1 deletes file using FTP. Assert with CMIS that file doesn't exist in repository");
+ ftpProtocol.authenticateUser(testUser1).usingResource(testFile1).delete().assertThat().doesNotExistInRepo();
+ }
+
+ /**
+ * Scenario 2
+ * 1. Using CMIS create two test users: u1, u2
+ * 2. U1 creates a test site using CMIS
+ * 3. Using CMIS add u2 as site member with Contributor role
+ * 4. U1 creates one folder F1 using FTP
+ * 5. U1 creates one file in F1 using WEBDAV
+ * 6. U2 adds file to favorites using REST API
+ * 7. U2 gets favorites using REST API. Assert that only file is favorite.
+ * 8. U1 gets favorites using REST API. Assert that U1 has his site at favorites.
+ * 9. U1 adds file to favorites using REST API
+ * 10. U1 adds folder to favorites using REST API
+ * 11. U2 remove file from favorites using REST API
+ * 12. U2 adds site to favorites using REST API
+ * 13. U2 gets favorites using REST API. Assert that only site is favorite.
+ * 14. U1 gets favorites using REST API. Assert that site, file and folder are favorites.
+ * 15. U1 deletes file using WebDAV. Assert with WebDAV that file doesn't exist in repository
+ * 16. U1 gets favorites using REST API. Assert that only site and folder are favorites.
+ * 17. U2 gets favorites using REST API. Assert that only site is favorite.
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.SANITY })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.FAVORITES }, executionType = ExecutionType.SANITY,
+ description = "Verify two new users are able to manage favorites.")
+ public void usersAreAbleToManageFavorites() throws Exception
+ {
+ STEP("* 1. Using CMIS create two test users: u1, u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("* 2. U1 creates a test site using CMIS");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+ restAPI.authenticateUser(dataUser.getAdminUser());
+
+ STEP("* 3. Using CMIS add u2 as site member with Contributor role");
+ dataUser.usingUser(testUser1).addUserToSite(testUser2, testSitePublic, UserRole.SiteContributor);
+
+ STEP("* 4. U1 creates one folder F1 using FTP");
+ testFolder1 = FolderModel.getRandomFolderModel();
+ ftpProtocol.authenticateUser(testUser1).usingSite(testSitePublic).createFolder(testFolder1).and().assertThat().existsInRepo();
+
+ STEP("* 5. U1 creates one file in F1 using WEBDAV");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFolder1).createFile(testFile1).and().assertThat().existsInWebdav();
+
+ STEP("* 6. U2 adds file to favorites using REST API");
+ restAPI.authenticateUser(testUser2).withCoreAPI()
+ .usingAuthUser().addFileToFavorites(testFile1)
+ .assertThat().field("targetGuid").is(testFile1.getNodeRef().replace(";1.0", ""));
+
+ STEP("* 7. U2 gets favorites using REST API. Assert that only the file is favorite.");
+ restAPI.withCoreAPI().usingAuthUser().getFavorites()
+ .assertThat().entriesListContains("targetGuid", testFile1.getNodeRef().replace(";1.0", ""))
+ .and().paginationField("totalItems").is("1");
+
+ STEP("* 8. U1 gets favorites using REST API. Assert that U1 has his site at favorites.");
+ restAPI.authenticateUser(testUser1).withCoreAPI()
+ .usingAuthUser().getFavorites()
+ .assertThat().entriesListContains("targetGuid", testSitePublic.getGuid())
+ .and().paginationField("totalItems").is("1");
+
+ STEP("* 9. U1 adds file to favorites using REST API");
+ restAPI.withCoreAPI().usingAuthUser().addFileToFavorites(testFile1)
+ .assertThat().field("targetGuid").is(testFile1.getNodeRef().replace(";1.0", ""));
+
+ STEP("* 10. U1 adds folder to favorites using REST API");
+ restAPI.withCoreAPI().usingAuthUser().addFolderToFavorites(testFolder1)
+ .assertThat().field("targetGuid").is(testFolder1.getNodeRef());
+
+ STEP("* 11. U2 remove file from favorites using REST API");
+ restAPI.authenticateUser(testUser2).withCoreAPI()
+ .usingAuthUser().deleteFileFromFavorites(testFile1);
+
+ STEP("* 12. U2 adds site to favorites using REST API");
+ restAPI.withCoreAPI().usingAuthUser().addSiteToFavorites(testSitePublic)
+ .assertThat().field("targetGuid").is(testSitePublic.getGuid());
+
+ STEP("* 13. U2 gets favorites using REST API. Assert that only site is favorite.");
+ restAPI.withCoreAPI().usingAuthUser().getFavorites()
+ .assertThat().entriesListDoesNotContain("targetGuid", testFile1.getNodeRef().replace(";1.0", "")).and()
+ .entriesListContains("targetGuid", testSitePublic.getGuid()).and().paginationField("totalItems").is("1");
+
+ STEP("* 14. U1 gets favorites using REST API. Assert that site, file and folder are favorites.");
+ restAPI.authenticateUser(testUser1).withCoreAPI().usingAuthUser().getFavorites()
+ .assertThat().entriesListContains("targetGuid", testSitePublic.getGuid())
+ .assertThat().entriesListContains("targetGuid", testFile1.getNodeRef().replace(";1.0", ""))
+ .and().entriesListContains("targetGuid", testFolder1.getNodeRef())
+ .and().paginationField("totalItems").is("3");
+
+ STEP("* 15. U1 deletes file using WebDAV. Assert with WebDAV that file doesn't exist in repository");
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFile1).delete().and().assertThat().doesNotExistInWebdav();
+
+ STEP("* 16. U1 gets favorites using REST API. Assert that only site and folder are favorites.");
+ restAPI.withCoreAPI().usingAuthUser().getFavorites()
+ .assertThat().entriesListContains("targetGuid", testSitePublic.getGuid())
+ .assertThat().entriesListContains("targetGuid", testFolder1.getNodeRef())
+ .and().paginationField("totalItems").is("2");
+
+ STEP("* 17. U2 gets favorites using REST API. Assert that only site is favorite.");
+ restAPI.authenticateUser(testUser2).withCoreAPI().usingAuthUser().getFavorites()
+ .assertThat().entriesListContains("targetGuid", testSitePublic.getGuid())
+ .and().paginationField("totalItems").is("1");
+ }
+
+ /**
+ * Scenario 3
+ * 1. Using CMIS create two test users: u1, u2
+ * 2. U1 creates a test site using CMIS
+ * 3. Using CMIS add u2 as site member with Manager role
+ * 4. U1 creates 3 folders: F1 using FTP, F2 using WebDAV as a subfolder of F1, F3 using WEBDAV as a subfolder of F2
+ * 5. U1 creates one file in each folder using FTP and WEBDAV
+ * 6. U1 renames F2 using IMAP
+ * 7. U1 updates file1 using WebDAV
+ * 8. U1 deletes file2 using FTP
+ * 9. U1 deletes non empty folder3 using WEBDAV
+ * 10. Assert with CMIS that U2 is able to see all the above changes
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.SANITY })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.SANITY,
+ description = "Verify user is able to manage files and folders.")
+ public void userIsAbleToManageFilesAndFolders() throws Exception
+ {
+ STEP("* 1. Using CMIS create two test users: u1, u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("* 2. U1 creates a test site using CMIS");
+ testSitePublic = dataSite.usingUser(testUser1).createIMAPSite();
+
+ STEP("* 3. Using CMIS add u2 as site member with Manager role");
+ dataUser.usingUser(testUser1).addUserToSite(testUser2, testSitePublic, UserRole.SiteManager);
+
+ STEP("* 4. U1 creates 3 folders: F1 using FTP, F2 using WebDAV as a subfolder of F1, F3 using WEBDAV as a subfolder of F2. "
+ + "* 5. U1 creates one file in each folder using FTP and WEBDAV");
+ testFolder1 = FolderModel.getRandomFolderModel();
+ testFolder2 = FolderModel.getRandomFolderModel();
+ testFolder3 = FolderModel.getRandomFolderModel();
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ testFile2 = FileModel.getRandomFileModel(FileType.HTML);
+ testFile3 = FileModel.getRandomFileModel(FileType.MSWORD, "some content");
+
+ ftpProtocol.authenticateUser(testUser1).usingSite(testSitePublic).createFolder(testFolder1).and().assertThat().existsInFtp();
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFolder1).createFolder(testFolder2).assertThat().existsInWebdav()
+ .and().createFile(testFile1).assertThat().existsInWebdav();
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFolder2).createFolder(testFolder3).assertThat().existsInWebdav()
+ .and().createFile(testFile2).assertThat().existsInWebdav();
+ ftpProtocol.authenticateUser(testUser1).usingResource(testFolder3).createFile(testFile3).then().assertThat().existsInFtp();
+
+ STEP(" * 6. U1 renames F2 using IMAP");
+ imapProtocol.authenticateUser(testUser1).usingResource(testFolder2).rename("F2 rename")
+ .then().usingResource(testFolder1)
+ .assertThat().contains(new FolderModel("F2 rename"))
+ .and().assertThat().doesNotContain(testFolder2);
+
+ STEP(" * 7. U1 updates file1 using WebDAV");
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFile1).update("testFile1 content.").then().assertThat().contentIs("testFile1 content.");
+
+ STEP("* 8. U1 deletes file2 using FTP");
+ ftpProtocol.authenticateUser(testUser1).usingResource(testFile2).delete().then().assertThat().doesNotExistInRepo();
+
+ STEP(" * 9. U1 deletes non empty folder3 using WEBDAV");
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFolder3).delete().then().assertThat().doesNotExistInWebdav();
+
+ STEP("* 10. Assert with CMIS that U2 is able to see all the above changes");
+ cmisAPI.authenticateUser(testUser2)
+ .usingResource(testFolder1).assertThat().hasChildren(testFile1)
+ .usingResource(testFile1).assertThat().contentIs("testFile1 content.")
+ .usingResource(testFile2).assertThat().doesNotExistInRepo()
+ .usingResource(testFolder3).assertThat().doesNotExistInRepo()
+ .usingResource(testFile3).assertThat().doesNotExistInRepo();
+
+ FolderModel renamedFolder = cmisAPI.usingResource(testFolder1).getFolders().get(0);
+ Assert.assertEquals(renamedFolder.getName(), "F2 rename", "User2 is able to see the renamed folder");
+ }
+
+ /**
+ * Scenario 4
+ * 1. Using CMIS create two test users: u1, u2
+ * 2. U1 creates a test site using CMIS
+ * 3. Using REST API add u2 as site member with Collaborator role
+ * 4. U2 creates file1 with using CMIS
+ * 5. U1 creates file2 from source using CMIS
+ * 6. U1 uploads file3 using FTP
+ * 7. U1 creates file4 using CMIS
+ * 8. U1 marks file1 and 3 as favorite using REST API
+ * 9. U2 marks file 1, 2, 4 as favorite using REST API
+ * 10. U2 marks site as favorite using REST API
+ * 11. U1 removes file1 from favorites using REST API
+ * 12. U2 checks file favorites using REST API. Assert that U2 gets only his favorite files.
+ * 13. U2 removes file1 from favorites using REST API
+ * 14. U2 checks file favorites using REST API. Assert that U2 gets only his favorite files.
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.SANITY })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT, TestGroup.FAVORITES }, executionType = ExecutionType.SANITY,
+ description = "Verify two new users are able to manage favorite files.")
+ public void usersAreAbleToManageFavoriteFiles() throws Exception
+ {
+ STEP("* 1. Using CMIS create two test users: u1, u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("* 2. U1 creates a test site using CMIS");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+ restAPI.authenticateUser(dataUser.getAdminUser());
+ testSitePublic.setGuid(restAPI.withCoreAPI().usingSite(testSitePublic).getSite().getGuid());
+
+ STEP("* 3. Using REST API add u2 as site member with Collaborator role");
+ testUser2.setUserRole(UserRole.SiteCollaborator);
+ restAPI.authenticateUser(testUser1).withCoreAPI().usingSite(testSitePublic).addPerson(testUser2);
+
+ STEP(" * 4. U2 creates file1 with using CMIS");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ cmisAPI.authenticateUser(testUser2).usingSite(testSitePublic).createFile(testFile1).then().assertThat().existsInRepo();
+
+ STEP("* 5. U1 creates file2 from source using CMIS");
+ testFile2 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN);
+ cmisAPI.authenticateUser(testUser1).usingSite(testSitePublic).createFileFromSource(testFile2, testFile1).and().refreshResource().then()
+ .assertThat().existsInRepo();
+
+ STEP(" * 6. U1 uploads file3 using FTP");
+ testFile3 = FileModel.getFileModelBasedOnTestDataFile("testUploadFile.txt");
+ ftpProtocol.authenticateUser(testUser1).usingSite(testSitePublic).createFile(testFile3).then().assertThat().existsInRepo();
+
+ STEP("* 7. U1 creates file4 using CMIS");
+ testFile4 = FileModel.getRandomFileModel(FileType.MSWORD, "file4 content");
+ cmisAPI.authenticateUser(testUser1).usingSite(testSitePublic).createFile(testFile4).then().assertThat().existsInRepo();
+
+ STEP("* 8. U1 marks file1 and 3 as favorite using REST API");
+ restAPI.authenticateUser(testUser1).withCoreAPI()
+ .usingAuthUser().addFileToFavorites(testFile1)
+ .assertThat().field("targetGuid").is(testFile1.getNodeRef().replace(";1.0", ""));
+ restAPI.withCoreAPI().usingAuthUser().addFileToFavorites(testFile3)
+ .assertThat().field("targetGuid").is(testFile3.getNodeRef().replace(";1.0", ""));
+
+ STEP("* 9. U2 marks file 1, 2, 4 as favorite using REST API");
+ restAPI.authenticateUser(testUser2).withCoreAPI()
+ .usingAuthUser().addFileToFavorites(testFile1)
+ .assertThat().field("targetGuid").is(testFile1.getNodeRef().replace(";1.0", ""));
+ restAPI.withCoreAPI().usingAuthUser().addFileToFavorites(testFile2)
+ .assertThat().field("targetGuid").is(testFile2.getNodeRef().replace(";1.0", ""));
+ restAPI.withCoreAPI().usingAuthUser().addFileToFavorites(testFile4)
+ .assertThat().field("targetGuid").is(testFile4.getNodeRef().replace(";1.0", ""));
+
+ STEP("* 10. U2 marks site as favorite using REST API");
+ restAPI.withCoreAPI().usingAuthUser().addSiteToFavorites(testSitePublic)
+ .assertThat().field("targetGuid").is(testSitePublic.getGuid());
+
+ STEP("* 11. U1 removes file1 from favorites using REST API");
+ restAPI.authenticateUser(testUser1).withCoreAPI().usingAuthUser().deleteFileFromFavorites(testFile1);
+
+ STEP("* 12. U2 checks file favorites using REST API. Assert that U2 gets only his favorite files.");
+ restAPI.authenticateUser(testUser2).withCoreAPI().usingAuthUser()
+ .where().targetFileExist().getFavorites().assertThat()
+ .entriesListContains("targetGuid", testFile1.getNodeRef().replace(";1.0", "")).and()
+ .entriesListContains("targetGuid", testFile2.getNodeRef().replace(";1.0", "")).and()
+ .entriesListContains("targetGuid", testFile4.getNodeRef().replace(";1.0", "")).and()
+ .paginationField("totalItems").is("3");
+
+ STEP("* 13. U2 removes file1 from favorites using REST API");
+ restAPI.withCoreAPI().usingAuthUser().deleteFileFromFavorites(testFile1);
+
+ STEP("* 14. U2 checks file favorites using REST API. Assert that U2 gets only his favorite files.");
+ restAPI.withCoreAPI().usingAuthUser()
+ .where().targetFileExist().getFavorites().assertThat()
+ .entriesListContains("targetGuid", testFile2.getNodeRef().replace(";1.0", "")).and()
+ .entriesListContains("targetGuid", testFile4.getNodeRef().replace(";1.0", "")).and()
+ .paginationField("totalItems").is("2");
+ }
+
+ /**
+ * Scenario 5
+ * 1. Using CMIS create a test user: u1
+ * 2. U1 creates a test site using CMIS
+ * 3. U1 creates 2 files in site's document library using FTP
+ * 4. U1 creates folder1 in site's document library using WebDAV
+ * 5. U1 creates another 2 files in folder1 using WEBDAV
+ * 6. U1 adds tag1, tag2 on file1, tag2 on file2 using REST API
+ * 7. U1 adds tag1 on folder1, tag3 on file3 using REST API
+ * 8. U1 gets tags and verify all tags are listed
+ * 9. U1 gets file1 tags and verify only tag1 and tag2 are listed
+ * 10. U1 deletes tag2 from file1
+ * 11. U1 deletes file3 using WebDAV
+ * 12. U1 gets tags and verify all tags are listed
+ * 13. U1 gets file1 tags and verify tag2 was removed.
+ * 14. U1 gets folder1 tags and verify only tag1 is listed.
+ * 15. U1 deletes non empty folder1 using CMIS
+ * 16. U1 gets tags and verify all tags are listed
+ */
+ @Bug(id = "REPO-4789")
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.SANITY })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT, TestGroup.TAGS }, executionType = ExecutionType.SANITY,
+ description = "Verify site manager is able to manage tags.")
+ public void siteManagerIsAbleToManageTags() throws Exception
+ {
+ STEP("* 1. Using CMIS create a test user: u1");
+ testUser1 = dataUser.createRandomTestUser();
+
+ STEP("* 2. U1 creates a test site using CMIS");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("* 3. U1 creates 2 files in site's document library using FTP");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ testFile2 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file2 content");
+ ftpProtocol.authenticateUser(testUser1).usingSite(testSitePublic)
+ .createFile(testFile1).then().assertThat().existsInRepo()
+ .createFile(testFile2).then().assertThat().existsInRepo();
+
+ STEP("* 4. U1 creates folder1 in site's document library using WebDAV");
+ testFolder1 = FolderModel.getRandomFolderModel();
+ webDavProtocol.authenticateUser(testUser1).usingSite(testSitePublic).createFolder(testFolder1).then().assertThat().existsInRepo();
+
+ STEP("* 5. U1 creates another 2 files in folder1 using WEBDAV");
+ testFile3 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file3 content");
+ testFile4 = FileModel.getRandomFileModel(FileType.MSWORD, "file4 content");
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFolder1)
+ .createFile(testFile3).then().assertThat().existsInRepo()
+ .createFile(testFile4).then().assertThat().existsInRepo();
+
+ STEP("* 6. U1 adds tag1, tag2 on file1, tag2 on file2 using REST API");
+ restAPI.authenticateUser(testUser1).withCoreAPI()
+ .usingResource(testFile1).addTags("integration_tag1", "integration_tag2")
+ .assertThat().entriesListContains("tag", "integration_tag1")
+ .and().entriesListContains("tag", "integration_tag2");
+ RestTagModel tag2 = restAPI.withCoreAPI()
+ .usingResource(testFile2).addTag("integration_tag2")
+ .assertThat().field("tag").is("integration_tag2");
+
+ STEP("* 7. U1 adds tag1 on folder1, tag3 on file3 using REST API");
+ restAPI.withCoreAPI()
+ .usingResource(testFolder1).addTag("integration_tag1")
+ .assertThat().field("tag").is("integration_tag1");
+
+ restAPI.withCoreAPI()
+ .usingResource(testFile3).addTag("integration_tag3")
+ .assertThat().field("tag").is("integration_tag3");
+
+ STEP("* 8. U1 gets tags and verify all tags are listed");
+ Utility.sleep(500, 30000, () ->
+ restAPI.withParams("maxItems=10000").withCoreAPI().getTags()
+ .assertThat().entriesListContains("tag", "integration_tag1")
+ .and().entriesListContains("tag", "integration_tag2")
+ .and().entriesListContains("tag", "integration_tag3"));
+ STEP("* 9. U1 gets file1 tags and verify only tag1 and tag2 are listed");
+ restAPI.withCoreAPI()
+ .usingResource(testFile1).getNodeTags()
+ .assertThat().entriesListContains("tag", "integration_tag1")
+ .and().entriesListContains("tag", "integration_tag2")
+ .and().paginationField("totalItems").is("2");
+
+ STEP("* 10. U1 deletes tag2 from file1");
+ restAPI.withCoreAPI().usingResource(testFile1).deleteTag(tag2);
+ restAPI.assertStatusCodeIs(HttpStatus.NO_CONTENT);
+
+ STEP("* 11. U1 deletes file3 using WebDAV");
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFile3).delete().then().assertThat().doesNotExistInWebdav();
+
+ STEP("* 12. U1 gets tags and verify all tags are listed");
+ restAPI.withParams("maxItems=10000").withCoreAPI().getTags()
+ .assertThat().entriesListContains("tag", "integration_tag1")
+ .and().entriesListContains("tag", "integration_tag2")
+ .and().entriesListContains("tag", "integration_tag3");
+
+ STEP(" * 13. U1 gets file1 tags and verify tag2 was removed.");
+ restAPI.withCoreAPI().usingResource(testFile1).getNodeTags()
+ .assertThat().entriesListContains("tag", "integration_tag1")
+ .and().entriesListDoesNotContain("tag", "integration_tag2")
+ .and().paginationField("totalItems").is("1");
+
+ STEP("* 14. U1 gets folder1 tags and verify only tag1 is listed.");
+ restAPI.withCoreAPI().usingResource(testFolder1).getNodeTags()
+ .assertThat().entriesListContains("tag", "integration_tag1")
+ .and().paginationField("totalItems").is("1");
+
+ STEP("* 15. U1 deletes non empty folder1 using CMIS");
+ cmisAPI.authenticateUser(testUser1).usingResource(testFolder1).deleteFolderTree().assertThat().doesNotExistInRepo();
+
+ STEP("* 16. U1 gets tags and verify all tags are listed");
+ restAPI.withParams("maxItems=10000").withCoreAPI().getTags()
+ .assertThat().entriesListContains("tag", "integration_tag1")
+ .and().entriesListContains("tag", "integration_tag2")
+ .and().entriesListContains("tag", "integration_tag3");
+ }
+
+ /**
+ * Scenario 6
+ * 1. Using CMIS create 3 test user: u1, u2, u3
+ * 2. Using CMIS U1 creates a public test site, a moderated test site and a private test site
+ * 3. Using REST API, U2 request to join the public site
+ * 4. Using REST API, U3 request to join the public site
+ * 5. Using REST API, check that u2 and u3 are added to public site with Consumer role
+ * 6. Using REST API, U2 request to join the moderated site
+ * 7. Using REST API, U3 request to join the moderated site
+ * 8. Using REST API, check that u2 and u3 requests to join the moderated site are added to site membership request list
+ * 9. Using REST API, U1 cancels the request for U3
+ * 10. Using REST API, check that u2 can't make requests to join the private site
+ * 11. Using REST API, check that only u2 request remains in site membership request list
+ * 12. Using REST API, U1 change U2 role to Collaborator in public site
+ * 13. Using REST API, get site membership information for each user
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.SANITY })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.SITES }, executionType = ExecutionType.SANITY,
+ description = "Verify site manager is able to manage site membership.")
+ public void siteManagerIsAbleToManageSiteMembership() throws Exception
+ {
+ STEP("* 1. Using CMIS create 3 test user: u1, u2, u3");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+ testUser3 = dataUser.createRandomTestUser();
+
+ STEP(" * 2. Using CMIS U1 creates a public test site, a moderated test site and a private test site");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+ testSiteModerated = dataSite.usingUser(testUser1).createModeratedRandomSite();
+ testSitePrivate = dataSite.usingUser(testUser1).createPrivateRandomSite();
+
+ STEP("* 3. Using REST API, U2 request to join the public site");
+ restAPI.authenticateUser(testUser2).withCoreAPI()
+ .usingAuthUser().addSiteMembershipRequest(testSitePublic);
+
+ STEP("* 4. Using REST API, U3 request to join the public site");
+ restAPI.authenticateUser(testUser3).withCoreAPI()
+ .usingAuthUser().addSiteMembershipRequest(testSitePublic);
+
+ STEP(" * 5. Using REST API, check that u2 and u3 are added to public site with Consumer role");
+ restAPI.withCoreAPI()
+ .usingSite(testSitePublic).getSiteMembers()
+ .assertThat().entriesListContains("id", testUser2.getUsername())
+ .and().entriesListContains("id", testUser3.getUsername());
+ restAPI.withCoreAPI()
+ .usingSite(testSitePublic).getSiteMember(testUser2)
+ .assertThat().field("role").is("SiteConsumer");
+
+ restAPI.withCoreAPI()
+ .usingSite(testSitePublic).getSiteMember(testUser3)
+ .assertThat().field("role").is("SiteConsumer");
+
+ STEP("* 6. Using REST API, U3 request to join the moderated site");
+ restAPI.withCoreAPI()
+ .usingAuthUser().addSiteMembershipRequest(testSiteModerated);
+
+ STEP("* 7. Using REST API, U2 request to join the moderated site");
+ restAPI.authenticateUser(testUser2).withCoreAPI()
+ .usingAuthUser().addSiteMembershipRequest(testSiteModerated);
+
+ STEP("* 8. Using REST API, check that u2 and u3 requests to join the moderated site are added to site membership request list");
+ restAPI.authenticateUser(testUser1).withCoreAPI()
+ .usingSite(testSiteModerated).getSiteMembers()
+ .assertThat().entriesListDoesNotContain("id", testUser2.getUsername())
+ .and().entriesListDoesNotContain("id", testUser3.getUsername());
+
+ restAPI.withCoreAPI()
+ .usingUser(testUser2).getSiteMembershipRequest(testSiteModerated)
+ .assertThat().field("id").is(testSiteModerated.getId());
+
+ restAPI.withCoreAPI()
+ .usingUser(testUser3).getSiteMembershipRequest(testSiteModerated)
+ .assertThat().field("id").is(testSiteModerated.getId());
+
+ STEP("* 9. Using REST API, U1 cancels the request for U3");
+ restAPI.withCoreAPI().usingUser(testUser3).deleteSiteMembershipRequest(testSiteModerated);
+
+ STEP("* 10. Using REST API, check that u2 can't make requests to join the private site.");
+ restAPI.authenticateUser(testUser2).withCoreAPI()
+ .usingAuthUser().addSiteMembershipRequest(testSitePrivate);
+ restAPI.assertStatusCodeIs(HttpStatus.NOT_FOUND);
+
+ STEP("* 11. Using REST API, check that only u2 request remains in site membership request list");
+ restAPI.withCoreAPI()
+ .usingAuthUser().getSiteMembershipRequests()
+ .assertThat().entriesListContains("id", testSiteModerated.getId())
+ .and().paginationField("totalItems").is("1");
+
+ restAPI.authenticateUser(testUser3).withCoreAPI()
+ .usingAuthUser().getSiteMembershipRequests()
+ .assertThat().entriesListIsEmpty();
+
+ STEP("* 12. Using REST API, U1 change U2 role to Collaborator in public site");
+ testUser2.setUserRole(UserRole.SiteCollaborator);
+ restAPI.authenticateUser(testUser1).withCoreAPI()
+ .usingSite(testSitePublic).updateSiteMember(testUser2)
+ .assertThat().field("role").is(testUser2.getUserRole());
+
+ STEP("* 13. Using REST API, get site membership information for each user");
+ restAPI.withCoreAPI()
+ .usingAuthUser().getSitesMembershipInformation()
+ .assertThat().paginationField("count").is("3");
+ restAPI.withCoreAPI()
+ .usingUser(testUser2).getSitesMembershipInformation()
+ .assertThat().entriesListContains("id", testSitePublic.getId()).and()
+ .entriesListContains("role", "SiteCollaborator").and().paginationField("count").is("1");
+ restAPI.withCoreAPI()
+ .usingUser(testUser3).getSitesMembershipInformation()
+ .assertThat().entriesListContains("id", testSitePublic.getId()).and()
+ .entriesListContains("role", "SiteConsumer").and().paginationField("count").is("1");
+ }
+
+ /**
+ * Scenario 7
+ * 1. Using CMIS create 1 test user: u1
+ * 2. Using CMIS U1 creates a public site, a moderated test site and a private test site
+ * 3. Using WEBDAV, U1 adds file1 to site1
+ * 4. Using REST API, check the u1 favorites sites list
+ * 5. Using REST API, U1 removes site1 from favorites
+ * 6. Using REST API, check the u1 favorites sites list
+ * 7. Using CMIS, U1 deletes site2
+ * 8. Using REST API, check the u1 favorites sites list
+ * 9. Using REST API, U1 marks site1 as favorite
+ * 10. Using REST API, check the u1 favorites sites list
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.SANITY })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.SITES, TestGroup.FAVORITES }, executionType = ExecutionType.SANITY,
+ description = "Verify users are able to manage favorite sites.")
+ public void userIsAbleToManageFavoriteSites() throws Exception
+ {
+ STEP("* 1. Using CMIS create a test user: u1");
+ testUser1 = dataUser.createRandomTestUser();
+
+ STEP("* 2. Using CMIS U1 creates a public site, a moderated test site and a private test site");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+ testSiteModerated = dataSite.usingUser(testUser1).createModeratedRandomSite();
+ testSitePrivate = dataSite.usingUser(testUser1).createPrivateRandomSite();
+
+ STEP("* 3. Using WEBDAV, U1 adds file1 to site1");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ webDavProtocol.authenticateUser(testUser1).usingSite(testSitePublic).createFile(testFile1).assertThat().existsInRepo();
+
+ STEP("* 4. Using REST API, check the u1 favorites sites list");
+ restAPI.authenticateUser(testUser1)
+ .withCoreAPI().usingAuthUser().where().targetSiteExist().getFavorites().assertThat()
+ .entriesListContains("targetGuid", testSitePublic.getGuid()).and()
+ .entriesListContains("targetGuid", testSiteModerated.getGuid()).and()
+ .entriesListContains("targetGuid", testSitePrivate.getGuid()).and()
+ .paginationField("totalItems").is("3");
+
+ STEP("* 5. Using REST API, U1 removes site1 from favorites");
+ restAPI.withCoreAPI().usingAuthUser().deleteSiteFromFavorites(testSitePublic);
+
+ STEP("* 6. Using REST API, check the u1 favorites sites list");
+ restAPI.withCoreAPI().usingAuthUser()
+ .where().targetSiteExist().getFavorites().assertThat()
+ .entriesListContains("targetGuid", testSiteModerated.getGuid()).and()
+ .entriesListContains("targetGuid", testSitePrivate.getGuid()).and()
+ .paginationField("totalItems").is("2");
+
+ STEP("* 7. Using CMIS, U1 deletes site2");
+ dataSite.usingUser(testUser1).deleteSite(testSiteModerated);
+
+ STEP("* 8. Using REST API, check the u1 favorites sites list");
+ restAPI.withCoreAPI().usingAuthUser()
+ .where().targetSiteExist().getFavorites().assertThat()
+ .entriesListContains("targetGuid", testSitePrivate.getGuid()).and()
+ .paginationField("totalItems").is("1");
+
+ STEP("* 9. Using REST API, U1 marks site1 as favorite");
+ restAPI.withCoreAPI().usingAuthUser().addSiteToFavorites(testSitePublic)
+ .assertThat().field("targetGuid").is(testSitePublic.getGuid());
+
+ STEP("* 10. Using REST API, check the u1 favorites sites list");
+ restAPI.withCoreAPI().usingAuthUser().where().targetSiteExist().getFavorites().assertThat()
+ .entriesListContains("targetGuid", testSitePublic.getGuid()).and()
+ .entriesListContains("targetGuid", testSitePrivate.getGuid()).and()
+ .paginationField("totalItems").is("2");
+ }
+
+ /**
+ * Scenario 10
+ * 1. Using CMIS create 3 test user: u1, u2, u3
+ * 2. Using CMIS U1 creates a a moderated test site
+ * 3. Using REST API, U2 request to join the moderated site
+ * 4. Using REST API, U3 request to join the moderated site
+ * 5. Using REST API, check that u2 and u3 requests to join the moderated site are added to site membership request list
+ * 6. Using REST API, U1 cancels the request for U3
+ * 7. Using REST API, check that only u2 request remains in site membership request list
+ * 8. Using REST API, U1 cancels the request for U2
+ * 9. Using REST API, verify that there is no request to join left in the site membership request list.
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.SANITY })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.SITES }, executionType = ExecutionType.SANITY,
+ description = "Verify site manager is able to cancel requests to join moderated site.")
+ public void siteManagerIsAbleToCancelSiteMembership() throws Exception
+ {
+ STEP("* 1. Using CMIS create 3 test user: u1, u2, u3");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+ testUser3 = dataUser.createRandomTestUser();
+
+ STEP("* 2. Using CMIS U1 creates a a moderated test site");
+ testSiteModerated = dataSite.usingUser(testUser1).createModeratedRandomSite();
+
+ STEP("* 3. Using REST API, U2 request to join the moderated site");
+ restAPI.authenticateUser(testUser2).withCoreAPI()
+ .usingAuthUser().addSiteMembershipRequest(testSiteModerated);
+
+ STEP("* 4. Using REST API, U3 request to join the moderated site");
+ restAPI.authenticateUser(testUser3).withCoreAPI()
+ .usingAuthUser().addSiteMembershipRequest(testSiteModerated);
+
+ STEP("* 5. Using REST API, check that u2 and u3 requests to join the moderated site are added to site membership request list");
+ restAPI.authenticateUser(testUser1).withCoreAPI()
+ .usingUser(testUser2).getSiteMembershipRequest(testSiteModerated)
+ .assertThat().field("id").is(testSiteModerated.getId());
+ restAPI.withCoreAPI()
+ .usingUser(testUser3).getSiteMembershipRequest(testSiteModerated)
+ .assertThat().field("id").is(testSiteModerated.getId());
+
+ STEP("* 6. Using REST API, U1 cancels the request for U3");
+ restAPI.withCoreAPI()
+ .usingUser(testUser3).deleteSiteMembershipRequest(testSiteModerated);
+
+ STEP("* 7. Using REST API, check that u3 request isn't in site membership request list");
+ restAPI.withCoreAPI()
+ .usingUser(testUser3).getSiteMembershipRequest(testSiteModerated);
+ restAPI.assertStatusCodeIs(HttpStatus.NOT_FOUND).assertLastError()
+ .containsSummary(String.format(RestErrorModel.ENTITY_NOT_FOUND, "The relationship resource"))
+ .containsSummary(testUser3.getUsername());
+
+ STEP("* 8. Using REST API, U1 cancels the request for U2");
+ restAPI.withCoreAPI()
+ .usingUser(testUser2).deleteSiteMembershipRequest(testSiteModerated);
+
+ STEP("* 9. Using REST API, check that u2 request isn't in site membership request list.");
+ restAPI.withCoreAPI()
+ .usingUser(testUser2).getSiteMembershipRequest(testSiteModerated);
+ restAPI.assertStatusCodeIs(HttpStatus.NOT_FOUND).assertLastError()
+ .containsSummary(String.format(RestErrorModel.ENTITY_NOT_FOUND, "The relationship resource"))
+ .containsSummary(testUser2.getUsername());
+ }
+
+ /**
+ * Scenario 11
+ * 1. Using CMIS create 2 test user: u1, u2
+ * 2. Using CMIS U1 creates 3 test sites
+ * 3. Using CMIS U1 adds U2 to site1 with "Consumer" role
+ * 4. Using CMIS U1 adds U2 to site2 with "Collaborator" role
+ * 5. Using REST API, admin adds U2 to site3 with "Manager" role
+ * 6. Using REST API, verify that site1, site2, site3 are present in the list of sites for U2
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.SANITY })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.SITES }, executionType = ExecutionType.SANITY,
+ description = "Verify user is able to get site membership informations.")
+ public void userIsAbleToGetSiteMembershipInfo() throws Exception
+ {
+ STEP("* 1. Using CMIS create 2 test user: u1, u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("* 2. Using CMIS U1 creates 3 test sites");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+ testSiteModerated = dataSite.usingUser(testUser1).createModeratedRandomSite();
+ testSitePrivate = dataSite.usingUser(testUser1).createPrivateRandomSite();
+
+ STEP("* 3. Using CMIS U1 adds U2 to site1 with \"Consumer\" role");
+ dataUser.usingUser(testUser1).addUserToSite(testUser2, testSitePublic, UserRole.SiteConsumer);
+
+ STEP("* 4. Using CMIS U1 adds U2 to site2 with \"Collaborator\" role");
+ dataUser.usingUser(testUser1).addUserToSite(testUser2, testSiteModerated, UserRole.SiteCollaborator);
+
+ STEP("* 5. Using REST API, admin adds U2 to site3 with \"Manager\" role");
+ testUser2.setUserRole(UserRole.SiteManager);
+ restAPI.authenticateUser(dataUser.getAdminUser()).withCoreAPI()
+ .usingSite(testSitePrivate).addPerson(testUser2);
+
+ STEP("* 6. Using REST API, verify that site1, site2, site3 are present in the list of sites for U2");
+ restAPI.withCoreAPI()
+ .usingUser(testUser2).getSitesMembershipInformation()
+ .assertThat().entriesListContains("id", testSitePublic.getId())
+ .and().entriesListContains("id", testSiteModerated.getId())
+ .and().entriesListContains("id", testSitePrivate.getId())
+ .and().paginationField("count").is("3");
+
+ restAPI.withCoreAPI()
+ .usingSite(testSitePublic).getSiteMember(testUser2)
+ .assertThat().field("role").is("SiteConsumer");
+ restAPI.withCoreAPI()
+ .usingSite(testSiteModerated).getSiteMember(testUser2)
+ .assertThat().field("role").is("SiteCollaborator");
+ restAPI.withCoreAPI()
+ .usingSite(testSitePrivate).getSiteMember(testUser2)
+ .assertThat().field("role").is("SiteManager");
+ }
+
+ /**
+ * Scenario 12
+ * 1. Using CMIS create a test user: u1
+ * 2. U1 creates a test site using CMIS
+ * 3. U1 creates a file in site's document library using WebDAV
+ * 4. U1 creates another site using CMIS
+ * 5. U1 creates a folder in site's document library using FTP
+ * 6. U1 copy file to folder using WEBDAV
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.SANITY })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.SANITY,
+ description = "Verify user is able to copy file to a folder from another site.")
+ public void userIsAbleToCopyFileToAFolderFromAnotherSite() throws Exception
+ {
+ STEP("* 1. Using CMIS create a test user: u1");
+ testUser1 = dataUser.createRandomTestUser();
+
+ STEP("* 2. U1 creates a test site using CMIS");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("* 3. U1 creates a file in site's document library using WebDAV");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ webDavProtocol.authenticateUser(testUser1).usingSite(testSitePublic).createFile(testFile1).then().assertThat().existsInRepo();
+
+ STEP("* 4. U1 creates another site using CMIS");
+ secondTestSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("* 5. U1 creates a folder in second site's document library using FTP");
+ testFolder1 = FolderModel.getRandomFolderModel();
+ ftpProtocol.authenticateUser(testUser1).usingSite(secondTestSitePublic).createFolder(testFolder1).then().assertThat().existsInRepo();
+
+ STEP("* 6. U1 copy file to folder using WEBDAV");
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFile1).copyTo(testFolder1).assertThat().existsInRepo();
+ }
+
+ /**
+ * Scenario 13
+ * 1. Using CMIS create a test user: u1
+ * 2. U1 creates a test site using CMIS
+ * 3. U1 creates a file in site's document library using FTP
+ * 4. U1 creates another site using CMIS
+ * 5. U1 creates a folder in site's document library using WebDAV
+ * 6. U1 moves file to folder using FTP
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.SANITY })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.SANITY,
+ description = "Verify user is able to move file to a folder from another site.")
+ public void userIsAbleToMoveFileToAFolderFromAnotherSite() throws Exception
+ {
+ STEP("* 1. Using CMIS create a test user: u1");
+ testUser1 = dataUser.createRandomTestUser();
+
+ STEP("* 2. U1 creates a test site using CMIS");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("* 3. U1 creates a file in site's document library using FTP");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ ftpProtocol.authenticateUser(testUser1).usingSite(testSitePublic).createFile(testFile1).then().assertThat().existsInRepo();
+
+ STEP("* 4. U1 creates another site using CMIS");
+ secondTestSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("* 5. U1 creates a folder in second site's document library using WebDAV");
+ testFolder1 = FolderModel.getRandomFolderModel();
+ webDavProtocol.authenticateUser(testUser1).usingSite(secondTestSitePublic).createFolder(testFolder1).then().assertThat().existsInRepo();
+
+ STEP("* 6. U1 moves file to folder using FTP");
+ ftpProtocol.authenticateUser(testUser1).usingResource(testFile1).moveTo(testFolder1).assertThat().existsInRepo();
+ }
+
+ /**
+ * Scenario 14
+ * 1. Using CMIS create a test user: u1
+ * 2. U1 creates a public test site, a moderated test site and a private test site using CMIS
+ * 3. U1 gets each site with REST API: public, moderated and private sites are listed
+ * 4. U1 deletes moderated site using CMIS
+ * 5. U1 gets each site with REST API: public and private sites are listed
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.SANITY })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.SITES }, executionType = ExecutionType.SANITY,
+ description = "Verify user is able to get created sites with different visibility.")
+ public void userIsAbleToGetSitesWithDifferentVisibility() throws Exception
+ {
+ STEP("* 1. Using CMIS create a test user: u1");
+ testUser1 = dataUser.createRandomTestUser();
+
+ STEP("* 2. U1 creates a public test site, a moderated test site and a private test site using CMIS ");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+ testSiteModerated = dataSite.usingUser(testUser1).createModeratedRandomSite();
+ testSitePrivate = dataSite.usingUser(testUser1).createPrivateRandomSite();
+
+ STEP("* 3. U1 gets each site with REST API: public, moderated and private sites are listed");
+ restAPI.authenticateUser(testUser1);
+
+ List createdSites = new ArrayList();
+ createdSites.add(testSitePublic);
+ createdSites.add(testSiteModerated);
+ createdSites.add(testSitePrivate);
+
+ for(SiteModel site : createdSites)
+ {
+ restAPI.withCoreAPI()
+ .usingSite(site).getSite()
+ .assertThat().field("id").is(site.getId())
+ .and().field("title").is(site.getTitle());
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ }
+
+ STEP("* 4. U1 deletes moderated site using CMIS");
+ dataSite.usingUser(testUser1).deleteSite(testSiteModerated);
+
+ STEP("* 5. U1 gets each site with REST API: public and private sites are listed");
+ restAPI.withParams("maxItems=10000").withCoreAPI().getSites()
+ .assertThat().entriesListContains("id", testSitePublic.getId())
+ .assertThat().entriesListContains("id", testSitePrivate.getId())
+ .assertThat().entriesListDoesNotContain("id", testSiteModerated.getId());
+ }
+
+ /**
+ * Scenario 15
+ * 1. Using CMIS create two users: u1 and u2
+ * 2. U1 creates a public site using CMIS
+ * 3. U1 creates a file in public site's document library using FTP
+ * 4. U2 creates a private site using CMIS
+ * 5. U2 creates a folder in public site's document library using WebDAV
+ * 6. U1 copies the file in private site's document library using WEBDAV
+ * 7. Using WEBDAV, verify that file was not copied
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.SANITY })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.SANITY,
+ description = "Verify uninvited user is not able to copy document to a private site.")
+ public void userIsNotAbleToCopyAFileToAPrivateSite() throws Exception
+ {
+ STEP("* 1. Using CMIS create two users: u1 and u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("* 2. U1 creates a public site using CMIS");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("* 3. U1 creates a file in public site's document library using FTP");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ ftpProtocol.authenticateUser(testUser1).usingSite(testSitePublic).createFile(testFile1).then().assertThat().existsInRepo();
+
+ STEP("* 4. U2 creates a private site using CMIS");
+ testSitePrivate = dataSite.usingUser(testUser2).createPrivateRandomSite();
+
+ STEP("* 5. U2 creates a folder in public site's document library using WebDAV");
+ testFolder1 = FolderModel.getRandomFolderModel();
+ webDavProtocol.authenticateUser(testUser2).usingSite(testSitePrivate).createFolder(testFolder1).then().assertThat().existsInRepo();
+
+ STEP("* 6. U1 copies the file in private site's document library using WEBDAV"
+ + "* 7. Using WEBDAV, verify that file was not copied");
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFile1).copyTo(testFolder1).assertThat().doesNotExistInRepo();
+ }
+
+ /**
+ * Scenario 16
+ * 1. Using CMIS create two users: u1 and u2
+ * 2. U1 creates a public site using CMIS
+ * 3. U1 adds U2 to site with "Consumer" role using CMIS
+ * 4. Using REST API, verify membership information for u2 on public site
+ * 5. Using REST API, U1 change U2 role to Collaborator in public site
+ * 6. Using REST API, verify membership information for u2 on public site
+ * 7. Using REST API, U1 remove U2 from public site
+ * 8. Using REST API, verify that u2 isn't member of u1 public site
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.SANITY })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.SITES }, executionType = ExecutionType.SANITY,
+ description = "Verify user is able to get user membership information.")
+ public void userIsAbleToGetASiteMember() throws Exception
+ {
+ STEP("* 1: Using CMIS create two users: u1 and u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("* 2: U1 creates a public site using CMIS");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("* 3. U1 adds U2 to site with \"Consumer\" role using CMIS");
+ dataUser.usingUser(testUser1).addUserToSite(testUser2, testSitePublic, UserRole.SiteConsumer);
+
+ STEP("* 4. Using REST API, verify membership information for u2 on public site");
+ restAPI.authenticateUser(testUser1).withCoreAPI()
+ .usingSite(testSitePublic).getSiteMember(testUser2)
+ .assertThat().field("role").is("SiteConsumer");
+
+ STEP("* 5. Using REST API, U1 change U2 role to Collaborator in public site");
+ testUser2.setUserRole(UserRole.SiteCollaborator);
+ restAPI.withCoreAPI()
+ .usingSite(testSitePublic).updateSiteMember(testUser2)
+ .assertThat().field("role").is(testUser2.getUserRole());
+
+ STEP("* 6. Using REST API, verify membership information for u2 on public site");
+ restAPI.withCoreAPI()
+ .usingSite(testSitePublic).getSiteMember(testUser2)
+ .assertThat().field("role").is("SiteCollaborator");
+
+ STEP("* 7. Using REST API, U1 remove U2 from public site");
+ restAPI.withCoreAPI()
+ .usingSite(testSitePublic).deleteSiteMember(testUser2);
+ restAPI.assertStatusCodeIs(HttpStatus.NO_CONTENT);
+
+ STEP("* 8. Using REST API, verify that u2 isn't member of u1 public site");
+ restAPI.withCoreAPI()
+ .usingSite(testSitePublic).getSiteMember(testUser2);
+ restAPI.assertStatusCodeIs(HttpStatus.NOT_FOUND)
+ .assertLastError().containsSummary(String.format("The relationship resource was not found for the entity with id: %s and a relationship id of %s", testUser2.getUsername(), testSitePublic.getId()));
+ }
+
+ /**
+ * Scenario 17
+ * 1. Using CMIS create 3 test user: u1, u2, u3
+ * 2. Using CMIS U1 creates a public site
+ * 3. Using CMIS U1 adds U2 to site with "Contributor" role
+ * 4. Using CMIS U1 adds U3 to site with "Collaborator" role
+ * 5. Using REST API, verify the information related to site's containers and members
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.SANITY })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.SITES }, executionType = ExecutionType.SANITY,
+ description = "Verify user is able to get site membership informations.")
+ public void userIsAbleToGetSite() throws Exception
+ {
+ STEP("* 1. Using CMIS create 3 test user: u1, u2, u3");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+ testUser3 = dataUser.createRandomTestUser();
+
+ STEP("* 2. Using CMIS U1 creates a public site");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+
+ STEP("* 3. Using CMIS U1 adds U2 to site with \"Contributor\" role");
+ dataUser.usingUser(testUser1).addUserToSite(testUser2, testSitePublic, UserRole.SiteContributor);
+
+ STEP("* 4. Using CMIS U1 adds U3 to site with \"Collaborator\" role");
+ dataUser.usingUser(testUser1).addUserToSite(testUser3, testSitePublic, UserRole.SiteCollaborator);
+
+ STEP("* 5. Using REST API, verify the information related to site's containers and members");
+ restAPI.authenticateUser(testUser1).withCoreAPI()
+ .usingSite(testSitePublic).getSite()
+ .assertThat().field("visibility").is("PUBLIC")
+ .and().field("id").is(testSitePublic.getId());
+ restAPI.withCoreAPI()
+ .usingSite(testSitePublic).getSiteMembers()
+ .assertThat().paginationField("count").is("3");
+ restAPI.withCoreAPI()
+ .usingSite(testSitePublic).getSiteContainers()
+ .assertThat().entriesListContains("folderId", "documentLibrary")
+ .and().paginationField("totalItems").is("1");
+ }
+
+ /**
+ * Scenario 18
+ * 1. Using CMIS create 2 test users: u1 and u2
+ * 2. U1 creates a public test site and U2 a moderated test site using CMIS
+ * 3. U1 creates a folder with a file in public site's document library using WEBDAV
+ * 4. U2 creates a folder in moderated site's document library using FTP
+ * 5. U1 tries to copy the folder to moderated site using WebDAV
+ * 6. Verify folder is not copied. U1 is not authorized to access the moderated site
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.SANITY })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.SANITY,
+ description = "Verify user is not able to copy folder to a moderated site if it is not a member of that site.")
+ public void copyFolderToModeratedSiteByUninvitedUser() throws Exception
+ {
+ STEP("* 1. Using CMIS create two users: u1 and u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("* 2. U1 creates a public test site and U2 a moderated test site using CMIS");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+ testSiteModerated = dataSite.usingUser(testUser2).createModeratedRandomSite();
+
+ STEP("* 3. U1 creates a folder with a file in public site's document library using WEBDAV");
+ testFolder1 = FolderModel.getRandomFolderModel();
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ webDavProtocol.authenticateUser(testUser1).usingSite(testSitePublic).createFolder(testFolder1).assertThat().existsInWebdav()
+ .then().usingResource(testFolder1).createFile(testFile1).then().assertThat().existsInRepo();
+
+ STEP("* 4. U2 creates a folder in moderated site's document library using FTP");
+ testFolder2 = FolderModel.getRandomFolderModel();
+ ftpProtocol.authenticateUser(testUser2).usingSite(testSiteModerated).createFolder(testFolder2).assertThat().existsInRepo();
+
+ STEP("* 5. U1 tries to copy the folder to moderated site using WebDAV"
+ + "* 6. Verify folder is not copied. U1 is not authorized to access the moderated site");
+ testFolder2.setProtocolLocation(webDavProtocol.getPrefixSpace() + testFolder2.getCmisLocation());
+ webDavProtocol.authenticateUser(testUser1).usingResource(testFolder1).copyTo(testFolder2).assertThat().doesNotExistInRepo()
+ .and().assertThat().doesNotExistInWebdav();
+ }
+
+ /**
+ * Scenario 20
+ * 1. Using CMIS create 2 test users: u1 and u2
+ * 2. U1 creates a public test site and U2 a private test site using CMIS
+ * 3. U1 creates a file in public site's document library using WEBDAV
+ * 4. U2 creates a folder in private site's document library using WebDAV
+ * 5. U1 tries to move his file to folder from U2 private site using IMAP
+ * 6. Verify file is not moved. U1 is not authorized to access the private site
+ */
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.SANITY }, expectedExceptions = MessagingException.class)
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.CONTENT }, executionType = ExecutionType.SANITY,
+ description = "Verify user is not able to move file to a private site if he is not a member of that site.")
+ public void moveFileToPrivateSiteByUninvitedUser() throws Exception
+ {
+ STEP("1. Using CMIS create 2 test users: u1 and u2");
+ testUser1 = dataUser.createRandomTestUser();
+ testUser2 = dataUser.createRandomTestUser();
+
+ STEP("2. U1 creates a public test site and U2 a private test site using CMIS");
+ testSitePublic = dataSite.usingUser(testUser1).createPublicRandomSite();
+ testSitePrivate = dataSite.usingUser(testUser2).createPrivateRandomSite();
+
+ STEP("3. U1 creates a file in public site's document library using WEBDAV");
+ testFile1 = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, "file1 content");
+ webDavProtocol.authenticateUser(testUser1).usingSite(testSitePublic).createFile(testFile1).assertThat().existsInRepo();
+
+ STEP("4. U2 creates a folder in private site's document library using WebDAV");
+ testFolder1 = FolderModel.getRandomFolderModel();
+ webDavProtocol.authenticateUser(testUser2).usingSite(testSitePrivate).createFolder(testFolder1).assertThat().existsInRepo();
+
+ STEP("5. U1 tries to move his file to folder from U2 private site using IMAP. 6. Verify file is not moved. U1 is not authorized to access the private site ");
+ testFolder1.setProtocolLocation(testFolder1.getCmisLocation());
+ imapProtocol.authenticateUser(testUser1).usingResource(testFile1).moveMessageTo(testFolder1).assertThat().doesNotContainMessages(testFile1);
+ }
+}
diff --git a/packaging/tests/tas-integration/src/test/java/org/alfresco/tas/integration/IntegrationTest.java b/packaging/tests/tas-integration/src/test/java/org/alfresco/tas/integration/IntegrationTest.java
new file mode 100644
index 00000000000..4765948b5ac
--- /dev/null
+++ b/packaging/tests/tas-integration/src/test/java/org/alfresco/tas/integration/IntegrationTest.java
@@ -0,0 +1,106 @@
+package org.alfresco.tas.integration;
+
+import java.lang.reflect.Method;
+
+import org.alfresco.cmis.CmisProperties;
+import org.alfresco.cmis.CmisWrapper;
+import org.alfresco.dataprep.WorkflowService;
+import org.alfresco.email.EmailProperties;
+import org.alfresco.email.ImapWrapper;
+import org.alfresco.email.SmtpWrapper;
+import org.alfresco.ftp.FTPWrapper;
+import org.alfresco.rest.core.RestProperties;
+import org.alfresco.rest.core.RestWrapper;
+import org.alfresco.utility.LogFactory;
+import org.alfresco.utility.data.DataContent;
+import org.alfresco.utility.data.DataGroup;
+import org.alfresco.utility.data.DataSite;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.data.DataWorkflow;
+import org.alfresco.utility.extension.ExtentionPointTestUtility;
+import org.alfresco.utility.network.ServerHealth;
+import org.alfresco.webdav.WebDavWrapper;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.BeforeSuite;
+
+@ContextConfiguration("classpath:alfresco-integration-context.xml")
+public abstract class IntegrationTest extends AbstractTestNGSpringContextTests
+{
+ private static Logger LOG = LogFactory.getLogger();
+
+ @Autowired
+ protected DataUser dataUser;
+
+ @Autowired
+ protected DataSite dataSite;
+
+ @Autowired
+ protected DataContent dataContent;
+
+ @Autowired
+ protected DataGroup dataGroup;
+
+ @Autowired
+ protected DataWorkflow dataWorkflow;
+
+ @Autowired
+ protected WorkflowService workflow;
+
+ @Autowired
+ protected FTPWrapper ftpProtocol;
+
+ @Autowired
+ protected WebDavWrapper webDavProtocol;
+
+ @Autowired
+ protected CmisWrapper cmisAPI;
+
+ @Autowired
+ protected CmisProperties cmisProperties;
+
+ @Autowired
+ protected ImapWrapper imapProtocol;
+
+ @Autowired
+ protected RestWrapper restAPI;
+
+ @Autowired
+ protected ServerHealth serverHealth;
+
+ @Autowired
+ protected RestProperties restProperties;
+
+ @Autowired
+ protected ExtentionPointTestUtility extentionPointTestUtility;
+
+ @Autowired
+ protected SmtpWrapper smtpProtocol;
+
+ @Autowired
+ EmailProperties emailProperties;
+
+ @BeforeSuite(alwaysRun = true)
+ public void checkServerHealth() throws Exception
+ {
+ super.springTestContextPrepareTestInstance();
+ serverHealth.assertServerIsOnline();
+ }
+
+ @BeforeMethod(alwaysRun=true)
+ public void showStartTestInfo(Method method)
+ {
+ LOG.info(String.format("*** STARTING Test: [%s] ***",method.getName()));
+ }
+
+ @AfterMethod(alwaysRun=true)
+ public void showEndTestInfo(Method method)
+ {
+ LOG.info(String.format("*** ENDING Test: [%s] ***", method.getName()));
+ }
+
+}
diff --git a/packaging/tests/tas-integration/src/test/java/org/alfresco/tas/integration/IntegrationWithAosTests.java b/packaging/tests/tas-integration/src/test/java/org/alfresco/tas/integration/IntegrationWithAosTests.java
new file mode 100644
index 00000000000..c91e948b288
--- /dev/null
+++ b/packaging/tests/tas-integration/src/test/java/org/alfresco/tas/integration/IntegrationWithAosTests.java
@@ -0,0 +1,88 @@
+package org.alfresco.tas.integration;
+
+import static org.alfresco.utility.report.log.Step.STEP;
+
+import io.restassured.RestAssured;
+import io.restassured.http.ContentType;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.json.JsonObject;
+
+import org.alfresco.rest.core.JsonBodyGenerator;
+import org.alfresco.rest.core.RestRequest;
+import org.alfresco.rest.model.RestHtmlResponse;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.report.Bug;
+import org.alfresco.utility.report.Bug.Status;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.apache.commons.codec.binary.Base64;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.testng.annotations.Test;
+
+/**
+ * @author Catalin Gornea
+ */
+public class IntegrationWithAosTests extends IntegrationTest
+{
+ @Bug(id = "REPO-2096", status = Status.FIXED)
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.AOS, TestGroup.FULL, TestGroup.SSO })
+ @TestRail(section = { TestGroup.INTEGRATION,
+ TestGroup.AOS }, executionType = ExecutionType.REGRESSION, description = "Security check for AOS Protocol with External Authentification - MNT-17474")
+ public void aosCSRFVulnerabilityInSSOEnvironment() throws Exception
+ {
+ STEP("1. Post call using RestAPI for specific AOS Security issue");
+ UserModel adminUser = dataUser.getAdminUser();
+ Map headers = new HashMap();
+ String authCookie = String.format("%s:%s", adminUser.getUsername(), adminUser.getPassword());
+ String authCookieEncoded = new String(Base64.encodeBase64(authCookie.getBytes()));
+ headers.put("Authorization", String.format("Basic %s", authCookieEncoded));
+
+ restAPI.configureRequestSpec().addHeaders(headers);
+ JsonObject postBody = JsonBodyGenerator.defineJSON().add("method", "create url-directories:6.0.2.8164")
+ .add("urldirs", "[[url=ExploitedMNT17474;meta_info=[]]]").build();
+ restAPI.authenticateUser(adminUser).usingContentType(ContentType.URLENC).withAosAPI();
+ RestRequest request = RestRequest.requestWithBody(HttpMethod.POST, postBody.toString(), "_vti_bin/_vti_aut/author.dll");
+ restAPI.process(request);
+ restAPI.assertStatusCodeIs(HttpStatus.BAD_REQUEST);
+ }
+
+ @Bug(id = "REPO-2172", status = Status.FIXED)
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.AOS, TestGroup.FULL, TestGroup.SSO })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.AOS },
+ executionType = ExecutionType.REGRESSION, description = "Non domain user can login to aos through Kerberos successfully.")
+ public void nonDomainKerberosUserCanLoginSuccessfulInAos() throws Exception {
+
+ STEP("1. Perform a GET request of aos using a non-domain kerberos user");
+ String webDavUrl = "alfresco/aos";
+
+ RestAssured.basePath = "";
+ restAPI.configureRequestSpec().setBasePath(RestAssured.basePath);
+ RestRequest request = RestRequest.simpleRequest(HttpMethod.GET, webDavUrl);
+ RestHtmlResponse response = restAPI.authenticateUser(dataUser.getAdminUser()).processHtmlResponse(request);
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ response.assertPathInHtmlBodyEquals("html.body.table.tr[1].td[0].text()", "Shared");
+ response.assertPathInHtmlBodyEquals("html.body.table.tr[2].td[0].text()", "Imap Attachments");
+ }
+
+ @Bug(id = "REPO-2172", status = Status.FIXED)
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.WEBDAV, TestGroup.FULL, TestGroup.SSO })
+ @TestRail(section = { TestGroup.INTEGRATION, TestGroup.WEBDAV },
+ executionType = ExecutionType.REGRESSION, description = "Non domain user can login to webdav through Kerberos successfully.")
+ public void nonDomainKerberosUserCanLoginSuccessfulInWebDav() throws Exception {
+
+ STEP("1. Perform a GET request of webdav using a non-domain kerberos user");
+ String webDavUrl = "alfresco/webdav";
+
+ RestAssured.basePath = "";
+ restAPI.configureRequestSpec().setBasePath(RestAssured.basePath);
+ RestRequest request = RestRequest.simpleRequest(HttpMethod.GET, webDavUrl);
+ RestHtmlResponse response = restAPI.authenticateUser(dataUser.getAdminUser()).processHtmlResponse(request);
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ response.assertPathInHtmlBodyEquals("html.body.table.tr.td[0].text()", "Directory listing for /");
+ response.assertPathInHtmlBodyEquals("html.body.table.tr.td.find{it.@class=='textData'}[0].text()", "Shared");
+ }
+}
diff --git a/packaging/tests/tas-integration/src/test/java/org/alfresco/tas/integration/IntegrationWithCmisTests.java b/packaging/tests/tas-integration/src/test/java/org/alfresco/tas/integration/IntegrationWithCmisTests.java
new file mode 100644
index 00000000000..b3a5be9a8f9
--- /dev/null
+++ b/packaging/tests/tas-integration/src/test/java/org/alfresco/tas/integration/IntegrationWithCmisTests.java
@@ -0,0 +1,189 @@
+package org.alfresco.tas.integration;
+
+import static org.alfresco.utility.report.log.Step.STEP;
+
+import io.restassured.RestAssured;
+import java.util.HashMap;
+
+import org.alfresco.rest.core.JsonBodyGenerator;
+import org.alfresco.rest.core.RestRequest;
+import org.alfresco.rest.core.RestResponse;
+import org.alfresco.rest.model.RestNodeModel;
+import org.alfresco.rest.model.RestRenditionInfoModel;
+import org.alfresco.utility.Utility;
+import org.alfresco.utility.exception.DataPreparationException;
+import org.alfresco.utility.model.FileModel;
+import org.alfresco.utility.model.FileType;
+import org.alfresco.utility.model.FolderModel;
+import org.alfresco.utility.model.SiteModel;
+import org.alfresco.utility.model.TestGroup;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.report.Bug;
+import org.alfresco.utility.testrail.ExecutionType;
+import org.alfresco.utility.testrail.annotation.TestRail;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+
+public class IntegrationWithCmisTests extends IntegrationTest
+{
+ private UserModel user;
+ private SiteModel site;
+
+ @BeforeClass(alwaysRun = true)
+ public void createUserAndSite() throws DataPreparationException
+ {
+ user = dataUser.createRandomTestUser();
+ site = dataSite.usingUser(user).createPublicRandomSite();
+ }
+
+// @Test(groups = { TestGroup.INTEGRATION, TestGroup.CMIS, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION,
+ TestGroup.CMIS }, executionType = ExecutionType.REGRESSION, description = "Verify getChildren action for a large number of files from CMIS returns only unique values with few retries")
+ public void verifyGetChildrenReturnsUniqueValues() throws Exception
+ {
+ STEP("1. Create user, site, folder.");
+ FolderModel folder = FolderModel.getRandomFolderModel();
+ folder = dataContent.usingUser(user).usingSite(site).createFolder(folder);
+
+ STEP("2. Create 5000 files in folder using webscript");
+ int totalFiles = 5000;
+ String fileCreationWebScript = "alfresco/s/api/model/filefolder/load";
+ HashMap input = new HashMap();
+ input.put("folderPath", folder.getCmisLocation());
+ input.put("fileCount", String.valueOf(totalFiles));
+ String postBody = JsonBodyGenerator.keyValueJson(input);
+
+ RestAssured.basePath = "";
+ restAPI.configureRequestSpec().setBasePath(RestAssured.basePath);
+ RestRequest request = RestRequest.requestWithBody(HttpMethod.POST, postBody, fileCreationWebScript);
+ RestResponse response = restAPI.authenticateUser(user).process(request);
+ Assert.assertEquals(response.getResponse().getStatusCode(), HttpStatus.OK.value());
+
+ STEP("3. Verify getChildren from CMIS returns unique values");
+ cmisAPI.authenticateUser(user).usingSite(site).usingResource(folder);
+ for (int i = 1; i <= 20; i++)
+ {
+ System.out.println(String.format("Try no: %d", i));
+ cmisAPI.usingResource(folder).assertThat().hasUniqueChildren(totalFiles);
+ }
+ }
+
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.CMIS, TestGroup.CORE })
+ @TestRail(section = { TestGroup.INTEGRATION,
+ TestGroup.CMIS }, executionType = ExecutionType.REGRESSION, description = "Verify content and thumbnail of TIF files are retrieved by CMIS ")
+ @Bug(id = "REPO-2042", description = "Should fail only on MAC OS System and Linux")
+ public void verifyContentAndThumbnailForTifFile() throws Exception
+ {
+ STEP("1. Create user, site and a folder ");
+ FolderModel folder = FolderModel.getRandomFolderModel();
+ folder = dataContent.usingUser(user).usingSite(site).createFolder(folder);
+
+ STEP("2. Upload existing TIF file using RESTAPI");
+ restAPI.authenticateUser(user).configureRequestSpec().addMultiPart("filedata", Utility.getResourceTestDataFile("my-file.tif"));
+
+ RestNodeModel fileNode = restAPI.authenticateUser(user).withCoreAPI().usingNode(folder).createNode();
+ restAPI.assertStatusCodeIs(HttpStatus.CREATED);
+ FileModel file = new FileModel("my-file.tif");
+ file.setCmisLocation(folder.getCmisLocation() + "/my-file.tif");
+ file.setNodeRef(fileNode.getId());
+
+ STEP("3. Create thumbnail and content of TIF files using file");
+ restAPI.withCoreAPI().usingNode(file).createNodeRendition("pdf");
+ restAPI.assertStatusCodeIs(HttpStatus.ACCEPTED);
+ restAPI.withCoreAPI().usingNode(file).createNodeRendition("doclib");
+ restAPI.assertStatusCodeIs(HttpStatus.ACCEPTED);
+
+ STEP("4. Verify thumbnail and content of TIF files are created using RESTAPI");
+ cmisAPI.authenticateUser(user).usingSite(site).usingResource(folder).usingResource(file).assertThat().contentContains("Adobe Photoshop CC 2015");
+ RestRenditionInfoModel renditionInfo = restAPI.withCoreAPI().usingNode(file).getNodeRendition("pdf");
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ renditionInfo.assertThat().field("status").is("CREATED");
+ renditionInfo = restAPI.withCoreAPI().usingNode(file).getNodeRendition("doclib");
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ renditionInfo.assertThat().field("status").is("CREATED");
+ }
+
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.CMIS, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION,
+ TestGroup.CMIS }, executionType = ExecutionType.REGRESSION, description = "Verify getChildren action for a large number of files from CMIS returns only unique values with few retries")
+ public void verifyContentDispositionForContentThatAreWhiteListed() throws Exception
+ {
+
+ STEP("1. Create a .pdf and a .html file in the Shared folder in CMIS");
+ FolderModel sharedFolder = FolderModel.getSharedFolderModel();
+ FileModel pdfFile = FileModel.getRandomFileModel(FileType.PDF);
+ FileModel htmlFile = FileModel.getRandomFileModel(FileType.HTML);
+
+ STEP("2. Upload the .pdf file and verify the reponse header adding the download=inline/attachement parameters (accepted both).");
+ cmisAPI.authenticateUser(user).usingResource(sharedFolder).createFile(pdfFile);
+
+ RestResponse response = restAPI.authenticateUser(user).withCMISApi().getRootObjectByLocation(pdfFile);
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ response.assertThat().header("Content-Disposition", String.format("inline; filename=%s", pdfFile.getName()));
+
+ response = restAPI.authenticateUser(user).withCMISApi().usingParams("download=inline").getRootObjectByLocation(pdfFile);
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ response.assertThat().header("Content-Disposition", String.format("inline; filename=%s", pdfFile.getName()));
+
+ response = restAPI.authenticateUser(user).withCMISApi().usingParams("download=attachment").getRootObjectByLocation(pdfFile);
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ response.assertThat().header("Content-Disposition", String.format("attachment; filename=%s", pdfFile.getName()));
+
+ STEP("3. Upload the .html file and verify the reponse header adding the download=inline/attachement parameters (accepted only attachment) .");
+ cmisAPI.usingResource(sharedFolder).createFile(htmlFile);
+
+ response = restAPI.authenticateUser(user).withCMISApi().getRootObjectByLocation(htmlFile);
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ response.assertThat().header("Content-Disposition", String.format("attachment; filename=%s", htmlFile.getName()));
+
+ response = restAPI.authenticateUser(user).withCMISApi().usingParams("download=attachment").getRootObjectByLocation(htmlFile);
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ response.assertThat().header("Content-Disposition", String.format("attachment; filename=%s", htmlFile.getName()));
+
+ response = restAPI.authenticateUser(user).withCMISApi().usingParams("download=inline").getRootObjectByLocation(htmlFile);
+ restAPI.assertStatusCodeIs(HttpStatus.OK);
+ response.assertThat().header("Content-Disposition", String.format("attachment; filename=%s", htmlFile.getName()));
+ }
+
+ @Test(groups = { TestGroup.INTEGRATION, TestGroup.CMIS, TestGroup.FULL })
+ @TestRail(section = { TestGroup.INTEGRATION,
+ TestGroup.CMIS }, executionType = ExecutionType.SANITY, description = "Verify that alfresco returns the correct encoding for files created via CMIS.")
+ public void verifyFileEncodingUsingCMIS() throws Exception
+ {
+ STEP("1. Create a folder, two text file with specific encoding content and define the expected encoding.");
+ FileModel utf8File = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, " ∮ E⋅da = Q");
+ FileModel iso8859File = FileModel.getRandomFileModel(FileType.TEXT_PLAIN,
+ "aegif Mind Share Leader Generating New Paradigms by aegif corporation Test html